rjmccall added a comment.

I can understand how we got here, but it's a bad place to have ended up.

Toolchains that do dead-stripping need a way to prevent it for specific objects 
and functions.  Windows and Darwin toolchains have historically done aggressive 
dead-stripping in both the compiler and linker, so they've always had this 
need.  ELF toolchains have historically emitted code and restricted the linker 
in ways that, together, largely inhibit link-time dead-stripping (except of 
specific things like C++ entities with vague linkage).  As a result, ELF has 
gotten away with not providing a fine-grained way to prevent link-time 
dead-stripping for a long time, when otherwise that would have been a major 
blocker.

There are basically three broad categories of reasons why programs need to use 
features like this:

1. Some system at runtime needs to be able to find the entity "reflectively" 
(generally, because it's in a section with a special name or will be looked up 
by its symbol name).  Usually this is intended as a kind of passive global 
registration, and so dead-stripping needs to be completely blocked for the 
entity.
2. Some system at runtime that finds the entity "reflectively" will access it 
in weird ways that the compiler can't hope to understand.  The attribute is not 
being used to prevent dead-stripping (unless the entity is *also* a passive 
registration), but to block compiler analysis and optimization if the value 
*does* end up being used.  This tends to be a language-implementation thing 
more than something that a library would do.
3. The entity isn't actually unreferenced, but some portion of the toolchain is 
just unable to see that.  The most important example of this is a reference 
from inline assembly.

If I were a GCC developer reacting to the addition of `retain` to ELF, I would 
have given `__attribute__((used))` the stronger semantics, forcing the entity 
to be retained at link-time, and I would have introduced a weaker attribute (or 
attributes) that people could use selectively in the second and third cases if 
they wanted better dead-stripping.  To me, that's conservatively living up to 
user expectations about what they're trying to achieve with 
`__attribute__((used))` while giving them an opportunity to be more precise if 
it's useful; and it also unifies the semantics across object formats now that 
it's possible to do so.  But that's not generally how GCC developers do things; 
they tend to treat the current compiler behavior as an inviolate contract down 
to a very low level, and if you want different behavior, you need to use 
different options.  I can understand and sympathize with that approach, even if 
I think it also tends to create situations like this one.

At the end of the day, I don't think we have much choice but to follow GCC's 
lead on ELF platforms.  They get to define what these attributes mean, and if 
they want to make weaker guarantees on ELF, that's their decision.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97446/new/

https://reviews.llvm.org/D97446

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to