summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2017-06-22 17:41:22 +0000
committerKevin Enderby <enderby@apple.com>2017-06-22 17:41:22 +0000
commitabf10f2d2e3c18dc5825ad0dcd5b70de0bc00ba1 (patch)
tree81c3c043dd53ac387623b44a3d0d860eeb868c2d
parent4402a39981063992cd8f4ca81e240a6fe7cdf4fd (diff)
downloadbcm5719-llvm-abf10f2d2e3c18dc5825ad0dcd5b70de0bc00ba1.tar.gz
bcm5719-llvm-abf10f2d2e3c18dc5825ad0dcd5b70de0bc00ba1.zip
Updated llvm-objdump symbolic disassembly with x86_64 Mach-O MH_KEXT_BUNDLE
file types so it symbolically disassembles operands using the external relocation entries. rdar://31521343 llvm-svn: 306037
-rw-r--r--llvm/include/llvm/Object/MachO.h6
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp39
-rwxr-xr-xllvm/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64bin0 -> 4152 bytes
-rw-r--r--llvm/test/tools/llvm-objdump/X86/macho-disassembly-kextbundle.test9
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp42
5 files changed, 83 insertions, 13 deletions
diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h
index 3fc726f4ccb..2c3c89d1054 100644
--- a/llvm/include/llvm/Object/MachO.h
+++ b/llvm/include/llvm/Object/MachO.h
@@ -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;
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 7804bbe06f8..2e4da9f15aa 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -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/llvm/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64 b/llvm/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64
new file mode 100755
index 00000000000..ea9938b8631
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64
Binary files differ
diff --git a/llvm/test/tools/llvm-objdump/X86/macho-disassembly-kextbundle.test b/llvm/test/tools/llvm-objdump/X86/macho-disassembly-kextbundle.test
new file mode 100644
index 00000000000..b6c53a22f0c
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/X86/macho-disassembly-kextbundle.test
@@ -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
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 960ef6be414..ec4c44a2665 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -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)
OpenPOWER on IntegriCloud