From a25032214d92adb613a5db84adeec88e71d59b30 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Tue, 4 Nov 2014 00:43:16 +0000 Subject: [PATCH] =?utf8?q?Add=20the=20code=20and=20test=20cases=20for=2032?= =?utf8?q?-bit=20Intel=20to=20llvm-objdump=E2=80=99s=20Mach-O=20symbolizer?= =?utf8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221211 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/MachO.h | 2 + lib/Object/MachOObjectFile.cpp | 5 + .../X86/Inputs/hello.exe.macho-i386 | Bin 0 -> 8476 bytes .../X86/Inputs/hello.obj.macho-i386 | Bin 0 -> 472 bytes .../X86/macho-symbolized-disassembly.test | 7 ++ .../X86/macho-symbolized-subtractor-i386.test | 10 ++ tools/llvm-objdump/MachODump.cpp | 108 +++++++++++++++--- 7 files changed, 118 insertions(+), 14 deletions(-) create mode 100755 test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386 create mode 100644 test/tools/llvm-objdump/X86/Inputs/hello.obj.macho-i386 create mode 100644 test/tools/llvm-objdump/X86/macho-symbolized-subtractor-i386.test diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 2497b7aea66..768cda6800e 100644 --- a/include/llvm/Object/MachO.h +++ b/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/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 75e39fdf720..678728e1de7 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/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/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386 b/test/tools/llvm-objdump/X86/Inputs/hello.exe.macho-i386 new file mode 100755 index 0000000000000000000000000000000000000000..b1f7bd8ecfb1f4c17a423717f78dfe9fb6e623f1 GIT binary patch literal 8476 zcmeHN%}Z2K6u+Zmy>!wsB7!8JGKPJi5d|(>jNy<{rk0unb#a_$GcaGwyg}U!sKKCt z?OIFQaNQyhDymHo1npWCSQxZu5iXj3zxU?mYqb7=x(Cmkdp_^Izjp`To#X56FF*DR zA!@-j;2=2U7h*}6J|D(CU@1rXE=6uet_?#`#K1og^H%U7nhAB zDQ#=c=E$Y${BWxf{cwewguoJa$S;aYkupD@ie{2BZx^C4R@YcWjeW2$q6XKg$f$E` z(1#jGmT@bYwQ`RB`#x4s;|T04s6otrQKbfTDW~&xE|I=daaONm4K)tJw}u*C^462G zke*GXV=|GR$snk@#yV;Yz`kBp!&{Gg+yG12-#6Ch@t7E^=TUhU>I^VS$}})^q0HL3 zJ@X9)BGJIr?YS%PnbfqAc#3? zUJOOM5JiU2&#)lmQAkCdrfctkJOd;5K>tJNJX;?iId21a1necoD)!pFrN)3-Ld&(4EixJ*UK#6%blO0j z*emn+z3>v}I1i?e>-G5_VQapfc`^6(`MhnVx-NEM4T-1_ClJTEVy3(PlNCJfJQ(gpb^jrXaqC@8iD@_f$`GEiG{7uCigtKJQQ3W4=fjqd&LRpFCyP* zE)~9&#=n+^wo3lcCf}VOJJ!f%>E*(+(Cu4K%N>SEQ``?x?%XHjMY0=99|ztUdh*czW(!dpS)DL3UJJ8T>zOuCmYIM^Z<8BO&S4>fJQ(gpb^jr zXaqC@8Uc-fMnEH=5zq+yn+P5HX?zU!Yvo)jGVsn_yNVfqVMei96@X?%D6*;3h zEVF26+cVHWK8fCajZDR*HD^s1YzzJJDTcSDrV?qaj+L^w1_lOZAZCQp8X$%Ognt0Y#0CO^f-XRHAR43}gqeUC1mfdMQY%UzYzRNZ zH6jGT2eDj07^t5GNY4P$Ap3!w1`q`T@$t#UB}JKe=@2fEk7@=;KQ9n>0QDjRm>WQ1 zAhrY$Zvd(Ru}=VL0U*r{!~sBz3_!-fFtRu??9k4qVa;z;UVzj_bo&Z)hw^lna`ZM> z0QtvVe}IHLOTTo6e(3al)5)Up;>`d5|965#U0-ybXg;D67kk(vH76%up*+7RCxr_n wWdOuL_wWMUzXar0AXvx)BtUND2N6I33UeqE7+|@HnRyKH1;8*XNn>CD06>&HZvX%Q literal 0 HcmV?d00001 diff --git a/test/tools/llvm-objdump/X86/macho-symbolized-disassembly.test b/test/tools/llvm-objdump/X86/macho-symbolized-disassembly.test index cb9b8b276ee..1e1080a30f0 100644 --- a/test/tools/llvm-objdump/X86/macho-symbolized-disassembly.test +++ b/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 . // std::__1::ostreambuf_iterator > std::__1::__pad_and_output >(std::__1::ostreambuf_iterator >, 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/test/tools/llvm-objdump/X86/macho-symbolized-subtractor-i386.test b/test/tools/llvm-objdump/X86/macho-symbolized-subtractor-i386.test new file mode 100644 index 00000000000..a0f753bdb7a --- /dev/null +++ b/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/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index c62a92e2c67..50afab7b54c 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/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); -- 2.34.1