mijin2/source/mijin/debug/symbol_info.cpp
2023-05-29 14:51:44 +02:00

88 lines
1.6 KiB
C++

#include "symbol_info.hpp"
#include <unordered_map>
#include "../detect.hpp"
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
#endif
#if MIJIN_COMPILER == MIJIN_COMPILER_GCC
#include <cxxabi.h>
#endif
namespace mijin
{
//
// internal defines
//
//
// internal constants
//
//
// internal types
//
//
// internal variables
//
static thread_local std::unordered_map<const void*, std::string> 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 = "<unknown>";
#endif
return g_functionNameCache.insert({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 "";
}
#else
std::string demangleCPPIdentifier(const char* /* identifier */)
{
return "";
}
#endif
} // namespace mijin