diff options
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 68 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.h | 1 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 6 |
3 files changed, 68 insertions, 7 deletions
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<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 { 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<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(); |