]> granicus.if.org Git - llvm/commitdiff
[llvm-readobj] Print MIPS .MIPS.options section content
authorSimon Atanasyan <simon@atanasyan.com>
Wed, 4 May 2016 05:58:57 +0000 (05:58 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Wed, 4 May 2016 05:58:57 +0000 (05:58 +0000)
.MIPS.options section specifies miscellaneous options to be applied
to an object file. LLVM as well as modern versions of GNU tools emit
the only type of the options - ODK_REGINFO. The patch teaches llvm-readobj
to print details of the ODK_REGINFO and skip contents of other options.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268478 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-readobj/Inputs/options.obj.elf-mipsel [new file with mode: 0644]
test/tools/llvm-readobj/mips-options-sec.test [new file with mode: 0644]
tools/llvm-readobj/ELFDumper.cpp
tools/llvm-readobj/ObjDumper.h
tools/llvm-readobj/llvm-readobj.cpp

diff --git a/test/tools/llvm-readobj/Inputs/options.obj.elf-mipsel b/test/tools/llvm-readobj/Inputs/options.obj.elf-mipsel
new file mode 100644 (file)
index 0000000..6309d87
Binary files /dev/null and b/test/tools/llvm-readobj/Inputs/options.obj.elf-mipsel differ
diff --git a/test/tools/llvm-readobj/mips-options-sec.test b/test/tools/llvm-readobj/mips-options-sec.test
new file mode 100644 (file)
index 0000000..0fe8aad
--- /dev/null
@@ -0,0 +1,12 @@
+RUN: llvm-readobj -mips-options %p/Inputs/options.obj.elf-mipsel | FileCheck %s
+
+CHECK:      MIPS Options {
+CHECK-NEXT:   ODK_REGINFO {
+CHECK-NEXT:     GP: 0x0
+CHECK-NEXT:     General Mask: 0xF2000017
+CHECK-NEXT:     Co-Proc Mask0: 0x0
+CHECK-NEXT:     Co-Proc Mask1: 0x0
+CHECK-NEXT:     Co-Proc Mask2: 0x0
+CHECK-NEXT:     Co-Proc Mask3: 0x0
+CHECK-NEXT:   }
+CHECK-NEXT: }
index 31bf56935021f4455ce5f30e53e2f8ed90ae6669..8315cedf7be18591f43426929726ba45343d244f 100644 (file)
@@ -120,6 +120,7 @@ public:
   void printMipsPLTGOT() override;
   void printMipsABIFlags() override;
   void printMipsReginfo() override;
+  void printMipsOptions() override;
 
   void printStackMap() const override;
 
@@ -1214,6 +1215,25 @@ static const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {
   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)
 };
 
+static const char *getElfMipsOptionsOdkType(unsigned Odk) {
+  switch (Odk) {
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_REGINFO);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_EXCEPTIONS);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAD);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWPATCH);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_FILL);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_TAGS);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWAND);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWOR);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_GP_GROUP);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_IDENT);
+  LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAGESIZE);
+  default:
+    return "Unknown";
+  }
+}
+
 template <typename ELFT>
 ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer)
     : ObjDumper(Writer), Obj(Obj) {
@@ -2187,6 +2207,17 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() {
   W.printHex("Flags 2", Flags->flags2);
 }
 
+template <class ELFT>
+static void printMipsReginfoData(ScopedPrinter &W,
+                                 const Elf_Mips_RegInfo<ELFT> &Reginfo) {
+  W.printHex("GP", Reginfo.ri_gp_value);
+  W.printHex("General Mask", Reginfo.ri_gprmask);
+  W.printHex("Co-Proc Mask0", Reginfo.ri_cprmask[0]);
+  W.printHex("Co-Proc Mask1", Reginfo.ri_cprmask[1]);
+  W.printHex("Co-Proc Mask2", Reginfo.ri_cprmask[2]);
+  W.printHex("Co-Proc Mask3", Reginfo.ri_cprmask[3]);
+}
+
 template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
   const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo");
   if (!Shdr) {
@@ -2199,15 +2230,38 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
     return;
   }
 
+  DictScope GS(W, "MIPS RegInfo");
   auto *Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(Sec.data());
+  printMipsReginfoData(W, *Reginfo);
+}
 
-  DictScope GS(W, "MIPS RegInfo");
-  W.printHex("GP", Reginfo->ri_gp_value);
-  W.printHex("General Mask", Reginfo->ri_gprmask);
-  W.printHex("Co-Proc Mask0", Reginfo->ri_cprmask[0]);
-  W.printHex("Co-Proc Mask1", Reginfo->ri_cprmask[1]);
-  W.printHex("Co-Proc Mask2", Reginfo->ri_cprmask[2]);
-  W.printHex("Co-Proc Mask3", Reginfo->ri_cprmask[3]);
+template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
+  const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.options");
+  if (!Shdr) {
+    W.startLine() << "There is no .MIPS.options section in the file.\n";
+    return;
+  }
+
+  DictScope GS(W, "MIPS Options");
+
+  ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr));
+  while (!Sec.empty()) {
+    if (Sec.size() < sizeof(Elf_Mips_Options<ELFT>)) {
+      W.startLine() << "The .MIPS.options section has a wrong size.\n";
+      return;
+    }
+    auto *O = reinterpret_cast<const Elf_Mips_Options<ELFT> *>(Sec.data());
+    DictScope GS(W, getElfMipsOptionsOdkType(O->kind));
+    switch (O->kind) {
+    case ODK_REGINFO:
+      printMipsReginfoData(W, O->getRegInfo());
+      break;
+    default:
+      W.startLine() << "Unsupported MIPS options tag.\n";
+      break;
+    }
+    Sec = Sec.slice(O->size);
+  }
 }
 
 template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
index e34789e1bdb0132fee72e558c13133fe16cee517..318a171d49d1b1fc59e0fc2aee07c73979cf2655 100644 (file)
@@ -52,6 +52,7 @@ public:
   virtual void printMipsPLTGOT() { }
   virtual void printMipsABIFlags() { }
   virtual void printMipsReginfo() { }
+  virtual void printMipsOptions() { }
 
   // Only implemented for PE/COFF.
   virtual void printCOFFImports() { }
index fe075a54f966b95124e82c1262dc524fe8cd1e2c..c2964c5f5e1cca714f842f02ef1c09241641b53a 100644 (file)
@@ -168,6 +168,10 @@ namespace opts {
   cl::opt<bool> MipsReginfo("mips-reginfo",
                             cl::desc("Display the MIPS .reginfo section"));
 
+  // -mips-options
+  cl::opt<bool> MipsOptions("mips-options",
+                            cl::desc("Display the MIPS .MIPS.options section"));
+
   // -coff-imports
   cl::opt<bool>
   COFFImports("coff-imports", cl::desc("Display the PE/COFF import table"));
@@ -363,6 +367,8 @@ static void dumpObject(const ObjectFile *Obj) {
         Dumper->printMipsABIFlags();
       if (opts::MipsReginfo)
         Dumper->printMipsReginfo();
+      if (opts::MipsOptions)
+        Dumper->printMipsOptions();
     }
     if (opts::SectionGroups)
       Dumper->printGroupSections();