lld bug workaround

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

lld bug workaround

Mark Kettenis
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 | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: lld bug workaround

Philip Guenther-2
On Saturday, March 18, 2017, Mark Kettenis <[hidden email]> wrote:

> 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?
>

I guess the alternative would be to change crt0 to pass &_end as an
additional argument to _csu_finish(), which could then set a variable local
to libc for brk/sbrk to use...but that'll require a major bump and now is
not the time for that.

So yeah, this diff seems like the reasonable fix for now.


Philip
Loading...