forked from OSchip/llvm-project
[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
This commit is contained in:
parent
e21a21a977
commit
108ba4f4a4
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -339,7 +339,8 @@ protected:
|
|||
return DynRegionInfo(ObjF, *this, Obj.base() + Offset, Size, EntSize);
|
||||
}
|
||||
|
||||
void printAttributes();
|
||||
void printAttributes(unsigned, std::unique_ptr<ELFAttributeParser>,
|
||||
support::endianness);
|
||||
void printMipsReginfo();
|
||||
void printMipsOptions();
|
||||
|
||||
|
@ -2557,8 +2558,22 @@ template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {
|
|||
template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {
|
||||
switch (Obj.getHeader().e_machine) {
|
||||
case EM_ARM:
|
||||
if (Obj.isLE())
|
||||
printAttributes(ELF::SHT_ARM_ATTRIBUTES,
|
||||
std::make_unique<ARMAttributeParser>(&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<RISCVAttributeParser>(&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 <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFDumper<ELFT>::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 <class ELFT>
|
||||
void ELFDumper<ELFT>::printAttributes(
|
||||
unsigned AttrShType, std::unique_ptr<ELFAttributeParser> 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<uint8_t> Contents;
|
||||
|
@ -2613,13 +2623,7 @@ template <class ELFT> void ELFDumper<ELFT>::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)));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue