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 --- /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 --- 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 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -339,7 +339,8 @@ 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::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::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 @@ 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))); }