summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp68
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h1
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp6
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();
OpenPOWER on IntegriCloud