For llvm-objdump and Mach-O files, fix the printing of module init and
authorKevin Enderby <enderby@apple.com>
Tue, 20 Mar 2018 20:29:52 +0000 (20:29 +0000)
committerKevin Enderby <enderby@apple.com>
Tue, 20 Mar 2018 20:29:52 +0000 (20:29 +0000)
term sections from .o files to look to see if the pointers have a relocation
entry and if so print the symbol name from the relocation entry.  If not fall
back to the existing code and use the pointer value to look up that value
in the symbol table.

rdar://38337506

llvm-svn: 328037

llvm/test/tools/llvm-objdump/X86/Inputs/objModInit.macho-x86_64 [new file with mode: 0644]
llvm/test/tools/llvm-objdump/X86/macho-section.test
llvm/tools/llvm-objdump/MachODump.cpp

diff --git a/llvm/test/tools/llvm-objdump/X86/Inputs/objModInit.macho-x86_64 b/llvm/test/tools/llvm-objdump/X86/Inputs/objModInit.macho-x86_64
new file mode 100644 (file)
index 0000000..52dd9ca
Binary files /dev/null and b/llvm/test/tools/llvm-objdump/X86/Inputs/objModInit.macho-x86_64 differ
index e4d7857f1414d02dabf7045971028eb9019301e3..a8eaa49d88de3e51e267087d80334175b79b3baf 100644 (file)
@@ -1,8 +1,12 @@
 // RUN: llvm-objdump -m -section __DATA,__mod_init_func %p/Inputs/dylibModInit.macho-x86_64 | FileCheck %s -check-prefix=MODINIT
 // RUN: llvm-objdump -m -section __DATA,__mod_init_func -non-verbose %p/Inputs/dylibModInit.macho-x86_64 | FileCheck %s -check-prefix=NON_VERBOSE
+// RUN: llvm-objdump -m -section __DATA,__mod_init_func %p/Inputs/objModInit.macho-x86_64 | FileCheck %s -check-prefix=OBJ_MODINIT
 
 MODINIT: Contents of (__DATA,__mod_init_func) section
 MODINIT: 0x0000000000001000 0x0000000000000f30 _libinit
 
 NON_VERBOSE: Contents of (__DATA,__mod_init_func) section
 NON_VERBOSE: 0000000000001000  30 0f 00 00 00 00 00 00 
+
+OBJ_MODINIT: Contents of (__DATA,__mod_init_func) section
+OBJ_MODINIT: 0x0000000000000018 0x0000000000000000 _constructor_func
index c5aba86b20e100a04d8403a05477213565a0be6e..69e95b4a29e751db2a2156de1e8f38efcdbeb0f0 100644 (file)
@@ -1284,14 +1284,35 @@ static void DumpLiteralPointerSection(MachOObjectFile *O,
   }
 }
 
-static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect,
+static void DumpInitTermPointerSection(MachOObjectFile *O,
+                                       const SectionRef &Section,
+                                       const char *sect,
                                        uint32_t sect_size, uint64_t sect_addr,
                                        SymbolAddressMap *AddrMap,
                                        bool verbose) {
   uint32_t stride;
   stride = (O->is64Bit()) ? sizeof(uint64_t) : sizeof(uint32_t);
+
+  // Collect the external relocation symbols for the pointers.
+  std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
+  for (const RelocationRef &Reloc : Section.relocations()) {
+    DataRefImpl Rel;
+    MachO::any_relocation_info RE;
+    bool isExtern = false;
+    Rel = Reloc.getRawDataRefImpl();
+    RE = O->getRelocation(Rel);
+    isExtern = O->getPlainRelocationExternal(RE);
+    if (isExtern) {
+      uint64_t RelocOffset = Reloc.getOffset();
+      symbol_iterator RelocSym = Reloc.getSymbol();
+      Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
+    }
+  }
+  array_pod_sort(Relocs.begin(), Relocs.end());
+
   for (uint32_t i = 0; i < sect_size; i += stride) {
     const char *SymbolName = nullptr;
+    uint64_t p;
     if (O->is64Bit()) {
       outs() << format("0x%016" PRIx64, sect_addr + i * stride) << " ";
       uint64_t pointer_value;
@@ -1299,8 +1320,7 @@ static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect,
       if (O->isLittleEndian() != sys::IsLittleEndianHost)
         sys::swapByteOrder(pointer_value);
       outs() << format("0x%016" PRIx64, pointer_value);
-      if (verbose)
-        SymbolName = GuessSymbolName(pointer_value, AddrMap);
+      p = pointer_value;
     } else {
       outs() << format("0x%08" PRIx64, sect_addr + i * stride) << " ";
       uint32_t pointer_value;
@@ -1308,11 +1328,25 @@ static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect,
       if (O->isLittleEndian() != sys::IsLittleEndianHost)
         sys::swapByteOrder(pointer_value);
       outs() << format("0x%08" PRIx32, pointer_value);
-      if (verbose)
-        SymbolName = GuessSymbolName(pointer_value, AddrMap);
+      p = pointer_value;
+    }
+    if (verbose) {
+      // First look for an external relocation entry for this pointer.
+      auto Reloc = find_if(Relocs, [&](const std::pair<uint64_t, SymbolRef> &P) {
+        return P.first == i;
+      });
+      if (Reloc != Relocs.end()) {
+        symbol_iterator RelocSym = Reloc->second;
+        Expected<StringRef> SymName = RelocSym->getName();
+        if (!SymName)
+          report_error(O->getFileName(), SymName.takeError());
+        outs() << " " << *SymName;
+      } else {
+        SymbolName = GuessSymbolName(p, AddrMap);
+        if (SymbolName)
+          outs() << " " << SymbolName;
+      }
     }
-    if (SymbolName)
-      outs() << " " << SymbolName;
     outs() << "\n";
   }
 }
@@ -1463,8 +1497,8 @@ static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
             break;
           case MachO::S_MOD_INIT_FUNC_POINTERS:
           case MachO::S_MOD_TERM_FUNC_POINTERS:
-            DumpInitTermPointerSection(O, sect, sect_size, sect_addr, &AddrMap,
-                                       verbose);
+            DumpInitTermPointerSection(O, Section, sect, sect_size, sect_addr,
+                                       &AddrMap, verbose);
             break;
           default:
             outs() << "Unknown section type ("