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>
* cpu-arm.c (processors): Add Cortex-A78C.

View file

@ -1897,14 +1897,15 @@ struct output_elf_obj_tdata
bfd_boolean flags_init;
};
/* Indicate if the bfd contains SHF_GNU_MBIND sections or symbols that
have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE binding. Used
to set the osabi field in the ELF header structure. */
/* Indicate if the bfd contains SHF_GNU_MBIND/SHF_GNU_RETAIN sections or
symbols that have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE
binding. Used to set the osabi field in the ELF header structure. */
enum elf_gnu_osabi
{
elf_gnu_osabi_mbind = 1 << 0,
elf_gnu_osabi_ifunc = 1 << 1,
elf_gnu_osabi_unique = 1 << 2,
elf_gnu_osabi_retain = 1 << 3,
};
typedef struct elf_section_list
@ -2034,7 +2035,7 @@ struct elf_obj_tdata
ENUM_BITFIELD (dynamic_lib_link_class) dyn_lib_class : 4;
/* 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
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,
but binutils as of 2019-07-23 did not set the EI_OSABI header
byte. */
case ELFOSABI_NONE:
case ELFOSABI_GNU:
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)
elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_mbind;
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;
/* Set the osabi field to ELFOSABI_GNU if the binary contains
SHF_GNU_MBIND sections or symbols of STT_GNU_IFUNC type or
STB_GNU_UNIQUE binding. */
SHF_GNU_MBIND or SHF_GNU_RETAIN sections or symbols of STT_GNU_IFUNC type
or STB_GNU_UNIQUE binding. */
if (elf_tdata (abfd)->has_gnu_osabi != 0)
{
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)
{
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)
_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)
_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);
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;
}
/* 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. */
isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
if (isymbuf == NULL && locsymcount != 0)
@ -14116,7 +14124,9 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
== SHT_FINI_ARRAY)))
|| (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE
&& 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))
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>
* 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,
--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:
* 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") },
/* VLE specific. */
/* 25 */ { STRING_COMMA_LEN ("VLE") },
/* GNU specific. */
/* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
};
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_EXCLUDE: sindex = 18; break;
case SHF_COMPRESSED: sindex = 20; break;
case SHF_GNU_MBIND: sindex = 24; break;
default:
sindex = -1;
@ -6080,10 +6081,28 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
if (flag == SHF_PPC_VLE)
sindex = 25;
break;
default:
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)
@ -6126,7 +6145,6 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
case SHF_TLS: *p = 'T'; break;
case SHF_EXCLUDE: *p = 'E'; break;
case SHF_COMPRESSED: *p = 'C'; break;
case SHF_GNU_MBIND: *p = 'D'; break;
default:
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';
else if (filedata->file_header.e_machine == EM_ARM
&& flag == SHF_ARM_PURECODE)
*p = 'y';
*p = 'y';
else if (filedata->file_header.e_machine == EM_PPC
&& flag == SHF_PPC_VLE)
*p = 'v';
*p = 'v';
else if (flag & SHF_MASKOS)
{
*p = 'o';
sh_flags &= ~ SHF_MASKOS;
switch (filedata->file_header.e_ident[EI_OSABI])
{
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)
{

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_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.
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
# 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
# number of exceptions for bare metal targets as follows. The MSP430
# and Visium targets set OSABI to ELFOSABI_STANDALONE. Likewise
# 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,
# 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.)
@ -227,6 +229,7 @@ proc supports_gnu_osabi {} {
}
if { [istarget "arm*-*-*"]
|| [istarget "msp430-*-*"]
|| [istarget "hppa-unknown-elf"]
|| [istarget "visium-*-*"] } {
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>
* NEWS: Update news.

View file

@ -52,6 +52,11 @@
* 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:
* 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);
}
else
/* FIXME: Maybe we should consider removing a previously set
processor or application specific attribute as suspicious ? */
elf_section_flags (sec) = attr;
{
/* Don't overwrite a previously set SHF_GNU_RETAIN flag for the
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)
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':
*gnu_attr |= SHF_GNU_MBIND;
break;
case 'R':
*gnu_attr |= SHF_GNU_RETAIN;
break;
case '?':
*is_clone = TRUE;
break;
@ -890,8 +901,32 @@ obj_elf_parse_section_letters (char *str, size_t len,
if (ISDIGIT (*str))
{
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
we will execute str++ and len-- below. */
end --;
@ -1387,26 +1422,37 @@ obj_elf_section (int push)
done:
demand_empty_rest_of_line ();
obj_elf_change_section (name, type, attr, entsize, &match, linkonce,
push);
if ((gnu_attr & SHF_GNU_MBIND) != 0)
if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
{
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);
bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
if (bed->elf_osabi == ELFOSABI_NONE)
bed->elf_osabi = ELFOSABI_GNU;
else if (bed->elf_osabi != ELFOSABI_GNU
&& bed->elf_osabi != ELFOSABI_FREEBSD)
as_bad (_("GNU_MBIND section is supported only by GNU "
"and FreeBSD targets"));
elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
if (bed->elf_osabi != ELFOSABI_GNU
&& bed->elf_osabi != ELFOSABI_FREEBSD
&& bed->elf_osabi != ELFOSABI_NONE)
as_bad (_("%s section is supported only by GNU and FreeBSD targets"),
mbind_p ? "GNU_MBIND" : "GNU_RETAIN");
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)
{

View file

@ -6659,6 +6659,9 @@ section is a member of a section group
section is used for thread-local-storage
@item ?
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>}
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

View file

@ -261,8 +261,12 @@ if { [is_elf_format] } then {
run_dump_test "section19"
run_dump_test "section20"
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 "dwarf2-1" $dump_opts
run_dump_test "dwarf2-2" $dump_opts
run_dump_test "dwarf2-3" $dump_opts

View file

@ -18,7 +18,7 @@
#...
[ ]*\[.*\][ ]+sec3
[ ]*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
[ ]*LOOS\+0x11[ ].*
@ -26,7 +26,7 @@
#...
[ ]*\[.*\][ ]+sec5
[ ]*LOUSER\+0x9[ ].*
[ ]*\[.*feff0000\]:.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\)
[ ]*\[.*fedf0000\]:.* EXCLUDE, OS \(.*ed00000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\)
[ ]*\[.*\][ ]+.data.foo
[ ]*LOUSER\+0x7f000000[ ].*
[ ]*\[0+003\]: WRITE, ALLOC

View file

@ -7,7 +7,7 @@
.word 2
# Make sure that specifying further arguments to .sections is still supported
.section sec3, "0xfefff000MS", %progbits, 32
.section sec3, "0xfedff000MS", %progbits, 32
.word 3
# Make sure that extra flags can be set for well known sections as well.
@ -19,7 +19,7 @@
.word 5
# Test both together, with a quoted type value.
.section sec5, "0xfeff0000", "0x80000009"
.section sec5, "0xfedf0000", "0x80000009"
.word 6
# 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>
* 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 0x0FF00000 /* New value, Oct 4, 1999 Draft */
#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 */
/* 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>
PR 26882

View file

@ -23,6 +23,10 @@
unless you are working on a project that has its own analogue
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:
* 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}
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 --no-print-gc-sections
@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
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
discarded even if they are in an ELF section group which has other
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"
}
# 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]]
foreach t $test_list {
# 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