diff --git a/llvm/test/MC/ARM/elf-execute-only-section.ll b/llvm/test/MC/ARM/elf-execute-only-section.ll --- a/llvm/test/MC/ARM/elf-execute-only-section.ll +++ b/llvm/test/MC/ARM/elf-execute-only-section.ll @@ -5,8 +5,8 @@ ; RUN: llc < %s -mtriple=thumbv7m-eabi -mattr=+execute-only -filetype=obj %s -o - | \ ; RUN: llvm-readelf -S | FileCheck %s -; CHECK-NOT: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AX[^p]}} -; CHECK: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AXp}} +; CHECK-NOT: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AX[^y]}} +; CHECK: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AXy}} define void @test_func() { entry: ret void diff --git a/llvm/test/tools/llvm-readobj/ELF/check-output-order.test b/llvm/test/tools/llvm-readobj/ELF/check-output-order.test --- a/llvm/test/tools/llvm-readobj/ELF/check-output-order.test +++ b/llvm/test/tools/llvm-readobj/ELF/check-output-order.test @@ -10,7 +10,7 @@ # CHECK: Section header string table index # CHECK: There are 5 section headers, starting at offset # CHECK: Section Headers: -# CHECK: O (extra OS processing required) o (OS specific), p (processor specific) +# CHECK: Key to Flags: # CHECK: There are no relocations in this file. # CHECK: Symbol table '.symtab' contains 1 entries # CHECK: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND diff --git a/llvm/test/tools/llvm-readobj/ELF/gnu-sections.test b/llvm/test/tools/llvm-readobj/ELF/gnu-sections.test --- a/llvm/test/tools/llvm-readobj/ELF/gnu-sections.test +++ b/llvm/test/tools/llvm-readobj/ELF/gnu-sections.test @@ -1,22 +1,28 @@ +## In this test case we check how we print section and flag descriptions for different targets. + +## EM_386 is a target that does not have any processor and OS specific flags, +## we use it to show how the default flag key is printed. + # RUN: yaml2obj --docnum=1 %s -o %t-i386.o -# RUN: llvm-readelf -S %t-i386.o | FileCheck %s -check-prefix ELF32 +# RUN: llvm-readelf -S %t-i386.o | FileCheck %s --check-prefix=ELF32 --strict-whitespace --match-full-lines -# ELF32: There are 8 section headers, starting at offset 0x90: +# ELF32:There are 8 section headers, starting at offset 0x90: # ELF32-EMPTY: -# ELF32-NEXT: Section Headers: -# ELF32-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al -# ELF32-NEXT: [ 0] NULL 00000000 000000 000000 00 0 0 0 -# ELF32-NEXT: [ 1] .text PROGBITS 00000000 000034 000001 00 AX 0 0 4 -# ELF32-NEXT: [ 2] .rel.text REL 00000000 000038 000000 08 5 1 4 -# ELF32-NEXT: [ 3] .data PROGBITS 00000000 000038 000000 00 WA 0 0 4 -# ELF32-NEXT: [ 4] .bss NOBITS 00000000 000038 000000 00 WA 0 0 4 -# ELF32-NEXT: [ 5] .symtab SYMTAB 00000000 000038 000020 10 6 2 8 -# ELF32-NEXT: [ 6] .strtab STRTAB 00000000 000058 000007 00 0 0 1 -# ELF32-NEXT: [ 7] .shstrtab STRTAB 00000000 00005f 000030 00 0 0 1 -# ELF32-NEXT: Key to Flags: -# ELF32-NEXT: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) -# ELF32-NEXT: I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) -# ELF32-NEXT: O (extra OS processing required) o (OS specific), p (processor specific) +# ELF32-NEXT:Section Headers: +# ELF32-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# ELF32-NEXT: [ 0] NULL 00000000 000000 000000 00 0 0 0 +# ELF32-NEXT: [ 1] .text PROGBITS 00000000 000034 000001 00 AX 0 0 4 +# ELF32-NEXT: [ 2] .rel.text REL 00000000 000038 000000 08 5 1 4 +# ELF32-NEXT: [ 3] .data PROGBITS 00000000 000038 000000 00 WA 0 0 4 +# ELF32-NEXT: [ 4] .bss NOBITS 00000000 000038 000000 00 WA 0 0 4 +# ELF32-NEXT: [ 5] .symtab SYMTAB 00000000 000038 000020 10 6 2 8 +# ELF32-NEXT: [ 6] .strtab STRTAB 00000000 000058 000007 00 0 0 1 +# ELF32-NEXT: [ 7] .shstrtab STRTAB 00000000 00005f 000030 00 0 0 1 +# ELF32-NEXT:Key to Flags: +# ELF32-NEXT: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), +# ELF32-NEXT: L (link order), O (extra OS processing required), G (group), T (TLS), +# ELF32-NEXT: C (compressed), x (unknown), o (OS specific), E (exclude), +# ELF32-NEXT: p (processor specific) --- !ELF FileHeader: @@ -52,33 +58,37 @@ Type: STT_SECTION Section: .text +## For an EM_X86_64 target we print "l" for the SHF_X86_64_LARGE section flag. +## Check we mention it in the flag key. + # RUN: yaml2obj --docnum=2 %s -o %t-x64.o -# RUN: llvm-readelf -S %t-x64.o | FileCheck %s -check-prefix ELF64 +# RUN: llvm-readelf -S %t-x64.o | FileCheck %s --check-prefix=ELF64 --strict-whitespace --match-full-lines ## Check that --wide is the same as -W and ignored and also ## that --section is the same as -S. # RUN: llvm-readobj --wide --sections %t-x64.o --elf-output-style=GNU \ -# RUN: | FileCheck %s -check-prefix ELF64 +# RUN: | FileCheck %s --check-prefix=ELF64 # RUN: llvm-readobj -W --sections %t-x64.o --elf-output-style=GNU \ -# RUN: | FileCheck %s -check-prefix ELF64 -# RUN: llvm-readelf -W -S %t-x64.o | FileCheck %s -check-prefix ELF64 +# RUN: | FileCheck %s --check-prefix=ELF64 +# RUN: llvm-readelf -W -S %t-x64.o | FileCheck %s --check-prefix=ELF64 -# ELF64: There are 8 section headers, starting at offset 0xb0: -# ELF64-EMPTY: -# ELF64-NEXT: Section Headers: -# ELF64-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al -# ELF64-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 -# ELF64-NEXT: [ 1] .text PROGBITS 0000000000000000 000040 000001 00 AX 0 0 4 -# ELF64-NEXT: [ 2] .rela.text RELA 0000000000000000 000048 000000 18 5 1 8 -# ELF64-NEXT: [ 3] .data PROGBITS 0000000000000000 000048 000000 00 WA 0 0 4 -# ELF64-NEXT: [ 4] .bss NOBITS 0000000000000000 000048 000000 00 WA 0 0 4 -# ELF64-NEXT: [ 5] .symtab SYMTAB 0000000000000000 000048 000030 18 6 2 8 -# ELF64-NEXT: [ 6] .strtab STRTAB 0000000000000000 000078 000007 00 0 0 1 -# ELF64-NEXT: [ 7] .shstrtab STRTAB 0000000000000000 00007f 000031 00 0 0 1 -# ELF64-NEXT: Key to Flags: -# ELF64-NEXT: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) -# ELF64-NEXT: I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) -# ELF64-NEXT: O (extra OS processing required) o (OS specific), p (processor specific) +# ELF64:There are 8 section headers, starting at offset 0xb0: +# ELF64-EMPTY: +# ELF64-NEXT:Section Headers: +# ELF64-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# ELF64-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 +# ELF64-NEXT: [ 1] .text PROGBITS 0000000000000000 000040 000001 00 AX 0 0 4 +# ELF64-NEXT: [ 2] .rela.text RELA 0000000000000000 000048 000000 18 5 1 8 +# ELF64-NEXT: [ 3] .data PROGBITS 0000000000000000 000048 000000 00 WA 0 0 4 +# ELF64-NEXT: [ 4] .bss NOBITS 0000000000000000 000048 000000 00 WA 0 0 4 +# ELF64-NEXT: [ 5] .symtab SYMTAB 0000000000000000 000048 000030 18 6 2 8 +# ELF64-NEXT: [ 6] .strtab STRTAB 0000000000000000 000078 000007 00 0 0 1 +# ELF64-NEXT: [ 7] .shstrtab STRTAB 0000000000000000 00007f 000031 00 0 0 1 +# ELF64-NEXT:Key to Flags: +# ELF64-NEXT: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), +# ELF64-NEXT: L (link order), O (extra OS processing required), G (group), T (TLS), +# ELF64-NEXT: C (compressed), x (unknown), o (OS specific), E (exclude), +# ELF64-NEXT: l (large), p (processor specific) --- !ELF FileHeader: @@ -113,3 +123,23 @@ - Name: .text Type: STT_SECTION Section: .text + +## For an EM_ARM target we print "y" for the SHF_ARM_PURECODE section flag. +## Check we mention it in the flag key. + +# RUN: yaml2obj --docnum=3 %s -o %t-arm.o +# RUN: llvm-readelf -S %t-arm.o | FileCheck %s --check-prefix=ARM --strict-whitespace --match-full-lines + +# ARM:Key to Flags: +# ARM-NEXT: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), +# ARM-NEXT: L (link order), O (extra OS processing required), G (group), T (TLS), +# ARM-NEXT: C (compressed), x (unknown), o (OS specific), E (exclude), +# ARM-NEXT: y (purecode), p (processor specific) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_ARM +Sections: [] diff --git a/llvm/test/tools/llvm-readobj/ELF/section-arch-flags.test b/llvm/test/tools/llvm-readobj/ELF/section-arch-flags.test --- a/llvm/test/tools/llvm-readobj/ELF/section-arch-flags.test +++ b/llvm/test/tools/llvm-readobj/ELF/section-arch-flags.test @@ -85,12 +85,23 @@ # RUN: llvm-readobj -S %t-x86_64.o | FileCheck --check-prefix=X86_64-LLVM %s # RUN: llvm-readelf -S %t-x86_64.o | FileCheck --check-prefix=X86_64-GNU %s -# X86_64-LLVM: Flags [ (0x10000000) +# X86_64-LLVM: Name: .x86_64 +# X86_64-LLVM-NEXT: Type: SHT_PROGBITS +# X86_64-LLVM-NEXT: Flags [ (0x10000000) # X86_64-LLVM-NEXT: SHF_X86_64_LARGE (0x10000000) # X86_64-LLVM-NEXT: ] -# X86_64-GNU: [Nr] Name Type Address Off Size ES Flg Lk Inf Al -# X86_64-GNU: [ 1] .x86_64 PROGBITS 0000000000000000 000040 000000 00 p 0 0 0 +# X86_64-LLVM: Name: .with.exclude +# X86_64-LLVM-NEXT: Type: SHT_PROGBITS +# X86_64-LLVM-NEXT: Flags [ (0x90000000) +# X86_64-LLVM-NEXT: SHF_EXCLUDE (0x80000000) +# X86_64-LLVM-NEXT: SHF_X86_64_LARGE (0x10000000) +# X86_64-LLVM-NEXT: ] + +## GNU prints 'l' before 'E', despite otherwise printing upper-case letters first. +# X86_64-GNU: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# X86_64-GNU: [ 1] .x86_64 PROGBITS 0000000000000000 000040 000000 00 l 0 0 0 +# X86_64-GNU: [ 2] .with.exclude PROGBITS 0000000000000000 000040 000000 00 lE 0 0 0 --- !ELF FileHeader: @@ -102,6 +113,9 @@ - Name: .x86_64 Type: SHT_PROGBITS Flags: [ SHF_X86_64_LARGE ] + - Name: .with.exclude + Type: SHT_PROGBITS + Flags: [ SHF_X86_64_LARGE, SHF_EXCLUDE ] # RUN: yaml2obj --docnum 5 %s -o %t-arm.o # RUN: llvm-readobj -S %t-arm.o | FileCheck --check-prefix=ARM-LLVM %s @@ -112,7 +126,7 @@ # ARM-LLVM-NEXT: ] # ARM-GNU: [Nr] Name Type Address Off Size ES Flg Lk Inf Al -# ARM-GNU: [ 1] foo PROGBITS 0000000000000000 000040 000000 00 p 0 0 0 +# ARM-GNU: [ 1] foo PROGBITS 0000000000000000 000040 000000 00 y 0 0 0 --- !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 @@ -1474,7 +1474,7 @@ LLVM_READOBJ_ENUM_ENT(ELF, SHF_X86_64_LARGE) }; -static std::string getGNUFlags(uint64_t Flags) { +static std::string getGNUFlags(unsigned EMachine, uint64_t Flags) { // Here we are trying to build the flags string in the same way as GNU does. // It is not that straightforward. Imagine we have sh_flags == 0x90000000. // SHF_EXCLUDE ("E") has a value of 0x80000000 and SHF_MASKPROC is 0xf0000000. @@ -1500,7 +1500,11 @@ // If we did not find a matching regular flag, then we deal with an OS // specific flag, processor specific flag or an unknown flag. - if (Flag & ELF::SHF_MASKOS) { + if (EMachine == EM_X86_64 && Flag == SHF_X86_64_LARGE) { + Str += 'l'; + } else if (EMachine == EM_ARM && Flag == SHF_ARM_PURECODE) { + Str += 'y'; + } else if (Flag & ELF::SHF_MASKOS) { HasOSFlag = true; Flags &= ~ELF::SHF_MASKOS; } else if (Flag & ELF::SHF_MASKPROC) { @@ -3513,6 +3517,25 @@ return ""; } +static void printSectionDescription(formatted_raw_ostream &OS, + unsigned EMachine) { + OS << "Key to Flags:\n"; + OS << " W (write), A (alloc), X (execute), M (merge), S (strings), I " + "(info),\n"; + OS << " L (link order), O (extra OS processing required), G (group), T " + "(TLS),\n"; + OS << " C (compressed), x (unknown), o (OS specific), E (exclude),\n"; + + if (EMachine == EM_X86_64) + OS << " l (large), "; + else if (EMachine == EM_ARM) + OS << " y (purecode), "; + else + OS << " "; + + OS << "p (processor specific)\n"; +} + template void GNUStyle::printSectionHeaders(const ELFO *Obj) { unsigned Bias = ELFT::Is64Bits ? 0 : 8; @@ -3543,7 +3566,7 @@ Fields[4].Str = to_string(format_hex_no_prefix(Sec.sh_offset, 6)); Fields[5].Str = to_string(format_hex_no_prefix(Sec.sh_size, 6)); Fields[6].Str = to_string(format_hex_no_prefix(Sec.sh_entsize, 2)); - Fields[7].Str = getGNUFlags(Sec.sh_flags); + Fields[7].Str = getGNUFlags(Obj->getHeader()->e_machine, Sec.sh_flags); Fields[8].Str = to_string(Sec.sh_link); Fields[9].Str = to_string(Sec.sh_info); Fields[10].Str = to_string(Sec.sh_addralign); @@ -3563,13 +3586,7 @@ OS << "\n"; ++SectionIndex; } - OS << "Key to Flags:\n" - << " W (write), A (alloc), X (execute), M (merge), S (strings), l " - "(large)\n" - << " I (info), L (link order), G (group), T (TLS), E (exclude),\ - x (unknown)\n" - << " O (extra OS processing required) o (OS specific),\ - p (processor specific)\n"; + printSectionDescription(OS, Obj->getHeader()->e_machine); } template