1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[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
This commit is contained in:
Simon Atanasyan 2016-05-04 05:58:57 +00:00
parent 87e1a609f6
commit eba22b7e3c
5 changed files with 81 additions and 8 deletions

Binary file not shown.

View File

@ -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: }

View 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;
}
auto *Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(Sec.data());
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]);
auto *Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(Sec.data());
printMipsReginfoData(W, *Reginfo);
}
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 {

View 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() { }

View 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();