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

Reply via email to