aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump/MachODump.cpp
diff options
context:
space:
mode:
authorDaniel Bertalan <dani@danielbertalan.dev>2022-08-17 16:14:03 +0200
committerDaniel Bertalan <dani@danielbertalan.dev>2022-08-28 09:22:41 +0200
commit47e4663c4eacaedab63e407651f5b045446bb36d (patch)
tree2f6a9e1483d4de9f2c11cfd014e2df91659a5d7e /llvm/tools/llvm-objdump/MachODump.cpp
parentf4feb7dd6ae42e3a50cbe25a71c7f69f1f1acb69 (diff)
downloadllvm-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.cpp74
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) {