[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