#include "symbol_info.hpp" #include #include "../detect.hpp" #if MIJIN_TARGET_OS == MIJIN_OS_LINUX #if !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif #include #endif #if MIJIN_COMPILER == MIJIN_COMPILER_GCC #include #endif namespace mijin { // // internal defines // // // internal constants // // // internal types // // // internal variables // static thread_local std::unordered_map g_functionNameCache; // // internal functions // // // public functions // const char* lookupFunctionName(const void* function) { auto it = g_functionNameCache.find(function); if (it != g_functionNameCache.end()) { return it->second.c_str(); } #if MIJIN_TARGET_OS == MIJIN_OS_LINUX Dl_info info; dladdr(function, &info); std::string name = demangleCPPIdentifier(info.dli_sname); if (name.empty()) { name = info.dli_sname; } #else std::string name = ""; #endif return g_functionNameCache.emplace(function, std::move(name)).first->second.c_str(); } #if MIJIN_COMPILER == MIJIN_COMPILER_GCC std::string demangleCPPIdentifier(const char* identifier) { char* demangled = abi::__cxa_demangle(identifier, /* output_buffer = */ nullptr, /* length = */ nullptr, /* status = */ nullptr); if (demangled != nullptr) { std::string name = demangled; std::free(demangled); // NOLINT(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc) return name; } return identifier; } #else std::string demangleCPPIdentifier(const char* identifier) { return identifier; } #endif } // namespace mijin