Support SHF_GNU_RETAIN ELF section flag

The SHF_GNU_RETAIN section flag is an extension to the GNU ELF OSABI.
It is defined as follows:

=========================================================
Section Attribute Flags
+-------------------------------------+
| Name           | Value              |
+-------------------------------------+
| SHF_GNU_RETAIN | 0x200000 (1 << 21) |
+-------------------------------------+

SHF_GNU_RETAIN
  The link editor should not garbage collect the section.
=========================================================

The .section directive accepts the "R" flag, which indicates
SHF_GNU_RETAIN should be applied to the section.

There is not a direct mapping of SHF_GNU_RETAIN to the BFD
section flag SEC_KEEP. Keeping these flags distinct allows
SHF_GNU_RETAIN sections to be explicitly removed by placing them in
/DISCARD/.

bfd/ChangeLog:

	* elf-bfd.h (enum elf_gnu_osabi): Add elf_gnu_osabi_retain.
	(struct elf_obj_tdata): Increase has_gnu_osabi to 4 bits.
	* elf.c (_bfd_elf_make_section_from_shdr): Set elf_gnu_osabi_retain
	for SHF_GNU_RETAIN.
	(_bfd_elf_final_write_processing): Report if SHF_GNU_RETAIN is
	not supported by the OSABI.
	Adjust error messages.
	* elflink.c (elf_link_input_bfd): Copy enabled has_gnu_osabi bits from
	input BFD to output BFD.
	(bfd_elf_gc_sections): gc_mark the section if SHF_GNU_RETAIN is set.

binutils/ChangeLog:

	* NEWS: Announce SHF_GNU_RETAIN support.
	* readelf.c (get_elf_section_flags): Handle SHF_GNU_RETAIN.
	Recognize SHF_GNU_RETAIN and SHF_GNU_MBIND only for supported OSABIs.
	* testsuite/binutils-all/readelf.exp: Run new tests.
	Don't run run_dump_test when there isn't an assembler available.
	* testsuite/lib/binutils-common.exp (supports_gnu_osabi): Adjust
	comment.
	* testsuite/binutils-all/readelf-maskos-1a.d: New test.
	* testsuite/binutils-all/readelf-maskos-1b.d: New test.
	* testsuite/binutils-all/readelf-maskos.s: New test.
	* testsuite/binutils-all/retain1.s: New test.
	* testsuite/binutils-all/retain1a.d: New test.
	* testsuite/binutils-all/retain1b.d: New test.

gas/ChangeLog:

	* NEWS: Announce SHF_GNU_RETAIN support.
	* config/obj-elf.c (obj_elf_change_section): Merge SHF_GNU_RETAIN bit
	between section declarations.
	(obj_elf_parse_section_letters): Handle 'R' flag.
	Handle numeric flag values within the SHF_MASKOS range.
	(obj_elf_section): Validate SHF_GNU_RETAIN usage.
	* doc/as.texi: Document 'R' flag to .section directive.
	* testsuite/gas/elf/elf.exp: Run new tests.
	* testsuite/gas/elf/section10.d: Unset SHF_GNU_RETAIN bit.
	* testsuite/gas/elf/section10.s: Likewise.
	* testsuite/gas/elf/section22.d: New test.
	* testsuite/gas/elf/section22.s: New test.
	* testsuite/gas/elf/section23.s: New test.
	* testsuite/gas/elf/section23a.d: New test.
	* testsuite/gas/elf/section23b.d: New test.
	* testsuite/gas/elf/section23b.err: New test.
	* testsuite/gas/elf/section24.l: New test.
	* testsuite/gas/elf/section24.s: New test.
	* testsuite/gas/elf/section24a.d: New test.
	* testsuite/gas/elf/section24b.d: New test.

include/ChangeLog:

	* elf/common.h (SHF_GNU_RETAIN): Define.

ld/ChangeLog:

	* NEWS: Announce support for SHF_GNU_RETAIN.
	* ld.texi (garbage collection): Document SHF_GNU_RETAIN.
	(Output Section Discarding): Likewise.
	* testsuite/ld-elf/elf.exp: Run new tests.
	* testsuite/ld-elf/retain1.s: New test.
	* testsuite/ld-elf/retain1a.d: New test.
	* testsuite/ld-elf/retain1b.d: New test.
	* testsuite/ld-elf/retain2.d: New test.
	* testsuite/ld-elf/retain2.ld: New test.
	* testsuite/ld-elf/retain2.map: New test.
	* testsuite/ld-elf/retain3.d: New test.
	* testsuite/ld-elf/retain3.s: New test.
	* testsuite/ld-elf/retain4.d: New test.
	* testsuite/ld-elf/retain4.s: New test.
	* testsuite/ld-elf/retain5.d: New test.
	* testsuite/ld-elf/retain5.map: New test.
	* testsuite/ld-elf/retain5lib.s: New test.
	* testsuite/ld-elf/retain5main.s: New test.
	* testsuite/ld-elf/retain6a.d: New test.
	* testsuite/ld-elf/retain6b.d: New test.
	* testsuite/ld-elf/retain6lib.s: New test.
	* testsuite/ld-elf/retain6main.s: New test.
This commit is contained in:
Jozef Lawrynowicz 2020-11-18 11:51:13 +00:00
parent 40d9d2fd79
commit 99fabbc973
55 changed files with 944 additions and 42 deletions

View file

@ -1,3 +1,17 @@
2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
H.J. Lu <hongjiu.lu@intel.com>
* elf-bfd.h (enum elf_gnu_osabi): Add elf_gnu_osabi_retain.
(struct elf_obj_tdata): Increase has_gnu_osabi to 4 bits.
* elf.c (_bfd_elf_make_section_from_shdr): Set elf_gnu_osabi_retain
for SHF_GNU_RETAIN.
(_bfd_elf_final_write_processing): Report if SHF_GNU_RETAIN is
not supported by the OSABI.
Adjust error messages.
* elflink.c (elf_link_input_bfd): Copy enabled has_gnu_osabi bits from
input BFD to output BFD.
(bfd_elf_gc_sections): gc_mark the section if SHF_GNU_RETAIN is set.
2020-11-16 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com> 2020-11-16 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com>
* cpu-arm.c (processors): Add Cortex-A78C. * cpu-arm.c (processors): Add Cortex-A78C.

View file

@ -1897,14 +1897,15 @@ struct output_elf_obj_tdata
bfd_boolean flags_init; bfd_boolean flags_init;
}; };
/* Indicate if the bfd contains SHF_GNU_MBIND sections or symbols that /* Indicate if the bfd contains SHF_GNU_MBIND/SHF_GNU_RETAIN sections or
have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE binding. Used symbols that have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE
to set the osabi field in the ELF header structure. */ binding. Used to set the osabi field in the ELF header structure. */
enum elf_gnu_osabi enum elf_gnu_osabi
{ {
elf_gnu_osabi_mbind = 1 << 0, elf_gnu_osabi_mbind = 1 << 0,
elf_gnu_osabi_ifunc = 1 << 1, elf_gnu_osabi_ifunc = 1 << 1,
elf_gnu_osabi_unique = 1 << 2, elf_gnu_osabi_unique = 1 << 2,
elf_gnu_osabi_retain = 1 << 3,
}; };
typedef struct elf_section_list typedef struct elf_section_list
@ -2034,7 +2035,7 @@ struct elf_obj_tdata
ENUM_BITFIELD (dynamic_lib_link_class) dyn_lib_class : 4; ENUM_BITFIELD (dynamic_lib_link_class) dyn_lib_class : 4;
/* Whether the bfd uses OS specific bits that require ELFOSABI_GNU. */ /* Whether the bfd uses OS specific bits that require ELFOSABI_GNU. */
ENUM_BITFIELD (elf_gnu_osabi) has_gnu_osabi : 3; ENUM_BITFIELD (elf_gnu_osabi) has_gnu_osabi : 4;
/* Whether if the bfd contains the GNU_PROPERTY_NO_COPY_ON_PROTECTED /* Whether if the bfd contains the GNU_PROPERTY_NO_COPY_ON_PROTECTED
property. */ property. */

View file

@ -1066,9 +1066,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
/* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE, /* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE,
but binutils as of 2019-07-23 did not set the EI_OSABI header but binutils as of 2019-07-23 did not set the EI_OSABI header
byte. */ byte. */
case ELFOSABI_NONE:
case ELFOSABI_GNU: case ELFOSABI_GNU:
case ELFOSABI_FREEBSD: case ELFOSABI_FREEBSD:
if ((hdr->sh_flags & SHF_GNU_RETAIN) != 0)
elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_retain;
/* Fall through */
case ELFOSABI_NONE:
if ((hdr->sh_flags & SHF_GNU_MBIND) != 0) if ((hdr->sh_flags & SHF_GNU_MBIND) != 0)
elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_mbind; elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_mbind;
break; break;
@ -12456,8 +12459,8 @@ _bfd_elf_final_write_processing (bfd *abfd)
i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi; i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
/* Set the osabi field to ELFOSABI_GNU if the binary contains /* Set the osabi field to ELFOSABI_GNU if the binary contains
SHF_GNU_MBIND sections or symbols of STT_GNU_IFUNC type or SHF_GNU_MBIND or SHF_GNU_RETAIN sections or symbols of STT_GNU_IFUNC type
STB_GNU_UNIQUE binding. */ or STB_GNU_UNIQUE binding. */
if (elf_tdata (abfd)->has_gnu_osabi != 0) if (elf_tdata (abfd)->has_gnu_osabi != 0)
{ {
if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE) if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE)
@ -12466,11 +12469,17 @@ _bfd_elf_final_write_processing (bfd *abfd)
&& i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_FREEBSD) && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
{ {
if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind)
_bfd_error_handler (_("GNU_MBIND section is unsupported")); _bfd_error_handler (_("GNU_MBIND section is supported only by GNU "
"and FreeBSD targets"));
if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_ifunc) if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_ifunc)
_bfd_error_handler (_("symbol type STT_GNU_IFUNC is unsupported")); _bfd_error_handler (_("symbol type STT_GNU_IFUNC is supported "
"only by GNU and FreeBSD targets"));
if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_unique) if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_unique)
_bfd_error_handler (_("symbol binding STB_GNU_UNIQUE is unsupported")); _bfd_error_handler (_("symbol binding STB_GNU_UNIQUE is supported "
"only by GNU and FreeBSD targets"));
if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_retain)
_bfd_error_handler (_("GNU_RETAIN section is supported "
"only by GNU and FreeBSD targets"));
bfd_set_error (bfd_error_sorry); bfd_set_error (bfd_error_sorry);
return FALSE; return FALSE;
} }

View file

@ -10746,6 +10746,14 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
extsymoff = symtab_hdr->sh_info; extsymoff = symtab_hdr->sh_info;
} }
/* Enable GNU OSABI features in the output BFD that are used in the input
BFD. */
if (bed->elf_osabi == ELFOSABI_NONE
|| bed->elf_osabi == ELFOSABI_GNU
|| bed->elf_osabi == ELFOSABI_FREEBSD)
elf_tdata (output_bfd)->has_gnu_osabi
|= elf_tdata (input_bfd)->has_gnu_osabi;
/* Read the local symbols. */ /* Read the local symbols. */
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL && locsymcount != 0) if (isymbuf == NULL && locsymcount != 0)
@ -14116,7 +14124,9 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
== SHT_FINI_ARRAY))) == SHT_FINI_ARRAY)))
|| (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE || (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE
&& elf_next_in_group (o) == NULL && elf_next_in_group (o) == NULL
&& elf_linked_to_section (o) == NULL))) && elf_linked_to_section (o) == NULL)
|| ((elf_tdata (sub)->has_gnu_osabi & elf_gnu_osabi_retain)
&& (elf_section_flags (o) & SHF_GNU_RETAIN))))
{ {
if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
return FALSE; return FALSE;

View file

@ -1,3 +1,19 @@
2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
* NEWS: Announce SHF_GNU_RETAIN support.
* readelf.c (get_elf_section_flags): Handle SHF_GNU_RETAIN.
Recognize SHF_GNU_RETAIN and SHF_GNU_MBIND only for supported OSABIs.
* testsuite/binutils-all/readelf.exp: Run new tests.
Don't run run_dump_test when there isn't an assembler available.
* testsuite/lib/binutils-common.exp (supports_gnu_osabi): Adjust
comment.
* testsuite/binutils-all/readelf-maskos-1a.d: New test.
* testsuite/binutils-all/readelf-maskos-1b.d: New test.
* testsuite/binutils-all/readelf-maskos.s: New test.
* testsuite/binutils-all/retain1.s: New test.
* testsuite/binutils-all/retain1a.d: New test.
* testsuite/binutils-all/retain1b.d: New test.
2020-11-17 Howard Chu <hyc@symas.com> 2020-11-17 Howard Chu <hyc@symas.com>
* ar.c (main): Place the libdeps record in the second archive * ar.c (main): Place the libdeps record in the second archive

View file

@ -12,6 +12,10 @@
symbol names. In addition the --demangle=<style>, --no-demangle, symbol names. In addition the --demangle=<style>, --no-demangle,
--recurse-limit and --no-recurse-limit options are also now availale. --recurse-limit and --no-recurse-limit options are also now availale.
* Add support for the SHF_GNU_RETAIN ELF section flag.
This flag specifies that the section should not be garbage collected by the
linker.
Changes in 2.35: Changes in 2.35:
* Changed readelf's display of symbol names when wide mode is not enabled. * Changed readelf's display of symbol names when wide mode is not enabled.

View file

@ -5996,6 +5996,8 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
/* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") }, /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
/* VLE specific. */ /* VLE specific. */
/* 25 */ { STRING_COMMA_LEN ("VLE") }, /* 25 */ { STRING_COMMA_LEN ("VLE") },
/* GNU specific. */
/* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
}; };
if (do_section_details) if (do_section_details)
@ -6028,7 +6030,6 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
case SHF_TLS: sindex = 9; break; case SHF_TLS: sindex = 9; break;
case SHF_EXCLUDE: sindex = 18; break; case SHF_EXCLUDE: sindex = 18; break;
case SHF_COMPRESSED: sindex = 20; break; case SHF_COMPRESSED: sindex = 20; break;
case SHF_GNU_MBIND: sindex = 24; break;
default: default:
sindex = -1; sindex = -1;
@ -6080,10 +6081,28 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
if (flag == SHF_PPC_VLE) if (flag == SHF_PPC_VLE)
sindex = 25; sindex = 25;
break; break;
default: default:
break; break;
} }
switch (filedata->file_header.e_ident[EI_OSABI])
{
case ELFOSABI_GNU:
case ELFOSABI_FREEBSD:
if (flag == SHF_GNU_RETAIN)
sindex = 26;
/* Fall through */
case ELFOSABI_NONE:
if (flag == SHF_GNU_MBIND)
/* We should not recognize SHF_GNU_MBIND for
ELFOSABI_NONE, but binutils as of 2019-07-23 did
not set the EI_OSABI header byte. */
sindex = 24;
break;
default:
break;
}
break;
} }
if (sindex != -1) if (sindex != -1)
@ -6126,7 +6145,6 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
case SHF_TLS: *p = 'T'; break; case SHF_TLS: *p = 'T'; break;
case SHF_EXCLUDE: *p = 'E'; break; case SHF_EXCLUDE: *p = 'E'; break;
case SHF_COMPRESSED: *p = 'C'; break; case SHF_COMPRESSED: *p = 'C'; break;
case SHF_GNU_MBIND: *p = 'D'; break;
default: default:
if ((filedata->file_header.e_machine == EM_X86_64 if ((filedata->file_header.e_machine == EM_X86_64
@ -6136,14 +6154,37 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
*p = 'l'; *p = 'l';
else if (filedata->file_header.e_machine == EM_ARM else if (filedata->file_header.e_machine == EM_ARM
&& flag == SHF_ARM_PURECODE) && flag == SHF_ARM_PURECODE)
*p = 'y'; *p = 'y';
else if (filedata->file_header.e_machine == EM_PPC else if (filedata->file_header.e_machine == EM_PPC
&& flag == SHF_PPC_VLE) && flag == SHF_PPC_VLE)
*p = 'v'; *p = 'v';
else if (flag & SHF_MASKOS) else if (flag & SHF_MASKOS)
{ {
*p = 'o'; switch (filedata->file_header.e_ident[EI_OSABI])
sh_flags &= ~ SHF_MASKOS; {
case ELFOSABI_GNU:
case ELFOSABI_FREEBSD:
if (flag == SHF_GNU_RETAIN)
{
*p = 'R';
break;
}
/* Fall through */
case ELFOSABI_NONE:
if (flag == SHF_GNU_MBIND)
{
/* We should not recognize SHF_GNU_MBIND for
ELFOSABI_NONE, but binutils as of 2019-07-23 did
not set the EI_OSABI header byte. */
*p = 'D';
break;
}
/* Fall through */
default:
*p = 'o';
sh_flags &= ~SHF_MASKOS;
break;
}
} }
else if (flag & SHF_MASKPROC) else if (flag & SHF_MASKPROC)
{ {

View file

@ -0,0 +1,10 @@
#name: Unknown SHF_MASKOS value in section
#source: readelf-maskos.s
#notarget: [supports_gnu_osabi] msp430-*-elf visium-*-elf
#xfail: arm-*-elf
#readelf: -S --wide
# PR26722 for the arm-*-elf XFAIL
#...
\[[ 0-9]+\] .data.retain_var.*WAo.*
#pass

View file

@ -0,0 +1,12 @@
#name: -t (section details) for unknown SHF_MASKOS value in section
#source: readelf-maskos.s
#notarget: [supports_gnu_osabi] msp430-*-elf visium-*-elf
#xfail: arm-*-elf
#readelf: -S -t --wide
# PR26722 for the arm-*-elf XFAIL
#...
\[[ 0-9]+\] .data.retain_var
PROGBITS +0+ +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +0 +0 +(1|2|4|8)
\[00200003\]: WRITE, ALLOC, OS \(00200000\)
#pass

View file

@ -0,0 +1,11 @@
.section .data.retain_var,"0x200003"
.global retain_var
.type retain_var, %object
retain_var:
.long 2
.section .text._start,"ax"
.global _start
.type _start, %function
_start:
.word 0

View file

@ -364,8 +364,15 @@ readelf_wi_test
readelf_compressed_wa_test readelf_compressed_wa_test
readelf_dump_test readelf_dump_test
run_dump_test "pr25543"
# These dump tests require an assembler.
if {[which $AS] != 0} then {
run_dump_test "pr25543"
run_dump_test "retain1a"
run_dump_test "retain1b"
run_dump_test "readelf-maskos-1a"
run_dump_test "readelf-maskos-1b"
}
# PR 13482 - Check for off-by-one errors when dumping .note sections. # PR 13482 - Check for off-by-one errors when dumping .note sections.
if {![binutils_assemble $srcdir/$subdir/version.s tmpdir/version.o]} then { if {![binutils_assemble $srcdir/$subdir/version.s tmpdir/version.o]} then {

View file

@ -0,0 +1,104 @@
.global discard0
.section .bss.discard0,"aw"
.type discard0, %object
discard0:
.zero 2
.global discard1
.section .bss.discard1,"aw"
.type discard1, %object
discard1:
.zero 2
.global discard2
.section .data.discard2,"aw"
.type discard2, %object
discard2:
.word 1
.section .bss.sdiscard0,"aw"
.type sdiscard0, %object
sdiscard0:
.zero 2
.section .bss.sdiscard1,"aw"
.type sdiscard1, %object
sdiscard1:
.zero 2
.section .data.sdiscard2,"aw"
.type sdiscard2, %object
sdiscard2:
.word 1
.section .text.fndiscard0,"ax"
.global fndiscard0
.type fndiscard0, %function
fndiscard0:
.word 0
.global retain0
.section .bss.retain0,"awR"
.type retain0, %object
retain0:
.zero 2
.global retain1
.section .bss.retain1,"awR"
.type retain1, %object
retain1:
.zero 2
.global retain2
.section .data.retain2,"awR"
.type retain2, %object
retain2:
.word 1
.section .bss.sretain0,"awR"
.type sretain0, %object
sretain0:
.zero 2
.section .bss.sretain1,"awR"
.type sretain1, %object
sretain1:
.zero 2
.section .data.sretain2,"aRw"
.type sretain2, %object
sretain2:
.word 1
.section .text.fnretain1,"Rax"
.global fnretain1
.type fnretain1, %function
fnretain1:
.word 0
.section .text.fndiscard2,"ax"
.global fndiscard2
.type fndiscard2, %function
fndiscard2:
.word 0
.section .bss.lsretain0,"awR"
.type lsretain0.2, %object
lsretain0.2:
.zero 2
.section .bss.lsretain1,"aRw"
.type lsretain1.1, %object
lsretain1.1:
.zero 2
.section .data.lsretain2,"aRw"
.type lsretain2.0, %object
lsretain2.0:
.word 1
.section .text._start,"ax"
.global _start
.type _start, %function
_start:
.word 0

View file

@ -0,0 +1,18 @@
#name: readelf SHF_GNU_RETAIN
#source: retain1.s
#target: [supports_gnu_osabi]
#readelf: -S --wide
#...
\[[ 0-9]+\] .bss.retain0.*WAR.*
\[[ 0-9]+\] .bss.retain1.*WAR.*
\[[ 0-9]+\] .data.retain2.*WAR.*
\[[ 0-9]+\] .bss.sretain0.*WAR.*
\[[ 0-9]+\] .bss.sretain1.*WAR.*
\[[ 0-9]+\] .data.sretain2.*WAR.*
\[[ 0-9]+\] .text.fnretain1.*AXR.*
#...
\[[ 0-9]+\] .bss.lsretain0.*WAR.*
\[[ 0-9]+\] .bss.lsretain1.*WAR.*
\[[ 0-9]+\] .data.lsretain2.*WAR.*
#pass

View file

@ -0,0 +1,46 @@
#name: -t (section details) for readelf SHF_GNU_RETAIN
#source: retain1.s
#target: [supports_gnu_osabi]
#readelf: -S -t --wide
#...
\[[ 0-9]+\] .bss.retain0
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#...
\[[ 0-9]+\] .bss.retain1
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#...
\[[ 0-9]+\] .data.retain2
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#...
\[[ 0-9]+\] .bss.sretain0
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#...
\[[ 0-9]+\] .bss.sretain1
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#...
\[[ 0-9]+\] .data.sretain2
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#...
\[[ 0-9]+\] .text.fnretain1
#...
\[0+200006\]: ALLOC, EXEC, GNU_RETAIN
#...
\[[ 0-9]+\] .bss.lsretain0
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#...
\[[ 0-9]+\] .bss.lsretain1
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#...
\[[ 0-9]+\] .data.lsretain2
#...
\[0+200003\]: WRITE, ALLOC, GNU_RETAIN
#pass

View file

@ -195,13 +195,15 @@ proc match_target { target } {
# True if the ELF target supports setting the ELF header OSABI field # True if the ELF target supports setting the ELF header OSABI field
# to ELFOSABI_GNU or ELFOSABI_FREEBSD, a requirement for STT_GNU_IFUNC # to ELFOSABI_GNU or ELFOSABI_FREEBSD, a requirement for STT_GNU_IFUNC
# symbol and SHF_GNU_MBIND section support. # symbol and SHF_GNU_MBIND or SHF_GNU_RETAIN section support.
# #
# This generally depends on the target OS only, however there are a # This generally depends on the target OS only, however there are a
# number of exceptions for bare metal targets as follows. The MSP430 # number of exceptions for bare metal targets as follows. The MSP430
# and Visium targets set OSABI to ELFOSABI_STANDALONE. Likewise # and Visium targets set OSABI to ELFOSABI_STANDALONE. Likewise
# non-EABI ARM targets set OSABI to ELFOSABI_ARM # non-EABI ARM targets set OSABI to ELFOSABI_ARM
# #
# Non-Linux HPPA defaults to ELFOSABI_HPUX.
#
# Note that some TI C6X targets use ELFOSABI_C6000_* but one doesn't, # Note that some TI C6X targets use ELFOSABI_C6000_* but one doesn't,
# so we don't try to sort out tic6x here. (The effect is that linker # so we don't try to sort out tic6x here. (The effect is that linker
# testcases will generally need to exclude tic6x or use a -m option.) # testcases will generally need to exclude tic6x or use a -m option.)
@ -227,6 +229,7 @@ proc supports_gnu_osabi {} {
} }
if { [istarget "arm*-*-*"] if { [istarget "arm*-*-*"]
|| [istarget "msp430-*-*"] || [istarget "msp430-*-*"]
|| [istarget "hppa-unknown-elf"]
|| [istarget "visium-*-*"] } { || [istarget "visium-*-*"] } {
return 0 return 0
} }

View file

@ -1,3 +1,26 @@
2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
H.J. Lu <hongjiu.lu@intel.com>
* NEWS: Announce SHF_GNU_RETAIN support.
* config/obj-elf.c (obj_elf_change_section): Merge SHF_GNU_RETAIN bit
between section declarations.
(obj_elf_parse_section_letters): Handle 'R' flag.
Handle numeric flag values within the SHF_MASKOS range.
(obj_elf_section): Validate SHF_GNU_RETAIN usage.
* doc/as.texi: Document 'R' flag to .section directive.
* testsuite/gas/elf/elf.exp: Run new tests.
* testsuite/gas/elf/section10.d: Unset SHF_GNU_RETAIN bit.
* testsuite/gas/elf/section10.s: Likewise.
* testsuite/gas/elf/section22.d: New test.
* testsuite/gas/elf/section22.s: New test.
* testsuite/gas/elf/section23.s: New test.
* testsuite/gas/elf/section23a.d: New test.
* testsuite/gas/elf/section23b.d: New test.
* testsuite/gas/elf/section23b.err: New test.
* testsuite/gas/elf/section24.s: New test.
* testsuite/gas/elf/section24a.d: New test.
* testsuite/gas/elf/section24b.d: New test.
2020-11-13 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com> 2020-11-13 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com>
* NEWS: Update news. * NEWS: Update news.

View file

@ -52,6 +52,11 @@
* Configure with --enable-x86-used-note by default for Linux/x86. * Configure with --enable-x86-used-note by default for Linux/x86.
* Add support for the SHF_GNU_RETAIN flag, which can be applied to
sections using the 'R' flag in the .section directive.
SHF_GNU_RETAIN specifies that the section should not be garbage
collected by the linker. It requires the GNU or FreeBSD ELF OSABIs.
Changes in 2.35: Changes in 2.35:
* X86 NaCl target support is removed. * X86 NaCl target support is removed.

View file

@ -806,9 +806,17 @@ obj_elf_change_section (const char *name,
as_bad (_("changed section attributes for %s"), name); as_bad (_("changed section attributes for %s"), name);
} }
else else
/* FIXME: Maybe we should consider removing a previously set {
processor or application specific attribute as suspicious ? */ /* Don't overwrite a previously set SHF_GNU_RETAIN flag for the
elf_section_flags (sec) = attr; section. The entire section must be marked retained. */
if ((elf_tdata (stdoutput)->has_gnu_osabi & elf_gnu_osabi_retain)
&& ((elf_section_flags (old_sec) & SHF_GNU_RETAIN)))
attr |= SHF_GNU_RETAIN;
/* FIXME: Maybe we should consider removing a previously set
processor or application specific attribute as suspicious ? */
elf_section_flags (sec) = attr;
}
if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize) if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
as_bad (_("changed section entity size for %s"), name); as_bad (_("changed section entity size for %s"), name);
@ -861,6 +869,9 @@ obj_elf_parse_section_letters (char *str, size_t len,
case 'd': case 'd':
*gnu_attr |= SHF_GNU_MBIND; *gnu_attr |= SHF_GNU_MBIND;
break; break;
case 'R':
*gnu_attr |= SHF_GNU_RETAIN;
break;
case '?': case '?':
*is_clone = TRUE; *is_clone = TRUE;
break; break;
@ -890,8 +901,32 @@ obj_elf_parse_section_letters (char *str, size_t len,
if (ISDIGIT (*str)) if (ISDIGIT (*str))
{ {
char * end; char * end;
struct elf_backend_data *bed;
bfd_vma numeric_flags = strtoul (str, &end, 0);
attr |= numeric_flags;
bed = (struct elf_backend_data *)
get_elf_backend_data (stdoutput);
if (bed->elf_osabi == ELFOSABI_NONE
|| bed->elf_osabi == ELFOSABI_STANDALONE
|| bed->elf_osabi == ELFOSABI_GNU
|| bed->elf_osabi == ELFOSABI_FREEBSD)
{
/* Add flags in the SHF_MASKOS range to gnu_attr for
OSABIs that support those flags.
Also adding the flags for ELFOSABI_{NONE,STANDALONE}
allows them to be validated later in obj_elf_section.
We can't just always set these bits in gnu_attr for
all OSABIs, since Binutils does not recognize all
SHF_MASKOS bits for non-GNU OSABIs. It's therefore
possible that numeric flags are being used to set bits
in the SHF_MASKOS range for those targets, and we
don't want assembly to fail in those situations. */
*gnu_attr |= (numeric_flags & SHF_MASKOS);
}
attr |= strtoul (str, & end, 0);
/* Update str and len, allowing for the fact that /* Update str and len, allowing for the fact that
we will execute str++ and len-- below. */ we will execute str++ and len-- below. */
end --; end --;
@ -1387,26 +1422,37 @@ obj_elf_section (int push)
done: done:
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
obj_elf_change_section (name, type, attr, entsize, &match, linkonce, if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
push);
if ((gnu_attr & SHF_GNU_MBIND) != 0)
{ {
struct elf_backend_data *bed; struct elf_backend_data *bed;
bfd_boolean mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
if ((attr & SHF_ALLOC) == 0) if (mbind_p && (attr & SHF_ALLOC) == 0)
as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name); as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput); bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
if (bed->elf_osabi == ELFOSABI_NONE)
bed->elf_osabi = ELFOSABI_GNU; if (bed->elf_osabi != ELFOSABI_GNU
else if (bed->elf_osabi != ELFOSABI_GNU && bed->elf_osabi != ELFOSABI_FREEBSD
&& bed->elf_osabi != ELFOSABI_FREEBSD) && bed->elf_osabi != ELFOSABI_NONE)
as_bad (_("GNU_MBIND section is supported only by GNU " as_bad (_("%s section is supported only by GNU and FreeBSD targets"),
"and FreeBSD targets")); mbind_p ? "GNU_MBIND" : "GNU_RETAIN");
elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind; else
{
if (bed->elf_osabi == ELFOSABI_NONE)
bed->elf_osabi = ELFOSABI_GNU;
if (mbind_p)
elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
if ((gnu_attr & SHF_GNU_RETAIN) != 0)
elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
attr |= gnu_attr;
}
} }
elf_section_flags (now_seg) |= gnu_attr;
obj_elf_change_section (name, type, attr, entsize, &match, linkonce,
push);
if (linked_to_section_index != -1UL) if (linked_to_section_index != -1UL)
{ {

View file

@ -6659,6 +6659,9 @@ section is a member of a section group
section is used for thread-local-storage section is used for thread-local-storage
@item ? @item ?
section is a member of the previously-current section's group, if any section is a member of the previously-current section's group, if any
@item R
retained section (apply SHF_GNU_RETAIN to prevent linker garbage
collection, GNU ELF extension)
@item @code{<number>} @item @code{<number>}
a numeric value indicating the bits to be set in the ELF section header's flags a numeric value indicating the bits to be set in the ELF section header's flags
field. Note - if one or more of the alphabetic characters described above is field. Note - if one or more of the alphabetic characters described above is

View file

@ -261,8 +261,12 @@ if { [is_elf_format] } then {
run_dump_test "section19" run_dump_test "section19"
run_dump_test "section20" run_dump_test "section20"
run_dump_test "section21" run_dump_test "section21"
run_dump_test "section22"
run_dump_test "section23a"
run_dump_test "section23b"
run_dump_test "section24a"
run_dump_test "section24b"
run_dump_test "sh-link-zero" run_dump_test "sh-link-zero"
run_dump_test "dwarf2-1" $dump_opts run_dump_test "dwarf2-1" $dump_opts
run_dump_test "dwarf2-2" $dump_opts run_dump_test "dwarf2-2" $dump_opts
run_dump_test "dwarf2-3" $dump_opts run_dump_test "dwarf2-3" $dump_opts

View file

@ -18,7 +18,7 @@
#... #...
[ ]*\[.*\][ ]+sec3 [ ]*\[.*\][ ]+sec3
[ ]*PROGBITS.* [ ]*PROGBITS.*
[ ]*\[.*fefff030\]: MERGE, STRINGS,.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[3467]0000000\), UNKNOWN \(0+0ff000\) [ ]*\[.*fedff030\]: MERGE, STRINGS,.* EXCLUDE, OS \(.*ed00000\), PROC \(.*[3467]0000000\), UNKNOWN \(0+0ff000\)
#... #...
[ ]*\[.*\][ ]+sec4 [ ]*\[.*\][ ]+sec4
[ ]*LOOS\+0x11[ ].* [ ]*LOOS\+0x11[ ].*
@ -26,7 +26,7 @@
#... #...
[ ]*\[.*\][ ]+sec5 [ ]*\[.*\][ ]+sec5
[ ]*LOUSER\+0x9[ ].* [ ]*LOUSER\+0x9[ ].*
[ ]*\[.*feff0000\]:.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\) [ ]*\[.*fedf0000\]:.* EXCLUDE, OS \(.*ed00000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\)
[ ]*\[.*\][ ]+.data.foo [ ]*\[.*\][ ]+.data.foo
[ ]*LOUSER\+0x7f000000[ ].* [ ]*LOUSER\+0x7f000000[ ].*
[ ]*\[0+003\]: WRITE, ALLOC [ ]*\[0+003\]: WRITE, ALLOC

View file

@ -7,7 +7,7 @@
.word 2 .word 2
# Make sure that specifying further arguments to .sections is still supported # Make sure that specifying further arguments to .sections is still supported
.section sec3, "0xfefff000MS", %progbits, 32 .section sec3, "0xfedff000MS", %progbits, 32
.word 3 .word 3
# Make sure that extra flags can be set for well known sections as well. # Make sure that extra flags can be set for well known sections as well.
@ -19,7 +19,7 @@
.word 5 .word 5
# Test both together, with a quoted type value. # Test both together, with a quoted type value.
.section sec5, "0xfeff0000", "0x80000009" .section sec5, "0xfedf0000", "0x80000009"
.word 6 .word 6
# Test that declaring an extended version of a known special section works. # Test that declaring an extended version of a known special section works.

View file

@ -0,0 +1,19 @@
#readelf: -h -S --wide
#name: SHF_GNU_RETAIN sections 22
#notarget: ![supports_gnu_osabi]
#...
+OS/ABI: +UNIX - GNU
#...
\[..\] .text.discard0[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX.*
#...
\[..\] .data.discard1[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WA.*
#...
\[..\] .bss.discard2[ ]+NOBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WA.*
#...
\[..\] .bss.retain0[ ]+NOBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR.*
#...
\[..\] .data.retain1[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR.*
#...
\[..\] .text.retain2[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AXR.*
#pass

View file

@ -0,0 +1,34 @@
.section .text.discard0,"ax",%progbits
.global discard0
.type discard0, %function
discard0:
.word 0
.section .data.discard1,"aw"
.global discard1
.type discard1, %object
discard1:
.word 1
.section .bss.discard2,"aw"
.global discard2
.type discard2, %object
discard2:
.zero 2
.section .bss.retain0,"awR",%nobits
.global retain0
.type retain0, %object
retain0:
.zero 2
.section .data.retain1,"awR",%progbits
.type retain1, %object
retain1:
.word 1
.section .text.retain2,"axR",%progbits
.global retain2
.type retain2, %function
retain2:
.word 0

View file

@ -0,0 +1,11 @@
.section .data.retain_var,"0x200003"
.global retain_var
.type retain_var, %object
retain_var:
.long 2
.section .text._start,"ax"
.global _start
.type _start, %function
_start:
.word 0

View file

@ -0,0 +1,10 @@
#name: SHF_GNU_RETAIN set with numeric flag value in .section
#source: section23.s
#target: [supports_gnu_osabi]
#readelf: -h -S --wide
#...
+OS/ABI: +UNIX - GNU
#...
\[..\] .data.retain_var[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR.*
#pass

View file

@ -0,0 +1,6 @@
#name: SHF_GNU_RETAIN set with numeric flag value in .section for non-GNU OSABI target
#source: section23.s
#error_output: section23b.err
#target: msp430-*-elf visium-*-elf
# This test only runs for targets which set ELFOSABI_STANDALONE.

View file

@ -0,0 +1,2 @@
.*: Assembler messages:
.*:1: Error: GNU_RETAIN section is supported only by GNU and FreeBSD targets

View file

@ -0,0 +1,38 @@
.section .text,"ax",%progbits
.word 0
.section .data,"aw"
.word 0
.section .bss,"aw",%nobits
.word 0
.section .rodata,"a"
.word 0
/* Test that we can set the 'R' flag on an existing section. */
.section .text,"axR",%progbits
.word 0
.section .data,"awR"
.word 0
.section .bss,"awR",%nobits
.word 0
.section .rodata,"aR"
.word 0
/* Test that the 'R' flag does not get clobbered when the section is switched
back to. */
.section .text,"ax",%progbits
.word 0
.section .data,"aw"
.word 0
.section .bss,"aw",%nobits
.word 0
.section .rodata,"a"
.word 0
.section .text
.word 0
.section .data
.word 0
.section .bss
.word 0
.section .rodata
.word 0

View file

@ -0,0 +1,17 @@
#name: Merge SHF_GNU_RETAIN for non-unique sections
#notarget: ![supports_gnu_osabi]
#source: section24.s
#readelf: -h -S --wide
#...
+OS/ABI: +UNIX - GNU
#...
\[..\] .text[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AXR .*
#...
\[..\] .data[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR .*
#...
\[..\] .bss[ ]+NOBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 WAR .*
#...
\[..\] .rodata[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AR .*
#pass

View file

@ -0,0 +1,10 @@
#name: Merge SHF_GNU_RETAIN for non-unique sections (check no unmerged)
#notarget: ![supports_gnu_osabi]
#source: section24.s
#readelf: -S --wide
#failif
#...
\[..\] .(text|data|bss|rodata)[ ]+PROGBITS[ ]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 [^R] .*
#pass

View file

@ -1,3 +1,7 @@
2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
* elf/common.h (SHF_GNU_RETAIN): Define.
2020-11-16 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com> 2020-11-16 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com>
* opcode/aarch64.h (AARCH64_FEATURE_FLAGM): Add new feature. * opcode/aarch64.h (AARCH64_FEATURE_FLAGM): Add new feature.

View file

@ -554,6 +554,7 @@
/* #define SHF_MASKOS 0x0F000000 *//* OS-specific semantics */ /* #define SHF_MASKOS 0x0F000000 *//* OS-specific semantics */
#define SHF_MASKOS 0x0FF00000 /* New value, Oct 4, 1999 Draft */ #define SHF_MASKOS 0x0FF00000 /* New value, Oct 4, 1999 Draft */
#define SHF_GNU_BUILD_NOTE (1 << 20) /* Section contains GNU BUILD ATTRIBUTE notes. */ #define SHF_GNU_BUILD_NOTE (1 << 20) /* Section contains GNU BUILD ATTRIBUTE notes. */
#define SHF_GNU_RETAIN (1 << 21) /* Section should not be garbage collected by the linker. */
#define SHF_MASKPROC 0xF0000000 /* Processor-specific semantics */ #define SHF_MASKPROC 0xF0000000 /* Processor-specific semantics */
/* This used to be implemented as a processor specific section flag. /* This used to be implemented as a processor specific section flag.

View file

@ -1,3 +1,28 @@
2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
* NEWS: Announce support for SHF_GNU_RETAIN.
* ld.texi (garbage collection): Document SHF_GNU_RETAIN.
(Output Section Discarding): Likewise.
* testsuite/ld-elf/elf.exp: Run new tests.
* testsuite/ld-elf/retain1.s: New test.
* testsuite/ld-elf/retain1a.d: New test.
* testsuite/ld-elf/retain1b.d: New test.
* testsuite/ld-elf/retain2.d: New test.
* testsuite/ld-elf/retain2.ld: New test.
* testsuite/ld-elf/retain2.map: New test.
* testsuite/ld-elf/retain3.d: New test.
* testsuite/ld-elf/retain3.s: New test.
* testsuite/ld-elf/retain4.d: New test.
* testsuite/ld-elf/retain4.s: New test.
* testsuite/ld-elf/retain5.d: New test.
* testsuite/ld-elf/retain5.map: New test.
* testsuite/ld-elf/retain5lib.s: New test.
* testsuite/ld-elf/retain5main.s: New test.
* testsuite/ld-elf/retain6a.d: New test.
* testsuite/ld-elf/retain6b.d: New test.
* testsuite/ld-elf/retain6lib.s: New test.
* testsuite/ld-elf/retain6main.s: New test.
2020-11-17 Alan Modra <amodra@gmail.com> 2020-11-17 Alan Modra <amodra@gmail.com>
PR 26882 PR 26882

View file

@ -23,6 +23,10 @@
unless you are working on a project that has its own analogue unless you are working on a project that has its own analogue
of symbol tables that are not reflected in the ELF symtabs. of symbol tables that are not reflected in the ELF symtabs.
* Add support for the SHF_GNU_RETAIN ELF section flag.
This flag specifies that the section should not be garbage collected by the
linker.
Changes in 2.35: Changes in 2.35:
* X86 NaCl target support is removed. * X86 NaCl target support is removed.

View file

@ -1807,6 +1807,9 @@ specified either by one of the options @samp{--entry},
@samp{--undefined}, or @samp{--gc-keep-exported} or by a @code{ENTRY} @samp{--undefined}, or @samp{--gc-keep-exported} or by a @code{ENTRY}
command in the linker script. command in the linker script.
As a GNU extension, ELF input sections marked with the
@code{SHF_GNU_RETAIN} flag will not be garbage collected.
@kindex --print-gc-sections @kindex --print-gc-sections
@kindex --no-print-gc-sections @kindex --no-print-gc-sections
@cindex garbage collection @cindex garbage collection
@ -5291,6 +5294,10 @@ The special output section name @samp{/DISCARD/} may be used to discard
input sections. Any input sections which are assigned to an output input sections. Any input sections which are assigned to an output
section named @samp{/DISCARD/} are not included in the output file. section named @samp{/DISCARD/} are not included in the output file.
This can be used to discard input sections marked with the ELF flag
@code{SHF_GNU_RETAIN}, which would otherwise have been saved from linker
garbage collection.
Note, sections that match the @samp{/DISCARD/} output section will be Note, sections that match the @samp{/DISCARD/} output section will be
discarded even if they are in an ELF section group which has other discarded even if they are in an ELF section group which has other
members which are not being discarded. This is deliberate. members which are not being discarded. This is deliberate.

View file

@ -119,6 +119,16 @@ if { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
set ASFLAGS "$ASFLAGS -mx86-used-note=no" set ASFLAGS "$ASFLAGS -mx86-used-note=no"
} }
# Build libraries required for SHF_GNU_RETAIN tests.
if { [check_gc_sections_available] && [supports_gnu_osabi] } {
run_ld_link_tests [list \
[list "Build libretain5.a" "" "" "" \
{retain5lib.s} {} "libretain5.a"] \
[list "Build libretain6.a" "" "" "" \
{retain6lib.s} {} "libretain6.a"] \
]
}
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
foreach t $test_list { foreach t $test_list {
# We need to strip the ".d", but can leave the dirname. # We need to strip the ".d", but can leave the dirname.

View file

@ -0,0 +1,104 @@
.global discard0
.section .bss.discard0,"aw"
.type discard0, %object
discard0:
.zero 2
.global discard1
.section .bss.discard1,"aw"
.type discard1, %object
discard1:
.zero 2
.global discard2
.section .data.discard2,"aw"
.type discard2, %object
discard2:
.word 1
.section .bss.sdiscard0,"aw"
.type sdiscard0, %object
sdiscard0:
.zero 2
.section .bss.sdiscard1,"aw"
.type sdiscard1, %object
sdiscard1:
.zero 2
.section .data.sdiscard2,"aw"
.type sdiscard2, %object
sdiscard2:
.word 1
.section .text.fndiscard0,"ax"
.global fndiscard0
.type fndiscard0, %function
fndiscard0:
.word 0
.global retain0
.section .bss.retain0,"awR"
.type retain0, %object
retain0:
.zero 2
.global retain1
.section .bss.retain1,"awR"
.type retain1, %object
retain1:
.zero 2
.global retain2
.section .data.retain2,"awR"
.type retain2, %object
retain2:
.word 1
.section .bss.sretain0,"awR"
.type sretain0, %object
sretain0:
.zero 2
.section .bss.sretain1,"awR"
.type sretain1, %object
sretain1:
.zero 2
.section .data.sretain2,"aRw"
.type sretain2, %object
sretain2:
.word 1
.section .text.fnretain1,"Rax"
.global fnretain1
.type fnretain1, %function
fnretain1:
.word 0
.section .text.fndiscard2,"ax"
.global fndiscard2
.type fndiscard2, %function
fndiscard2:
.word 0
.section .bss.lsretain0,"awR"
.type lsretain0.2, %object
lsretain0.2:
.zero 2
.section .bss.lsretain1,"aRw"
.type lsretain1.1, %object
lsretain1.1:
.zero 2
.section .data.lsretain2,"aRw"
.type lsretain2.0, %object
lsretain2.0:
.word 1
.section .text._start,"ax"
.global _start
.type _start, %function
_start:
.word 0

View file

@ -0,0 +1,27 @@
#name: SHF_GNU_RETAIN 1a
#source: retain1.s
#ld: -e _start --gc-sections
#notarget: ![supports_gnu_osabi] ![check_gc_sections_available]
#DUMPPROG: nm
#...
[0-9a-f]+ . fnretain1
#...
[0-9a-f]+ . lsretain0.2
#...
[0-9a-f]+ . lsretain1.1
#...
[0-9a-f]+ . lsretain2.0
#...
[0-9a-f]+ . retain0
#...
[0-9a-f]+ . retain1
#...
[0-9a-f]+ . retain2
#...
[0-9a-f]+ . sretain0
#...
[0-9a-f]+ . sretain1
#...
[0-9a-f]+ . sretain2
#pass

View file

@ -0,0 +1,10 @@
#name: SHF_GNU_RETAIN 1b
#source: retain1.s
#ld: -e _start --gc-sections
#notarget: ![supports_gnu_osabi] ![check_gc_sections_available]
#nm: -n
#failif
#...
[0-9a-f]+ . .*discard.*
#...

View file

@ -0,0 +1,5 @@
#name: SHF_GNU_RETAIN 2 (remove SHF_GNU_RETAIN sections by placing in /DISCARD/)
#source: retain1.s
#ld: -e _start -Map=retain2.map --gc-sections --script=retain2.ld
#map: retain2.map
#notarget: ![supports_gnu_osabi] ![check_gc_sections_available]

View file

@ -0,0 +1,7 @@
SECTIONS
{
/DISCARD/ :
{
*(.text.fnretain1)
}
}

View file

@ -0,0 +1,32 @@
# Test that .text.fnretain1, which has the SHF_GNU_RETAIN flag, can still be
# explicitly discarded from the output file.
#...
Discarded input sections
.text.*
#...
.data.*
#...
.bss.*
#...
.bss.discard0.*
#...
.bss.discard1.*
#...
.data.discard2.*
#...
.bss.sdiscard0.*
#...
.bss.sdiscard1.*
#...
.data.sdiscard2.*
#...
.text.fndiscard0.*
#...
.text.fnretain1.*
#...
.text.fndiscard2.*
#...
Memory Configuration
#pass

View file

@ -0,0 +1,11 @@
#name: SHF_GNU_RETAIN 3 (keep sections referenced by retained sections)
#source: retain3.s
#ld: -e _start --gc-sections
#notarget: ![supports_gnu_osabi] ![check_gc_sections_available]
#DUMPPROG: nm
#...
[0-9a-f]+ . bar
#...
[0-9a-f]+ . foo
#pass

View file

@ -0,0 +1,19 @@
/* The retention of bar should also prevent foo from being gc'ed, since bar
references foo. */
.section .text.foo,"ax"
.global foo
.type foo, %function
foo:
.word 0
.section .text.bar,"axR"
.global bar
.type bar, %function
bar:
.long foo
.section .text._start,"ax"
.global _start
.type _start, %function
_start:
.word 0

View file

@ -0,0 +1,9 @@
#name: SHF_GNU_RETAIN 4 (keep orphaned sections when not discarding)
#source: retain4.s
#ld: -e _start --gc-sections --orphan-handling=place
#notarget: ![supports_gnu_osabi] ![check_gc_sections_available]
#DUMPPROG: nm
#...
[0-9a-f]+ . orphaned_fn
#pass

View file

@ -0,0 +1,13 @@
/* A section that doesn't match any linker script input section rules but
has SHF_GNU_RETAIN applied should not be garbage collected. */
.section .orphaned_section,"axR"
.global orphaned_fn
.type orphaned_fn, %function
orphaned_fn:
.word 0
.section .text._start,"ax"
.global _start
.type _start, %function
_start:
.word 0

View file

@ -0,0 +1,11 @@
#name: SHF_GNU_RETAIN 5 (don't pull SHF_GNU_RETAIN section out of lib)
#source: retain5main.s
#ld: --gc-sections -e _start --print-gc-sections -Ltmpdir -lretain5 -Map=retain5.map
#notarget: ![supports_gnu_osabi] ![check_gc_sections_available]
#map: retain5.map
#DUMPPROG: nm
#failif
#...
[0-9a-f]+ . foo
#...

View file

@ -0,0 +1,5 @@
# Check that the library was actually loaded to catch any false PASS.
#...
LOAD tmpdir/libretain5.a
#pass

View file

@ -0,0 +1,6 @@
/* The link will fail if foo is included because undefined_sym is not defined. */
.section .text.foo,"axR"
.global foo
.type foo, %function
foo:
.long undefined_sym

View file

@ -0,0 +1,5 @@
.section .text._start,"ax"
.global _start
.type _start, %function
_start:
.word 0

View file

@ -0,0 +1,13 @@
#name: SHF_GNU_RETAIN 6a (pull section out of lib required by SHF_GNU_RETAIN section)
#source: retain6main.s
#ld: --gc-sections -e _start -u bar -Ltmpdir -lretain6
#notarget: ![supports_gnu_osabi] ![check_gc_sections_available]
#DUMPPROG: nm
#...
[0-9a-f]+ . bar
#...
[0-9a-f]+ . retain_from_lib
#...
[0-9a-f]+ . retained_fn
#pass

View file

@ -0,0 +1,10 @@
#name: SHF_GNU_RETAIN 6b (pull section out of lib required by SHF_GNU_RETAIN section)
#source: retain6main.s
#ld: --gc-sections -e _start -u bar -Ltmpdir -lretain6
#notarget: ![supports_gnu_osabi] ![check_gc_sections_available]
#DUMPPROG: nm
#failif
#...
[0-9a-f]+ . .*discard.*
#...

View file

@ -0,0 +1,17 @@
.section .text.bar,"ax"
.global bar
.type bar, %function
bar:
.word 0
.section .text.retain_from_lib,"axR"
.global retain_from_lib
.type retain_from_lib, %function
retain_from_lib:
.word 0
.section .text.discard_from_lib,"ax"
.global discard_from_lib
.type discard_from_lib, %function
discard_from_lib:
.word 0

View file

@ -0,0 +1,13 @@
/* Undefined symbol reference in retained section .text.retained_fn requires
symbol definition to be pulled out of library. */
.section .text.retained_fn,"axR"
.global retained_fn
.type retained_fn, %function
retained_fn:
.long bar
.section .text._start,"ax"
.global _start
.type _start, %function
_start:
.word 0