[llvm-readobj/elf] - Cleanup helpers that are used to print segment types. NFCI.

`getElfSegmentType` and `getElfPtType` are methods that are used for printing
segment types for LLVM and GNU styles accordingly.

This patch does a cleanup and simplification that allows to avoid
the code duplication and to get rid of one macro.

Differential revision: https://reviews.llvm.org/D85830
This commit is contained in:
Georgii Rymar 2020-08-12 14:47:15 +03:00
parent 130098228d
commit 02e2bd8c4b
1 changed files with 34 additions and 61 deletions

View File

@ -82,10 +82,6 @@ using namespace ELF;
#define ENUM_ENT_1(enum) \
{ #enum, #enum, ELF::enum }
#define LLVM_READOBJ_PHDR_ENUM(ns, enum) \
case ns::enum: \
return std::string(#enum).substr(3);
#define TYPEDEF_ELF_TYPES(ELFT) \
using ELFO = ELFFile<ELFT>; \
using Elf_Addr = typename ELFT::Addr; \
@ -1666,9 +1662,8 @@ static std::string getGNUFlags(unsigned EMachine, uint64_t Flags) {
return Str;
}
static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
// Check potentially overlapped processor-specific
// program header type.
static StringRef segmentTypeToString(unsigned Arch, unsigned Type) {
// Check potentially overlapped processor-specific program header type.
switch (Arch) {
case ELF::EM_ARM:
switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); }
@ -1677,25 +1672,25 @@ static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
case ELF::EM_MIPS_RS3_LE:
switch (Type) {
LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO);
LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC);
LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS);
LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS);
}
break;
}
switch (Type) {
LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL );
LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD );
LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP );
LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE );
LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB );
LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR );
LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS );
LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL);
LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD);
LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC);
LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP);
LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE);
LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB);
LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR);
LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS);
LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME);
LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND);
LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK);
LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO);
@ -1704,50 +1699,28 @@ static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE);
LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED);
LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA);
default:
return "";
}
}
static std::string getElfPtType(unsigned Arch, unsigned Type) {
switch (Type) {
LLVM_READOBJ_PHDR_ENUM(ELF, PT_NULL)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_LOAD)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_DYNAMIC)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_INTERP)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_NOTE)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_SHLIB)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_PHDR)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_TLS)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_GNU_EH_FRAME)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_SUNW_UNWIND)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_GNU_STACK)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_GNU_RELRO)
LLVM_READOBJ_PHDR_ENUM(ELF, PT_GNU_PROPERTY)
default:
// All machine specific PT_* types
switch (Arch) {
case ELF::EM_ARM:
if (Type == ELF::PT_ARM_EXIDX)
return "EXIDX";
break;
case ELF::EM_MIPS:
case ELF::EM_MIPS_RS3_LE:
switch (Type) {
case PT_MIPS_REGINFO:
return "REGINFO";
case PT_MIPS_RTPROC:
return "RTPROC";
case PT_MIPS_OPTIONS:
return "OPTIONS";
case PT_MIPS_ABIFLAGS:
return "ABIFLAGS";
}
break;
}
}
return std::string("<unknown>: ") + to_string(format_hex(Type, 1));
static std::string getGNUPtType(unsigned Arch, unsigned Type) {
StringRef Seg = segmentTypeToString(Arch, Type);
// GNU doesn't recognize PT_OPENBSD_*.
if (Seg.empty() || Seg.startswith("PT_OPENBSD_"))
return std::string("<unknown>: ") + to_string(format_hex(Type, 1));
// E.g. "PT_ARM_EXIDX" -> "EXIDX".
if (Seg.startswith("PT_ARM_"))
return Seg.drop_front(7).str();
// E.g. "PT_MIPS_REGINFO" -> "REGINFO".
if (Seg.startswith("PT_MIPS_"))
return Seg.drop_front(8).str();
// E.g. "PT_LOAD" -> "LOAD".
assert(Seg.startswith("PT_"));
return Seg.drop_front(3).str();
}
static const EnumEntry<unsigned> ElfSegmentFlags[] = {
@ -4300,7 +4273,7 @@ void GNUStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
}
for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
Fields[0].Str = getElfPtType(Header->e_machine, Phdr.p_type);
Fields[0].Str = getGNUPtType(Header->e_machine, Phdr.p_type);
Fields[1].Str = to_string(format_hex(Phdr.p_offset, 8));
Fields[2].Str = to_string(format_hex(Phdr.p_vaddr, Width));
Fields[3].Str = to_string(format_hex(Phdr.p_paddr, Width));
@ -6525,7 +6498,7 @@ void LLVMStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
DictScope P(W, "ProgramHeader");
W.printHex("Type",
getElfSegmentType(Obj->getHeader()->e_machine, Phdr.p_type),
segmentTypeToString(Obj->getHeader()->e_machine, Phdr.p_type),
Phdr.p_type);
W.printHex("Offset", Phdr.p_offset);
W.printHex("VirtualAddress", Phdr.p_vaddr);