summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objdump
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
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')
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp106
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp20
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h1
3 files changed, 126 insertions, 1 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());
+ }
+}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 7debbe9a961..2b70167d135 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -82,6 +82,9 @@ static cl::opt<bool>
ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
static cl::opt<bool>
+Rebase("rebase", cl::desc("Display mach-o rebasing info"));
+
+static cl::opt<bool>
MachOOpt("macho", cl::desc("Use MachO specific object file parser"));
static cl::alias
MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt));
@@ -720,6 +723,18 @@ static void printExportsTrie(const ObjectFile *o) {
}
}
+static void printRebaseTable(const ObjectFile *o) {
+ outs() << "Rebase table:\n";
+ if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+ printMachORebaseTable(MachO);
+ else {
+ errs() << "This operation is only currently supported "
+ "for Mach-O executable files.\n";
+ return;
+ }
+}
+
+
static void printPrivateFileHeader(const ObjectFile *o) {
if (o->isELF()) {
printELFFileHeader(o);
@@ -751,6 +766,8 @@ static void DumpObject(const ObjectFile *o) {
printPrivateFileHeader(o);
if (ExportsTrie)
printExportsTrie(o);
+ if (Rebase)
+ printRebaseTable(o);
}
/// @brief Dump each object file in \a a;
@@ -833,7 +850,8 @@ int main(int argc, char **argv) {
&& !SymbolTable
&& !UnwindInfo
&& !PrivateHeaders
- && !ExportsTrie) {
+ && !ExportsTrie
+ && !Rebase) {
cl::PrintHelpMessage();
return 2;
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index c259042c39d..a328e635ee0 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -36,6 +36,7 @@ void DisassembleInputMachO(StringRef Filename);
void printCOFFUnwindInfo(const object::COFFObjectFile* o);
void printMachOUnwindInfo(const object::MachOObjectFile* o);
void printMachOExportsTrie(const object::MachOObjectFile* o);
+void printMachORebaseTable(const object::MachOObjectFile* o);
void printELFFileHeader(const object::ObjectFile *o);
void printCOFFFileHeader(const object::ObjectFile *o);
void printMachOFileHeader(const object::ObjectFile *o);
OpenPOWER on IntegriCloud