]> granicus.if.org Git - llvm/commitdiff
Updated llvm-objdump symbolic disassembly with x86_64 Mach-O MH_KEXT_BUNDLE
authorKevin Enderby <enderby@apple.com>
Thu, 22 Jun 2017 17:41:22 +0000 (17:41 +0000)
committerKevin Enderby <enderby@apple.com>
Thu, 22 Jun 2017 17:41:22 +0000 (17:41 +0000)
file types so it symbolically disassembles operands using the external
relocation entries.

rdar://31521343

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306037 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/MachO.h
lib/Object/MachOObjectFile.cpp
test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64 [new file with mode: 0755]
test/tools/llvm-objdump/X86/macho-disassembly-kextbundle.test [new file with mode: 0644]
tools/llvm-objdump/MachODump.cpp

index 3fc726f4ccb8e4e489aaf6fcedf848abd35faf91..2c3c89d10546ff3dc598f5e144d90b279354e08b 100644 (file)
@@ -304,6 +304,12 @@ public:
   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
 
+  relocation_iterator extrel_begin() const;
+  relocation_iterator extrel_end() const;
+  iterator_range<relocation_iterator> external_relocations() const {
+    return make_range(extrel_begin(), extrel_end());
+  }
+
   void moveRelocationNext(DataRefImpl &Rel) const override;
   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
index 7804bbe06f83ecbd0f02ae201db86e5cbcef021b..2e4da9f15aa13f14cf5bad46bcb03d31ef08d90f 100644 (file)
@@ -1951,13 +1951,29 @@ MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
   return relocation_iterator(RelocationRef(Ret, this));
 }
 
+relocation_iterator MachOObjectFile::extrel_begin() const {
+  DataRefImpl Ret;
+  Ret.d.a = 0; // Would normally be a section index.
+  Ret.d.b = 0; // Index into the external relocations
+  return relocation_iterator(RelocationRef(Ret, this));
+}
+
+relocation_iterator MachOObjectFile::extrel_end() const {
+  MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
+  DataRefImpl Ret;
+  Ret.d.a = 0; // Would normally be a section index.
+  Ret.d.b = DysymtabLoadCmd.nextrel; // Index into the external relocations
+  return relocation_iterator(RelocationRef(Ret, this));
+}
+
 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
   ++Rel.d.b;
 }
 
 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const {
-  assert(getHeader().filetype == MachO::MH_OBJECT &&
-         "Only implemented for MH_OBJECT");
+  assert((getHeader().filetype == MachO::MH_OBJECT ||
+          getHeader().filetype == MachO::MH_KEXT_BUNDLE) &&
+         "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE");
   MachO::any_relocation_info RE = getRelocation(Rel);
   return getAnyRelocationAddress(RE);
 }
@@ -4086,15 +4102,20 @@ MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const {
 
 MachO::any_relocation_info
 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
-  DataRefImpl Sec;
-  Sec.d.a = Rel.d.a;
   uint32_t Offset;
-  if (is64Bit()) {
-    MachO::section_64 Sect = getSection64(Sec);
-    Offset = Sect.reloff;
+  if (getHeader().filetype == MachO::MH_OBJECT) {
+    DataRefImpl Sec;
+    Sec.d.a = Rel.d.a;
+    if (is64Bit()) {
+      MachO::section_64 Sect = getSection64(Sec);
+      Offset = Sect.reloff;
+    } else {
+      MachO::section Sect = getSection(Sec);
+      Offset = Sect.reloff;
+    }
   } else {
-    MachO::section Sect = getSection(Sec);
-    Offset = Sect.reloff;
+    MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand();
+    Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations
   }
 
   auto P = reinterpret_cast<const MachO::any_relocation_info *>(
diff --git a/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64 b/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64
new file mode 100755 (executable)
index 0000000..ea9938b
Binary files /dev/null and b/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64 differ
diff --git a/test/tools/llvm-objdump/X86/macho-disassembly-kextbundle.test b/test/tools/llvm-objdump/X86/macho-disassembly-kextbundle.test
new file mode 100644 (file)
index 0000000..b6c53a2
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/kextbundle.macho-x86_64 | FileCheck %s
+
+CHECK: (__TEXT,__text) section
+CHECK: _foo:
+CHECK: 0000000000000fb0        pushq   %rbp
+CHECK: 0000000000000fb1        movq    %rsp, %rbp
+CHECK: 0000000000000fb4        callq   _bar
+CHECK: 0000000000000fb9        popq    %rbp
+CHECK: 0000000000000fba        retq
index 960ef6be4146c4dc3f59047790d07f7ed8ed50ba..ec4c44a2665b44d69f5bbda85be31880278ed402 100644 (file)
@@ -1921,11 +1921,45 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
   if (Arch == Triple::x86_64) {
     if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
       return 0;
+    // For non MH_OBJECT types, like MH_KEXT_BUNDLE, Search the external
+    // relocation entries of a linked image (if any) for an entry that matches
+    // this segment offset.
     if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
-      // TODO:
-      // Search the external relocation entries of a fully linked image
-      // (if any) for an entry that matches this segment offset.
-      // uint64_t seg_offset = (Pc + Offset);
+      uint64_t seg_offset = Pc + Offset;
+      bool reloc_found = false;
+      DataRefImpl Rel;
+      MachO::any_relocation_info RE;
+      bool isExtern = false;
+      SymbolRef Symbol;
+      for (const RelocationRef &Reloc : info->O->external_relocations()) {
+        uint64_t RelocOffset = Reloc.getOffset();
+        if (RelocOffset == seg_offset) {
+          Rel = Reloc.getRawDataRefImpl();
+          RE = info->O->getRelocation(Rel);
+          // external relocation entries should always be external.
+          isExtern = info->O->getPlainRelocationExternal(RE);
+          if (isExtern) {
+            symbol_iterator RelocSym = Reloc.getSymbol();
+            Symbol = *RelocSym;
+          }
+          reloc_found = true;
+          break;
+        }
+      }
+      if (reloc_found && isExtern) {
+        // The Value passed in will be adjusted by the Pc if the instruction
+        // adds the Pc.  But for x86_64 external relocation entries the Value
+        // is the offset from the external symbol.
+        if (info->O->getAnyRelocationPCRel(RE))
+          op_info->Value -= Pc + Offset + Size;
+        Expected<StringRef> SymName = Symbol.getName();
+        if (!SymName)
+          report_error(info->O->getFileName(), SymName.takeError());
+        const char *name = SymName->data();
+        op_info->AddSymbol.Present = 1;
+        op_info->AddSymbol.Name = name;
+        return 1;
+      }
       return 0;
     }
     // In MH_OBJECT filetypes search the section's relocation entries (if any)