PING [PATCH] gold: Support SHF_GNU_RETAIN

H.J. Lu hjl.tools@gmail.com
Mon Dec 14 14:59:28 GMT 2020


On Wed, Dec 9, 2020 at 8:07 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> Keep input SHF_GNU_RETAIN sections and strip output SHF_GNU_RETAIN for
> GNU/FreBSD ELFOSABIs.
>
> elfcpp/
>
>         PR gold/27039
>         * elfcpp.h (SHF): Add SHF_GNU_RETAIN.
>
> gold/
>
>         PR gold/27039
>         * layout.cc (Layout::layout): Strip SHF_GNU_RETAIN.
>         * object.cc (Sized_relobj_file::Sized_relobj_file): Initialize
>         osabi_.
>         (Sized_relobj_file::do_layout): Keep SHF_GNU_RETAIN sections for
>         GNU/FreBSD ELFOSABIs.
>         * object.h (Sized_relobj_file): Add osabi() and osabi_.
>         * testsuite/Makefile.am (check_SCRIPTS): Add retain.sh.
>         (check_DATA): Add retain_1.out retain_2.out.
>         (MOSTLYCLEANFILES): Add retain_1 retain_2.
>         (retain_1.out): New target.
>         (retain_1): Likewise.
>         (retain_1.o): Likewise.
>         (retain_2.out): Likewise.
>         (retain_2): Likewise.
>         (retain_2.o): Likewise.
>         * testsuite/Makefile.in: Regenerated.
>         * testsuite/retain.sh: New file.
>         * testsuite/retain_1.s: Likewise.
>         * testsuite/retain_2.s: Likewise.
> ---
>  elfcpp/elfcpp.h            |   1 +
>  gold/layout.cc             |  20 +++++--
>  gold/object.cc             |   7 ++-
>  gold/object.h              |   7 +++
>  gold/testsuite/Makefile.am |  16 ++++++
>  gold/testsuite/Makefile.in |  26 ++++++++--
>  gold/testsuite/retain.sh   |  60 +++++++++++++++++++++
>  gold/testsuite/retain_1.s  | 104 +++++++++++++++++++++++++++++++++++++
>  gold/testsuite/retain_2.s  |  22 ++++++++
>  9 files changed, 254 insertions(+), 9 deletions(-)
>  create mode 100755 gold/testsuite/retain.sh
>  create mode 100644 gold/testsuite/retain_1.s
>  create mode 100644 gold/testsuite/retain_2.s
>
> diff --git a/elfcpp/elfcpp.h b/elfcpp/elfcpp.h
> index 4b6ff94a65..2d333e992f 100644
> --- a/elfcpp/elfcpp.h
> +++ b/elfcpp/elfcpp.h
> @@ -438,6 +438,7 @@ enum SHF
>    SHF_TLS = 0x400,
>    SHF_COMPRESSED = 0x800,
>    SHF_MASKOS = 0x0ff00000,
> +  SHF_GNU_RETAIN = 0x200000,
>    SHF_MASKPROC = 0xf0000000,
>
>    // Indicates this section requires ordering in relation to
> diff --git a/gold/layout.cc b/gold/layout.cc
> index 8563f11099..9c245a8e76 100644
> --- a/gold/layout.cc
> +++ b/gold/layout.cc
> @@ -1186,10 +1186,18 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
>           = (parameters->options().text_unlikely_segment()
>              && is_prefix_of(".text.unlikely",
>                              object->section_name(shndx).c_str()));
> +      elfcpp::Elf_Xword ignored_flags;
> +      elfcpp::ELFOSABI osabi = object->osabi();
> +      if (osabi == elfcpp::ELFOSABI_GNU
> +         || osabi == elfcpp::ELFOSABI_FREEBSD)
> +       ignored_flags = elfcpp::SHF_GNU_RETAIN;
> +      else
> +       ignored_flags = 0;
>        if (text_unlikely_segment)
>         {
>           elfcpp::Elf_Xword flags
> -           = this->get_output_section_flags(shdr.get_sh_flags());
> +           = this->get_output_section_flags(shdr.get_sh_flags()
> +                                            & ~ignored_flags);
>
>           Stringpool::Key name_key;
>           const char* os_name = this->namepool_.add(".text.unlikely", true,
> @@ -1212,16 +1220,18 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
>           if (it == this->section_segment_map_.end())
>             {
>               os = this->choose_output_section(object, name, sh_type,
> -                                              shdr.get_sh_flags(), true,
> -                                              ORDER_INVALID, false, false,
> -                                              true);
> +                                              (shdr.get_sh_flags()
> +                                               & ~ignored_flags),
> +                                              true, ORDER_INVALID,
> +                                              false, false, true);
>             }
>           else
>             {
>               // We know the name of the output section, directly call
>               // get_output_section here by-passing choose_output_section.
>               elfcpp::Elf_Xword flags
> -               = this->get_output_section_flags(shdr.get_sh_flags());
> +               = this->get_output_section_flags(shdr.get_sh_flags()
> +                                                & ~ignored_flags);
>
>               const char* os_name = it->second->name;
>               Stringpool::Key name_key;
> diff --git a/gold/object.cc b/gold/object.cc
> index 61aed805c2..0e2bcc131a 100644
> --- a/gold/object.cc
> +++ b/gold/object.cc
> @@ -498,6 +498,7 @@ Sized_relobj_file<size, big_endian>::Sized_relobj_file(
>      deferred_layout_relocs_(),
>      output_views_(NULL)
>  {
> +  this->osabi_ = static_cast<elfcpp::ELFOSABI>(ehdr.get_e_ident()[elfcpp::EI_OSABI]);
>    this->e_type_ = ehdr.get_e_type();
>  }
>
> @@ -1716,10 +1717,14 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
>
>        if (is_pass_one && parameters->options().gc_sections())
>         {
> +         elfcpp::ELFOSABI osabi = this->osabi();
>           if (this->is_section_name_included(name)
>               || layout->keep_input_section (this, name)
>               || sh_type == elfcpp::SHT_INIT_ARRAY
> -             || sh_type == elfcpp::SHT_FINI_ARRAY)
> +             || sh_type == elfcpp::SHT_FINI_ARRAY
> +             || ((osabi == elfcpp::ELFOSABI_GNU
> +                  || osabi == elfcpp::ELFOSABI_FREEBSD)
> +                 && shdr.get_sh_flags() & elfcpp::SHF_GNU_RETAIN) != 0)
>             {
>               symtab->gc()->worklist().push_back(Section_id(this, i));
>             }
> diff --git a/gold/object.h b/gold/object.h
> index 656443f062..e73328663d 100644
> --- a/gold/object.h
> +++ b/gold/object.h
> @@ -2209,6 +2209,11 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
>    e_type() const
>    { return this->e_type_; }
>
> +  // Return the EI_OSABI.
> +  elfcpp::ELFOSABI
> +  osabi() const
> +  { return this->osabi_; }
> +
>    // Return the number of symbols.  This is only valid after
>    // Object::add_symbols has been called.
>    unsigned int
> @@ -2849,6 +2854,8 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
>
>    // General access to the ELF file.
>    elfcpp::Elf_file<size, big_endian, Object> elf_file_;
> +  // The EI_OSABI.
> +  elfcpp::ELFOSABI osabi_;
>    // Type of ELF file (ET_REL or ET_EXEC).  ET_EXEC files are allowed
>    // as input files only for the --just-symbols option.
>    int e_type_;
> diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
> index 739ea98dbe..abaaba6661 100644
> --- a/gold/testsuite/Makefile.am
> +++ b/gold/testsuite/Makefile.am
> @@ -4466,4 +4466,20 @@ pr26936c.o: pr26936c.s
>  pr26936d.o: pr26936d.s
>         $(TEST_AS) --gen-debug -mx86-used-note=yes -o $@ $<
>
> +check_SCRIPTS += retain.sh
> +check_DATA += retain_1.out retain_2.out
> +MOSTLYCLEANFILES += retain_1 retain_2
> +retain_1.out: retain_1
> +       $(TEST_NM) $< >$@
> +retain_1: retain_1.o ../ld-new
> +       ../ld-new  -e _start --gc-sections -o $@  retain_1.o
> +retain_1.o: retain_1.s
> +       $(TEST_AS) -o $@ $<
> +retain_2.out: retain_2
> +       $(TEST_READELF) -d $< >$@
> +retain_2: retain_2.o ../ld-new
> +       ../ld-new -pie -e _start --gc-sections -o $@  retain_2.o
> +retain_2.o: retain_2.s
> +       $(TEST_AS) -o $@ $<
> +
>  endif DEFAULT_TARGET_X86_64
> diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
> index 2c03a992cf..79aed4a763 100644
> --- a/gold/testsuite/Makefile.in
> +++ b/gold/testsuite/Makefile.in
> @@ -1143,12 +1143,13 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
>  @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@        split_s390x_z4_ns split_s390x_n1_ns split_s390x_n2_ns split_s390x_r
>
>  @DEFAULT_TARGET_X86_64_TRUE@am__append_116 = *.dwo *.dwp pr26936a \
> -@DEFAULT_TARGET_X86_64_TRUE@   pr26936b
> +@DEFAULT_TARGET_X86_64_TRUE@   pr26936b retain_1 retain_2
>  @DEFAULT_TARGET_X86_64_TRUE@am__append_117 = dwp_test_1.sh \
> -@DEFAULT_TARGET_X86_64_TRUE@   dwp_test_2.sh pr26936.sh
> +@DEFAULT_TARGET_X86_64_TRUE@   dwp_test_2.sh pr26936.sh retain.sh
>  @DEFAULT_TARGET_X86_64_TRUE@am__append_118 = dwp_test_1.stdout \
>  @DEFAULT_TARGET_X86_64_TRUE@   dwp_test_2.stdout pr26936a.stdout \
> -@DEFAULT_TARGET_X86_64_TRUE@   pr26936b.stdout
> +@DEFAULT_TARGET_X86_64_TRUE@   pr26936b.stdout retain_1.out \
> +@DEFAULT_TARGET_X86_64_TRUE@   retain_2.out
>  subdir = testsuite
>  ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
>  am__aclocal_m4_deps = $(top_srcdir)/../config/ax_pthread.m4 \
> @@ -6492,6 +6493,13 @@ pr26936.sh.log: pr26936.sh
>         --log-file $$b.log --trs-file $$b.trs \
>         $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
>         "$$tst" $(AM_TESTS_FD_REDIRECT)
> +retain.sh.log: retain.sh
> +       @p='retain.sh'; \
> +       b='retain.sh'; \
> +       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
> +       --log-file $$b.log --trs-file $$b.trs \
> +       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
> +       "$$tst" $(AM_TESTS_FD_REDIRECT)
>  object_unittest.log: object_unittest$(EXEEXT)
>         @p='object_unittest$(EXEEXT)'; \
>         b='object_unittest'; \
> @@ -10463,6 +10471,18 @@ uninstall-am:
>  @DEFAULT_TARGET_X86_64_TRUE@   $(TEST_AS) --gen-debug -mx86-used-note=yes -o $@ $<
>  @DEFAULT_TARGET_X86_64_TRUE@pr26936d.o: pr26936d.s
>  @DEFAULT_TARGET_X86_64_TRUE@   $(TEST_AS) --gen-debug -mx86-used-note=yes -o $@ $<
> +@DEFAULT_TARGET_X86_64_TRUE@retain_1.out: retain_1
> +@DEFAULT_TARGET_X86_64_TRUE@   $(TEST_NM) $< >$@
> +@DEFAULT_TARGET_X86_64_TRUE@retain_1: retain_1.o ../ld-new
> +@DEFAULT_TARGET_X86_64_TRUE@   ../ld-new  -e _start --gc-sections -o $@  retain_1.o
> +@DEFAULT_TARGET_X86_64_TRUE@retain_1.o: retain_1.s
> +@DEFAULT_TARGET_X86_64_TRUE@   $(TEST_AS) -o $@ $<
> +@DEFAULT_TARGET_X86_64_TRUE@retain_2.out: retain_2
> +@DEFAULT_TARGET_X86_64_TRUE@   $(TEST_READELF) -d $< >$@
> +@DEFAULT_TARGET_X86_64_TRUE@retain_2: retain_2.o ../ld-new
> +@DEFAULT_TARGET_X86_64_TRUE@   ../ld-new -pie -e _start --gc-sections -o $@  retain_2.o
> +@DEFAULT_TARGET_X86_64_TRUE@retain_2.o: retain_2.s
> +@DEFAULT_TARGET_X86_64_TRUE@   $(TEST_AS) -o $@ $<
>
>  # Tell versions [3.59,3.63) of GNU make to not export all variables.
>  # Otherwise a system limit (for SysV at least) may be exceeded.
> diff --git a/gold/testsuite/retain.sh b/gold/testsuite/retain.sh
> new file mode 100755
> index 0000000000..0f5c6951c5
> --- /dev/null
> +++ b/gold/testsuite/retain.sh
> @@ -0,0 +1,60 @@
> +#!/bin/sh
> +
> +# retain.sh -- Tests for SHF_GNU_RETAIN.
> +
> +# Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +# This file is part of gold.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> +# MA 02110-1301, USA.
> +
> +set -e
> +
> +check()
> +{
> +    number_of_occurrence=`egrep "$2" ./$1 -o | wc -l`
> +    if [ $number_of_occurrence != $3 ]
> +    then
> +       echo "$1: \"$2\" $3: Failed"
> +       status=1
> +    fi
> +}
> +
> +status=0
> +check retain_1.out " T fnretain1" 1
> +check retain_1.out " b lsretain0.2" 1
> +check retain_1.out " b lsretain1.1" 1
> +check retain_1.out " d lsretain2.0" 1
> +check retain_1.out " B retain0" 1
> +check retain_1.out " B retain1" 1
> +check retain_1.out " D retain2" 1
> +check retain_1.out " b sretain0" 1
> +check retain_1.out " b sretain1" 1
> +check retain_1.out " d sretain2" 1
> +if grep discard retain_1.out
> +then
> +  echo "retain_1.out: Garbage collection failed"
> +  status=1
> +fi
> +
> +check retain_2.out " \(PREINIT_ARRAY\)" 1
> +check retain_2.out " \(PREINIT_ARRAYSZ\)" 1
> +check retain_2.out " \(INIT_ARRAY\)" 1
> +check retain_2.out " \(INIT_ARRAYSZ\)" 1
> +check retain_2.out " \(FINI_ARRAY\)" 1
> +check retain_2.out " \(FINI_ARRAYSZ\)" 1
> +
> +exit $status
> diff --git a/gold/testsuite/retain_1.s b/gold/testsuite/retain_1.s
> new file mode 100644
> index 0000000000..f7716faabe
> --- /dev/null
> +++ b/gold/testsuite/retain_1.s
> @@ -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
> diff --git a/gold/testsuite/retain_2.s b/gold/testsuite/retain_2.s
> new file mode 100644
> index 0000000000..67d86d10cb
> --- /dev/null
> +++ b/gold/testsuite/retain_2.s
> @@ -0,0 +1,22 @@
> +       .section .preinit_array.01000,"aw",%preinit_array
> +       .dc.a 0
> +
> +       .section .init_array.01000,"aw",%init_array
> +       .dc.a 0
> +
> +       .section .fini_array.01000,"aw",%fini_array
> +       .dc.a 0
> +
> +       .section .preinit_array.01000,"awR",%preinit_array
> +       .dc.a 0
> +
> +       .section .init_array.01000,"awR",%init_array
> +       .dc.a 0
> +
> +       .section .fini_array.01000,"awR",%fini_array
> +       .dc.a 0
> +
> +       .text
> +       .globl _start
> +_start:
> +       .dc.a 0
> --
> 2.29.2
>

Hi Cary,

Gold is broken with SHF_GNU_RETAIN is used.  I'd like to fix it before
2.36 is released.  Do you have any comments for this patch?

Thanks.

-- 
H.J.


More information about the Binutils mailing list