[ELF] Make foo@@v1 resolve undefined foo@v1
authorFangrui Song <i@maskray.me>
Tue, 1 Dec 2020 16:54:01 +0000 (08:54 -0800)
committerFangrui Song <i@maskray.me>
Tue, 1 Dec 2020 16:54:01 +0000 (08:54 -0800)
commit941e9336d092f0ccef35e0f425d97f7def5ed1b0
tree39a4ab45c8bdcc3c37d881d9677c8cea759fcc53
parenta5f95887d0f8d27f1c33f19944d0c1da66aef606
[ELF] Make foo@@v1 resolve undefined foo@v1

The symbol resolution rules for versioned symbols are:

* foo@@v1 (default version) resolves both undefined foo and foo@v1
* foo@v1 (non-default version) resolves undefined foo@v1

Note, foo@@v1 must be defined (the assembler errors if attempting to
create an undefined foo@@v1).

For defined foo@@v1 in a shared object, we call `SymbolTable::addSymbol` twice,
one for foo and the other for foo@v1. We don't do the same for object files, so
foo@@v1 defined in one object file incorrectly does not resolve a foo@v1
reference in another object file.

This patch fixes the issue by reusing the --wrap code to redirect symbols in
object files. This has to be done after processing input files because
foo and foo@v1 are two separate symbols if we haven't seen foo@@v1.

Add a helper `Symbol::getVersionSuffix` to retrieve the optional trailing
`@...` or `@@...` from the possibly truncated symbol name.

Depends on D92258

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D92259
lld/ELF/Driver.cpp
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h
lld/test/ELF/symver.s