This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Make --version-script/--dynamic-list work for lazy symbols fetched by LTO libcalls
ClosedPublic

Authored by MaskRay on Apr 1 2020, 5:12 PM.

Details

Summary

Fixes https://bugs.llvm.org/show_bug.cgi?id=45391

The LTO code generator happens after version script scanning and may
create references which will fetch some lazy symbols.

Currently a version script does not assign VER_NDX_LOCAL to lazy symbols
and such symbols will be made global after they are fetched.

Change findByVersion and findAllByVersion to work on lazy symbols.
For unfetched lazy symbols, we should keep them non-local (D35263).
Check isDefined() in computeBinding() as a compensation.

This patch fixes a companion bug that --dynamic-list does not export
such symbols.

Diff Detail

Event Timeline

MaskRay created this revision.Apr 1 2020, 5:12 PM
MaskRay updated this revision to Diff 254377.Apr 1 2020, 5:35 PM
MaskRay retitled this revision from [ELF] Make --version-script work for lazy symbols fetched by LTO libcalls to [ELF] Make --version-script/--dynamic-list work for lazy symbols fetched by LTO libcalls.
MaskRay edited the summary of this revision. (Show Details)

State that this fixes --dynamic-list as well

grimar added inline comments.Apr 2 2020, 3:47 AM
lld/ELF/SymbolTable.cpp
128–129

Seems this change is untested.

156

What do you think about adding a helper like the following?
(to avoid the duplication in 3 places)

// <comment>
static bool canBeVersioned(const Symbol& Sym) {
 return b->isDefined() || b->isCommon() || b->isLazy()
}
MaskRay updated this revision to Diff 254540.Apr 2 2020, 9:08 AM
MaskRay marked 2 inline comments as done.

Add canBeVersioned()

MaskRay marked an inline comment as done.Apr 2 2020, 9:09 AM
MaskRay added inline comments.
lld/ELF/SymbolTable.cpp
128–129

This can't be tested because no libcall has a C++ style mangled name.

I did this just for consistency.

grimar added a comment.Apr 3 2020, 1:11 AM

I have no more comments, I'd like someone more familar with LTO to take a look.

MaskRay added a comment.EditedApr 3 2020, 3:54 PM

I have no more comments, I'd like someone more familar with LTO to take a look.

There is not much about LTO. Version script scanning happens before LTO because LTO needs to know what symbols are local and can thus internalize them. Some library call undefined references (e.g. __udivti3) are not recorded in the symbol table of bitcode files but they may be generated on the fly. The reference will fetch the lazy __udivti3. We thus need to track the version of lazy libcall symbol as well.

if (!config->relocatable)
  symtab->scanVersionScript();

// Do link-time optimization if given files are LLVM bitcode files.
// This compiles bitcode files into real object files.
//
// With this the symbol table should be complete. After this, no new names
// except a few linker-synthesized ones will be added to the symbol table.
compileBitcodeFiles<ELFT>();
grimar accepted this revision.Apr 6 2020, 5:49 AM

Some library call undefined references (e.g. __udivti3) are not recorded in the symbol table of bitcode files but they may be generated on the fly.

This detail filled some gap in my head, so LGTM, thanks!

This revision is now accepted and ready to land.Apr 6 2020, 5:49 AM
This revision was automatically updated to reflect the committed changes.