mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +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:
parent
aeb9ee0261
commit
7118c73867
@ -5,3 +5,4 @@ OBJ: 0000000000000008 leaq L_.str(%rip), %rax ## literal pool for: "Hello w
|
||||
OBJ: 0000000000000026 callq _printf
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
// for the address passed in as ReferenceValue for printing as a comment with
|
||||
// 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())
|
||||
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,
|
||||
ReferenceType, info);
|
||||
if (*ReferenceName == nullptr)
|
||||
|
Loading…
Reference in New Issue
Block a user