[PATCH] D92259: [ELF] Make foo@@v1 resolve undefined foo at v1
James Henderson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 30 00:48:51 PST 2020
jhenderson added a comment.
I'm not much of a symbol versioning expert (see my inline comment), but this approach seems reasonable to me at least.
In D92259#2421021 <https://reviews.llvm.org/D92259#2421021>, @MaskRay wrote:
> (FWIW I have made some notes about symbol versioning at https://translate.google.com/translate?sl=zh-CN&tl=en&u=https%3A%2F%2Fmaskray.me%2Fblog%2F2020-11-26-all-about-symbol-versioning)
> (Apparently people are annoyed by lack of symbol versioning documentation https://invisible-island.net/ncurses/ncurses-mapsyms.html :) )
> (We may need one document under `docs/ELF/` describing the LLD behavior)
In my opinion, you can never have too much documentation.
================
Comment at: lld/ELF/Driver.cpp:1915
// so that wrapped symbols are swapped as instructed by the command line.
-static void wrapSymbols(ArrayRef<WrappedSymbol> wrapped) {
+static void redirectSymbols(ArrayRef<WrappedSymbol> wrapped) {
DenseMap<Symbol *, Symbol *> map;
----------------
Given the possibility for a significant link time cost to this section of code where there are lots of (versioned) symbols, perhaps it is worth adding a time scope to this function with this change?
================
Comment at: lld/ELF/Driver.cpp:1921
}
+ for (Symbol *sym : symtab->symbols()) {
+ // Enumerate symbols with a non-default version (foo at v1). Its name was
----------------
Seems to me like iterating through all symbols could be quite expensive, based on an assumption that most symbols aren't versioned. At least for our platform, we don't even support symbol versioning, so there shouldn't be ANY versioned symbols, meaning an unnecessary trawl through the symbols. Would we be better off recording earlier and then using here a list of versioned symbols?
================
Comment at: lld/ELF/Driver.cpp:1922-1923
+ for (Symbol *sym : symtab->symbols()) {
+ // Enumerate symbols with a non-default version (foo at v1). Its name was
+ // truncated at '@' by Symbol::parseSymbolVersion().
+ StringRef name = sym->getName();
----------------
There's a slight inconsistency in your grammar here - the first sentence refers to multiple symbols, but "Its name" implies a singular symbol. Probably best to rewrite as suggested.
================
Comment at: lld/ELF/Driver.cpp:1929
+
+ // Check whether the default version foo@@v1 exists. If exists, the symbol
+ // can be found by the name "foo" in the symbol table.
----------------
================
Comment at: lld/ELF/Driver.cpp:1939
+
+ // foo at v1 and foo@@v1 should be considered as one symbol. So we redirect
+ // foo at v1 references to foo@@v1.
----------------
================
Comment at: lld/test/ELF/symver.s:15
-# TODO Report an duplicate definition error for foo at v1 and foo@@v1.
-# RUN: ld.lld -shared --version-script=%t/ver %t/def1.o %t/hid1.o -o /dev/null
-
+# Report an duplicate definition error for foo at v1 and foo@@v1.
+# RUN: not ld.lld -shared --version-script=%t/ver %t/def1.o %t/hid1.o -o /dev/null 2>&1 | \
----------------
================
Comment at: lld/test/ELF/symver.s:41
-# CHECK: 1: {{.*}} NOTYPE GLOBAL DEFAULT UND foo{{$}}
-# CHECK-NEXT: 2: {{.*}} NOTYPE GLOBAL DEFAULT {{[1-9]}} foo@@v1
+# CHECK: 1: {{.*}} NOTYPE GLOBAL DEFAULT {{[1-9]}} foo@@v1
# CHECK-EMPTY:
----------------
Optional improvement to this check, as it will a) still pass if there are more than 10 section headers, and b) is shorter. (It will start matching against `0` too, but that should be printed as `UND` so there is no issue here).
You can use the same technique for the protected case too, if you want.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D92259/new/
https://reviews.llvm.org/D92259
More information about the llvm-commits
mailing list