public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* LLD and glibc
@ 2021-10-25 14:53 Adhemerval Zanella
  2021-10-25 16:53 ` Fangrui Song
  0 siblings, 1 reply; 2+ messages in thread
From: Adhemerval Zanella @ 2021-10-25 14:53 UTC (permalink / raw)
  To: Fangrui Song, H.J. Lu, Libc-alpha

I tracked down the issues with lld on glibc and it seems slight better
than my previous attempt.

To use lld without having to mess with my toolchain installation, I was
trying to use -fuse-ld=lld plus -B option.  However it does not work
correctly with the LIBC_PROG_BINUTILS macro, since it issues the
passed CC with -print-prog-name=ld.  In this case gcc will always dump
the ld path, not the lld (it does work if I use -print-prog-name=lld).
I think this is a gcc issue since it should be agnostic whether
-fuse-ld is used, but I think we can try to workaround it on glibc
configure (use the -fuse-ld argument on -print-prog-name if the former
is presented).

So to actually use lld I had to adjust the links on my build-many-glibcs
built toolchain to explicit point to lld (both bin/x86_64-glibc-linux-gnu-ld
and x86_64-glibc-linux-gnu/bin/ld).

The new issue is the same H.J has reported some time earlier:

ld: error: cannot preempt symbol: foo_protected
>>> defined in /home/azanella/Projects/glibc/build/x86_64-linux-gnu-lld/elf/ifuncmod5.so
>>> referenced by ifuncmain5.c:22 (/home/azanella/Projects/glibc/glibc-git/elf/ifuncmain5.c:22)
>>>               /home/azanella/Projects/glibc/build/x86_64-linux-gnu-lld/elf/ifuncmain5.o:(get_foo_protected)

I think we should just disable the tests ldd does not support (with the
patch below) instead of get back of the discussion whether it should be
supported or not.

The good news is with release clang+llvm 13 and with the testcase patch
I could build and run make check successfully without any regression.

I am writing this because we need to fix both issues (configure with -fuse-ld
and the failure on make check) so we can start review the DT_RELR patchset [1]

[1] https://patchwork.sourceware.org/project/glibc/list/?series=3895

---

diff --git a/elf/Makefile b/elf/Makefile
index bdcf4cb885..7ddc4b39a3 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -427,11 +427,14 @@ ifeq (yes,$(build-shared))
 tests += tst-ifunc-fault-lazy tst-ifunc-fault-bindnow
 # Note: sysdeps/x86_64/ifuncmain8.c uses ifuncmain8.
 tests-internal += \
-        ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
+        ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
         ifuncmain1staticpic \
         ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \
-        ifuncmain5 ifuncmain5pic ifuncmain5staticpic \
+        ifuncmain5pic ifuncmain5staticpic \
         ifuncmain7 ifuncmain7pic
+ifeq (no,$(with-lld))
+test-internal += ifuncmain1 ifuncmain5
+endif
 ifeq (yes,$(have-gcc-ifunc))
 tests-internal += ifuncmain9 ifuncmain9pic
 endif
@@ -451,7 +454,10 @@ endif
 tests-internal += $(ifunc-pie-tests)
 tests-pie += $(ifunc-pie-tests)
 endif
-modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6
+modules-names += ifuncmod1 ifuncmod3 ifuncmod6
+ifeq (no,$(with-lld))
+modules-names += ifuncmod5
+endif
 endif
 endif
 



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: LLD and glibc
  2021-10-25 14:53 LLD and glibc Adhemerval Zanella
@ 2021-10-25 16:53 ` Fangrui Song
  0 siblings, 0 replies; 2+ messages in thread
From: Fangrui Song @ 2021-10-25 16:53 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: H.J. Lu, Libc-alpha

On 2021-10-25, Adhemerval Zanella wrote:
>I tracked down the issues with lld on glibc and it seems slight better
>than my previous attempt.
>
>To use lld without having to mess with my toolchain installation, I was
>trying to use -fuse-ld=lld plus -B option.  However it does not work
>correctly with the LIBC_PROG_BINUTILS macro, since it issues the
>passed CC with -print-prog-name=ld.  In this case gcc will always dump
>the ld path, not the lld (it does work if I use -print-prog-name=lld).
>I think this is a gcc issue since it should be agnostic whether
>-fuse-ld is used, but I think we can try to workaround it on glibc
>configure (use the -fuse-ld argument on -print-prog-name if the former
>is presented).
>
>So to actually use lld I had to adjust the links on my build-many-glibcs
>built toolchain to explicit point to lld (both bin/x86_64-glibc-linux-gnu-ld
>and x86_64-glibc-linux-gnu/bin/ld).
>
>The new issue is the same H.J has reported some time earlier:
>
>ld: error: cannot preempt symbol: foo_protected
>>>> defined in /home/azanella/Projects/glibc/build/x86_64-linux-gnu-lld/elf/ifuncmod5.so
>>>> referenced by ifuncmain5.c:22 (/home/azanella/Projects/glibc/glibc-git/elf/ifuncmain5.c:22)
>>>>               /home/azanella/Projects/glibc/build/x86_64-linux-gnu-lld/elf/ifuncmain5.o:(get_foo_protected)
>
>I think we should just disable the tests ldd does not support (with the
>patch below) instead of get back of the discussion whether it should be
>supported or not.
>
>The good news is with release clang+llvm 13 and with the testcase patch
>I could build and run make check successfully without any regression.
>
>I am writing this because we need to fix both issues (configure with -fuse-ld
>and the failure on make check) so we can start review the DT_RELR patchset [1]
>
>[1] https://patchwork.sourceware.org/project/glibc/list/?series=3895
>
>---
>
>diff --git a/elf/Makefile b/elf/Makefile
>index bdcf4cb885..7ddc4b39a3 100644
>--- a/elf/Makefile
>+++ b/elf/Makefile
>@@ -427,11 +427,14 @@ ifeq (yes,$(build-shared))
> tests += tst-ifunc-fault-lazy tst-ifunc-fault-bindnow
> # Note: sysdeps/x86_64/ifuncmain8.c uses ifuncmain8.
> tests-internal += \
>-        ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
>+        ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
>         ifuncmain1staticpic \
>         ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \
>-        ifuncmain5 ifuncmain5pic ifuncmain5staticpic \
>+        ifuncmain5pic ifuncmain5staticpic \
>         ifuncmain7 ifuncmain7pic
>+ifeq (no,$(with-lld))
>+test-internal += ifuncmain1 ifuncmain5
>+endif
> ifeq (yes,$(have-gcc-ifunc))
> tests-internal += ifuncmain9 ifuncmain9pic
> endif
>@@ -451,7 +454,10 @@ endif
> tests-internal += $(ifunc-pie-tests)
> tests-pie += $(ifunc-pie-tests)
> endif
>-modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6
>+modules-names += ifuncmod1 ifuncmod3 ifuncmod6
>+ifeq (no,$(with-lld))
>+modules-names += ifuncmod5 >+endif
> endif
> endif
>
>
>

ifuncmain1.c and ifuncmain5.c take the address of the function `foo_protected`.
If compiled with -fno-pic, the produced relocation is R_X86_64_PC32.

In gold and LLD, it is an error to reference an undefined function symbol
with a non-GOT-generating non-PLT-generating relocation from the main
executable (LLD call it "cannot preempt symbol: foo_protected").
This is to guard against risky canonical PLT entry which cannot work
with a protected definition
(https://maskray.me/blog/2021-01-09-copy-relocations-canonical-plt-entries-and-protected).

(I wonder why the test can link with GNU ld. We know it has some limited
support for "copy relocations on protected data symbols" "on x86 but I
don't know it does anything with function symbols. Anyway, protected
function symbols are quite broken in GCC that is why ifuncmod5.c uses
inline assembly instead of proper visibility attribute.)

I could not reproduce the link error because on most Linux
distributions, GCC is configured with enable-default-pie and
ifuncmain5.c is compiled with the implicit -fpie. If I manually compile
ifuncmain5.c with -fno-pic and re-link ifuncmain5 with LLD, I can see
the intended diagnostic "cannot preempt symbol: foo_protected".

You may want to take some of the description to make up a better commit
message.

Reviewed-by: Fangrui Song <maskray@google.com>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-10-25 16:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-25 14:53 LLD and glibc Adhemerval Zanella
2021-10-25 16:53 ` Fangrui Song

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).