[PATCH] "used" attribute saves decl from linker garbage collection

H.J. Lu hjl.tools@gmail.com
Tue Nov 3 21:09:43 GMT 2020


On Tue, Nov 3, 2020 at 1:00 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Tue, Nov 3, 2020 at 12:46 PM Jozef Lawrynowicz
> <jozef.l@mittosystems.com> wrote:
> >
> > On Tue, Nov 03, 2020 at 11:58:04AM -0800, H.J. Lu via Gcc-patches wrote:
> > > On Tue, Nov 3, 2020 at 10:22 AM Jozef Lawrynowicz
> > > <jozef.l@mittosystems.com> wrote:
> > > >
> > > > On Tue, Nov 03, 2020 at 09:57:58AM -0800, H.J. Lu via Gcc-patches wrote:
> > > > > On Tue, Nov 3, 2020 at 9:41 AM Jozef Lawrynowicz
> > > > > <jozef.l@mittosystems.com> wrote:
> > > > > >
> > > > > > The attached patch implements TARGET_ASM_MARK_DECL_PRESERVED for ELF GNU
> > > > > > OSABI targets, so that declarations that have the "used" attribute
> > > > > > applied will be saved from linker garbage collection.
> > > > > >
> > > > > > TARGET_ASM_MARK_DECL_PRESERVED will emit an assembler ".retain"
> > > > >
> > > > > Can you use the "R" flag instead?
> > > > >
> > > >
> > > > For the benefit of this mailing list, I have copied my response from the
> > > > Binutils mailing list regarding this.
> > > > The "comm_section" example I gave is actually innacurate, but you can
> > > > see the examples of the variety of sections that would need to be
> > > > handled by doing
> > > >
> > > > $ git grep -A2 "define.*SECTION_ASM_OP" gcc/ | grep "\".*\."
> > > >
> > > > > ... snip ...
> > > > > Secondly, for seamless integration with the "used" attribute, we must be
> > > > > able to to mark the symbol with the used attribute applied as "retained"
> > > > > without changing its section name. For GCC "named" sections, this is
> > > > > straightforward, but for "unnamed" sections it is a giant mess.
> > > > >
> > > > > The section name for a GCC "unnamed" section is not readily available,
> > > > > instead a string which contains the full assembly code to switch to one
> > > > > of these text/data/bss/rodata/comm etc. sections is encoded in the
> > > > > structure.
> > > > >
> > > > > Backends define the assembly code to switch to these sections (some
> > > > > "*ASM_OP*" macro) in a variety of ways. For example, the unnamed section
> > > > > "comm_section", might correspond to a .bss section, or emit a .comm
> > > > > directive. I even looked at trying to parse them to extract what the
> > > > > name of a section will be, but it would be very messy and not robust.
> > > > >
> > > > > Meanwhile, having a .retain <symbol_name> directive is a very simmple
> > > > > solution, and keeps the GCC implementation really concise (patch
> > > > > attached). The assembler will know for sure what the section containing
> > > > > the symbol will be, and can apply the SHF_GNU_RETAIN flag directly.
> > > > >
> > >
> > > Please take a look at
> > >
> > > https://gitlab.com/x86-gcc/gcc/-/commits/users/hjl/elf/shf_retain
> > >
> > > which is built in top of
> > >
> > > https://gcc.gnu.org/pipermail/gcc-patches/2020-February/539963.html
> > >
> > > I think SECTION2_RETAIN matches SHF_GNU_RETAIN well.  If you
> > > want, you extract my flags2 change and use it for SHF_GNU_RETAIN.
> >
> > In your patch you have to make the assumption that data_section, always
> > corresponds to a section named .data. For just this example, c6x (which
> > supports the GNU ELF OSABI) does not fit the rule:
> >
> > > c6x/elf-common.h:#define DATA_SECTION_ASM_OP "\t.section\t\".fardata\",\"aw\""
> >
> > data_section for c6x corresponds to .fardata, not .data. So the use of
> > "used" on a data declaration would place it in a different section, that
> > if the "used" attribute was not applied.
> >
> > For c6x and mips, readonly_data_section does not correspond to .rodata,
> > so that assumption cannot be made either:
> > > c6x/elf-common.h:#define READONLY_DATA_SECTION_ASM_OP "\t.section\t\".const\",\"a\",@progbits"
> > > mips/mips.h:#define READONLY_DATA_SECTION_ASM_OP        "\t.rdata"      /* read-only data */
> >
> > The same can be said for bss_section for c6x as well.
>
> Just add and use named_xxx_section.
>
> > Furthermore, this is only considering the examples in
> > default_elf_select_section - the less standard unnamed section are used
> > in many backend's implementation of select_section, and we would need to
> > work out what section name they correspond to to properly support
> > SHF_GNU_RETAIN.
> >
> > For every unnamed section, you either have to assume what the
> > corresponding section name is, or parse the associated assembly output
> > string for the section.
>
> My change is just  an example to show how it can be done, not a complete one.
>
> > Given these edge cases which must be handled for GCC to robustly emit
> > the "R" flag for sections containing "used" symbols, surely it is
> > preferable to leverage the existing TARGET_ASM_MARK_DECL_PRESERVED and
> > emit a .retain <symname> directive, which is extremely simple and
> > doesn't require any handling of these edge cases and non-standard
> > backend implementations.
>
> It is used to update the symbol table.  Other usage is abuse.
>

For

[hjl@gnu-cfl-2 gcc]$ cat /tmp/x.c
static int xyzzy __attribute__((__used__)) = 1;
int foo[0x40000];
[hjl@gnu-cfl-2 gcc]$

foo should be removed by ld --gc-sections if it is unreferenced.  But your
patch makes it impossible.

-- 
H.J.


More information about the Gcc-patches mailing list