This is an archive of the discontinued LLVM Phabricator instance.

[LLD][ELF] Add --lto-export-symbol-list
Changes PlannedPublic

Authored by samitolvanen on Jan 19 2023, 3:48 PM.

Details

Summary

Normally when compiling bitcode in a relocatable link, LLD sets
the VisibleToRegularObj flag in the symbol resolution for all
globals, which prevents LTO from dropping globals that may be
needed later. However, in situations where we know which globals
we want to export, LTO could better optimize the code if we
marked only the exported symbols visible. This is the case in the
Linux kernel, for example, where all the bitcode in the kernel
is compiled during a relocatable link, and we have a list of
exported symbols.

Add an --lto-export-symbol-list flag to LLD, which accepts a list
of exported globals in the version script format, and uses the
list to set the bindings for non-exported globals to STB_LOCAL,
and sets the VisibleToRegularObj flag in symbol resolution only
for the exported symbols.

Diff Detail

Event Timeline

samitolvanen created this revision.Jan 19 2023, 3:48 PM
Herald added a project: Restricted Project. · View Herald Transcript
samitolvanen requested review of this revision.Jan 19 2023, 3:48 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 19 2023, 3:48 PM
samitolvanen added a subscriber: pcc.

@pcc, @MaskRay, based on earlier discussions (e.g. https://github.com/ClangBuiltLinux/linux/issues/1737), does something like this look like a reasonable approach?

pcc added a comment.Jan 19 2023, 8:26 PM

What do you think about making this apply not only to LTO but to other -r links as well? This would be useful for use cases like the internal symbolizer used by the sanitizers, which currently (ab)uses LTO for a similar effect. I was imagining that the user interface would be that we would make --version-script compatible with -r links, with the restriction being that it would not be possible to specify a symbol version (as this patch does).

What do you think about making this apply not only to LTO but to other -r links as well?

Sure, I'm fine with that. Looks like we would just have to apply computeBinding to relocatable links as well when export symbols are specified. @MaskRay, what do you think?

What do you think about making this apply not only to LTO but to other -r links as well?

Sure, I'm fine with that. Looks like we would just have to apply computeBinding to relocatable links as well when export symbols are specified. @MaskRay, what do you think?

(On a trip; don't have much time checking emails or looking into patch details)
The feature applying to -r makes sense.

lld/ELF/Symbols.h
175

wrong case

Don't apply to isUsedInRegularObj symbols.

So, I looked into applying this to all object files with by adding similar code to Writer<ELFT>::finalizeSections(). This is not quite what we want in the kernel though. The primary goal is to better optimize bitcode during a relocatable link, and while we can conveniently generate a list of functions exported to kernel modules, we don't necessarily have a complete list of symbols (typically defined in stand-alone assembly) that are later needed in linker scripts or whose bindings objtool etc. assume to remain untouched, for example. In order to avoid additional hacks in the kernel, I would prefer to keep this flag specific to LTO. I do see the value in having a similar option for all object files, but perhaps that can be a separate option?

MaskRay added inline comments.Feb 7 2023, 9:03 PM
lld/ELF/LTO.cpp
262

objSym.isExecutable() this condition is strange and does not fit into the spirit that we ignore symbol types for various symbol list features.
Can the user specify all data symbols?

lld/ELF/Symbols.cpp
272

This makes the Writer.cpp caller slow. Suggest: add a new function. I need to think more why we don't make the feature available to non-LTO use cases.

lld/test/ELF/driver.test
74

Move this to the end of lto-export-symbol-list.ll.

lld/test/ELF/lto/lto-export-symbol-list-unexpected-end.s
1

Move this to the end of lto-export-symbol-list.ll. Use RUN: rm -rf %t && split-file %s %t && cd %t.

lld/test/ELF/lto/lto-export-symbol-list.ll
5

llvm-readobj -s is not recommended for new tests (too verbose). Use llvm-readelf -s (see my changes rewriting some tests to use it)

samitolvanen planned changes to this revision.Feb 23 2023, 8:13 AM
samitolvanen added inline comments.
lld/ELF/LTO.cpp
262

I agree, this is bit awkward. I'll have to see if there's a convenient way for us to specify data symbols in the kernel. The problem is that some of these are referenced from linker scripts that are used later when linking vmlinux.