[llvm] r217853 - [llvm-objdump] for mach-o add -bind, -lazy-bind, and -weak-bind options
Nick Kledzik
kledzik at apple.com
Mon Sep 15 18:41:52 PDT 2014
Author: kledzik
Date: Mon Sep 15 20:41:51 2014
New Revision: 217853
URL: http://llvm.org/viewvc/llvm-project?rev=217853&view=rev
Log:
[llvm-objdump] for mach-o add -bind, -lazy-bind, and -weak-bind options
This finishes the ability of llvm-objdump to print out all information from
the LC_DYLD_INFO load command.
The -bind option prints out symbolic references that dyld must resolve
immediately.
The -lazy-bind option prints out symbolc reference that are lazily resolved on
first use.
The -weak-bind option prints out information about symbols which dyld must
try to coalesce across images.
Added:
llvm/trunk/test/tools/llvm-objdump/Inputs/bind.macho-x86_64 (with props)
llvm/trunk/test/tools/llvm-objdump/Inputs/lazy-bind.macho-x86_64 (with props)
llvm/trunk/test/tools/llvm-objdump/Inputs/weak-bind.macho-x86_64 (with props)
llvm/trunk/test/tools/llvm-objdump/macho-bind.test
llvm/trunk/test/tools/llvm-objdump/macho-lazy-bind.test
llvm/trunk/test/tools/llvm-objdump/macho-weak-bind.test
Modified:
llvm/trunk/include/llvm/Object/MachO.h
llvm/trunk/lib/Object/MachOObjectFile.cpp
llvm/trunk/tools/llvm-objdump/MachODump.cpp
llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
llvm/trunk/tools/llvm-objdump/llvm-objdump.h
Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=217853&r1=217852&r2=217853&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Mon Sep 15 20:41:51 2014
@@ -136,6 +136,54 @@ private:
};
typedef content_iterator<MachORebaseEntry> rebase_iterator;
+/// MachOBindEntry encapsulates the current state in the decompression of
+/// binding opcodes. This allows you to iterate through the compressed table of
+/// bindings using:
+/// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable()) {
+/// }
+class MachOBindEntry {
+public:
+ enum class Kind { Regular, Lazy, Weak };
+
+ MachOBindEntry(ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
+
+ uint32_t segmentIndex() const;
+ uint64_t segmentOffset() const;
+ StringRef typeName() const;
+ StringRef symbolName() const;
+ uint32_t flags() const;
+ int64_t addend() const;
+ int ordinal() const;
+
+ bool operator==(const MachOBindEntry &) const;
+
+ void moveNext();
+
+private:
+ friend class MachOObjectFile;
+ void moveToFirst();
+ void moveToEnd();
+ uint64_t readULEB128();
+ int64_t readSLEB128();
+
+ ArrayRef<uint8_t> Opcodes;
+ const uint8_t *Ptr;
+ uint64_t SegmentOffset;
+ uint32_t SegmentIndex;
+ StringRef SymbolName;
+ int Ordinal;
+ uint32_t Flags;
+ int64_t Addend;
+ uint64_t RemainingLoopCount;
+ uint64_t AdvanceAmount;
+ uint8_t BindType;
+ uint8_t PointerSize;
+ Kind TableKind;
+ bool Malformed;
+ bool Done;
+};
+typedef content_iterator<MachOBindEntry> bind_iterator;
+
class MachOObjectFile : public ObjectFile {
public:
struct LoadCommandInfo {
@@ -245,6 +293,21 @@ public:
static iterator_range<rebase_iterator> rebaseTable(ArrayRef<uint8_t> Opcodes,
bool is64);
+ /// For use iterating over all bind table entries.
+ iterator_range<bind_iterator> bindTable() const;
+
+ /// For use iterating over all lazy bind table entries.
+ iterator_range<bind_iterator> lazyBindTable() const;
+
+ /// For use iterating over all lazy bind table entries.
+ iterator_range<bind_iterator> weakBindTable() const;
+
+ /// For use examining bind opcodes not in a MachOObjectFile.
+ static iterator_range<bind_iterator> bindTable(ArrayRef<uint8_t> Opcodes,
+ bool is64,
+ MachOBindEntry::Kind);
+
+
// In a MachO file, sections have a segment name. This is used in the .o
// files. They have a single segment, but this field specifies which segment
// a section should be put in in the final object.
@@ -342,6 +405,8 @@ public:
bool isRelocatableObject() const override;
+ bool hasPageZeroSegment() const { return HasPageZeroSegment; }
+
static bool classof(const Binary *v) {
return v->isMachO();
}
@@ -357,6 +422,7 @@ private:
const char *DysymtabLoadCmd;
const char *DataInCodeLoadCmd;
const char *DyldInfoLoadCmd;
+ bool HasPageZeroSegment;
};
/// DiceRef
Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=217853&r1=217852&r2=217853&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Mon Sep 15 20:41:51 2014
@@ -58,6 +58,17 @@ getSegmentLoadCommandNumSections(const M
return S.nsects;
}
+static bool isPageZeroSegment(const MachOObjectFile *O,
+ const MachOObjectFile::LoadCommandInfo &L) {
+ if (O->is64Bit()) {
+ MachO::segment_command_64 S = O->getSegment64LoadCommand(L);
+ return StringRef("__PAGEZERO").equals(S.segname);
+ }
+ MachO::segment_command S = O->getSegmentLoadCommand(L);
+ return StringRef("__PAGEZERO").equals(S.segname);
+}
+
+
static const char *
getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
unsigned Sec) {
@@ -229,7 +240,8 @@ MachOObjectFile::MachOObjectFile(MemoryB
bool Is64bits, std::error_code &EC)
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
- DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr) {
+ DataInCodeLoadCmd(nullptr), DyldInfoLoadCmd(nullptr),
+ HasPageZeroSegment(false) {
uint32_t LoadCommandCount = this->getHeader().ncmds;
MachO::LoadCommandType SegmentLoadType = is64Bit() ?
MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
@@ -255,6 +267,8 @@ MachOObjectFile::MachOObjectFile(MemoryB
const char *Sec = getSectionPtr(this, Load, J);
Sections.push_back(Sec);
}
+ if (isPageZeroSegment(this, Load))
+ HasPageZeroSegment = true;
} else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
@@ -1860,6 +1874,272 @@ iterator_range<rebase_iterator> MachOObj
return rebaseTable(getDyldInfoRebaseOpcodes(), is64Bit());
}
+
+MachOBindEntry::MachOBindEntry(ArrayRef<uint8_t> Bytes, bool is64Bit,
+ Kind BK)
+ : Opcodes(Bytes), Ptr(Bytes.begin()), SegmentOffset(0), SegmentIndex(0),
+ Ordinal(0), Flags(0), Addend(0), RemainingLoopCount(0), AdvanceAmount(0),
+ BindType(0), PointerSize(is64Bit ? 8 : 4),
+ TableKind(BK), Malformed(false), Done(false) {}
+
+void MachOBindEntry::moveToFirst() {
+ Ptr = Opcodes.begin();
+ moveNext();
+}
+
+void MachOBindEntry::moveToEnd() {
+ Ptr = Opcodes.end();
+ RemainingLoopCount = 0;
+ Done = true;
+}
+
+void MachOBindEntry::moveNext() {
+ // If in the middle of some loop, move to next binding in loop.
+ SegmentOffset += AdvanceAmount;
+ if (RemainingLoopCount) {
+ --RemainingLoopCount;
+ return;
+ }
+ if (Ptr == Opcodes.end()) {
+ Done = true;
+ return;
+ }
+ bool More = true;
+ while (More && !Malformed) {
+ // Parse next opcode and set up next loop.
+ uint8_t Byte = *Ptr++;
+ uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK;
+ uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
+ int8_t SignExtended;
+ const uint8_t *SymStart;
+ switch (Opcode) {
+ case MachO::BIND_OPCODE_DONE:
+ if (TableKind == Kind::Lazy) {
+ // Lazying bindings have a DONE opcode between entries. Need to ignore
+ // it to advance to next entry. But need not if this is last entry.
+ bool NotLastEntry = false;
+ for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) {
+ if (*P) {
+ NotLastEntry = true;
+ }
+ }
+ if (NotLastEntry)
+ break;
+ }
+ More = false;
+ Done = true;
+ moveToEnd();
+ DEBUG_WITH_TYPE("mach-o-bind", llvm::dbgs() << "BIND_OPCODE_DONE\n");
+ break;
+ case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
+ Ordinal = ImmValue;
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: "
+ << "Ordinal=" << Ordinal << "\n");
+ break;
+ case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
+ Ordinal = readULEB128();
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: "
+ << "Ordinal=" << Ordinal << "\n");
+ break;
+ case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
+ if (ImmValue) {
+ SignExtended = MachO::BIND_OPCODE_MASK | ImmValue;
+ Ordinal = SignExtended;
+ } else
+ Ordinal = 0;
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: "
+ << "Ordinal=" << Ordinal << "\n");
+ break;
+ case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
+ Flags = ImmValue;
+ SymStart = Ptr;
+ while (*Ptr) {
+ ++Ptr;
+ }
+ ++Ptr;
+ SymbolName = StringRef(reinterpret_cast<const char*>(SymStart),
+ Ptr-SymStart);
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: "
+ << "SymbolName=" << SymbolName << "\n");
+ if (TableKind == Kind::Weak) {
+ if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION)
+ return;
+ }
+ break;
+ case MachO::BIND_OPCODE_SET_TYPE_IMM:
+ BindType = ImmValue;
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_SET_TYPE_IMM: "
+ << "BindType=" << (int)BindType << "\n");
+ break;
+ case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
+ Addend = readSLEB128();
+ if (TableKind == Kind::Lazy)
+ Malformed = true;
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: "
+ << "Addend=" << Addend << "\n");
+ break;
+ case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
+ SegmentIndex = ImmValue;
+ SegmentOffset = readULEB128();
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: "
+ << "SegmentIndex=" << SegmentIndex << ", "
+ << format("SegmentOffset=0x%06X", SegmentOffset)
+ << "\n");
+ break;
+ case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
+ SegmentOffset += readULEB128();
+ DEBUG_WITH_TYPE("mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: "
+ << format("SegmentOffset=0x%06X",
+ SegmentOffset) << "\n");
+ break;
+ case MachO::BIND_OPCODE_DO_BIND:
+ AdvanceAmount = PointerSize;
+ RemainingLoopCount = 0;
+ DEBUG_WITH_TYPE("mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_DO_BIND: "
+ << format("SegmentOffset=0x%06X",
+ SegmentOffset) << "\n");
+ return;
+ case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
+ AdvanceAmount = readULEB128();
+ RemainingLoopCount = 0;
+ if (TableKind == Kind::Lazy)
+ Malformed = true;
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_DO_BIND_IMM_TIMES: "
+ << format("SegmentOffset=0x%06X", SegmentOffset)
+ << ", AdvanceAmount=" << AdvanceAmount
+ << ", RemainingLoopCount=" << RemainingLoopCount
+ << "\n");
+ return;
+ case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
+ AdvanceAmount = ImmValue * PointerSize;
+ RemainingLoopCount = 0;
+ if (TableKind == Kind::Lazy)
+ Malformed = true;
+ DEBUG_WITH_TYPE("mach-o-bind",
+ llvm::dbgs()
+ << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: "
+ << format("SegmentOffset=0x%06X",
+ SegmentOffset) << "\n");
+ return;
+ case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
+ RemainingLoopCount = readULEB128() - 1;
+ AdvanceAmount = readULEB128() + PointerSize;
+ if (TableKind == Kind::Lazy)
+ Malformed = true;
+ DEBUG_WITH_TYPE(
+ "mach-o-bind",
+ llvm::dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: "
+ << format("SegmentOffset=0x%06X", SegmentOffset)
+ << ", AdvanceAmount=" << AdvanceAmount
+ << ", RemainingLoopCount=" << RemainingLoopCount
+ << "\n");
+ return;
+ default:
+ Malformed = true;
+ }
+ }
+}
+
+uint64_t MachOBindEntry::readULEB128() {
+ unsigned Count;
+ uint64_t Result = decodeULEB128(Ptr, &Count);
+ Ptr += Count;
+ if (Ptr > Opcodes.end()) {
+ Ptr = Opcodes.end();
+ Malformed = true;
+ }
+ return Result;
+}
+
+int64_t MachOBindEntry::readSLEB128() {
+ unsigned Count;
+ int64_t Result = decodeSLEB128(Ptr, &Count);
+ Ptr += Count;
+ if (Ptr > Opcodes.end()) {
+ Ptr = Opcodes.end();
+ Malformed = true;
+ }
+ return Result;
+}
+
+
+uint32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; }
+
+uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; }
+
+StringRef MachOBindEntry::typeName() const {
+ switch (BindType) {
+ case MachO::BIND_TYPE_POINTER:
+ return "pointer";
+ case MachO::BIND_TYPE_TEXT_ABSOLUTE32:
+ return "text abs32";
+ case MachO::BIND_TYPE_TEXT_PCREL32:
+ return "text rel32";
+ }
+ return "unknown";
+}
+
+StringRef MachOBindEntry::symbolName() const { return SymbolName; }
+
+int64_t MachOBindEntry::addend() const { return Addend; }
+
+uint32_t MachOBindEntry::flags() const { return Flags; }
+
+int MachOBindEntry::ordinal() const { return Ordinal; }
+
+bool MachOBindEntry::operator==(const MachOBindEntry &Other) const {
+ assert(Opcodes == Other.Opcodes && "compare iterators of different files");
+ return (Ptr == Other.Ptr) &&
+ (RemainingLoopCount == Other.RemainingLoopCount) &&
+ (Done == Other.Done);
+}
+
+iterator_range<bind_iterator>
+MachOObjectFile::bindTable(ArrayRef<uint8_t> Opcodes, bool is64,
+ MachOBindEntry::Kind BKind) {
+ MachOBindEntry Start(Opcodes, is64, BKind);
+ Start.moveToFirst();
+
+ MachOBindEntry Finish(Opcodes, is64, BKind);
+ Finish.moveToEnd();
+
+ return iterator_range<bind_iterator>(bind_iterator(Start),
+ bind_iterator(Finish));
+}
+
+iterator_range<bind_iterator> MachOObjectFile::bindTable() const {
+ return bindTable(getDyldInfoBindOpcodes(), is64Bit(),
+ MachOBindEntry::Kind::Regular);
+}
+
+iterator_range<bind_iterator> MachOObjectFile::lazyBindTable() const {
+ return bindTable(getDyldInfoLazyBindOpcodes(), is64Bit(),
+ MachOBindEntry::Kind::Lazy);
+}
+
+iterator_range<bind_iterator> MachOObjectFile::weakBindTable() const {
+ return bindTable(getDyldInfoWeakBindOpcodes(), is64Bit(),
+ MachOBindEntry::Kind::Weak);
+}
+
StringRef
MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
Added: llvm/trunk/test/tools/llvm-objdump/Inputs/bind.macho-x86_64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/bind.macho-x86_64?rev=217853&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/bind.macho-x86_64
------------------------------------------------------------------------------
svn:executable = *
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/bind.macho-x86_64
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: llvm/trunk/test/tools/llvm-objdump/Inputs/lazy-bind.macho-x86_64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/lazy-bind.macho-x86_64?rev=217853&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/lazy-bind.macho-x86_64
------------------------------------------------------------------------------
svn:executable = *
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/lazy-bind.macho-x86_64
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: llvm/trunk/test/tools/llvm-objdump/Inputs/weak-bind.macho-x86_64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/weak-bind.macho-x86_64?rev=217853&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/weak-bind.macho-x86_64
------------------------------------------------------------------------------
svn:executable = *
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/weak-bind.macho-x86_64
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: llvm/trunk/test/tools/llvm-objdump/macho-bind.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/macho-bind.test?rev=217853&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/macho-bind.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/macho-bind.test Mon Sep 15 20:41:51 2014
@@ -0,0 +1,10 @@
+# RUN: llvm-objdump -macho -bind -arch x86_64 \
+# RUN: %p/Inputs/bind.macho-x86_64 | FileCheck %s
+
+
+# CHECK:__DATA __data 0x00001028 pointer 0 flat-namespace _any
+# CHECK:__DATA __data 0x00001020 pointer 0 main-executable _fromApp
+# CHECK:__DATA __data 0x00001018 pointer 0 this-image _myfunc
+# CHECK:__DATA __data 0x00001000 pointer 0 libfoo.dylib _foo
+# CHECK:__DATA __data 0x00001008 pointer 0 libbar.dylib _bar
+# CHECK:__DATA __data 0x00001010 pointer 0 libSystem.B.dylib _malloc
Added: llvm/trunk/test/tools/llvm-objdump/macho-lazy-bind.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/macho-lazy-bind.test?rev=217853&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/macho-lazy-bind.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/macho-lazy-bind.test Mon Sep 15 20:41:51 2014
@@ -0,0 +1,7 @@
+# RUN: llvm-objdump -macho -lazy-bind -arch x86_64 \
+# RUN: %p/Inputs/lazy-bind.macho-x86_64 | FileCheck %s
+
+
+# CHECK: __DATA __la_symbol_ptr 0x100001010 libfoo.dylib _foo
+# CHECK: __DATA __la_symbol_ptr 0x100001018 libbar.dylib _bar
+# CHECK: __DATA __la_symbol_ptr 0x100001020 libSystem.B.dylib _malloc
Added: llvm/trunk/test/tools/llvm-objdump/macho-weak-bind.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/macho-weak-bind.test?rev=217853&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/macho-weak-bind.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/macho-weak-bind.test Mon Sep 15 20:41:51 2014
@@ -0,0 +1,10 @@
+# RUN: llvm-objdump -macho -weak-bind -arch x86_64 \
+# RUN: %p/Inputs/weak-bind.macho-x86_64 | FileCheck %s
+
+
+# CHECK: __DATA __data 0x100001018 pointer 0 __ZTISt12out_of_range
+# CHECK: __DATA __data 0x100001020 pointer 0 __ZTISt12out_of_range
+# CHECK: __DATA __data 0x100001028 pointer 0 __ZTISt12out_of_range
+# CHECK: strong __ZdlPv
+# CHECK: __DATA __data 0x100001018 pointer 0 __Znam
+# CHECK: strong __Znwm
Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=217853&r1=217852&r2=217853&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Mon Sep 15 20:41:51 2014
@@ -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 o
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";
+ }
+}
+
+
Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=217853&r1=217852&r2=217853&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Mon Sep 15 20:41:51 2014
@@ -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 Objec
}
}
+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
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;
}
Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=217853&r1=217852&r2=217853&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Mon Sep 15 20:41:51 2014
@@ -37,6 +37,9 @@ void printCOFFUnwindInfo(const object::C
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);
More information about the llvm-commits
mailing list