summaryrefslogtreecommitdiffstats
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp117
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp52
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h3
3 files changed, 170 insertions, 2 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 4d751099792..821cf82f418 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -2178,7 +2178,7 @@ private:
SegInfo::SegInfo(const object::MachOObjectFile *Obj) {
// Build table of sections so segIndex/offset pairs can be translated.
- uint32_t CurSegIndex = 0;
+ uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
StringRef CurSegName;
uint64_t CurSegAddress;
for (const SectionRef &Section : Obj->sections()) {
@@ -2253,3 +2253,118 @@ void llvm::printMachORebaseTable(const object::MachOObjectFile *Obj) {
Entry.typeName().str().c_str());
}
}
+
+static StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
+ StringRef DylibName;
+ switch (Ordinal) {
+ case MachO::BIND_SPECIAL_DYLIB_SELF:
+ return "this-image";
+ case MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
+ return "main-executable";
+ case MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
+ return "flat-namespace";
+ default:
+ Obj->getLibraryShortNameByIndex(Ordinal-1, DylibName);
+ return DylibName;
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// bind table dumping
+//===----------------------------------------------------------------------===//
+
+void llvm::printMachOBindTable(const object::MachOObjectFile *Obj) {
+ // Build table of sections so names can used in final output.
+ SegInfo sectionTable(Obj);
+
+ outs() << "segment section address type "
+ "addend dylib symbol\n";
+ for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable()) {
+ 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 __got 0x00012010 pointer 0 libSystem ___stack_chk_guard
+ outs() << format("%-8s %-18s 0x%08" PRIX64 " %-8s %-8" PRId64 " %-20s",
+ SegmentName.str().c_str(),
+ SectionName.str().c_str(),
+ Address,
+ Entry.typeName().str().c_str(),
+ Entry.addend(),
+ ordinalName(Obj, Entry.ordinal()))
+ << Entry.symbolName();
+ if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT)
+ outs() << " (weak_import)\n";
+ else
+ outs() << "\n";
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// lazy bind table dumping
+//===----------------------------------------------------------------------===//
+
+void llvm::printMachOLazyBindTable(const object::MachOObjectFile *Obj) {
+ // Build table of sections so names can used in final output.
+ SegInfo sectionTable(Obj);
+
+ outs() << "segment section address "
+ "dylib symbol\n";
+ for (const llvm::object::MachOBindEntry &Entry : Obj->lazyBindTable()) {
+ 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 __got 0x00012010 libSystem ___stack_chk_guard
+ outs() << format("%-8s %-18s 0x%08" PRIX64 " %-20s",
+ SegmentName.str().c_str(),
+ SectionName.str().c_str(),
+ Address,
+ ordinalName(Obj, Entry.ordinal()))
+ << Entry.symbolName() << "\n";
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// weak bind table dumping
+//===----------------------------------------------------------------------===//
+
+void llvm::printMachOWeakBindTable(const object::MachOObjectFile *Obj) {
+ // Build table of sections so names can used in final output.
+ SegInfo sectionTable(Obj);
+
+ outs() << "segment section address "
+ "type addend symbol\n";
+ for (const llvm::object::MachOBindEntry &Entry : Obj->weakBindTable()) {
+ // Strong symbols don't have a location to update.
+ if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
+ outs() << " strong "
+ << Entry.symbolName() << "\n";
+ continue;
+ }
+ 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 __data 0x00001000 pointer 0 _foo
+ outs() << format("%-8s %-18s 0x%08" PRIX64 " %-8s %-8" PRId64 " ",
+ SegmentName.str().c_str(),
+ SectionName.str().c_str(),
+ Address,
+ Entry.typeName().str().c_str(),
+ Entry.addend())
+ << Entry.symbolName() << "\n";
+ }
+}
+
+
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 790d08a1fc2..12cf1f72b09 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -85,6 +85,15 @@ static cl::opt<bool>
Rebase("rebase", cl::desc("Display mach-o rebasing info"));
static cl::opt<bool>
+Bind("bind", cl::desc("Display mach-o binding info"));
+
+static cl::opt<bool>
+LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
+
+static cl::opt<bool>
+WeakBind("weak-bind", cl::desc("Display mach-o weak binding 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));
@@ -736,6 +745,38 @@ static void printRebaseTable(const ObjectFile *o) {
}
}
+static void printBindTable(const ObjectFile *o) {
+ outs() << "Bind table:\n";
+ if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+ printMachOBindTable(MachO);
+ else {
+ errs() << "This operation is only currently supported "
+ "for Mach-O executable files.\n";
+ return;
+ }
+}
+
+static void printLazyBindTable(const ObjectFile *o) {
+ outs() << "Lazy bind table:\n";
+ if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+ printMachOLazyBindTable(MachO);
+ else {
+ errs() << "This operation is only currently supported "
+ "for Mach-O executable files.\n";
+ return;
+ }
+}
+
+static void printWeakBindTable(const ObjectFile *o) {
+ outs() << "Weak bind table:\n";
+ if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
+ printMachOWeakBindTable(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()) {
@@ -770,6 +811,12 @@ static void DumpObject(const ObjectFile *o) {
printExportsTrie(o);
if (Rebase)
printRebaseTable(o);
+ if (Bind)
+ printBindTable(o);
+ if (LazyBind)
+ printLazyBindTable(o);
+ if (WeakBind)
+ printWeakBindTable(o);
}
/// @brief Dump each object file in \a a;
@@ -853,7 +900,10 @@ int main(int argc, char **argv) {
&& !UnwindInfo
&& !PrivateHeaders
&& !ExportsTrie
- && !Rebase) {
+ && !Rebase
+ && !Bind
+ && !LazyBind
+ && !WeakBind) {
cl::PrintHelpMessage();
return 2;
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index a328e635ee0..cae10354a91 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -37,6 +37,9 @@ 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 printMachOBindTable(const object::MachOObjectFile* o);
+void printMachOLazyBindTable(const object::MachOObjectFile* o);
+void printMachOWeakBindTable(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