From 08bebae6019de215dc011d01b111339450de93e5 Mon Sep 17 00:00:00 2001 From: Georgii Rymar Date: Wed, 12 Aug 2020 14:47:15 +0300 Subject: [PATCH] [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 --- tools/llvm-readobj/ELFDumper.cpp | 95 ++++++++++++-------------------- 1 file changed, 34 insertions(+), 61 deletions(-) diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 629774246b6..b18c841ead9 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -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; \ 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(": ") + 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(": ") + 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 ElfSegmentFlags[] = { @@ -4300,7 +4273,7 @@ void GNUStyle::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::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);