diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -949,6 +949,9 @@ // Identifies a section containing compressed data. SHF_COMPRESSED = 0x800U, + // This section should not be garbage collected by the linker. + SHF_GNU_RETAIN = 0x200000, + // This section is excluded from the final executable or shared library. SHF_EXCLUDE = 0x80000000U, diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -555,6 +555,7 @@ BCase(SHF_GROUP); BCase(SHF_TLS); BCase(SHF_COMPRESSED); + BCase(SHF_GNU_RETAIN); switch (Object->getMachine()) { case ELF::EM_ARM: BCase(SHF_ARM_PURECODE); diff --git a/llvm/test/tools/llvm-readobj/ELF/section-flags-os-proc.test b/llvm/test/tools/llvm-readobj/ELF/section-flags-os-proc.test --- a/llvm/test/tools/llvm-readobj/ELF/section-flags-os-proc.test +++ b/llvm/test/tools/llvm-readobj/ELF/section-flags-os-proc.test @@ -11,10 +11,12 @@ # OS-PROC-LLVM: Name: .os.flags.high # OS-PROC-LLVM-NEXT: Type: SHT_PROGBITS # OS-PROC-LLVM-NEXT: Flags [ (0xFE00000) +# OS-PROC-LLVM-NEXT: SHF_GNU_RETAIN (0x200000) # OS-PROC-LLVM-NEXT: ] # OS-PROC-LLVM: Name: .os.flags.mask # OS-PROC-LLVM-NEXT: Type: SHT_PROGBITS # OS-PROC-LLVM-NEXT: Flags [ (0xFF00000) +# OS-PROC-LLVM-NEXT: SHF_GNU_RETAIN (0x200000) # OS-PROC-LLVM-NEXT: ] # OS-PROC-LLVM: Name: .proc.flags.low # OS-PROC-LLVM-NEXT: Type: SHT_PROGBITS @@ -38,11 +40,19 @@ # OS-PROC-LLVM-NEXT: Type: SHT_PROGBITS # OS-PROC-LLVM-NEXT: Flags [ (0xEFE00000) # OS-PROC-LLVM-NEXT: SHF_EXCLUDE (0x80000000) +# OS-PROC-LLVM-NEXT: SHF_GNU_RETAIN (0x200000) # OS-PROC-LLVM-NEXT: ] # OS-PROC-LLVM: Name: .both.flags.mask # OS-PROC-LLVM-NEXT: Type: SHT_PROGBITS # OS-PROC-LLVM-NEXT: Flags [ (0xFFF00000) # OS-PROC-LLVM-NEXT: SHF_EXCLUDE (0x80000000) +# OS-PROC-LLVM-NEXT: SHF_GNU_RETAIN (0x200000) +# OS-PROC-LLVM-NEXT: ] +# OS-PROC-LLVM: Name: .gnu.retain +# OS-PROC-LLVM-NEXT: Type: SHT_PROGBITS +# OS-PROC-LLVM-NEXT: Flags [ (0x200800) +# OS-PROC-LLVM-NEXT: SHF_COMPRESSED (0x800) +# OS-PROC-LLVM-NEXT: SHF_GNU_RETAIN (0x200000) # OS-PROC-LLVM-NEXT: ] # OS-PROC-LLVM: Name: .exclude # OS-PROC-LLVM-NEXT: Type: SHT_PROGBITS @@ -56,6 +66,7 @@ # OS-PROC-LLVM-NEXT: SHF_COMPRESSED (0x800) # OS-PROC-LLVM-NEXT: SHF_EXCLUDE (0x80000000) # OS-PROC-LLVM-NEXT: SHF_EXECINSTR (0x4) +# OS-PROC-LLVM-NEXT: SHF_GNU_RETAIN (0x200000) # OS-PROC-LLVM-NEXT: SHF_GROUP (0x200) # OS-PROC-LLVM-NEXT: SHF_INFO_LINK (0x40) # OS-PROC-LLVM-NEXT: SHF_LINK_ORDER (0x80) @@ -70,16 +81,17 @@ # OS-PROC-GNU-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al # OS-PROC-GNU-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 # OS-PROC-GNU-NEXT: [ 1] .os.flags.low PROGBITS 0000000000000000 000040 000000 00 o 0 0 0 -# OS-PROC-GNU-NEXT: [ 2] .os.flags.high PROGBITS 0000000000000000 000040 000000 00 o 0 0 0 +# OS-PROC-GNU-NEXT: [ 2] .os.flags.high PROGBITS 0000000000000000 000040 000000 00 Ro 0 0 0 # OS-PROC-GNU-NEXT: [ 3] .os.flags.mask PROGBITS 0000000000000000 000040 000000 00 o 0 0 0 # OS-PROC-GNU-NEXT: [ 4] .proc.flags.low PROGBITS 0000000000000000 000040 000000 00 p 0 0 0 # OS-PROC-GNU-NEXT: [ 5] .proc.flags.high PROGBITS 0000000000000000 000040 000000 00 p 0 0 0 # OS-PROC-GNU-NEXT: [ 6] .proc.flags.mask PROGBITS 0000000000000000 000040 000000 00 p 0 0 0 # OS-PROC-GNU-NEXT: [ 7] .both.flags.low PROGBITS 0000000000000000 000040 000000 00 op 0 0 0 -# OS-PROC-GNU-NEXT: [ 8] .both.flags.high PROGBITS 0000000000000000 000040 000000 00 op 0 0 0 +# OS-PROC-GNU-NEXT: [ 8] .both.flags.high PROGBITS 0000000000000000 000040 000000 00 Rop 0 0 0 # OS-PROC-GNU-NEXT: [ 9] .both.flags.mask PROGBITS 0000000000000000 000040 000000 00 op 0 0 0 -# OS-PROC-GNU-NEXT: [10] .exclude PROGBITS 0000000000000000 000040 000000 00 E 0 0 0 -# OS-PROC-GNU-NEXT: [11] .all.possible PROGBITS 0000000000000000 000040 000000 00 WAXMSILOGTCopx 0 0 0 +# OS-PROC-GNU-NEXT: [10] .gnu.retain PROGBITS 0000000000000000 000040 000000 00 CR 0 0 0 +# OS-PROC-GNU-NEXT: [11] .exclude PROGBITS 0000000000000000 000040 000000 00 E 0 0 0 +# OS-PROC-GNU-NEXT: [12] .all.possible PROGBITS 0000000000000000 000040 000000 00 WAXMSILOGTCopx 0 0 0 ## Use an arbitrary EM_* machine type that does not have specific SHF_* OS/Processor ## flags to test what we dump when bits in the OS and processor specific ranges are set. @@ -89,6 +101,7 @@ Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_REL + OSABI: ELFOSABI_GNU Sections: - Name: .os.flags.low Type: SHT_PROGBITS @@ -117,6 +130,11 @@ - Name: .both.flags.mask Type: SHT_PROGBITS ShFlags: 0xFFF00000 +## GNU readelf prints SHF_GNU_RETAIN (0x200000; 'R') for ELFOSABI_GNU and +## ELFOSABI_FREEBSD. Currently we don't inspect EI_OSABI. + - Name: .gnu.retain + Type: SHT_PROGBITS + ShFlags: 0x200800 ## SHF_MASKPROC has a value of 0xf0000000, SHF_EXCLUDE has a value of ## 0x80000000. When SHF_EXCLUDE is mixed with other processor specific ## flags, GNU readelf does not necessarily print "E", because it handles 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 @@ -1201,6 +1201,7 @@ ENUM_ENT(SHF_GROUP, "G"), ENUM_ENT(SHF_TLS, "T"), ENUM_ENT(SHF_COMPRESSED, "C"), + ENUM_ENT(SHF_GNU_RETAIN, "R"), ENUM_ENT(SHF_EXCLUDE, "E"), };