diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2022-08-12 15:10:58 +0200 |
---|---|---|
committer | Daniel Bertalan <dani@danielbertalan.dev> | 2022-08-18 09:29:27 +0200 |
commit | 11443ef85dbe4f3930f726b1be4d7f90f99d1021 (patch) | |
tree | 9e0c385d02e25463d41933e15024b6f1da52244c /llvm/tools/llvm-objdump/MachODump.cpp | |
parent | ed342d9d29898952e2d1fcd40716e83ed5b9f202 (diff) | |
download | llvm-11443ef85dbe4f3930f726b1be4d7f90f99d1021.zip llvm-11443ef85dbe4f3930f726b1be4d7f90f99d1021.tar.gz llvm-11443ef85dbe4f3930f726b1be4d7f90f99d1021.tar.bz2 |
[llvm-objdump] Support dumping segment information with -chained_fixups
This commit adds the definitions for `dyld_chained_starts_in_image`,
`dyld_chained_starts_in_segment`, and related enums. Dumping their
contents is possible with the -chained_fixups flag of llvm-otool.
The chained-fixups.yaml test was changed to cover bindings/rebases, as
well as weak imports, weak symbols and flat namespace symbols. Now that
we have actual fixup entries, the __DATA segment contains data that
would need to be hexdumped in YAML. We also test empty pages (to look
for the "DYLD_CHAINED_PTR_START_NONE" annotation), so the YAML would end
up quite large. So instead, this commit includes a binary file.
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/D131961
Diffstat (limited to 'llvm/tools/llvm-objdump/MachODump.cpp')
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index a2593cf..d95b1c4 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -1195,6 +1195,20 @@ static void printMachOChainedFixups(object::MachOObjectFile *Obj) { 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()) { + if (Command.C.cmd == MachO::LC_SEGMENT) { + MachO::segment_command SLC = O->getSegmentLoadCommand(Command); + Ret.push_back(SLC.segname); + } else if (Command.C.cmd == MachO::LC_SEGMENT_64) { + MachO::segment_command_64 SLC = O->getSegment64LoadCommand(Command); + Ret.push_back(SLC.segname); + } + } + return Ret; +} + static void PrintChainedFixupsHeader(const MachO::dyld_chained_fixups_header &H) { outs() << "chained fixups header (LC_DYLD_CHAINED_FIXUPS)\n"; @@ -1224,6 +1238,50 @@ PrintChainedFixupsHeader(const MachO::dyld_chained_fixups_header &H) { outs() << '\n'; } +static constexpr std::array<StringRef, 13> PointerFormats{ + "DYLD_CHAINED_PTR_ARM64E", + "DYLD_CHAINED_PTR_64", + "DYLD_CHAINED_PTR_32", + "DYLD_CHAINED_PTR_32_CACHE", + "DYLD_CHAINED_PTR_32_FIRMWARE", + "DYLD_CHAINED_PTR_64_OFFSET", + "DYLD_CHAINED_PTR_ARM64E_KERNEL", + "DYLD_CHAINED_PTR_64_KERNEL_CACHE", + "DYLD_CHAINED_PTR_ARM64E_USERLAND", + "DYLD_CHAINED_PTR_ARM64E_FIRMWARE", + "DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE", + "DYLD_CHAINED_PTR_ARM64E_USERLAND24", +}; + +static void +PrintChainedFixupsSegment(const MachOObjectFile::ChainedFixupsSegment &Segment, + StringRef SegName) { + outs() << "chained starts in segment " << Segment.SegIdx << " (" << SegName + << ")\n"; + outs() << " size = " << Segment.Header.size << '\n'; + outs() << " page_size = " << format("0x%0" PRIx16, Segment.Header.page_size) + << '\n'; + + outs() << " pointer_format = " << Segment.Header.pointer_format; + if ((Segment.Header.pointer_format - 1) < + MachO::DYLD_CHAINED_PTR_ARM64E_USERLAND24) + outs() << " (" << PointerFormats[Segment.Header.pointer_format - 1] << ")"; + outs() << '\n'; + + outs() << " segment_offset = " + << format("0x%0" PRIx64, Segment.Header.segment_offset) << '\n'; + outs() << " max_valid_pointer = " << Segment.Header.max_valid_pointer + << '\n'; + outs() << " page_count = " << Segment.Header.page_count << '\n'; + for (auto [Index, PageStart] : enumerate(Segment.PageStarts)) { + outs() << " page_start[" << Index << "] = " << PageStart; + // FIXME: Support DYLD_CHAINED_PTR_START_MULTI (32-bit only) + if (PageStart == MachO::DYLD_CHAINED_PTR_START_NONE) + outs() << " (DYLD_CHAINED_PTR_START_NONE)"; + outs() << '\n'; + } +} + static void PrintChainedFixups(MachOObjectFile *O) { // MachOObjectFile::getChainedFixupsHeader() reads LC_DYLD_CHAINED_FIXUPS. // FIXME: Support chained fixups in __TEXT,__chain_starts section too. @@ -1234,6 +1292,28 @@ static void PrintChainedFixups(MachOObjectFile *O) { PrintChainedFixupsHeader(*ChainedFixupHeader); + auto [SegCount, Segments] = + unwrapOrError(O->getChainedFixupsSegments(), O->getFileName()); + + auto SegNames = GetSegmentNames(O); + + size_t StartsIdx = 0; + outs() << "chained starts in image\n"; + outs() << " seg_count = " << SegCount << '\n'; + for (size_t I = 0; I < SegCount; ++I) { + uint64_t SegOffset = 0; + if (StartsIdx < Segments.size() && I == Segments[StartsIdx].SegIdx) { + SegOffset = Segments[StartsIdx].Offset; + ++StartsIdx; + } + + outs() << " seg_offset[" << I << "] = " << SegOffset << " (" + << SegNames[I] << ")\n"; + } + + for (const MachOObjectFile::ChainedFixupsSegment &S : Segments) + PrintChainedFixupsSegment(S, SegNames[S.SegIdx]); + // FIXME: Print more things. } |