From a3aa1d15da18b393e7399bac48f026228e90fd2b Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Thu, 7 May 2015 15:40:35 +0000 Subject: [PATCH] [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 --- include/llvm/Object/ELFTypes.h | 16 +++ .../llvm-readobj/Inputs/abiflags.obj.elf-mips | Bin 0 -> 920 bytes .../Inputs/abiflags.obj.elf-mipsel | Bin 0 -> 1320 bytes test/tools/llvm-readobj/mips-abiflags.test | 42 ++++++ tools/llvm-readobj/ELFDumper.cpp | 121 ++++++++++++++++++ tools/llvm-readobj/ObjDumper.h | 1 + tools/llvm-readobj/llvm-readobj.cpp | 9 +- 7 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 test/tools/llvm-readobj/Inputs/abiflags.obj.elf-mips create mode 100644 test/tools/llvm-readobj/Inputs/abiflags.obj.elf-mipsel create mode 100644 test/tools/llvm-readobj/mips-abiflags.test diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h index 5a4e03e7bbe..1952b9480d0 100644 --- a/include/llvm/Object/ELFTypes.h +++ b/include/llvm/Object/ELFTypes.h @@ -489,6 +489,22 @@ struct Elf_Phdr_Impl > { Elf_Xword p_align; // Segment alignment constraint }; +// .MIPS.abiflags section content +template struct Elf_Mips_ABIFlags { + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) + Elf_Half version; // Version of the structure + uint8_t isa_level; // ISA level: 1-5, 32, and 64 + uint8_t isa_rev; // ISA revision (0 for MIPS I - MIPS V) + uint8_t gpr_size; // General purpose registers size + uint8_t cpr1_size; // Co-processor 1 registers size + uint8_t cpr2_size; // Co-processor 2 registers size + uint8_t fp_abi; // Floating-point ABI flag + Elf_Word isa_ext; // Processor-specific extension + Elf_Word ases; // ASEs flags + Elf_Word flags1; // General flags + Elf_Word flags2; // General flags +}; + } // end namespace object. } // end namespace llvm. diff --git a/test/tools/llvm-readobj/Inputs/abiflags.obj.elf-mips b/test/tools/llvm-readobj/Inputs/abiflags.obj.elf-mips new file mode 100644 index 0000000000000000000000000000000000000000..edcd50becec4ebf60ebad1373409139051db2b51 GIT binary patch literal 920 zcma)5!AiqG5S_HOjaaeX1TT70MD|oYE2vOVD0uL^v1uAGX-T%AC-Vt@hDVS7mIuLG ze3N9t5=A>@cyHdk&hBjK^X2uG({iW|hg@)5cu#21rD5SXq&}_JUXVUMtHmCl(k{I& zV{yhg$W{<9i>lXYlS-c=qdlNWN}LHZ{-Yr^(MFT<(v(!<2Vp#&le!s=Z4OfS zFD418XySXzfYs9>DIB4+F-hnxji3H{<9g=~o3TFNfqK_lpVPBg?vM9RLS?_`TYN}<~gsZH<1#>yl?i+J4OHi literal 0 HcmV?d00001 diff --git a/test/tools/llvm-readobj/Inputs/abiflags.obj.elf-mipsel b/test/tools/llvm-readobj/Inputs/abiflags.obj.elf-mipsel new file mode 100644 index 0000000000000000000000000000000000000000..bb5f43d286239a7a70e7b7904de9bf255904fa3b GIT binary patch literal 1320 zcmbVMJx{|h5Ix6jDFQ?hOC=^IDug^C2Bt88R0&WeRu+eb5~*KmT&Ya(3lKknzsSHG z&W*2$k943{HFx*!o}YbA`*wYM69@rh0-8`{gaUMeJZ`|pd$9jusHR{LFe4r4$I0uC~N*gmvqPdCFHT%qAyT2NIXH`vdwR^uR!41ua zLE@*%B-k_i)?B7E9ls`VM^z@FUIn9SV-23Gc*T)U#_9>I^Y9ImBjnjr@EwG1y_WOj zcz%op%jc8p5rKKmKf$^^<)-{I@4XTLOmnxFlrs?u+}Me%Mu ELFO; @@ -170,6 +172,16 @@ findSectionByAddress(const ELFFile *Obj, uint64_t Addr) { return nullptr; } +template +static const typename ELFFile::Elf_Shdr * +findSectionByName(const ELFFile &Obj, StringRef Name) { + for (const auto &Shdr : Obj.sections()) { + if (Name == errorOrDefault(Obj.getSectionName(&Shdr))) + return &Shdr; + } + return nullptr; +} + static const EnumEntry ElfClass[] = { { "None", ELF::ELFCLASSNONE }, { "32-bit", ELF::ELFCLASS32 }, @@ -1249,3 +1261,112 @@ template void ELFDumper::printMipsPLTGOT() { MipsGOTParser(Obj, W).parseGOT(*GotShdr); } + +static const EnumEntry 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 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 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 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 void ELFDumper::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> Sec = Obj->getSectionContents(Shdr); + if (!Sec) { + W.startLine() << "The .MIPS.abiflags section is empty.\n"; + return; + } + if (Sec->size() != sizeof(Elf_Mips_ABIFlags)) { + W.startLine() << "The .MIPS.abiflags section has a wrong size.\n"; + return; + } + + auto *Flags = reinterpret_cast *>(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); +} diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index 27e658fc731..5750d6ffd28 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -42,6 +42,7 @@ public: // Only implemented for MIPS ELF at this time. virtual void printMipsPLTGOT() { } + virtual void printMipsABIFlags() { } // Only implemented for PE/COFF. virtual void printCOFFImports() { } diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 7e6ce496723..be7bbe94d9e 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -148,6 +148,10 @@ namespace opts { MipsPLTGOT("mips-plt-got", cl::desc("Display the MIPS GOT and PLT GOT sections")); + // -mips-abi-flags + cl::opt MipsABIFlags("mips-abi-flags", + cl::desc("Display the MIPS.abiflags section")); + // -coff-imports cl::opt COFFImports("coff-imports", cl::desc("Display the PE/COFF import table")); @@ -287,9 +291,12 @@ static void dumpObject(const ObjectFile *Obj) { if (Obj->getArch() == llvm::Triple::arm && Obj->isELF()) if (opts::ARMAttributes) Dumper->printAttributes(); - if (isMipsArch(Obj->getArch()) && Obj->isELF()) + if (isMipsArch(Obj->getArch()) && Obj->isELF()) { if (opts::MipsPLTGOT) Dumper->printMipsPLTGOT(); + if (opts::MipsABIFlags) + Dumper->printMipsABIFlags(); + } if (opts::COFFImports) Dumper->printCOFFImports(); if (opts::COFFExports)