diff options
| author | Kevin Enderby <enderby@apple.com> | 2017-06-22 17:41:22 +0000 |
|---|---|---|
| committer | Kevin Enderby <enderby@apple.com> | 2017-06-22 17:41:22 +0000 |
| commit | abf10f2d2e3c18dc5825ad0dcd5b70de0bc00ba1 (patch) | |
| tree | 81c3c043dd53ac387623b44a3d0d860eeb868c2d | |
| parent | 4402a39981063992cd8f4ca81e240a6fe7cdf4fd (diff) | |
| download | bcm5719-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.h | 6 | ||||
| -rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 39 | ||||
| -rwxr-xr-x | llvm/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64 | bin | 0 -> 4152 bytes | |||
| -rw-r--r-- | llvm/test/tools/llvm-objdump/X86/macho-disassembly-kextbundle.test | 9 | ||||
| -rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 42 |
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 Binary files differnew file mode 100755 index 00000000000..ea9938b8631 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/Inputs/kextbundle.macho-x86_64 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) |

