#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Config/config.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include <algorithm>
#include <cstring>
#include <system_error>
+
+#if HAVE_CXXABI_H
+#include <cxxabi.h>
+#endif
+
using namespace llvm;
using namespace object;
const char *class_name;
const char *selector_name;
char *method;
- BindTable *BindTable;
+ char *demangled_name;
+ BindTable *bindtable;
};
// SymbolizerGetOpInfo() is the operand information call back function.
const char *symbol_name = get_symbol_64(offset, S, info, n_value);
if (symbol_name == nullptr)
return nullptr;
- const char *class_name = rindex(symbol_name, '$');
+ const char *class_name = strrchr(symbol_name, '$');
if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
return class_name + 2;
else
const char *name = get_dyld_bind_info_symbolname(ReferenceValue, info);
if (name != nullptr) {
*ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
- const char *class_name = rindex(name, '$');
+ const char *class_name = strrchr(name, '$');
if (class_name != nullptr && class_name[1] == '_' &&
class_name[2] != '\0') {
info->class_name = class_name + 2;
// Out type and the ReferenceName will also be set which is added as a comment
// to the disassembled instruction.
//
-// TODO: If the symbol name is a C++ mangled name then the demangled name is
+#if HAVE_CXXABI_H
+// If the symbol name is a C++ mangled name then the demangled name is
// returned through ReferenceName and ReferenceType is set to
// LLVMDisassembler_ReferenceType_DeMangled_Name .
+#endif
//
// When this is called to get a symbol name for a branch target then the
// ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
}
const char *SymbolName = nullptr;
- if (ReferenceValue != 0xffffffffffffffffLLU &&
- ReferenceValue != 0xfffffffffffffffeLLU) {
+ if (ReferenceValue != 0xffffffffffffffffULL &&
+ ReferenceValue != 0xfffffffffffffffeULL) {
StringRef name = info->AddrMap->lookup(ReferenceValue);
if (!name.empty())
SymbolName = name.data();
if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
*ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
- if (*ReferenceName) {
+ if (*ReferenceName != nullptr) {
method_reference(info, ReferenceType, ReferenceName);
if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
*ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
} else
- // TODO: if SymbolName is not nullptr see if it is a C++ name
- // and demangle it.
+#if HAVE_CXXABI_H
+ if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
+ if (info->demangled_name != nullptr)
+ free(info->demangled_name);
+ int status;
+ info->demangled_name = abi::__cxa_demangle(SymbolName + 1, nullptr,
+ nullptr, &status);
+ if (info->demangled_name != nullptr) {
+ *ReferenceName = info->demangled_name;
+ *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
+ } else
+ *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
+ } else
+#endif
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
} else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
*ReferenceName =
else
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
}
- // TODO: if SymbolName is not nullptr see if it is a C++ name
- // and demangle it.
+#if HAVE_CXXABI_H
+ else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
+ if (info->demangled_name != nullptr)
+ free(info->demangled_name);
+ int status;
+ info->demangled_name = abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr,
+ &status);
+ if (info->demangled_name != nullptr) {
+ *ReferenceName = info->demangled_name;
+ *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
+ }
+ }
+#endif
else {
*ReferenceName = nullptr;
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
SymbolizerInfo.class_name = nullptr;
SymbolizerInfo.selector_name = nullptr;
SymbolizerInfo.method = nullptr;
- SymbolizerInfo.BindTable = nullptr;
+ SymbolizerInfo.demangled_name = nullptr;
+ SymbolizerInfo.bindtable = nullptr;
// Disassemble symbol by symbol.
for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
}
if (SymbolizerInfo.method != nullptr)
free(SymbolizerInfo.method);
- if (SymbolizerInfo.BindTable != nullptr)
- delete SymbolizerInfo.BindTable;
+ if (SymbolizerInfo.demangled_name != nullptr)
+ free(SymbolizerInfo.demangled_name);
+ if (SymbolizerInfo.bindtable != nullptr)
+ delete SymbolizerInfo.bindtable;
}
}
// name is returned. If not nullptr is returned.
static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
struct DisassembleInfo *info) {
- if (info->BindTable == nullptr) {
- info->BindTable = new (BindTable);
+ if (info->bindtable == nullptr) {
+ info->bindtable = new (BindTable);
SegInfo sectionTable(info->O);
for (const llvm::object::MachOBindEntry &Entry : info->O->bindTable()) {
uint32_t SegIndex = Entry.segmentIndex();
StringRef name = Entry.symbolName();
if (!name.empty())
SymbolName = name.data();
- info->BindTable->push_back(std::make_pair(Address, SymbolName));
+ info->bindtable->push_back(std::make_pair(Address, SymbolName));
}
}
- for (bind_table_iterator BI = info->BindTable->begin(),
- BE = info->BindTable->end();
+ for (bind_table_iterator BI = info->bindtable->begin(),
+ BE = info->bindtable->end();
BI != BE; ++BI) {
uint64_t Address = BI->first;
if (ReferenceValue == Address) {