From 99fabbc9739a87ba3433e66792e93b773896790e Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Wed, 18 Nov 2020 11:51:13 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 14 +++ bfd/elf-bfd.h | 9 +- bfd/elf.c | 21 +++- bfd/elflink.c | 12 +- binutils/ChangeLog | 16 +++ binutils/NEWS | 4 + binutils/readelf.c | 53 ++++++++- .../binutils-all/readelf-maskos-1a.d | 10 ++ .../binutils-all/readelf-maskos-1b.d | 12 ++ .../testsuite/binutils-all/readelf-maskos.s | 11 ++ binutils/testsuite/binutils-all/readelf.exp | 9 +- binutils/testsuite/binutils-all/retain1.s | 104 ++++++++++++++++++ binutils/testsuite/binutils-all/retain1a.d | 18 +++ binutils/testsuite/binutils-all/retain1b.d | 46 ++++++++ binutils/testsuite/lib/binutils-common.exp | 5 +- gas/ChangeLog | 23 ++++ gas/NEWS | 5 + gas/config/obj-elf.c | 80 +++++++++++--- gas/doc/as.texi | 3 + gas/testsuite/gas/elf/elf.exp | 6 +- gas/testsuite/gas/elf/section10.d | 4 +- gas/testsuite/gas/elf/section10.s | 4 +- gas/testsuite/gas/elf/section22.d | 19 ++++ gas/testsuite/gas/elf/section22.s | 34 ++++++ gas/testsuite/gas/elf/section23.s | 11 ++ gas/testsuite/gas/elf/section23a.d | 10 ++ gas/testsuite/gas/elf/section23b.d | 6 + gas/testsuite/gas/elf/section23b.err | 2 + gas/testsuite/gas/elf/section24.s | 38 +++++++ gas/testsuite/gas/elf/section24a.d | 17 +++ gas/testsuite/gas/elf/section24b.d | 10 ++ include/ChangeLog | 4 + include/elf/common.h | 1 + ld/ChangeLog | 25 +++++ ld/NEWS | 4 + ld/ld.texi | 7 ++ ld/testsuite/ld-elf/elf.exp | 10 ++ ld/testsuite/ld-elf/retain1.s | 104 ++++++++++++++++++ ld/testsuite/ld-elf/retain1a.d | 27 +++++ ld/testsuite/ld-elf/retain1b.d | 10 ++ ld/testsuite/ld-elf/retain2.d | 5 + ld/testsuite/ld-elf/retain2.ld | 7 ++ ld/testsuite/ld-elf/retain2.map | 32 ++++++ ld/testsuite/ld-elf/retain3.d | 11 ++ ld/testsuite/ld-elf/retain3.s | 19 ++++ ld/testsuite/ld-elf/retain4.d | 9 ++ ld/testsuite/ld-elf/retain4.s | 13 +++ ld/testsuite/ld-elf/retain5.d | 11 ++ ld/testsuite/ld-elf/retain5.map | 5 + ld/testsuite/ld-elf/retain5lib.s | 6 + ld/testsuite/ld-elf/retain5main.s | 5 + ld/testsuite/ld-elf/retain6a.d | 13 +++ ld/testsuite/ld-elf/retain6b.d | 10 ++ ld/testsuite/ld-elf/retain6lib.s | 17 +++ ld/testsuite/ld-elf/retain6main.s | 13 +++ 55 files changed, 943 insertions(+), 41 deletions(-) create mode 100644 binutils/testsuite/binutils-all/readelf-maskos-1a.d create mode 100644 binutils/testsuite/binutils-all/readelf-maskos-1b.d create mode 100644 binutils/testsuite/binutils-all/readelf-maskos.s create mode 100644 binutils/testsuite/binutils-all/retain1.s create mode 100644 binutils/testsuite/binutils-all/retain1a.d create mode 100644 binutils/testsuite/binutils-all/retain1b.d create mode 100644 gas/testsuite/gas/elf/section22.d create mode 100644 gas/testsuite/gas/elf/section22.s create mode 100644 gas/testsuite/gas/elf/section23.s create mode 100644 gas/testsuite/gas/elf/section23a.d create mode 100644 gas/testsuite/gas/elf/section23b.d create mode 100644 gas/testsuite/gas/elf/section23b.err create mode 100644 gas/testsuite/gas/elf/section24.s create mode 100644 gas/testsuite/gas/elf/section24a.d create mode 100644 gas/testsuite/gas/elf/section24b.d create mode 100644 ld/testsuite/ld-elf/retain1.s create mode 100644 ld/testsuite/ld-elf/retain1a.d create mode 100644 ld/testsuite/ld-elf/retain1b.d create mode 100644 ld/testsuite/ld-elf/retain2.d create mode 100644 ld/testsuite/ld-elf/retain2.ld create mode 100644 ld/testsuite/ld-elf/retain2.map create mode 100644 ld/testsuite/ld-elf/retain3.d create mode 100644 ld/testsuite/ld-elf/retain3.s create mode 100644 ld/testsuite/ld-elf/retain4.d create mode 100644 ld/testsuite/ld-elf/retain4.s create mode 100644 ld/testsuite/ld-elf/retain5.d create mode 100644 ld/testsuite/ld-elf/retain5.map create mode 100644 ld/testsuite/ld-elf/retain5lib.s create mode 100644 ld/testsuite/ld-elf/retain5main.s create mode 100644 ld/testsuite/ld-elf/retain6a.d create mode 100644 ld/testsuite/ld-elf/retain6b.d create mode 100644 ld/testsuite/ld-elf/retain6lib.s create mode 100644 ld/testsuite/ld-elf/retain6main.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a06d5a77b9..a23da61653 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,17 @@ +2020-11-18 Jozef Lawrynowicz + H.J. Lu + + * 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 * cpu-arm.c (processors): Add Cortex-A78C. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 140a98594d..ffb75f7919 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -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. */ diff --git a/bfd/elf.c b/bfd/elf.c index 3163d34e8d..288548d8e5 100644 --- a/bfd/elf.c +++ b/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; } diff --git a/bfd/elflink.c b/bfd/elflink.c index 4b035a2cd5..6cc636142c 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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; diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 2124c59aa6..e8bcd97e8c 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,19 @@ +2020-11-18 Jozef Lawrynowicz + + * 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 * ar.c (main): Place the libdeps record in the second archive diff --git a/binutils/NEWS b/binutils/NEWS index 02a19ea09b..e74b6a2dba 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -12,6 +12,10 @@ symbol names. In addition the --demangle=