The way lld applies version scripts is a bit broken for
linker-generated symbols. In particular, even if you explicitly mark
rhose symbols als global, they will end up local if that's the default.
So even with the following version script:
{ global: _end; local: *; };
The linker-generated _end will end up as a local symbol.
Unfortunately our brk()/sbrk() implementation relies on _end being
global. The diff below adds a workaround while I take this up with
upstream.
ok?
Index: gnu/llvm/tools/lld/ELF/SymbolTable.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/tools/lld/ELF/SymbolTable.cpp,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 SymbolTable.cpp
--- gnu/llvm/tools/lld/ELF/SymbolTable.cpp 14 Mar 2017 08:07:53 -0000
1.1.1.3
+++ gnu/llvm/tools/lld/ELF/SymbolTable.cpp 18 Mar 2017 15:20:08 -0000
@@ -142,6 +142,12 @@ DefinedRegular<ELFT> *SymbolTable<ELFT>:
SymbolBody *S = find(Name);
if (!S || S->isInCurrentDSO())
return nullptr;
+ if (Visibility == STV_DEFAULT) {
+ for (SymbolVersion &Ver : Config->VersionScriptGlobals) {
+ if (!Ver.HasWildcard && Ver.Name == S->getName())
+ S->symbol()->VersionId = VER_NDX_GLOBAL;
+ }
+ }
return addAbsolute(Name, Visibility);
}