summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Object/MachO.h2
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp5
-rwxr-xr-xllvm/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386bin0 -> 8476 bytes
-rw-r--r--llvm/test/tools/llvm-objdump/X86/Inputs/hello.obj.macho-i386bin0 -> 472 bytes
-rw-r--r--llvm/test/tools/llvm-objdump/X86/macho-symbolized-disassembly.test7
-rw-r--r--llvm/test/tools/llvm-objdump/X86/macho-symbolized-subtractor-i386.test10
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp108
7 files changed, 118 insertions, 14 deletions
diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h
index 2497b7aea66..768cda6800e 100644
--- a/llvm/include/llvm/Object/MachO.h
+++ b/llvm/include/llvm/Object/MachO.h
@@ -322,6 +322,8 @@ public:
const MachO::any_relocation_info &RE) const;
uint32_t getScatteredRelocationValue(
const MachO::any_relocation_info &RE) const;
+ uint32_t getScatteredRelocationType(
+ const MachO::any_relocation_info &RE) const;
unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const;
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const;
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const;
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 75e39fdf720..678728e1de7 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -2150,6 +2150,11 @@ uint32_t MachOObjectFile::getScatteredRelocationValue(
return RE.r_word1;
}
+uint32_t MachOObjectFile::getScatteredRelocationType(
+ const MachO::any_relocation_info &RE) const {
+ return (RE.r_word0 >> 24) & 0xf;
+}
+
unsigned MachOObjectFile::getAnyRelocationAddress(
const MachO::any_relocation_info &RE) const {
if (isRelocationScattered(RE))
diff --git a/llvm/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386 b/llvm/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386
new file mode 100755
index 00000000000..b1f7bd8ecfb
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386
Binary files differ
diff --git a/llvm/test/tools/llvm-objdump/X86/Inputs/hello.obj.macho-i386 b/llvm/test/tools/llvm-objdump/X86/Inputs/hello.obj.macho-i386
new file mode 100644
index 00000000000..b69d4beb60d
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/X86/Inputs/hello.obj.macho-i386
Binary files differ
diff --git a/llvm/test/tools/llvm-objdump/X86/macho-symbolized-disassembly.test b/llvm/test/tools/llvm-objdump/X86/macho-symbolized-disassembly.test
index cb9b8b276ee..1e1080a30f0 100644
--- a/llvm/test/tools/llvm-objdump/X86/macho-symbolized-disassembly.test
+++ b/llvm/test/tools/llvm-objdump/X86/macho-symbolized-disassembly.test
@@ -4,6 +4,9 @@
// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/ObjC.exe.macho-x86_64 | FileCheck %s -check-prefix=ObjC-EXE
// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/hello_cpp.exe.macho-x86_64 | FileCheck %s -check-prefix=CXX-EXE
+// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/hello.obj.macho-i386 | FileCheck %s -check-prefix=i386-OBJ
+// RUN: llvm-objdump -d -m -no-show-raw-insn -full-leading-addr -print-imm-hex %p/Inputs/hello.exe.macho-i386 | FileCheck %s -check-prefix=i386-EXE
+
OBJ: 0000000000000008 leaq L_.str(%rip), %rax ## literal pool for: "Hello world\n"
OBJ: 0000000000000026 callq _printf
@@ -29,3 +32,7 @@ CXX-EXE: 00000001000014cb callq __ZNSt3__116__pad_and_outputIcNS_11char_traitsIc
// FIXME: Demangler depends on host's <cxxabi.h>.
// std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char)
+
+i386-OBJ: 0000002f calll _printf
+
+i386-EXE: 00001f6f calll 0x1f84 ## symbol stub for: _printf
diff --git a/llvm/test/tools/llvm-objdump/X86/macho-symbolized-subtractor-i386.test b/llvm/test/tools/llvm-objdump/X86/macho-symbolized-subtractor-i386.test
new file mode 100644
index 00000000000..a0f753bdb7a
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/X86/macho-symbolized-subtractor-i386.test
@@ -0,0 +1,10 @@
+# RUN: llvm-mc < %s -triple x86_64-apple-darwin -filetype=obj | llvm-objdump -m -d - | FileCheck %s
+
+nop
+x:
+leal x-y(%eax), %ebx
+.data
+y:
+.quad 0
+
+# CHECK: leal x-y(%eax), %ebx
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index c62a92e2c67..50afab7b54c 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -248,6 +248,21 @@ struct DisassembleInfo {
BindTable *bindtable;
};
+// GuessSymbolName is passed the address of what might be a symbol and a
+// pointer to the DisassembleInfo struct. It returns the name of a symbol
+// with that address or nullptr if no symbol is found with that address.
+static const char *GuessSymbolName(uint64_t value,
+ struct DisassembleInfo *info) {
+ const char *SymbolName = nullptr;
+ // A DenseMap can't lookup up some values.
+ if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
+ StringRef name = info->AddrMap->lookup(value);
+ if (!name.empty())
+ SymbolName = name.data();
+ }
+ return SymbolName;
+}
+
// SymbolizerGetOpInfo() is the operand information call back function.
// This is called to get the symbolic information for operand(s) of an
// instruction when it is being done. This routine does this from
@@ -281,6 +296,83 @@ int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
unsigned int Arch = info->O->getArch();
if (Arch == Triple::x86) {
+ if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
+ return 0;
+ // First search the section's relocation entries (if any) for an entry
+ // for this section offset.
+ uint32_t sect_addr = info->S.getAddress();
+ uint32_t sect_offset = (Pc + Offset) - sect_addr;
+ bool reloc_found = false;
+ DataRefImpl Rel;
+ MachO::any_relocation_info RE;
+ bool isExtern = false;
+ SymbolRef Symbol;
+ bool r_scattered = false;
+ uint32_t r_value, pair_r_value, r_type;
+ for (const RelocationRef &Reloc : info->S.relocations()) {
+ uint64_t RelocOffset;
+ Reloc.getOffset(RelocOffset);
+ if (RelocOffset == sect_offset) {
+ Rel = Reloc.getRawDataRefImpl();
+ RE = info->O->getRelocation(Rel);
+ r_scattered = info->O->isRelocationScattered(RE);
+ if (r_scattered) {
+ r_value = info->O->getScatteredRelocationValue(RE);
+ r_type = info->O->getScatteredRelocationType(RE);
+ if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
+ r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
+ DataRefImpl RelNext = Rel;
+ info->O->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext;
+ RENext = info->O->getRelocation(RelNext);
+ if (info->O->isRelocationScattered(RENext))
+ pair_r_value = info->O->getPlainRelocationSymbolNum(RENext);
+ else
+ return 0;
+ }
+ } else {
+ isExtern = info->O->getPlainRelocationExternal(RE);
+ if (isExtern) {
+ symbol_iterator RelocSym = Reloc.getSymbol();
+ Symbol = *RelocSym;
+ }
+ }
+ reloc_found = true;
+ break;
+ }
+ }
+ if (reloc_found && isExtern) {
+ StringRef SymName;
+ Symbol.getName(SymName);
+ const char *name = SymName.data();
+ op_info->AddSymbol.Present = 1;
+ op_info->AddSymbol.Name = name;
+ // For i386 extern relocation entries the value in the instruction is
+ // the offset from the symbol, and value is already set in op_info->Value.
+ return 1;
+ }
+ if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
+ r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
+ const char *add = GuessSymbolName(r_value, info);
+ const char *sub = GuessSymbolName(pair_r_value, info);
+ uint32_t offset = value - (r_value - pair_r_value);
+ op_info->AddSymbol.Present = 1;
+ if (add != nullptr)
+ op_info->AddSymbol.Name = add;
+ else
+ op_info->AddSymbol.Value = r_value;
+ op_info->SubtractSymbol.Present = 1;
+ if (sub != nullptr)
+ op_info->SubtractSymbol.Name = sub;
+ else
+ op_info->SubtractSymbol.Value = pair_r_value;
+ op_info->Value = offset;
+ return 1;
+ }
+ // TODO:
+ // Second search the external relocation entries of a fully linked image
+ // (if any) for an entry that matches this segment offset.
+ // uint32_t seg_offset = (Pc + Offset);
return 0;
} else if (Arch == Triple::x86_64) {
if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
@@ -716,13 +808,7 @@ const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
//
// NOTE: need add passing the ReferenceValue to this routine. Then that code
// would simply be this:
- //
- // if (ReferenceValue != 0xffffffffffffffffLLU &&
- // ReferenceValue != 0xfffffffffffffffeLLU) {
- // StringRef name = info->AddrMap->lookup(ReferenceValue);
- // if (!name.empty())
- // SymbolName = name.data();
- // }
+ // SymbolName = GuessSymbolName(ReferenceValue, info);
return SymbolName;
}
@@ -1071,13 +1157,7 @@ const char *SymbolizerSymbolLookUp(void *DisInfo, uint64_t ReferenceValue,
return nullptr;
}
- const char *SymbolName = nullptr;
- if (ReferenceValue != 0xffffffffffffffffULL &&
- ReferenceValue != 0xfffffffffffffffeULL) {
- StringRef name = info->AddrMap->lookup(ReferenceValue);
- if (!name.empty())
- SymbolName = name.data();
- }
+ const char *SymbolName = GuessSymbolName(ReferenceValue, info);
if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
*ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
OpenPOWER on IntegriCloud