mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[llvm-objdump][MachO] Add support for dumping function starts
Add support for dumping function starts for Mach-O binaries. Test plan: make check-all Differential revision: https://reviews.llvm.org/D97027
This commit is contained in:
parent
8d4adfa7a5
commit
97b192e85f
@ -304,6 +304,10 @@ MACH-O ONLY OPTIONS AND COMMANDS
|
||||
|
||||
Display exported symbols.
|
||||
|
||||
.. option:: --function-starts
|
||||
|
||||
Print the function starts table for Mach-O objects.
|
||||
|
||||
.. option:: -g
|
||||
|
||||
Print line information from debug info if available.
|
||||
|
7
test/tools/llvm-objdump/MachO/function-starts.test
Normal file
7
test/tools/llvm-objdump/MachO/function-starts.test
Normal file
@ -0,0 +1,7 @@
|
||||
## This test verifies that llvm-objdump correctly prints function starts data.
|
||||
|
||||
RUN: llvm-objdump --macho --function-starts %p/Inputs/hello.exe.macho-i386 | FileCheck %s --check-prefix=32-BIT
|
||||
32-BIT: 00001f40
|
||||
|
||||
RUN: llvm-objdump --macho --function-starts %p/Inputs/hello.exe.macho-x86_64 | FileCheck %s --check-prefix=64-BIT
|
||||
64-BIT: 0000000100000f30
|
@ -128,6 +128,12 @@ cl::opt<bool> objdump::DataInCode(
|
||||
"Print the data in code table for Mach-O objects (requires --macho)"),
|
||||
cl::cat(MachOCat));
|
||||
|
||||
cl::opt<bool>
|
||||
objdump::FunctionStarts("function-starts",
|
||||
cl::desc("Print the function starts table for "
|
||||
"Mach-O objects (requires --macho)"),
|
||||
cl::cat(MachOCat));
|
||||
|
||||
cl::opt<bool>
|
||||
objdump::LinkOptHints("link-opt-hints",
|
||||
cl::desc("Print the linker optimization hints for "
|
||||
@ -1103,6 +1109,43 @@ static void PrintRelocations(const MachOObjectFile *O, const bool verbose) {
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintFunctionStarts(MachOObjectFile *O) {
|
||||
uint64_t BaseSegmentAddress = 0;
|
||||
for (const MachOObjectFile::LoadCommandInfo &Command : O->load_commands()) {
|
||||
if (Command.C.cmd == MachO::LC_SEGMENT) {
|
||||
MachO::segment_command SLC = O->getSegmentLoadCommand(Command);
|
||||
if (StringRef(SLC.segname) == "__TEXT") {
|
||||
BaseSegmentAddress = SLC.vmaddr;
|
||||
break;
|
||||
}
|
||||
} else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
|
||||
MachO::segment_command_64 SLC = O->getSegment64LoadCommand(Command);
|
||||
if (StringRef(SLC.segname) == "__TEXT") {
|
||||
BaseSegmentAddress = SLC.vmaddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SmallVector<uint64_t, 8> FunctionStarts;
|
||||
for (const MachOObjectFile::LoadCommandInfo &LC : O->load_commands()) {
|
||||
if (LC.C.cmd == MachO::LC_FUNCTION_STARTS) {
|
||||
MachO::linkedit_data_command FunctionStartsLC =
|
||||
O->getLinkeditDataLoadCommand(LC);
|
||||
O->ReadULEB128s(FunctionStartsLC.dataoff, FunctionStarts);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint64_t S : FunctionStarts) {
|
||||
uint64_t Addr = BaseSegmentAddress + S;
|
||||
if (O->is64Bit())
|
||||
outs() << format("%016" PRIx64, Addr) << "\n";
|
||||
else
|
||||
outs() << format("%08" PRIx32, static_cast<uint32_t>(Addr)) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintDataInCodeTable(MachOObjectFile *O, bool verbose) {
|
||||
MachO::linkedit_data_command DIC = O->getDataInCodeLoadCommand();
|
||||
uint32_t nentries = DIC.datasize / sizeof(struct MachO::data_in_code_entry);
|
||||
@ -1910,8 +1953,8 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
|
||||
// UniversalHeaders or ArchiveHeaders.
|
||||
if (Disassemble || Relocations || PrivateHeaders || ExportsTrie || Rebase ||
|
||||
Bind || SymbolTable || LazyBind || WeakBind || IndirectSymbols ||
|
||||
DataInCode || LinkOptHints || DylibsUsed || DylibId || ObjcMetaData ||
|
||||
(!FilterSections.empty())) {
|
||||
DataInCode || FunctionStarts || LinkOptHints || DylibsUsed || DylibId ||
|
||||
ObjcMetaData || (!FilterSections.empty())) {
|
||||
if (!NoLeadingHeaders) {
|
||||
outs() << Name;
|
||||
if (!ArchiveMemberName.empty())
|
||||
@ -1966,6 +2009,8 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
|
||||
PrintIndirectSymbols(MachOOF, !NonVerbose);
|
||||
if (DataInCode)
|
||||
PrintDataInCodeTable(MachOOF, !NonVerbose);
|
||||
if (FunctionStarts)
|
||||
PrintFunctionStarts(MachOOF);
|
||||
if (LinkOptHints)
|
||||
PrintLinkOptHints(MachOOF);
|
||||
if (Relocations)
|
||||
|
@ -34,6 +34,7 @@ extern cl::opt<bool> DylibsUsed;
|
||||
extern cl::opt<bool> DylibId;
|
||||
extern cl::opt<bool> ExportsTrie;
|
||||
extern cl::opt<bool> FirstPrivateHeader;
|
||||
extern cl::opt<bool> FunctionStarts;
|
||||
extern cl::opt<bool> IndirectSymbols;
|
||||
extern cl::opt<bool> InfoPlist;
|
||||
extern cl::opt<bool> LazyBind;
|
||||
|
@ -2994,9 +2994,9 @@ int main(int argc, char **argv) {
|
||||
!DynamicSymbolTable && !UnwindInfo && !FaultMapSection &&
|
||||
!(MachOOpt &&
|
||||
(Bind || DataInCode || DylibId || DylibsUsed || ExportsTrie ||
|
||||
FirstPrivateHeader || IndirectSymbols || InfoPlist || LazyBind ||
|
||||
LinkOptHints || ObjcMetaData || Rebase || UniversalHeaders ||
|
||||
WeakBind || !FilterSections.empty()))) {
|
||||
FirstPrivateHeader || FunctionStarts || IndirectSymbols || InfoPlist ||
|
||||
LazyBind || LinkOptHints || ObjcMetaData || Rebase ||
|
||||
UniversalHeaders || WeakBind || !FilterSections.empty()))) {
|
||||
cl::PrintHelpMessage();
|
||||
return 2;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user