[PATCH] Support SHF_GNU_RETAIN ELF section flag

Pedro Alves pedro@palves.net
Mon Sep 28 14:46:04 GMT 2020


On 9/28/20 1:28 PM, Jozef Lawrynowicz wrote:
> On Mon, Sep 28, 2020 at 12:35:28PM +0100, Pedro Alves wrote:
>> On 9/22/20 9:29 PM, Jozef Lawrynowicz wrote:
>>>
>>> The overall intention for this new flag is to enable a new "retain"
>>> attribute to be applied to declarations of functions and data in the
>>> source code. This attribute can be used to ensure the definition
>>> associated with the declaration is present in the linked output file,
>>> even if linker garbage collection would normally remove the containing
>>> section because it is unused.
>>
>> On a high level, this sounds pretty much like __attribute__((used)).
>> Couldn't the new section flag be wired to that attribute?  
>>
>> I mean, isn't it a bug if linker garbage collection eliminates a
>> function marked with __attribute__((used)) ?
>>
>>  "used
>>
>>    This attribute, attached to a function, means that code must be emitted 
>>    for the function even if it appears that the function is not referenced."
>>
>> I was surprised to not see any mention of the "used" attribute in the
>> proposal, neither here, nor in gABI mailing list discussion linked.
>> But maybe I missed it.
> 
> In an early version of the implementation, I tried tying the
> behavior to the "used" attribute, but it caused some problems.
> 
> I believe the issues mainly came from the usage of "used" in
> libgcc/crtstuff.c. The functions there are static and unused, so have
> "used" applied to prevent removal by the compiler. However, that does
> not mean that all of those functions should be included in every program
> linking against libgcc.
> 
> I don't remember the exact failure mode, I think it may have been that
> lots of tests were failing due to "multiple definition of ..." errors,
> or perhaps "undefined reference to ...".

That's really strange, and to be honest, not very convincing.

If there are multiple static functions with the same name in the same
translation unit, when you should be getting errors at compile time.

If OTOH, your early implementation resulted in undefined references,
then it just sounds like a bug in your implementation, since as you say,
__attribute__((retain)) is a superset of __attribute__((used)).  As in,
undefined references suggests the function wasn't emitted, contrary to
the point of the attribute.

> 
> The "retain" attribute implies the "used" attribute, so if the user
> wants to prevent compiler optimization AND linker optimization, "retain"
> can be used. To prevent only compiler optimization, "used" should be
> applied.

I'm not convinced such a distinction makes sense.  Maybe a small self
contained use case where the distinction makes a difference and is
desirable would help.

Pedro Alves


More information about the Binutils mailing list