diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2022-08-17 16:14:03 +0200 |
---|---|---|
committer | Daniel Bertalan <dani@danielbertalan.dev> | 2022-08-28 09:22:41 +0200 |
commit | 47e4663c4eacaedab63e407651f5b045446bb36d (patch) | |
tree | 2f6a9e1483d4de9f2c11cfd014e2df91659a5d7e /llvm/tools/llvm-objdump/MachODump.cpp | |
parent | f4feb7dd6ae42e3a50cbe25a71c7f69f1f1acb69 (diff) | |
download | llvm-47e4663c4eacaedab63e407651f5b045446bb36d.zip llvm-47e4663c4eacaedab63e407651f5b045446bb36d.tar.gz llvm-47e4663c4eacaedab63e407651f5b045446bb36d.tar.bz2 |
[llvm-objdump] Add -dyld_info to llvm-otool
This option outputs the location, encoded value and target of chained
fixups, using the same format as `otool -dyld_info`.
This initial implementation only supports the DYLD_CHAINED_PTR_64 and
DYLD_CHAINED_PTR_64_OFFSET pointer encodings, which are used in x86_64
and arm64 userspace binaries.
When Apple's effort to upstream their chained fixups code continues,
we'll replace this code with the then-upstreamed code. But we need
something in the meantime for testing ld64.lld's chained fixups code.
Differential Revision: https://reviews.llvm.org/D132036
Diffstat (limited to 'llvm/tools/llvm-objdump/MachODump.cpp')
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 74 |
1 files changed, 59 insertions, 15 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 31bb52a..c082038 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -1188,15 +1188,6 @@ static void PrintLinkOptHints(MachOObjectFile *O) { } } -static void printMachOChainedFixups(object::MachOObjectFile *Obj) { - Error Err = Error::success(); - for (const object::MachOChainedFixupEntry &Entry : Obj->fixupTable(Err)) { - (void)Entry; - } - if (Err) - reportError(std::move(Err), Obj->getFileName()); -} - static SmallVector<std::string> GetSegmentNames(object::MachOObjectFile *O) { SmallVector<std::string> Ret; for (const MachOObjectFile::LoadCommandInfo &Command : O->load_commands()) { @@ -1255,9 +1246,8 @@ static constexpr std::array<StringRef, 13> PointerFormats{ "DYLD_CHAINED_PTR_ARM64E_USERLAND24", }; -static void -PrintChainedFixupsSegment(const MachOObjectFile::ChainedFixupsSegment &Segment, - StringRef SegName) { +static void PrintChainedFixupsSegment(const ChainedFixupsSegment &Segment, + StringRef SegName) { outs() << "chained starts in segment " << Segment.SegIdx << " (" << SegName << ")\n"; outs() << " size = " << Segment.Header.size << '\n'; @@ -1333,7 +1323,7 @@ static void PrintChainedFixups(MachOObjectFile *O) { << SegNames[I] << ")\n"; } - for (const MachOObjectFile::ChainedFixupsSegment &S : Segments) + for (const ChainedFixupsSegment &S : Segments) PrintChainedFixupsSegment(S, SegNames[S.SegIdx]); auto FixupTargets = @@ -1345,8 +1335,62 @@ static void PrintChainedFixups(MachOObjectFile *O) { } static void PrintDyldInfo(MachOObjectFile *O) { - outs() << "dyld information:" << '\n'; - printMachOChainedFixups(O); + Error Err = Error::success(); + + size_t SegmentWidth = strlen("segment"); + size_t SectionWidth = strlen("section"); + size_t AddressWidth = strlen("address"); + size_t AddendWidth = strlen("addend"); + size_t DylibWidth = strlen("dylib"); + const size_t PointerWidth = 2 + O->getBytesInAddress() * 2; + + auto HexLength = [](uint64_t Num) { + return Num ? (size_t)divideCeil(Log2_64(Num), 4) : 1; + }; + for (const object::MachOChainedFixupEntry &Entry : O->fixupTable(Err)) { + SegmentWidth = std::max(SegmentWidth, Entry.segmentName().size()); + SectionWidth = std::max(SectionWidth, Entry.sectionName().size()); + AddressWidth = std::max(AddressWidth, HexLength(Entry.address()) + 2); + if (Entry.isBind()) { + AddendWidth = std::max(AddendWidth, HexLength(Entry.addend()) + 2); + DylibWidth = std::max(DylibWidth, Entry.symbolName().size()); + } + } + // Errors will be handled when printing the table. + if (Err) + consumeError(std::move(Err)); + + outs() << "dyld information:\n"; + outs() << left_justify("segment", SegmentWidth) << ' ' + << left_justify("section", SectionWidth) << ' ' + << left_justify("address", AddressWidth) << ' ' + << left_justify("pointer", PointerWidth) << " type " + << left_justify("addend", AddendWidth) << ' ' + << left_justify("dylib", DylibWidth) << " symbol/vm address\n"; + for (const object::MachOChainedFixupEntry &Entry : O->fixupTable(Err)) { + outs() << left_justify(Entry.segmentName(), SegmentWidth) << ' ' + << left_justify(Entry.sectionName(), SectionWidth) << ' ' << "0x" + << left_justify(utohexstr(Entry.address()), AddressWidth - 2) << ' ' + << format_hex(Entry.rawValue(), PointerWidth, true) << ' '; + if (Entry.isBind()) { + outs() << "bind " + << "0x" << left_justify(utohexstr(Entry.addend()), AddendWidth - 2) + << ' ' << left_justify(ordinalName(O, Entry.ordinal()), DylibWidth) + << ' ' << Entry.symbolName(); + if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT) + outs() << " (weak import)"; + outs() << '\n'; + } else { + assert(Entry.isRebase()); + outs() << "rebase"; + outs().indent(AddendWidth + DylibWidth + 2); + outs() << format("0x%" PRIX64, Entry.pointerValue()) << '\n'; + } + } + if (Err) + reportError(std::move(Err), O->getFileName()); + + // TODO: Print opcode-based fixups if the object uses those. } static void PrintDylibs(MachOObjectFile *O, bool JustId) { |