From 108ba4f4a48043067f0735f7f7c6f301045cf9b5 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 17 Aug 2021 13:28:31 -0700 Subject: [PATCH] [llvm-readobj] Refactor ELFDumper::printAttributes() The current implementation of printAttributes makes it fiddly to extend attribute support for new targets. By refactoring the code so all target specific variables are initialized in a switch/case statement, it becomes simpler to extend attribute support for new targets. Reviewed By: jhenderson, MaskRay Differential Revision: https://reviews.llvm.org/D107968 --- .../llvm-readobj/ELF/ARM/attribute-big-endian.test | 17 ++++++++ .../ELF/RISCV/validate-attr-section.test | 4 +- llvm/tools/llvm-readobj/ELFDumper.cpp | 46 ++++++++++++---------- 3 files changed, 44 insertions(+), 23 deletions(-) create mode 100644 llvm/test/tools/llvm-readobj/ELF/ARM/attribute-big-endian.test diff --git a/llvm/test/tools/llvm-readobj/ELF/ARM/attribute-big-endian.test b/llvm/test/tools/llvm-readobj/ELF/ARM/attribute-big-endian.test new file mode 100644 index 0000000..7d20b31 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/ARM/attribute-big-endian.test @@ -0,0 +1,17 @@ +## We only implement attribute section printing for little-endian encoding. + +# RUN: yaml2obj %s -o %t.o +# RUN: llvm-readobj -A %t.o 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: warning: '[[FILE]]': attribute printing not implemented for big-endian ARM objects + +--- !ELF +FileHeader: + Class: ELFCLASS32 +## Test big-endian encoding. + Data: ELFDATA2MSB + Type: ET_REL + Machine: EM_ARM +Sections: + - Name: .ARM.attributes + Type: SHT_ARM_ATTRIBUTES diff --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/validate-attr-section.test b/llvm/test/tools/llvm-readobj/ELF/RISCV/validate-attr-section.test index 66a5a7a..21bbb5e 100644 --- a/llvm/test/tools/llvm-readobj/ELF/RISCV/validate-attr-section.test +++ b/llvm/test/tools/llvm-readobj/ELF/RISCV/validate-attr-section.test @@ -1,9 +1,9 @@ ## We only implement attribute section printing for little-endian encoding. # RUN: yaml2obj %s -o %t.o -# RUN: llvm-readobj -A %t.o | FileCheck %s +# RUN: llvm-readobj -A %t.o 2>&1 | FileCheck %s -DFILE=%t.o -# CHECK: Attributes not implemented. +# CHECK: warning: '[[FILE]]': attribute printing not implemented for big-endian RISC-V objects --- !ELF FileHeader: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 000a10b..1073f22 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -339,7 +339,8 @@ protected: return DynRegionInfo(ObjF, *this, Obj.base() + Offset, Size, EntSize); } - void printAttributes(); + void printAttributes(unsigned, std::unique_ptr, + support::endianness); void printMipsReginfo(); void printMipsOptions(); @@ -2557,8 +2558,22 @@ template void ELFDumper::printLoadName() { template void ELFDumper::printArchSpecificInfo() { switch (Obj.getHeader().e_machine) { case EM_ARM: + if (Obj.isLE()) + printAttributes(ELF::SHT_ARM_ATTRIBUTES, + std::make_unique(&W), + support::little); + else + reportUniqueWarning("attribute printing not implemented for big-endian " + "ARM objects"); + break; case EM_RISCV: - printAttributes(); + if (Obj.isLE()) + printAttributes(ELF::SHT_RISCV_ATTRIBUTES, + std::make_unique(&W), + support::little); + else + reportUniqueWarning("attribute printing not implemented for big-endian " + "RISC-V objects"); break; case EM_MIPS: { printMipsABIFlags(); @@ -2581,20 +2596,15 @@ template void ELFDumper::printArchSpecificInfo() { } } -template void ELFDumper::printAttributes() { - if (!Obj.isLE()) { - W.startLine() << "Attributes not implemented.\n"; - return; - } - - const unsigned Machine = Obj.getHeader().e_machine; - assert((Machine == EM_ARM || Machine == EM_RISCV) && - "Attributes not implemented."); - +template +void ELFDumper::printAttributes( + unsigned AttrShType, std::unique_ptr AttrParser, + support::endianness Endianness) { + assert((AttrShType != ELF::SHT_NULL) && AttrParser && + "Incomplete ELF attribute implementation"); DictScope BA(W, "BuildAttributes"); for (const Elf_Shdr &Sec : cantFail(Obj.sections())) { - if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES && - Sec.sh_type != ELF::SHT_RISCV_ATTRIBUTES) + if (Sec.sh_type != AttrShType) continue; ArrayRef Contents; @@ -2613,13 +2623,7 @@ template void ELFDumper::printAttributes() { W.printHex("FormatVersion", Contents[0]); - auto ParseAttrubutes = [&]() { - if (Machine == EM_ARM) - return ARMAttributeParser(&W).parse(Contents, support::little); - return RISCVAttributeParser(&W).parse(Contents, support::little); - }; - - if (Error E = ParseAttrubutes()) + if (Error E = AttrParser->parse(Contents, Endianness)) reportUniqueWarning("unable to dump attributes from the " + describe(Sec) + ": " + toString(std::move(E))); } -- 2.7.4