[llvm-readobj][ELF] Teach llvm-readobj to show arch specific ELF section's flags

Some architecture specific ELF section flags might have the same value
(for example SHF_X86_64_LARGE and SHF_HEX_GPREL) and we have to check
machine architectures to select an appropriate set of possible flags.

The patch selects architecture specific flags into separate arrays
`ElfxxxSectionFlags` and combines `ElfSectionFlags` and `ElfxxxSectionFlags`
before pass to the `StreamWriter::printFlags()` method.

Differential Revision: http://reviews.llvm.org/D16269

llvm-svn: 258334
This commit is contained in:
Simon Atanasyan 2016-01-20 19:15:18 +00:00
parent 2d7fa7065f
commit 2d0d8530e3
4 changed files with 157 additions and 3 deletions

View File

@ -336,6 +336,9 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
BCase(EF_AVR_ARCH_XMEGA6)
BCase(EF_AVR_ARCH_XMEGA7)
break;
case ELF::EM_AMDGPU:
case ELF::EM_X86_64:
break;
default:
llvm_unreachable("Unsupported architecture");
}
@ -422,6 +425,22 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
BCase(SHF_AMDGPU_HSA_CODE)
BCase(SHF_AMDGPU_HSA_AGENT)
break;
case ELF::EM_HEXAGON:
BCase(SHF_HEX_GPREL)
break;
case ELF::EM_MIPS:
BCase(SHF_MIPS_NODUPES)
BCase(SHF_MIPS_NAMES)
BCase(SHF_MIPS_LOCAL)
BCase(SHF_MIPS_NOSTRIP)
BCase(SHF_MIPS_GPREL)
BCase(SHF_MIPS_MERGE)
BCase(SHF_MIPS_ADDR)
BCase(SHF_MIPS_STRING)
break;
case ELF::EM_X86_64:
BCase(SHF_X86_64_LARGE)
break;
default:
// Nothing to do.
break;

View File

@ -327,7 +327,7 @@ ELF-MIPS64EL-NEXT: Flags: [ SHF_WRITE, SHF_ALLOC ]
ELF-MIPS64EL-NEXT: AddressAlign: 0x0000000000000010
ELF-MIPS64EL-NEXT: - Name: .MIPS.options
ELF-MIPS64EL-NEXT: Type: SHT_MIPS_OPTIONS
ELF-MIPS64EL-NEXT: Flags: [ SHF_ALLOC ]
ELF-MIPS64EL-NEXT: Flags: [ SHF_ALLOC, SHF_MIPS_NOSTRIP ]
ELF-MIPS64EL-NEXT: AddressAlign: 0x0000000000000008
ELF-MIPS64EL-NEXT: Content: '01280000000000000000000000000000000000000000000000000000000000000000000000000000'
ELF-MIPS64EL-NEXT: - Name: .pdr

View File

@ -0,0 +1,90 @@
# Check that llvm-readobj shows arch specific ELF section flags.
# RUN: yaml2obj -format=elf -docnum 1 %s > %t-amdgpu.o
# RUN: llvm-readobj -s %t-amdgpu.o | FileCheck -check-prefix=AMD %s
# AMD: Flags [ (0x300000)
# AMD-NEXT: SHF_AMDGPU_HSA_GLOBAL (0x100000)
# AMD-NEXT: SHF_AMDGPU_HSA_READONLY (0x200000)
# AMD-NEXT: ]
# amdgpu.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
OSABI: ELFOSABI_GNU
Type: ET_REL
Machine: EM_AMDGPU
Flags: []
Sections:
- Name: .amdgpu
Type: SHT_PROGBITS
Flags: [SHF_AMDGPU_HSA_GLOBAL, SHF_AMDGPU_HSA_READONLY]
Size: 4
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-hex.o
# RUN: llvm-readobj -s %t-hex.o | FileCheck -check-prefix=HEX %s
# HEX: Flags [ (0x10000000)
# HEX-NEXT: SHF_HEX_GPREL (0x10000000)
# HEX-NEXT: ]
# hex.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_HEXAGON
Flags: []
Sections:
- Name: .hex
Type: SHT_PROGBITS
Flags: [SHF_HEX_GPREL]
Size: 4
# RUN: yaml2obj -format=elf -docnum 3 %s > %t-mips.o
# RUN: llvm-readobj -s %t-mips.o | FileCheck -check-prefix=MIPS %s
# MIPS: Flags [ (0x38000000)
# MIPS-NEXT: SHF_MIPS_GPREL (0x10000000)
# MIPS-NEXT: SHF_MIPS_MERGE (0x20000000)
# MIPS-NEXT: SHF_MIPS_NOSTRIP (0x8000000)
# MIPS-NEXT: ]
# mips.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Flags: []
Sections:
- Name: .mips
Type: SHT_PROGBITS
Flags: [SHF_MIPS_GPREL, SHF_MIPS_MERGE, SHF_MIPS_NOSTRIP]
Size: 4
# RUN: yaml2obj -format=elf -docnum 4 %s > %t-x86_64.o
# RUN: llvm-readobj -s %t-x86_64.o | FileCheck -check-prefix=X86_64 %s
# X86_64: Flags [ (0x10000000)
# X86_64-NEXT: SHF_X86_64_LARGE (0x10000000)
# X86_64-NEXT: ]
# x86_64.o
---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Flags: []
Sections:
- Name: .x86_64
Type: SHT_PROGBITS
Flags: [SHF_X86_64_LARGE]
Size: 4
...

View File

@ -806,13 +806,34 @@ static const EnumEntry<unsigned> ElfSectionFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS ),
LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION),
LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP ),
};
static const EnumEntry<unsigned> ElfAMDGPUSectionFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_GLOBAL),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_READONLY),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_CODE),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_AGENT)
};
static const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, SHF_HEX_GPREL)
};
static const EnumEntry<unsigned> ElfMipsSectionFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NODUPES),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NAMES ),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_LOCAL ),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_GPREL ),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_MERGE ),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_ADDR ),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_STRING )
};
static const EnumEntry<unsigned> ElfX86_64SectionFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, SHF_X86_64_LARGE)
};
static const char *getElfSegmentType(unsigned Arch, unsigned Type) {
// Check potentially overlapped processor-specific
// program header type.
@ -1118,7 +1139,31 @@ void ELFDumper<ELFT>::printSections() {
W.printHex("Type",
getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type),
Sec.sh_type);
W.printFlags("Flags", Sec.sh_flags, makeArrayRef(ElfSectionFlags));
std::vector<EnumEntry<unsigned>> SectionFlags(std::begin(ElfSectionFlags),
std::end(ElfSectionFlags));
switch (Obj->getHeader()->e_machine) {
case EM_AMDGPU:
SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),
std::end(ElfAMDGPUSectionFlags));
break;
case EM_HEXAGON:
SectionFlags.insert(SectionFlags.end(),
std::begin(ElfHexagonSectionFlags),
std::end(ElfHexagonSectionFlags));
break;
case EM_MIPS:
SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags),
std::end(ElfMipsSectionFlags));
break;
case EM_X86_64:
SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags),
std::end(ElfX86_64SectionFlags));
break;
default:
// Nothing to do.
break;
}
W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags));
W.printHex("Address", Sec.sh_addr);
W.printHex("Offset", Sec.sh_offset);
W.printNumber("Size", Sec.sh_size);