Thread overview
@llvm.used does not mean the linker will not kill the symbol
Apr 01, 2019
Johan Engelen
Apr 01, 2019
David Nadlinger
Apr 01, 2019
kinke
Apr 01, 2019
Johan Engelen
April 01, 2019
Hi all,
  Remember we looked into stripped symbols and @llvm.used? Just now, I am running into troubles with it again on something non-LDC related. Works on x86_64 but not on AArch64 (at least, that's what it looks like right now).
After looking more into `@llvm.used` and GCC's `__attribute__((used))`, I've come to the conclusion that `llvm.used` does _not_ mean that the linker won't strip it. It definitely will. Just try this:
  __attribute__((used)) void foo() {}
  int main() { return 0; }

I asked about it on LLVM list, and the answer:
"Unfortunately the linker part of @llvm.used is not implemented for ELF."

I think things work for LDC because we reference __start_minfo / __stop_minfo and the symbols that we don't want to disappear are in those segments. In other words: we actually _do_ reference (in a roundabout way) the symbols in the final executable and the linker sees that.

Cheers,
  Johan

April 01, 2019
On 1 Apr 2019, at 18:47, Johan Engelen via digitalmars-d-ldc wrote:
> I think things work for LDC because we reference __start_minfo / __stop_minfo and the symbols that we don't want to disappear are in those segments. In other words: we actually _do_ reference (in a roundabout way) the symbols in the final executable and the linker sees that.

It doesn't even work for LDC – compatibility with older linkers was broken when that "simplification" was merged.

 — David
April 01, 2019
On Monday, 1 April 2019 at 17:57:30 UTC, David Nadlinger wrote:
> It doesn't even work for LDC – compatibility with older linkers was broken when that "simplification" was merged.

For reference, the PR: https://github.com/ldc-developers/ldc/pull/2870

'Older linker' seems to be spot-on, as it works for Shippable (AArch64 with Ubuntu 16.04 ld.gold IIRC; LDC doesn't work if ModuleInfos are stripped) and also started to work with more recent gold for 32-bit MIPS and ARM (https://github.com/ldc-developers/ldc/issues/2994).

On Monday, 1 April 2019 at 17:47:52 UTC, Johan Engelen wrote:
> After looking more into `@llvm.used` and GCC's `__attribute__((used))`, I've come to the conclusion that `llvm.used` does _not_ mean that the linker won't strip it. It definitely will. Just try this:
>   __attribute__((used)) void foo() {}

So not even gcc works, or is that clang?
April 01, 2019
On Monday, 1 April 2019 at 18:58:58 UTC, kinke wrote:
>
> On Monday, 1 April 2019 at 17:47:52 UTC, Johan Engelen wrote:
>> After looking more into `@llvm.used` and GCC's `__attribute__((used))`, I've come to the conclusion that `llvm.used` does _not_ mean that the linker won't strip it. It definitely will. Just try this:
>>   __attribute__((used)) void foo() {}
>
> So not even gcc works, or is that clang?

Neither work. The documentation of __attribute__((used)) is only about codegen (emission into obj) and not about linking.
-------------------
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. This is useful, for example, when the function is referenced only in inline assembly.

When applied to a member function of a C++ class template, the attribute also means that the function is instantiated if the class itself is instantiated.
--------------------


However, responses on LLVM thread point to that it _is_ intended that `llvm.used` also means that the linker shouldn't remove it. It just has not been implemented for ELF (it is working correctly for MachO).

https://lists.llvm.org/pipermail/llvm-dev/2019-April/131484.html

-Johan