From 199325450932a06d4392cb4d87fd69fc163b00eb Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Thu, 25 Oct 2018 05:39:27 +0000 Subject: [PATCH] [llvm-readobj] Print ELF header flags names in GNU output GNU readelf tool prints hex value of the ELF header flags field and the flags names. This change adds the same functionality to llvm-readobj. Now llvm-readobj can print MIPS and RISCV flags. New GNUStyle::printFlags() method is a copy of ScopedPrinter::printFlags() routine. Probably we can escape code duplication and / or simplify the printFlags() method. But it's a task for separate commit. Differential revision: https://reviews.llvm.org/D52027 llvm-svn: 345238 --- llvm/test/tools/llvm-readobj/gnu-file-headers.test | 23 ++++ llvm/tools/llvm-readobj/ELFDumper.cpp | 133 +++++++++++++-------- 2 files changed, 108 insertions(+), 48 deletions(-) diff --git a/llvm/test/tools/llvm-readobj/gnu-file-headers.test b/llvm/test/tools/llvm-readobj/gnu-file-headers.test index 4b74d09..e246a3d 100644 --- a/llvm/test/tools/llvm-readobj/gnu-file-headers.test +++ b/llvm/test/tools/llvm-readobj/gnu-file-headers.test @@ -2,6 +2,8 @@ RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-i386 --elf-output-style=GNU \ RUN: | FileCheck %s -check-prefix ELF32 RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-x86-64 --elf-output-style=GNU \ RUN: | FileCheck %s -check-prefix ELF64 +RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-mipsel --elf-output-style=GNU \ +RUN: | FileCheck %s -check-prefix MIPSEL ELF32: ELF Header: ELF32-NEXT: Magic: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00 @@ -44,3 +46,24 @@ ELF64-NEXT: Number of program headers: 0 ELF64-NEXT: Size of section headers: 64 (bytes) ELF64-NEXT: Number of section headers: 10 ELF64-NEXT: Section header string table index: 7 + +MIPSEL: ELF Header: +MIPSEL-NEXT: Magic: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00 +MIPSEL-NEXT: Class: ELF32 +MIPSEL-NEXT: Data: 2's complement, little endian +MIPSEL-NEXT: Version: 1 (current) +MIPSEL-NEXT: OS/ABI: UNIX - GNU +MIPSEL-NEXT: ABI Version: 0x0 +MIPSEL-NEXT: Type: REL (Relocatable file) +MIPSEL-NEXT: Machine: MIPS R3000 +MIPSEL-NEXT: Version: 0x1 +MIPSEL-NEXT: Entry point address: 0x0 +MIPSEL-NEXT: Start of program headers: 0 (bytes into file) +MIPSEL-NEXT: Start of section headers: 172 (bytes into file) +MIPSEL-NEXT: Flags: 0x50001000, o32, mips32 +MIPSEL-NEXT: Size of this header: 52 (bytes) +MIPSEL-NEXT: Size of program headers: 0 (bytes) +MIPSEL-NEXT: Number of program headers: 0 +MIPSEL-NEXT: Size of section headers: 40 (bytes) +MIPSEL-NEXT: Number of section headers: 9 +MIPSEL-NEXT: Section header string table index: 6 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index bace24f..5e8a35f 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -390,6 +390,33 @@ private: return to_hexString(Value, false); } + template + std::string printFlags(T Value, ArrayRef> EnumValues, + TEnum EnumMask1 = {}, TEnum EnumMask2 = {}, + TEnum EnumMask3 = {}) { + std::string Str; + for (const auto &Flag : EnumValues) { + if (Flag.Value == 0) + continue; + + TEnum EnumMask{}; + if (Flag.Value & EnumMask1) + EnumMask = EnumMask1; + else if (Flag.Value & EnumMask2) + EnumMask = EnumMask2; + else if (Flag.Value & EnumMask3) + EnumMask = EnumMask3; + bool IsEnum = (Flag.Value & EnumMask) != 0; + if ((!IsEnum && (Value & Flag.Value) == Flag.Value) || + (IsEnum && (Value & EnumMask) == Flag.Value)) { + if (!Str.empty()) + Str += ", "; + Str += Flag.AltName; + } + } + return Str; + } + formatted_raw_ostream &printField(struct Field F) { if (F.Column != 0) OS.PadToColumn(F.Column); @@ -1247,49 +1274,49 @@ static const EnumEntry ElfSegmentFlags[] = { }; static const EnumEntry ElfHeaderMipsFlags[] = { - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NOREORDER), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_PIC), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_CPIC), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI2), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_32BITMODE), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_FP64), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NAN2008), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O32), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O64), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI32), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI64), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_3900), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4010), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4100), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4650), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4120), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4111), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_SB1), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_XLR), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON2), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON3), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5400), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5900), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5500), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_9000), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2E), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2F), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS3A), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MICROMIPS), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_M16), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_MDMX), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_1), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_2), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_3), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_4), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_5), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R2), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R2), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R6), - LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6) + ENUM_ENT(EF_MIPS_NOREORDER, "noreorder"), + ENUM_ENT(EF_MIPS_PIC, "pic"), + ENUM_ENT(EF_MIPS_CPIC, "cpic"), + ENUM_ENT(EF_MIPS_ABI2, "abi2"), + ENUM_ENT(EF_MIPS_32BITMODE, "32bitmode"), + ENUM_ENT(EF_MIPS_FP64, "fp64"), + ENUM_ENT(EF_MIPS_NAN2008, "nan2008"), + ENUM_ENT(EF_MIPS_ABI_O32, "o32"), + ENUM_ENT(EF_MIPS_ABI_O64, "o64"), + ENUM_ENT(EF_MIPS_ABI_EABI32, "eabi32"), + ENUM_ENT(EF_MIPS_ABI_EABI64, "eabi64"), + ENUM_ENT(EF_MIPS_MACH_3900, "3900"), + ENUM_ENT(EF_MIPS_MACH_4010, "4010"), + ENUM_ENT(EF_MIPS_MACH_4100, "4100"), + ENUM_ENT(EF_MIPS_MACH_4650, "4650"), + ENUM_ENT(EF_MIPS_MACH_4120, "4120"), + ENUM_ENT(EF_MIPS_MACH_4111, "4111"), + ENUM_ENT(EF_MIPS_MACH_SB1, "sb1"), + ENUM_ENT(EF_MIPS_MACH_OCTEON, "octeon"), + ENUM_ENT(EF_MIPS_MACH_XLR, "xlr"), + ENUM_ENT(EF_MIPS_MACH_OCTEON2, "octeon2"), + ENUM_ENT(EF_MIPS_MACH_OCTEON3, "octeon3"), + ENUM_ENT(EF_MIPS_MACH_5400, "5400"), + ENUM_ENT(EF_MIPS_MACH_5900, "5900"), + ENUM_ENT(EF_MIPS_MACH_5500, "5500"), + ENUM_ENT(EF_MIPS_MACH_9000, "9000"), + ENUM_ENT(EF_MIPS_MACH_LS2E, "loongson-2e"), + ENUM_ENT(EF_MIPS_MACH_LS2F, "loongson-2f"), + ENUM_ENT(EF_MIPS_MACH_LS3A, "loongson-3a"), + ENUM_ENT(EF_MIPS_MICROMIPS, "micromips"), + ENUM_ENT(EF_MIPS_ARCH_ASE_M16, "mips16"), + ENUM_ENT(EF_MIPS_ARCH_ASE_MDMX, "mdmx"), + ENUM_ENT(EF_MIPS_ARCH_1, "mips1"), + ENUM_ENT(EF_MIPS_ARCH_2, "mips2"), + ENUM_ENT(EF_MIPS_ARCH_3, "mips3"), + ENUM_ENT(EF_MIPS_ARCH_4, "mips4"), + ENUM_ENT(EF_MIPS_ARCH_5, "mips5"), + ENUM_ENT(EF_MIPS_ARCH_32, "mips32"), + ENUM_ENT(EF_MIPS_ARCH_64, "mips64"), + ENUM_ENT(EF_MIPS_ARCH_32R2, "mips32r2"), + ENUM_ENT(EF_MIPS_ARCH_64R2, "mips64r2"), + ENUM_ENT(EF_MIPS_ARCH_32R6, "mips32r6"), + ENUM_ENT(EF_MIPS_ARCH_64R6, "mips64r6") }; static const EnumEntry ElfHeaderAMDGPUFlags[] = { @@ -1330,11 +1357,11 @@ static const EnumEntry ElfHeaderAMDGPUFlags[] = { }; static const EnumEntry ElfHeaderRISCVFlags[] = { - LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_RVC), - LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_FLOAT_ABI_SINGLE), - LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_FLOAT_ABI_DOUBLE), - LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_FLOAT_ABI_QUAD), - LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_RVE) + ENUM_ENT(EF_RISCV_RVC, "RVC"), + ENUM_ENT(EF_RISCV_FLOAT_ABI_SINGLE, "single-float ABI"), + ENUM_ENT(EF_RISCV_FLOAT_ABI_DOUBLE, "double-float ABI"), + ENUM_ENT(EF_RISCV_FLOAT_ABI_QUAD, "quad-float ABI"), + ENUM_ENT(EF_RISCV_RVE, "RVE") }; static const EnumEntry ElfSymOtherFlags[] = { @@ -2518,7 +2545,17 @@ template void GNUStyle::printFileHeaders(const ELFO *Obj) { printFields(OS, "Start of program headers:", Str); Str = to_string(e->e_shoff) + " (bytes into file)"; printFields(OS, "Start of section headers:", Str); + std::string ElfFlags; + if (e->e_machine == EM_MIPS) + ElfFlags = + printFlags(e->e_flags, makeArrayRef(ElfHeaderMipsFlags), + unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI), + unsigned(ELF::EF_MIPS_MACH)); + else if (e->e_machine == EM_RISCV) + ElfFlags = printFlags(e->e_flags, makeArrayRef(ElfHeaderRISCVFlags)); Str = "0x" + to_hexString(e->e_flags); + if (!ElfFlags.empty()) + Str = Str + ", " + ElfFlags; printFields(OS, "Flags:", Str); Str = to_string(e->e_ehsize) + " (bytes)"; printFields(OS, "Size of this header:", Str); -- 2.7.4