[PATCH] D59275: [ELF] Do not emit weak-undef symbols in .dynsym if config is -static -pie.

Siva Chandra via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 13 13:08:45 PDT 2019


sivachandra added a comment.

In D59275#1426949 <https://reviews.llvm.org/D59275#1426949>, @pcc wrote:

> It looks like our handling of weak undef in executables is a little unusual. At least it does not match the other two linkers. Taking `ELF/weak-undef.s` as an example:
>
>   $ ld.lld ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie 
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp
>                    w foo
>   $ ld.gold ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie 
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp
>   nm: ra/obj/lld/test/ELF/Output/weak-undef.s.tmp: no symbols
>   $ ld.bfd ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie 
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp
>   nm: ra/obj/lld/test/ELF/Output/weak-undef.s.tmp: no symbols
>  
>   $ echo 'void foo() {}' | clang -shared -o foo.so -x c -
>   $ ld.bfd ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie foo.so
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp |grep foo
>                    w foo
>   $ ld.gold ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie foo.so
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp |grep foo
>                    w foo
>   $ ld.lld ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie foo.so
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp |grep foo
>                    w foo
>  
>   $ echo 'void bar() {}' | clang -shared -o bar.so -x c -
>   $ ld.bfd ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie bar.so
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp |grep foo
>   $ ld.gold ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie bar.so
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp |grep foo
>   $ ld.lld ra/obj/lld/test/ELF/Output/weak-undef.s.tmp.o -o ra/obj/lld/test/ELF/Output/weak-undef.s.tmp -pie bar.so
>   $ nm -D ra/obj/lld/test/ELF/Output/weak-undef.s.tmp |grep foo
>                    w foo
>
>
> So what the other linkers appear to implement is that a shared object defining the weak symbol must be available at link time in order for the symbol to be resolved at runtime, which is essentially what you've implemented here for static PIE. Maybe we should do the same thing for other executables?


Hmmm, I think ld.bfd atleast, is doing something more "involved" if I may say so.

In the example you have chosen, the weak symbol is being referenced in this manner:

.dc.a foo  // foo is the weak symbol.

If you replace it with this:

.long foo at gotpcrel

Then, you will find that ld.bfd does emit the symbol for it in .dynsym.

So, it seems to me that ld.bfd is making the decision based on whether a symbol can be resolved at run time or not . Another observation: ld.bfd does not emit weak undef symbols in .dynsym if we pass --no-dynamic-linker. In my case, I am happy if ld.lld also did this. So, I modified this change accordingly. I had to add a dummy path to a dynamic linker in few of the existing tests. The change to mimic ld.bfd is all cases is probably beyond the scope of this change.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59275/new/

https://reviews.llvm.org/D59275





More information about the llvm-commits mailing list