diff options
author | Simon Atanasyan <simon@atanasyan.com> | 2015-05-07 15:40:35 +0000 |
---|---|---|
committer | Simon Atanasyan <simon@atanasyan.com> | 2015-05-07 15:40:35 +0000 |
commit | c914de277059a2962178e3bf7d5ad50ad01ba73a (patch) | |
tree | 7262d2bcdf803abd704ff55df93bfb8938e9f952 /llvm/tools/llvm-readobj/ELFDumper.cpp | |
parent | 919ef9dc37f7b222fe7f11af5889c3a86a4c2469 (diff) | |
download | bcm5719-llvm-c914de277059a2962178e3bf7d5ad50ad01ba73a.tar.gz bcm5719-llvm-c914de277059a2962178e3bf7d5ad50ad01ba73a.zip |
[llvm-readobj] Print .MIPS.abiflags section content
This change adds new flag -mips-abi-flags to the llvm-readobj. This flag
forces printing of .MIPS.abiflags section content.
https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking#10.2.1._.MIPS.abiflags
llvm-svn: 236737
Diffstat (limited to 'llvm/tools/llvm-readobj/ELFDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index ed4dd2c5a70..8fa40c3c8ca 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -26,6 +26,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/MipsABIFlags.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -56,6 +57,7 @@ public: void printAttributes() override; void printMipsPLTGOT() override; + void printMipsABIFlags() override; private: typedef ELFFile<ELFT> ELFO; @@ -170,6 +172,16 @@ findSectionByAddress(const ELFFile<ELFT> *Obj, uint64_t Addr) { return nullptr; } +template <class ELFT> +static const typename ELFFile<ELFT>::Elf_Shdr * +findSectionByName(const ELFFile<ELFT> &Obj, StringRef Name) { + for (const auto &Shdr : Obj.sections()) { + if (Name == errorOrDefault(Obj.getSectionName(&Shdr))) + return &Shdr; + } + return nullptr; +} + static const EnumEntry<unsigned> ElfClass[] = { { "None", ELF::ELFCLASSNONE }, { "32-bit", ELF::ELFCLASS32 }, @@ -1249,3 +1261,112 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() { MipsGOTParser<ELFT>(Obj, W).parseGOT(*GotShdr); } + +static const EnumEntry<unsigned> ElfMipsISAExtType[] = { + {"None", Mips::AFL_EXT_NONE}, + {"Broadcom SB-1", Mips::AFL_EXT_SB1}, + {"Cavium Networks Octeon", Mips::AFL_EXT_OCTEON}, + {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2}, + {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP}, + {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3}, + {"LSI R4010", Mips::AFL_EXT_4010}, + {"Loongson 2E", Mips::AFL_EXT_LOONGSON_2E}, + {"Loongson 2F", Mips::AFL_EXT_LOONGSON_2F}, + {"Loongson 3A", Mips::AFL_EXT_LOONGSON_3A}, + {"MIPS R4650", Mips::AFL_EXT_4650}, + {"MIPS R5900", Mips::AFL_EXT_5900}, + {"MIPS R10000", Mips::AFL_EXT_10000}, + {"NEC VR4100", Mips::AFL_EXT_4100}, + {"NEC VR4111/VR4181", Mips::AFL_EXT_4111}, + {"NEC VR4120", Mips::AFL_EXT_4120}, + {"NEC VR5400", Mips::AFL_EXT_5400}, + {"NEC VR5500", Mips::AFL_EXT_5500}, + {"RMI Xlr", Mips::AFL_EXT_XLR}, + {"Toshiba R3900", Mips::AFL_EXT_3900} +}; + +static const EnumEntry<unsigned> ElfMipsASEFlags[] = { + {"DSP", Mips::AFL_ASE_DSP}, + {"DSPR2", Mips::AFL_ASE_DSPR2}, + {"Enhanced VA Scheme", Mips::AFL_ASE_EVA}, + {"MCU", Mips::AFL_ASE_MCU}, + {"MDMX", Mips::AFL_ASE_MDMX}, + {"MIPS-3D", Mips::AFL_ASE_MIPS3D}, + {"MT", Mips::AFL_ASE_MT}, + {"SmartMIPS", Mips::AFL_ASE_SMARTMIPS}, + {"VZ", Mips::AFL_ASE_VIRT}, + {"MSA", Mips::AFL_ASE_MSA}, + {"MIPS16", Mips::AFL_ASE_MIPS16}, + {"microMIPS", Mips::AFL_ASE_MICROMIPS}, + {"XPA", Mips::AFL_ASE_XPA} +}; + +static const EnumEntry<unsigned> ElfMipsFpABIType[] = { + {"Hard or soft float", Mips::Val_GNU_MIPS_ABI_FP_ANY}, + {"Hard float (double precision)", Mips::Val_GNU_MIPS_ABI_FP_DOUBLE}, + {"Hard float (single precision)", Mips::Val_GNU_MIPS_ABI_FP_SINGLE}, + {"Soft float", Mips::Val_GNU_MIPS_ABI_FP_SOFT}, + {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)", + Mips::Val_GNU_MIPS_ABI_FP_OLD_64}, + {"Hard float (32-bit CPU, Any FPU)", Mips::Val_GNU_MIPS_ABI_FP_XX}, + {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64}, + {"Hard float compat (32-bit CPU, 64-bit FPU)", + Mips::Val_GNU_MIPS_ABI_FP_64A} +}; + +static const EnumEntry<unsigned> ElfMipsFlags1[] { + {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG}, +}; + +static int getMipsRegisterSize(uint8_t Flag) { + switch (Flag) { + case Mips::AFL_REG_NONE: + return 0; + case Mips::AFL_REG_32: + return 32; + case Mips::AFL_REG_64: + return 64; + case Mips::AFL_REG_128: + return 128; + default: + return -1; + } +} + +template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() { + const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags"); + if (!Shdr) { + W.startLine() << "There is no .MIPS.abiflags section in the file.\n"; + return; + } + ErrorOr<ArrayRef<uint8_t>> Sec = Obj->getSectionContents(Shdr); + if (!Sec) { + W.startLine() << "The .MIPS.abiflags section is empty.\n"; + return; + } + if (Sec->size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) { + W.startLine() << "The .MIPS.abiflags section has a wrong size.\n"; + return; + } + + auto *Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Sec->data()); + + raw_ostream &OS = W.getOStream(); + DictScope GS(W, "MIPS ABI Flags"); + + W.printNumber("Version", Flags->version); + W.startLine() << "ISA: "; + if (Flags->isa_rev <= 1) + OS << format("MIPS%u", Flags->isa_level); + else + OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev); + OS << "\n"; + W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType)); + W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags)); + W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType)); + W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size)); + W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size)); + W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size)); + W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1)); + W.printHex("Flags 2", Flags->flags2); +} |