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); }