From: Davide Italiano Date: Wed, 2 Sep 2015 16:24:24 +0000 (+0000) Subject: [llvm-readobj] MachO: Dump segment command. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=885eb98ce3c45970f097b180a0b7c1dc3f59649c [llvm-readobj] MachO: Dump segment command. Example output: File: Format: Mach-O arm Arch: arm AddressSize: 32bit Segment { Cmd: LC_SEGMENT Name: Size: 260 vmaddr: 0x0 vmsize: 0x10 fileoff: 408 filesize: 408 maxprot: rwx initprot: rwx nsects: 3 flags: 0x0 } Differential Revision: http://reviews.llvm.org/D12542 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246665 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 7b99a1ac90e..a7c5d23b7e4 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -44,6 +44,7 @@ public: void printMachODataInCode() override; void printMachOVersionMin() override; void printMachODysymtab() override; + void printMachOSegment() override; private: template @@ -263,6 +264,20 @@ namespace { uint32_t Reserved3; }; + struct MachOSegment { + StringRef CmdName; + StringRef SegName; + uint64_t cmdsize; + uint64_t vmaddr; + uint64_t vmsize; + uint64_t fileoff; + uint64_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; + }; + struct MachOSymbol { uint32_t StringIndex; uint8_t Type; @@ -272,6 +287,18 @@ namespace { }; } +static std::string getMask(uint32_t prot) +{ + // TODO (davide): This always assumes prot is valid. + // Catch mistakes and report if needed. + std::string Prot; + Prot = ""; + Prot += (prot & MachO::VM_PROT_READ) ? "r" : "-"; + Prot += (prot & MachO::VM_PROT_WRITE) ? "w" : "-"; + Prot += (prot & MachO::VM_PROT_EXECUTE) ? "x" : "-"; + return Prot; +} + static void getSection(const MachOObjectFile *Obj, DataRefImpl Sec, MachOSection &Section) { @@ -301,6 +328,37 @@ static void getSection(const MachOObjectFile *Obj, Section.Reserved3 = Sect.reserved3; } +static void getSegment(const MachOObjectFile *Obj, + const MachOObjectFile::LoadCommandInfo &L, + MachOSegment &Segment) { + if (!Obj->is64Bit()) { + MachO::segment_command SC = Obj->getSegmentLoadCommand(L); + Segment.CmdName = "LC_SEGMENT"; + Segment.SegName = SC.segname; + Segment.cmdsize = SC.cmdsize; + Segment.vmaddr = SC.vmaddr; + Segment.vmsize = SC.vmsize; + Segment.fileoff = SC.fileoff; + Segment.filesize = SC.filesize; + Segment.maxprot = SC.maxprot; + Segment.initprot = SC.initprot; + Segment.nsects = SC.nsects; + Segment.flags = SC.flags; + return; + } + MachO::segment_command_64 SC = Obj->getSegment64LoadCommand(L); + Segment.CmdName = "LC_SEGMENT_64"; + Segment.SegName = SC.segname; + Segment.cmdsize = SC.cmdsize; + Segment.vmaddr = SC.vmaddr; + Segment.vmsize = SC.vmsize; + Segment.fileoff = SC.fileoff; + Segment.filesize = SC.filesize; + Segment.maxprot = SC.maxprot; + Segment.initprot = SC.initprot; + Segment.nsects = SC.nsects; + Segment.flags = SC.flags; +} static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, @@ -695,3 +753,24 @@ void MachODumper::printMachODysymtab() { } } } + +void MachODumper::printMachOSegment() { + for (const auto &Load : Obj->load_commands()) { + if (Load.C.cmd == MachO::LC_SEGMENT || Load.C.cmd == MachO::LC_SEGMENT_64) { + MachOSegment MOSegment; + getSegment(Obj, Load, MOSegment); + DictScope Group(W, "Segment"); + W.printString("Cmd", MOSegment.CmdName); + W.printString("Name", MOSegment.SegName); + W.printNumber("Size", MOSegment.cmdsize); + W.printHex("vmaddr", MOSegment.vmaddr); + W.printHex("vmsize", MOSegment.vmsize); + W.printNumber("fileoff", MOSegment.fileoff); + W.printNumber("filesize", MOSegment.fileoff); + W.printString("maxprot", getMask(MOSegment.maxprot)); + W.printString("initprot", getMask(MOSegment.initprot)); + W.printNumber("nsects", MOSegment.nsects); + W.printHex("flags", MOSegment.flags); + } + } +} diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index 22051708efa..5fea403322d 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -59,6 +59,7 @@ public: virtual void printMachODataInCode() { } virtual void printMachOVersionMin() { } virtual void printMachODysymtab() { } + virtual void printMachOSegment() { } virtual void printStackMap() const = 0; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index c0e6add4f2c..f63bc81002f 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -187,6 +187,11 @@ namespace opts { MachODataInCode("macho-data-in-code", cl::desc("Display MachO Data in Code command")); + // -macho-segment + cl::opt + MachOSegment("macho-segment", + cl::desc("Display MachO Segment command")); + // -macho-version-min cl::opt MachOVersionMin("macho-version-min", @@ -331,6 +336,8 @@ static void dumpObject(const ObjectFile *Obj) { if (Obj->isMachO()) { if (opts::MachODataInCode) Dumper->printMachODataInCode(); + if (opts::MachOSegment) + Dumper->printMachOSegment(); if (opts::MachOVersionMin) Dumper->printMachOVersionMin(); if (opts::MachODysymtab)