mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
Update llvm-objdump’s Mach-O symbolizer code to print the name of symbol stubs.
So in fully linked images when a call is made through a stub it now gets a comment like the following in the disassembly: callq 0x100000f6c ## symbol stub for: _printf indicating the call is to a symbol stub and which symbol it is for. This is done for branch reference types and seeing if the branch target is in a stub section and if so using the indirect symbol table entry for that stub and using that symbol table entries symbol name. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218546 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -5,3 +5,4 @@ OBJ: 0000000000000008 leaq L_.str(%rip), %rax ## literal pool for: "Hello w
|
|||||||
OBJ: 0000000000000026 callq _printf
|
OBJ: 0000000000000026 callq _printf
|
||||||
|
|
||||||
EXE: 0000000100000f38 leaq 0x4f(%rip), %rax ## literal pool for: "Hello world\n"
|
EXE: 0000000100000f38 leaq 0x4f(%rip), %rax ## literal pool for: "Hello world\n"
|
||||||
|
EXE: 0000000100000f56 callq 0x100000f6c ## symbol stub for: _printf
|
||||||
|
@@ -413,6 +413,94 @@ const char *GuessCstringPointer(uint64_t ReferenceValue,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GuessIndirectSymbol returns the name of the indirect symbol for the
|
||||||
|
// ReferenceValue passed in or nullptr. This is used when ReferenceValue maybe
|
||||||
|
// an address of a symbol stub or a lazy or non-lazy pointer to associate the
|
||||||
|
// symbol name being referenced by the stub or pointer.
|
||||||
|
static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
|
||||||
|
struct DisassembleInfo *info) {
|
||||||
|
uint32_t LoadCommandCount = info->O->getHeader().ncmds;
|
||||||
|
MachOObjectFile::LoadCommandInfo Load = info->O->getFirstLoadCommandInfo();
|
||||||
|
MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
|
||||||
|
MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
|
||||||
|
for (unsigned I = 0;; ++I) {
|
||||||
|
if (Load.C.cmd == MachO::LC_SEGMENT_64) {
|
||||||
|
MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
|
||||||
|
for (unsigned J = 0; J < Seg.nsects; ++J) {
|
||||||
|
MachO::section_64 Sec = info->O->getSection64(Load, J);
|
||||||
|
uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
|
||||||
|
if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
|
||||||
|
section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
|
||||||
|
section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
|
||||||
|
section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
|
||||||
|
section_type == MachO::S_SYMBOL_STUBS) &&
|
||||||
|
ReferenceValue >= Sec.addr &&
|
||||||
|
ReferenceValue < Sec.addr + Sec.size) {
|
||||||
|
uint32_t stride;
|
||||||
|
if (section_type == MachO::S_SYMBOL_STUBS)
|
||||||
|
stride = Sec.reserved2;
|
||||||
|
else
|
||||||
|
stride = 8;
|
||||||
|
if (stride == 0)
|
||||||
|
return nullptr;
|
||||||
|
uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
|
||||||
|
if (index < Dysymtab.nindirectsyms) {
|
||||||
|
uint32_t indirect_symbol =
|
||||||
|
info->O->getIndirectSymbolTableEntry(Dysymtab, index);
|
||||||
|
if (indirect_symbol < Symtab.nsyms) {
|
||||||
|
symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
|
||||||
|
SymbolRef Symbol = *Sym;
|
||||||
|
StringRef SymName;
|
||||||
|
Symbol.getName(SymName);
|
||||||
|
const char *name = SymName.data();
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (Load.C.cmd == MachO::LC_SEGMENT) {
|
||||||
|
MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
|
||||||
|
for (unsigned J = 0; J < Seg.nsects; ++J) {
|
||||||
|
MachO::section Sec = info->O->getSection(Load, J);
|
||||||
|
uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
|
||||||
|
if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
|
||||||
|
section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
|
||||||
|
section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
|
||||||
|
section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
|
||||||
|
section_type == MachO::S_SYMBOL_STUBS) &&
|
||||||
|
ReferenceValue >= Sec.addr &&
|
||||||
|
ReferenceValue < Sec.addr + Sec.size) {
|
||||||
|
uint32_t stride;
|
||||||
|
if (section_type == MachO::S_SYMBOL_STUBS)
|
||||||
|
stride = Sec.reserved2;
|
||||||
|
else
|
||||||
|
stride = 4;
|
||||||
|
if (stride == 0)
|
||||||
|
return nullptr;
|
||||||
|
uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
|
||||||
|
if (index < Dysymtab.nindirectsyms) {
|
||||||
|
uint32_t indirect_symbol =
|
||||||
|
info->O->getIndirectSymbolTableEntry(Dysymtab, index);
|
||||||
|
if (indirect_symbol < Symtab.nsyms) {
|
||||||
|
symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
|
||||||
|
SymbolRef Symbol = *Sym;
|
||||||
|
StringRef SymName;
|
||||||
|
Symbol.getName(SymName);
|
||||||
|
const char *name = SymName.data();
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (I == LoadCommandCount - 1)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
Load = info->O->getNextLoadCommandInfo(Load);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// GuessLiteralPointer returns a string which for the item in the Mach-O file
|
// GuessLiteralPointer returns a string which for the item in the Mach-O file
|
||||||
// for the address passed in as ReferenceValue for printing as a comment with
|
// for the address passed in as ReferenceValue for printing as a comment with
|
||||||
// the instruction and also returns the corresponding type of that item
|
// the instruction and also returns the corresponding type of that item
|
||||||
@@ -531,7 +619,14 @@ const char *SymbolizerSymbolLookUp(void *DisInfo, uint64_t ReferenceValue,
|
|||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
SymbolName = name.data();
|
SymbolName = name.data();
|
||||||
|
|
||||||
if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
|
if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
|
||||||
|
*ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
|
||||||
|
if (*ReferenceName)
|
||||||
|
*ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
|
||||||
|
else
|
||||||
|
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
|
||||||
|
}
|
||||||
|
else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
|
||||||
*ReferenceName = GuessLiteralPointer(ReferenceValue, ReferencePC,
|
*ReferenceName = GuessLiteralPointer(ReferenceValue, ReferencePC,
|
||||||
ReferenceType, info);
|
ReferenceType, info);
|
||||||
if (*ReferenceName == nullptr)
|
if (*ReferenceName == nullptr)
|
||||||
|
Reference in New Issue
Block a user