From 8a71b53ea9bab7fe0f8e01a89a427e78cbc46df3 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 4 May 2016 05:58:57 +0000 Subject: [llvm-readobj] Print MIPS .MIPS.options section content .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. llvm-svn: 268478 --- llvm/tools/llvm-readobj/ELFDumper.cpp | 68 ++++++++++++++++++++++++++++---- llvm/tools/llvm-readobj/ObjDumper.h | 1 + llvm/tools/llvm-readobj/llvm-readobj.cpp | 6 +++ 3 files changed, 68 insertions(+), 7 deletions(-) (limited to 'llvm/tools/llvm-readobj') diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 31bf5693502..8315cedf7be 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -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 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 ELFDumper::ELFDumper(const ELFFile *Obj, ScopedPrinter &Writer) : ObjDumper(Writer), Obj(Obj) { @@ -2187,6 +2207,17 @@ template void ELFDumper::printMipsABIFlags() { W.printHex("Flags 2", Flags->flags2); } +template +static void printMipsReginfoData(ScopedPrinter &W, + const Elf_Mips_RegInfo &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 void ELFDumper::printMipsReginfo() { const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo"); if (!Shdr) { @@ -2199,15 +2230,38 @@ template void ELFDumper::printMipsReginfo() { return; } + DictScope GS(W, "MIPS RegInfo"); auto *Reginfo = reinterpret_cast *>(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 void ELFDumper::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 Sec = unwrapOrError(Obj->getSectionContents(Shdr)); + while (!Sec.empty()) { + if (Sec.size() < sizeof(Elf_Mips_Options)) { + W.startLine() << "The .MIPS.options section has a wrong size.\n"; + return; + } + auto *O = reinterpret_cast *>(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 void ELFDumper::printStackMap() const { diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h index e34789e1bdb..318a171d49d 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.h +++ b/llvm/tools/llvm-readobj/ObjDumper.h @@ -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() { } diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index fe075a54f96..c2964c5f5e1 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -168,6 +168,10 @@ namespace opts { cl::opt MipsReginfo("mips-reginfo", cl::desc("Display the MIPS .reginfo section")); + // -mips-options + cl::opt MipsOptions("mips-options", + cl::desc("Display the MIPS .MIPS.options section")); + // -coff-imports cl::opt 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(); -- cgit v1.2.3