[llvm] 5f2f84a - [llvm-objdump][MachO] Add support for dumping function starts
Alexander Shaposhnikov via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 8 18:44:58 PST 2021
Author: Alexander Shaposhnikov
Date: 2021-03-08T18:44:44-08:00
New Revision: 5f2f84a68a2eb715c818365bbac233dc62af4120
URL: https://github.com/llvm/llvm-project/commit/5f2f84a68a2eb715c818365bbac233dc62af4120
DIFF: https://github.com/llvm/llvm-project/commit/5f2f84a68a2eb715c818365bbac233dc62af4120.diff
LOG: [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
Added:
llvm/test/tools/llvm-objdump/MachO/function-starts.test
Modified:
llvm/docs/CommandGuide/llvm-objdump.rst
llvm/tools/llvm-objdump/MachODump.cpp
llvm/tools/llvm-objdump/MachODump.h
llvm/tools/llvm-objdump/llvm-objdump.cpp
Removed:
################################################################################
diff --git a/llvm/docs/CommandGuide/llvm-objdump.rst b/llvm/docs/CommandGuide/llvm-objdump.rst
index 1ac7a05cbdb0..e92654b654ea 100644
--- a/llvm/docs/CommandGuide/llvm-objdump.rst
+++ b/llvm/docs/CommandGuide/llvm-objdump.rst
@@ -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.
diff --git a/llvm/test/tools/llvm-objdump/MachO/function-starts.test b/llvm/test/tools/llvm-objdump/MachO/function-starts.test
new file mode 100644
index 000000000000..a9cab10d3497
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/MachO/function-starts.test
@@ -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
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 6d18f6006fce..0ee32bc4a284 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -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)
diff --git a/llvm/tools/llvm-objdump/MachODump.h b/llvm/tools/llvm-objdump/MachODump.h
index adf6c3404f79..a4cc7de0860c 100644
--- a/llvm/tools/llvm-objdump/MachODump.h
+++ b/llvm/tools/llvm-objdump/MachODump.h
@@ -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;
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 016f12cc2164..6fccaa694afa 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -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;
}
More information about the llvm-commits
mailing list