Symbols in 'llvm.used' stripped by --gc-sections

Hi all,
The documentation of @llvm.used says:

“If a symbol appears in the @llvm.used list, then the compiler, assembler, and linker are required to treat the symbol as if there is a reference to the symbol that it cannot see (which is why they have to be named).”

We’ve always understood this as: the symbol will survive into the final executable, also when it is in its own section and with --gc-sections. But I think that’s not true.
My understanding now is that @llvm.used is completely ignored by the linker when creating a final whole-program binary. That is, the symbol is emitted by the compiler into the object file, so not stripped e.g. by DCE. But when the linker combines multiple object files into the final executable, the symbol will be removed by --gc-sections when the linker sees no reference to it.
It appears that the only way to keep an unreferenced symbol while linking with --gc-sections (compiling with -f{function,data}-sections) is to put it in a segment that is kept as specified by the linkerscript (KEEP).

I hope someone can tell me that my current understanding is correct, and that we have to use another way to keep a symbol until the very end (tips welcome, without modifying the system default linker script…).

Thanks!
Johan

Unfortunately the linker part of @llvm.used is not implemented for ELF. One way that it could be implemented is to emit a zero-length .init_array section with an R_*_NONE relocation pointing to the symbol.

If you just want a quick workaround, you could use the -u linker flag to keep the symbol alive.

Peter

The MachO implementation of the llvm.used list attaches a NoDeadStrip flag to each of the symbols on the llvm.used list, the MachO linker is aware of the NoDeadStrip flag and will retain symbols that are marked with the flag in the linked output file.

As noted below, the LLVM back end for ELF does not currently communicate anything to the object file about retaining a symbol in the linked output.

The armclang compiler generates a special tag symbol/label along with the definition of the function or object that it wants to retain. Its linker knows to scan for these special symbols and “retain” the sections that they are defined in.

One could also envision defining a special symbol to communicate additional information about a symbol in the object file. Again, the linker would need to comprehend the intended semantics of the special symbol and whatever value is attached to it to represent the additional information about a symbol.

~ Todd Snider