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/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 @@ -23,7 +23,7 @@ # 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) +# ELF32-NEXT: R (retain), p (processor specific) --- !ELF FileHeader: @@ -97,7 +97,7 @@ # 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) +# ELF64-NEXT: R (retain), l (large), p (processor specific) ## For an EM_ARM target we print "y" for the SHF_ARM_PURECODE section flag. ## Check we mention it in the flag key. @@ -109,4 +109,4 @@ # 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) +# ARM-NEXT: R (retain), y (purecode), p (processor specific) 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,13 @@ # 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: .exclude # OS-PROC-LLVM-NEXT: Type: SHT_PROGBITS @@ -56,6 +60,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,13 +75,13 @@ # 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 diff --git a/llvm/test/tools/llvm-readobj/ELF/section-flags.test b/llvm/test/tools/llvm-readobj/ELF/section-flags.test --- a/llvm/test/tools/llvm-readobj/ELF/section-flags.test +++ b/llvm/test/tools/llvm-readobj/ELF/section-flags.test @@ -6,11 +6,12 @@ # LLVM: Name: allflags # LLVM-NEXT: Type: SHT_PROGBITS -# LLVM-NEXT: Flags [ (0x80000FF7) +# LLVM-NEXT: Flags [ (0x80200FF7) # LLVM-NEXT: SHF_ALLOC (0x2) # LLVM-NEXT: SHF_COMPRESSED (0x800) # LLVM-NEXT: SHF_EXCLUDE (0x80000000) # LLVM-NEXT: SHF_EXECINSTR (0x4) +# LLVM-NEXT: SHF_GNU_RETAIN (0x200000) # LLVM-NEXT: SHF_GROUP (0x200) # LLVM-NEXT: SHF_INFO_LINK (0x40) # LLVM-NEXT: SHF_LINK_ORDER (0x80) @@ -92,6 +93,14 @@ # LLVM-NEXT: SHF_COMPRESSED (0x800) # LLVM-NEXT: ] +## SHF_GNU_RETAIN is defined in the OS-specific range, but we treat it generic +## and allow it to be used with OSABI values other than GNU and FREEBSD. +# LLVM: Name: retain +# LLVM-NEXT: Type: SHT_PROGBITS +# LLVM-NEXT: Flags [ (0x200000) +# LLVM-NEXT: SHF_GNU_RETAIN (0x200000) +# LLVM-NEXT: ] + # LLVM: Name: exclude # LLVM-NEXT: Type: SHT_PROGBITS # LLVM-NEXT: Flags [ (0x80000000) @@ -104,7 +113,7 @@ # LLVM-NEXT: ] # GNU: [Nr] Name Type Address Off Size ES Flg Lk Inf Al -# GNU: [ 1] allflags PROGBITS 0000000000000000 000040 000000 00 WAXMSILOGTCE 0 0 0 +# GNU: [ 1] allflags PROGBITS 0000000000000000 000040 000000 00 WAXMSILOGTCRE 0 0 0 # GNU: [ 2] noflags PROGBITS 0000000000000000 000040 000000 00 0 0 0 # GNU: [ 3] write PROGBITS 0000000000000000 000040 000000 00 W 0 0 0 # GNU: [ 4] alloc PROGBITS 0000000000000000 000040 000000 00 A 0 0 0 @@ -117,8 +126,9 @@ # GNU: [11] group PROGBITS 0000000000000000 000040 000000 00 G 0 0 0 # GNU: [12] tls PROGBITS 0000000000000000 000040 000000 00 T 0 0 0 # GNU: [13] compressed PROGBITS 0000000000000000 000040 000000 00 C 0 0 0 -# GNU: [14] exclude PROGBITS 0000000000000000 000040 000000 00 E 0 0 0 -# GNU: [15] unknown PROGBITS 0000000000000000 000040 000000 00 x 0 0 0 +# GNU: [14] retain PROGBITS 0000000000000000 000040 000000 00 R 0 0 0 +# GNU: [15] exclude PROGBITS 0000000000000000 000040 000000 00 E 0 0 0 +# GNU: [16] unknown PROGBITS 0000000000000000 000040 000000 00 x 0 0 0 --- !ELF FileHeader: @@ -131,7 +141,7 @@ Type: SHT_PROGBITS Flags: [ SHF_WRITE, SHF_ALLOC, SHF_EXECINSTR, SHF_MERGE, SHF_STRINGS, SHF_INFO_LINK, SHF_LINK_ORDER, SHF_OS_NONCONFORMING, - SHF_GROUP, SHF_TLS, SHF_COMPRESSED, SHF_EXCLUDE ] + SHF_GROUP, SHF_TLS, SHF_COMPRESSED, SHF_GNU_RETAIN, SHF_EXCLUDE ] - Name: noflags Type: SHT_PROGBITS Flags: [ ] @@ -168,6 +178,9 @@ - Name: compressed Type: SHT_PROGBITS Flags: [ SHF_COMPRESSED ] + - Name: retain + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] - Name: exclude Type: SHT_PROGBITS Flags: [ SHF_EXCLUDE ] 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"), }; @@ -3483,15 +3484,14 @@ 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"; + OS << " R (retain)"; if (EMachine == EM_X86_64) - OS << " l (large), "; + OS << ", l (large)"; else if (EMachine == EM_ARM) - OS << " y (purecode), "; - else - OS << " "; + OS << ", y (purecode)"; - OS << "p (processor specific)\n"; + OS << ", p (processor specific)\n"; } template void GNUELFDumper::printSectionHeaders() {