summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objdump/MachODump.cpp
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2014-09-12 21:34:15 +0000
committerNick Kledzik <kledzik@apple.com>2014-09-12 21:34:15 +0000
commitac43144e5a5a3e3d9e78e9d1460825498715e4a9 (patch)
treee4071699728a5fe724bc08a486b418fd2f51571d /llvm/tools/llvm-objdump/MachODump.cpp
parent54b112828f8df04af8b7ab326d23789f2bea0389 (diff)
downloadbcm5719-llvm-ac43144e5a5a3e3d9e78e9d1460825498715e4a9.tar.gz
bcm5719-llvm-ac43144e5a5a3e3d9e78e9d1460825498715e4a9.zip
[llvm-objdump] support -rebase option for mach-o to dump rebasing info
Similar to my previous -exports-trie option, the -rebase option dumps info from the LC_DYLD_INFO load command. The rebasing info is a list of the the locations that dyld needs to adjust if a mach-o image is not loaded at its preferred address. Since ASLR is now the default, images almost never load at their preferred address, and thus need to be rebased by dyld. llvm-svn: 217709
Diffstat (limited to 'llvm/tools/llvm-objdump/MachODump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 34933eb7071..debe33e9cfa 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -2146,3 +2146,109 @@ void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) {
outs() << "\n";
}
}
+
+
+//===----------------------------------------------------------------------===//
+// rebase table dumping
+//===----------------------------------------------------------------------===//
+
+namespace {
+class SegInfo {
+public:
+ SegInfo(const object::MachOObjectFile *Obj);
+
+ StringRef segmentName(uint32_t SegIndex);
+ StringRef sectionName(uint32_t SegIndex, uint64_t SegOffset);
+ uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
+
+private:
+ struct SectionInfo {
+ uint64_t Address;
+ uint64_t Size;
+ StringRef SectionName;
+ StringRef SegmentName;
+ uint64_t OffsetInSegment;
+ uint64_t SegmentStartAddress;
+ uint32_t SegmentIndex;
+ };
+ const SectionInfo &findSection(uint32_t SegIndex, uint64_t SegOffset);
+ SmallVector<SectionInfo, 32> Sections;
+};
+}
+
+SegInfo::SegInfo(const object::MachOObjectFile *Obj) {
+ // Build table of sections so segIndex/offset pairs can be translated.
+ uint32_t CurSegIndex = 0;
+ StringRef CurSegName;
+ uint64_t CurSegAddress;
+ for (const SectionRef &Section : Obj->sections()) {
+ SectionInfo Info;
+ if (error(Section.getName(Info.SectionName)))
+ return;
+ if (error(Section.getAddress(Info.Address)))
+ return;
+ if (error(Section.getSize(Info.Size)))
+ return;
+ Info.SegmentName =
+ Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
+ if (!Info.SegmentName.equals(CurSegName)) {
+ ++CurSegIndex;
+ CurSegName = Info.SegmentName;
+ CurSegAddress = Info.Address;
+ }
+ Info.SegmentIndex = CurSegIndex - 1;
+ Info.OffsetInSegment = Info.Address - CurSegAddress;
+ Info.SegmentStartAddress = CurSegAddress;
+ Sections.push_back(Info);
+ }
+}
+
+StringRef SegInfo::segmentName(uint32_t SegIndex) {
+ for (const SectionInfo &SI : Sections) {
+ if (SI.SegmentIndex == SegIndex)
+ return SI.SegmentName;
+ }
+ llvm_unreachable("invalid segIndex");
+}
+
+const SegInfo::SectionInfo &SegInfo::findSection(uint32_t SegIndex,
+ uint64_t OffsetInSeg) {
+ for (const SectionInfo &SI : Sections) {
+ if (SI.SegmentIndex != SegIndex)
+ continue;
+ if (SI.OffsetInSegment > OffsetInSeg)
+ continue;
+ if (OffsetInSeg >= (SI.OffsetInSegment + SI.Size))
+ continue;
+ return SI;
+ }
+ llvm_unreachable("segIndex and offset not in any section");
+}
+
+StringRef SegInfo::sectionName(uint32_t SegIndex, uint64_t OffsetInSeg) {
+ return findSection(SegIndex, OffsetInSeg).SectionName;
+}
+
+uint64_t SegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
+ const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
+ return SI.SegmentStartAddress + OffsetInSeg;
+}
+
+void llvm::printMachORebaseTable(const object::MachOObjectFile *Obj) {
+ // Build table of sections so names can used in final output.
+ SegInfo sectionTable(Obj);
+
+ outs() << "segment section address type\n";
+ for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) {
+ uint32_t SegIndex = Entry.segmentIndex();
+ uint64_t OffsetInSeg = Entry.segmentOffset();
+ StringRef SegmentName = sectionTable.segmentName(SegIndex);
+ StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
+ uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
+
+ // Table lines look like: __DATA __nl_symbol_ptr 0x0000F00C pointer
+ outs() << format("%-8s %-18s 0x%08X %s\n", SegmentName.str().c_str(),
+ SectionName.str().c_str(), Address,
+ Entry.typeName().str().c_str());
+ }
+}
OpenPOWER on IntegriCloud