diff options
| -rw-r--r-- | llvm/tools/llvm-readobj/MachODumper.cpp | 79 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.h | 1 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 7 | 
3 files changed, 87 insertions, 0 deletions
diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp index 7b99a1ac90e..a7c5d23b7e4 100644 --- a/llvm/tools/llvm-readobj/MachODumper.cpp +++ b/llvm/tools/llvm-readobj/MachODumper.cpp @@ -44,6 +44,7 @@ public:    void printMachODataInCode() override;    void printMachOVersionMin() override;    void printMachODysymtab() override; +  void printMachOSegment() override;  private:    template<class MachHeader> @@ -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/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h index 22051708efa..5fea403322d 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.h +++ b/llvm/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/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index c0e6add4f2c..f63bc81002f 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/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<bool> +  MachOSegment("macho-segment", +                  cl::desc("Display MachO Segment command")); +    // -macho-version-min    cl::opt<bool>    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)  | 

