88 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			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
 |