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:
parent
40d9d2fd79
commit
99fabbc973
55 changed files with 944 additions and 42 deletions
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
21
bfd/elf.c
21
bfd/elf.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
10
binutils/testsuite/binutils-all/readelf-maskos-1a.d
Normal file
10
binutils/testsuite/binutils-all/readelf-maskos-1a.d
Normal 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
|
12
binutils/testsuite/binutils-all/readelf-maskos-1b.d
Normal file
12
binutils/testsuite/binutils-all/readelf-maskos-1b.d
Normal 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
|
11
binutils/testsuite/binutils-all/readelf-maskos.s
Normal file
11
binutils/testsuite/binutils-all/readelf-maskos.s
Normal 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
|
|
@ -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 {
|
||||
|
|
104
binutils/testsuite/binutils-all/retain1.s
Normal file
104
binutils/testsuite/binutils-all/retain1.s
Normal 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
|
18
binutils/testsuite/binutils-all/retain1a.d
Normal file
18
binutils/testsuite/binutils-all/retain1a.d
Normal 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
|
46
binutils/testsuite/binutils-all/retain1b.d
Normal file
46
binutils/testsuite/binutils-all/retain1b.d
Normal 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
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
5
gas/NEWS
5
gas/NEWS
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
19
gas/testsuite/gas/elf/section22.d
Normal file
19
gas/testsuite/gas/elf/section22.d
Normal 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
|
34
gas/testsuite/gas/elf/section22.s
Normal file
34
gas/testsuite/gas/elf/section22.s
Normal 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
|
11
gas/testsuite/gas/elf/section23.s
Normal file
11
gas/testsuite/gas/elf/section23.s
Normal 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
|
10
gas/testsuite/gas/elf/section23a.d
Normal file
10
gas/testsuite/gas/elf/section23a.d
Normal 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
|
6
gas/testsuite/gas/elf/section23b.d
Normal file
6
gas/testsuite/gas/elf/section23b.d
Normal 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.
|
2
gas/testsuite/gas/elf/section23b.err
Normal file
2
gas/testsuite/gas/elf/section23b.err
Normal file
|
@ -0,0 +1,2 @@
|
|||
.*: Assembler messages:
|
||||
.*:1: Error: GNU_RETAIN section is supported only by GNU and FreeBSD targets
|
38
gas/testsuite/gas/elf/section24.s
Normal file
38
gas/testsuite/gas/elf/section24.s
Normal 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
|
17
gas/testsuite/gas/elf/section24a.d
Normal file
17
gas/testsuite/gas/elf/section24a.d
Normal 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
|
||||
|
10
gas/testsuite/gas/elf/section24b.d
Normal file
10
gas/testsuite/gas/elf/section24b.d
Normal 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
|
||||
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
25
ld/ChangeLog
25
ld/ChangeLog
|
@ -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
|
||||
|
|
4
ld/NEWS
4
ld/NEWS
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
104
ld/testsuite/ld-elf/retain1.s
Normal file
104
ld/testsuite/ld-elf/retain1.s
Normal 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
|
27
ld/testsuite/ld-elf/retain1a.d
Normal file
27
ld/testsuite/ld-elf/retain1a.d
Normal 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
|
10
ld/testsuite/ld-elf/retain1b.d
Normal file
10
ld/testsuite/ld-elf/retain1b.d
Normal 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.*
|
||||
#...
|
5
ld/testsuite/ld-elf/retain2.d
Normal file
5
ld/testsuite/ld-elf/retain2.d
Normal 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]
|
7
ld/testsuite/ld-elf/retain2.ld
Normal file
7
ld/testsuite/ld-elf/retain2.ld
Normal file
|
@ -0,0 +1,7 @@
|
|||
SECTIONS
|
||||
{
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.text.fnretain1)
|
||||
}
|
||||
}
|
32
ld/testsuite/ld-elf/retain2.map
Normal file
32
ld/testsuite/ld-elf/retain2.map
Normal 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
|
11
ld/testsuite/ld-elf/retain3.d
Normal file
11
ld/testsuite/ld-elf/retain3.d
Normal 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
|
19
ld/testsuite/ld-elf/retain3.s
Normal file
19
ld/testsuite/ld-elf/retain3.s
Normal 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
|
9
ld/testsuite/ld-elf/retain4.d
Normal file
9
ld/testsuite/ld-elf/retain4.d
Normal 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
|
13
ld/testsuite/ld-elf/retain4.s
Normal file
13
ld/testsuite/ld-elf/retain4.s
Normal 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
|
11
ld/testsuite/ld-elf/retain5.d
Normal file
11
ld/testsuite/ld-elf/retain5.d
Normal 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
|
||||
#...
|
5
ld/testsuite/ld-elf/retain5.map
Normal file
5
ld/testsuite/ld-elf/retain5.map
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Check that the library was actually loaded to catch any false PASS.
|
||||
|
||||
#...
|
||||
LOAD tmpdir/libretain5.a
|
||||
#pass
|
6
ld/testsuite/ld-elf/retain5lib.s
Normal file
6
ld/testsuite/ld-elf/retain5lib.s
Normal 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
|
5
ld/testsuite/ld-elf/retain5main.s
Normal file
5
ld/testsuite/ld-elf/retain5main.s
Normal file
|
@ -0,0 +1,5 @@
|
|||
.section .text._start,"ax"
|
||||
.global _start
|
||||
.type _start, %function
|
||||
_start:
|
||||
.word 0
|
13
ld/testsuite/ld-elf/retain6a.d
Normal file
13
ld/testsuite/ld-elf/retain6a.d
Normal 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
|
10
ld/testsuite/ld-elf/retain6b.d
Normal file
10
ld/testsuite/ld-elf/retain6b.d
Normal 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.*
|
||||
#...
|
17
ld/testsuite/ld-elf/retain6lib.s
Normal file
17
ld/testsuite/ld-elf/retain6lib.s
Normal 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
|
13
ld/testsuite/ld-elf/retain6main.s
Normal file
13
ld/testsuite/ld-elf/retain6main.s
Normal 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
|
Loading…
Add table
Reference in a new issue