1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

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
This commit is contained in:
Kevin Enderby 2017-06-22 17:41:22 +00:00
parent 5d34780d4b
commit 0b97356076
5 changed files with 83 additions and 13 deletions

View 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;

View 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 *>(

Binary file not shown.

View File

@ -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

View 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)