From 85b7a66eee81b0b2ff42aa6aeac14eb7bdac0b24 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Tue, 20 Mar 2018 20:29:52 +0000 Subject: [PATCH] For llvm-objdump and Mach-O files, fix the printing of module init and term sections from .o files to look to see if the pointers have a relocation entry and if so print the symbol name from the relocation entry. If not fall back to the existing code and use the pointer value to look up that value in the symbol table. rdar://38337506 llvm-svn: 328037 --- .../X86/Inputs/objModInit.macho-x86_64 | Bin 0 -> 828 bytes .../test/tools/llvm-objdump/X86/macho-section.test | 4 ++ llvm/tools/llvm-objdump/MachODump.cpp | 52 +++++++++++++++++---- 3 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/X86/Inputs/objModInit.macho-x86_64 diff --git a/llvm/test/tools/llvm-objdump/X86/Inputs/objModInit.macho-x86_64 b/llvm/test/tools/llvm-objdump/X86/Inputs/objModInit.macho-x86_64 new file mode 100644 index 0000000000000000000000000000000000000000..52dd9ca101186f48b3d910ad15cbf9f9d143a6db GIT binary patch literal 828 zcmbVKJxc>Y5S@#`M5DHJSNcK!;% zMzFR}-|WsBB?Q6YX5YN|c(()l^#1x$A`0dR2fPTU0z8s{XdQkhg&Fp!`ABA9oBGnB%;6(TWWZva4>^Wd+}S`Ki=S#H>*3EoF`Y5IfMis64Bit()) ? sizeof(uint64_t) : sizeof(uint32_t); + + // Collect the external relocation symbols for the pointers. + std::vector> Relocs; + for (const RelocationRef &Reloc : Section.relocations()) { + DataRefImpl Rel; + MachO::any_relocation_info RE; + bool isExtern = false; + Rel = Reloc.getRawDataRefImpl(); + RE = O->getRelocation(Rel); + isExtern = O->getPlainRelocationExternal(RE); + if (isExtern) { + uint64_t RelocOffset = Reloc.getOffset(); + symbol_iterator RelocSym = Reloc.getSymbol(); + Relocs.push_back(std::make_pair(RelocOffset, *RelocSym)); + } + } + array_pod_sort(Relocs.begin(), Relocs.end()); + for (uint32_t i = 0; i < sect_size; i += stride) { const char *SymbolName = nullptr; + uint64_t p; if (O->is64Bit()) { outs() << format("0x%016" PRIx64, sect_addr + i * stride) << " "; uint64_t pointer_value; @@ -1299,8 +1320,7 @@ static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect, if (O->isLittleEndian() != sys::IsLittleEndianHost) sys::swapByteOrder(pointer_value); outs() << format("0x%016" PRIx64, pointer_value); - if (verbose) - SymbolName = GuessSymbolName(pointer_value, AddrMap); + p = pointer_value; } else { outs() << format("0x%08" PRIx64, sect_addr + i * stride) << " "; uint32_t pointer_value; @@ -1308,11 +1328,25 @@ static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect, if (O->isLittleEndian() != sys::IsLittleEndianHost) sys::swapByteOrder(pointer_value); outs() << format("0x%08" PRIx32, pointer_value); - if (verbose) - SymbolName = GuessSymbolName(pointer_value, AddrMap); + p = pointer_value; + } + if (verbose) { + // First look for an external relocation entry for this pointer. + auto Reloc = find_if(Relocs, [&](const std::pair &P) { + return P.first == i; + }); + if (Reloc != Relocs.end()) { + symbol_iterator RelocSym = Reloc->second; + Expected SymName = RelocSym->getName(); + if (!SymName) + report_error(O->getFileName(), SymName.takeError()); + outs() << " " << *SymName; + } else { + SymbolName = GuessSymbolName(p, AddrMap); + if (SymbolName) + outs() << " " << SymbolName; + } } - if (SymbolName) - outs() << " " << SymbolName; outs() << "\n"; } } @@ -1463,8 +1497,8 @@ static void DumpSectionContents(StringRef Filename, MachOObjectFile *O, break; case MachO::S_MOD_INIT_FUNC_POINTERS: case MachO::S_MOD_TERM_FUNC_POINTERS: - DumpInitTermPointerSection(O, sect, sect_size, sect_addr, &AddrMap, - verbose); + DumpInitTermPointerSection(O, Section, sect, sect_size, sect_addr, + &AddrMap, verbose); break; default: outs() << "Unknown section type (" -- 2.7.4