aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Object/MachOFormat.h31
-rw-r--r--include/llvm/Object/MachOObject.h8
-rw-r--r--lib/Object/MachOObject.cpp46
-rw-r--r--tools/macho-dump/macho-dump.cpp78
4 files changed, 157 insertions, 6 deletions
diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h
index a6f0afbd94..320140773d 100644
--- a/include/llvm/Object/MachOFormat.h
+++ b/include/llvm/Object/MachOFormat.h
@@ -219,7 +219,38 @@ namespace macho {
};
/// @}
+ /// @name Section Data
+ /// @{
+
+ struct Section {
+ char Name[16];
+ char SegmentName[16];
+ uint32_t Address;
+ uint32_t Size;
+ uint32_t Offset;
+ uint32_t Align;
+ uint32_t RelocationTableOffset;
+ uint32_t NumRelocationTableEntries;
+ uint32_t Flags;
+ uint32_t Reserved1;
+ uint32_t Reserved2;
+ };
+ struct Section64 {
+ char Name[16];
+ char SegmentName[16];
+ uint64_t Address;
+ uint64_t Size;
+ uint32_t Offset;
+ uint32_t Align;
+ uint32_t RelocationTableOffset;
+ uint32_t NumRelocationTableEntries;
+ uint32_t Flags;
+ uint32_t Reserved1;
+ uint32_t Reserved2;
+ uint32_t Reserved3;
+ };
+ /// @}
/// @name Indirect Symbol Table
/// @{
diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h
index 79fbfd21b6..77a8d3592e 100644
--- a/include/llvm/Object/MachOObject.h
+++ b/include/llvm/Object/MachOObject.h
@@ -129,6 +129,14 @@ public:
const macho::DysymtabLoadCommand &DLC,
unsigned Index,
InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
+ void ReadSection(
+ const LoadCommandInfo &LCI,
+ unsigned Index,
+ InMemoryStruct<macho::Section> &Res) const;
+ void ReadSection64(
+ const LoadCommandInfo &LCI,
+ unsigned Index,
+ InMemoryStruct<macho::Section64> &Res) const;
/// @}
};
diff --git a/lib/Object/MachOObject.cpp b/lib/Object/MachOObject.cpp
index 236dfe0ce5..1e9ec70d42 100644
--- a/lib/Object/MachOObject.cpp
+++ b/lib/Object/MachOObject.cpp
@@ -243,3 +243,49 @@ MachOObject::ReadIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC,
Index * sizeof(macho::IndirectSymbolTableEntry));
ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
}
+
+
+template<>
+void SwapStruct(macho::Section &Value) {
+ SwapValue(Value.Address);
+ SwapValue(Value.Size);
+ SwapValue(Value.Offset);
+ SwapValue(Value.Align);
+ SwapValue(Value.RelocationTableOffset);
+ SwapValue(Value.NumRelocationTableEntries);
+ SwapValue(Value.Flags);
+ SwapValue(Value.Reserved1);
+ SwapValue(Value.Reserved2);
+}
+void MachOObject::ReadSection(const LoadCommandInfo &LCI,
+ unsigned Index,
+ InMemoryStruct<macho::Section> &Res) const {
+ assert(LCI.Command.Type == macho::LCT_Segment &&
+ "Unexpected load command info!");
+ uint64_t Offset = (LCI.Offset + sizeof(macho::SegmentLoadCommand) +
+ Index * sizeof(macho::Section));
+ ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
+}
+
+template<>
+void SwapStruct(macho::Section64 &Value) {
+ SwapValue(Value.Address);
+ SwapValue(Value.Size);
+ SwapValue(Value.Offset);
+ SwapValue(Value.Align);
+ SwapValue(Value.RelocationTableOffset);
+ SwapValue(Value.NumRelocationTableEntries);
+ SwapValue(Value.Flags);
+ SwapValue(Value.Reserved1);
+ SwapValue(Value.Reserved2);
+ SwapValue(Value.Reserved3);
+}
+void MachOObject::ReadSection64(const LoadCommandInfo &LCI,
+ unsigned Index,
+ InMemoryStruct<macho::Section64> &Res) const {
+ assert(LCI.Command.Type == macho::LCT_Segment64 &&
+ "Unexpected load command info!");
+ uint64_t Offset = (LCI.Offset + sizeof(macho::Segment64LoadCommand) +
+ Index * sizeof(macho::Section64));
+ ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
+}
diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp
index 487a00607b..68e61ba8d6 100644
--- a/tools/macho-dump/macho-dump.cpp
+++ b/tools/macho-dump/macho-dump.cpp
@@ -25,7 +25,7 @@ static cl::opt<std::string>
InputFile(cl::Positional, cl::desc("<input file>"), cl::init("-"));
static cl::opt<bool>
-DumpSectionData("dump-section-data", cl::desc("Dump the contents of sections"),
+ShowSectionData("dump-section-data", cl::desc("Dump the contents of sections"),
cl::init(false));
///
@@ -83,6 +83,31 @@ static void DumpSegmentCommandData(StringRef Name,
outs() << " ('flags', " << Flags << ")\n";
}
+static void DumpSectionData(unsigned Index, StringRef Name,
+ StringRef SegmentName, uint64_t Address,
+ uint64_t Size, uint32_t Offset,
+ uint32_t Align, uint32_t RelocationTableOffset,
+ uint32_t NumRelocationTableEntries,
+ uint32_t Flags, uint32_t Reserved1,
+ uint32_t Reserved2, uint64_t Reserved3 = ~0ULL) {
+ outs() << " # Section " << Index << "\n";
+ outs() << " (('section_name', '";
+ outs().write_escaped(Name, /*UseHexEscapes=*/true) << "')\n";
+ outs() << " ('segment_name', '";
+ outs().write_escaped(SegmentName, /*UseHexEscapes=*/true) << "')\n";
+ outs() << " ('address', " << Address << ")\n";
+ outs() << " ('size', " << Size << ")\n";
+ outs() << " ('offset', " << Offset << ")\n";
+ outs() << " ('alignment', " << Align << ")\n";
+ outs() << " ('reloc_offset', " << RelocationTableOffset << ")\n";
+ outs() << " ('num_reloc', " << NumRelocationTableEntries << ")\n";
+ outs() << " ('flags', " << format("%#x", Flags) << ")\n";
+ outs() << " ('reserved1', " << Reserved1 << ")\n";
+ outs() << " ('reserved2', " << Reserved2 << ")\n";
+ if (Reserved3 != ~0ULL)
+ outs() << " ('reserved3', " << Reserved3 << ")\n";
+}
+
static int DumpSegmentCommand(MachOObject &Obj,
const MachOObject::LoadCommandInfo &LCI) {
InMemoryStruct<macho::SegmentLoadCommand> SLC;
@@ -90,13 +115,34 @@ static int DumpSegmentCommand(MachOObject &Obj,
if (!SLC)
return Error("unable to read segment load command");
- DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress, SLC->VMSize,
- SLC->FileOffset, SLC->FileSize,
+ DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress,
+ SLC->VMSize, SLC->FileOffset, SLC->FileSize,
SLC->MaxVMProtection, SLC->InitialVMProtection,
SLC->NumSections, SLC->Flags);
- return 0;
+ // Dump the sections.
+ int Res = 0;
+ outs() << " ('sections', [\n";
+ for (unsigned i = 0; i != SLC->NumSections; ++i) {
+ InMemoryStruct<macho::Section> Sect;
+ Obj.ReadSection(LCI, i, Sect);
+ if (!SLC) {
+ Res = Error("unable to read section '" + Twine(i) + "'");
+ break;
+ }
+
+ DumpSectionData(i, StringRef(Sect->Name, 16),
+ StringRef(Sect->SegmentName, 16), Sect->Address, Sect->Size,
+ Sect->Offset, Sect->Align, Sect->RelocationTableOffset,
+ Sect->NumRelocationTableEntries, Sect->Flags,
+ Sect->Reserved1, Sect->Reserved2);
+ outs() << " ),\n";
+ }
+ outs() << " ])\n";
+
+ return Res;
}
+
static int DumpSegment64Command(MachOObject &Obj,
const MachOObject::LoadCommandInfo &LCI) {
InMemoryStruct<macho::Segment64LoadCommand> SLC;
@@ -104,11 +150,31 @@ static int DumpSegment64Command(MachOObject &Obj,
if (!SLC)
return Error("unable to read segment load command");
- DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress, SLC->VMSize,
- SLC->FileOffset, SLC->FileSize,
+ DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress,
+ SLC->VMSize, SLC->FileOffset, SLC->FileSize,
SLC->MaxVMProtection, SLC->InitialVMProtection,
SLC->NumSections, SLC->Flags);
+ // Dump the sections.
+ int Res = 0;
+ outs() << " ('sections', [\n";
+ for (unsigned i = 0; i != SLC->NumSections; ++i) {
+ InMemoryStruct<macho::Section64> Sect;
+ Obj.ReadSection64(LCI, i, Sect);
+ if (!SLC) {
+ Res = Error("unable to read section '" + Twine(i) + "'");
+ break;
+ }
+
+ DumpSectionData(i, StringRef(Sect->Name, 16),
+ StringRef(Sect->SegmentName, 16), Sect->Address, Sect->Size,
+ Sect->Offset, Sect->Align, Sect->RelocationTableOffset,
+ Sect->NumRelocationTableEntries, Sect->Flags,
+ Sect->Reserved1, Sect->Reserved2, Sect->Reserved3);
+ outs() << " ),\n";
+ }
+ outs() << " ])\n";
+
return 0;
}