www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - llvm.used does not mean the linker will not kill the symbol

reply Johan Engelen <j j.nl> writes:
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
Apr 01 2019
parent reply "David Nadlinger" <code klickverbot.at> writes:
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
Apr 01 2019
parent reply kinke <noone nowhere.com> writes:
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?
Apr 01 2019
parent Johan Engelen <j j.nl> writes:
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
Apr 01 2019