diff mbox series

[RFC,v8,18/20] Add DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE dynamic section+flag to glibc DSOs

Message ID 20210209171839.7911-19-vivek@collabora.com
State New
Delegated to: Adhemerval Zanella Netto
Headers show
Series Implementation of RTLD_SHARED for dlmopen | expand

Commit Message

Vivek Das Mohapatra Feb. 9, 2021, 5:18 p.m. UTC
libc.so, libpthread.so etc should have the new unique-dso-by-default
flag set to allow dlmopen to work better (libc et al instance shared
by default when DSOs dlmopened into a new namespace).
---
 Makeconfig         | 1 +
 Makerules          | 2 +-
 htl/Makefile       | 2 +-
 iconvdata/Makefile | 1 +
 nptl/Makefile      | 2 +-
 5 files changed, 5 insertions(+), 3 deletions(-)

Comments

Adhemerval Zanella Feb. 22, 2021, 8:39 p.m. UTC | #1
On 09/02/2021 14:18, Vivek Das Mohapatra via Libc-alpha wrote:
> libc.so, libpthread.so etc should have the new unique-dso-by-default
> flag set to allow dlmopen to work better (libc et al instance shared
> by default when DSOs dlmopened into a new namespace).

The DT_GNU_FLAGS_1 and -z,unique was added on binutils 2.36 (commit
6a0a0dd0cc437) and glibc currently only requires binutils 2.25.  It
means that glibc built with an older binutils won't set 
DF_GNU_1_UNIQUE for its own DSOs.

If I understood correctly, it means that libc.so and glibc libraries
won't really work on shared mode (dlmopen a library with DT_SHARED)
as indicated by the failures using the own set tests with a binutils
2.35:

FAIL: elf/tst-dlmopen-rtld-audit-unique1
FAIL: elf/tst-dlmopen-rtld-audit-unique3
FAIL: elf/tst-dlmopen-rtld-audit-unique6
FAIL: elf/tst-dlmopen-rtld-unique1
FAIL: elf/tst-dlmopen-rtld-unique3
FAIL: elf/tst-dlmopen-rtld-unique6

Since DF_GNU_1_UNIQUE is not supported, the namespace value is not the
expected one. So I think this support is required to avoid having a 
broken/incomplete support (where glibc dlmopen accepts the newer flags, 
but glibc shared libraries themselves do not support DF_GNU_1_UNIQUE).

We have some options to fix it:

  1. Bump the minimum supported binutils version to 2.36. It would be
     a large change, since we usually do incremental changes over releases
     (the binutils 2.25 change from 2.22 was done on glibc 2.26).

  2. Add a configure check and enable RTLD_SHARED iff ld supports
     -z unique.  It would require return EINVAL is RTLD_SHARED or
     RTLD_ISOLATE if the configure check see the binutils do not
     support it (and extend the check for the tests to return
     UNSUPPORTED in such case).

  3. Find a way to force add DF_GNU_1_UNIQUE on older binutils
     (since its support is just a dynamic section existence)

The 1. is simple but will force a large upgrade bump in toolchain for 
users (although it might also allow some further cleanups).  I would like
to avoid it, but I won't oppose if there is no easy solution.

The 2. would require add some internal support (to avoid running tests
if ld does not provide support and add ifdef over loader code to ignore
DF_GNU_1_UNIQUE) and make glibc supports a dmopen based on configure support
(not ideal). 

The 3. is a hackery solution, but might work without incurring a toolchain
requirement bump (however I am not this is a easy solution).

Thoughts?


> ---
>  Makeconfig         | 1 +
>  Makerules          | 2 +-
>  htl/Makefile       | 2 +-
>  iconvdata/Makefile | 1 +
>  nptl/Makefile      | 2 +-
>  5 files changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/Makeconfig b/Makeconfig
> index 0a4811b5e5..d0e52f26fd 100644
> --- a/Makeconfig
> +++ b/Makeconfig
> @@ -398,6 +398,7 @@ LDFLAGS-lib.so += -Wl,-z,now
>  # Extra flags for dynamically linked non-test main programs.
>  link-extra-flags += -Wl,-z,now
>  endif
> +LDFLAGS-lib.so += -Wl,-z,unique
>  
>  # Command to run after every final link (executable or shared object).
>  # This is invoked with $(call after-link,...), so it should operate on
> diff --git a/Makerules b/Makerules
> index ca9885436e..82adffdc27 100644
> --- a/Makerules
> +++ b/Makerules
> @@ -635,7 +635,7 @@ build-shlib-objlist = $(build-module-helper-objlist) \
>  # Don't try to use -lc when making libc.so itself.
>  # Also omits crti.o and crtn.o, which we do not want
>  # since we define our own `.init' section specially.
> -LDFLAGS-c.so = -nostdlib -nostartfiles
> +LDFLAGS-c.so = -nostdlib -nostartfiles -Wl,-z,unique
>  # But we still want to link libc.so against $(libc.so-gnulib).
>  LDLIBS-c.so += $(libc.so-gnulib)
>  # Give libc.so an entry point and make it directly runnable itself.
> diff --git a/htl/Makefile b/htl/Makefile
> index c15c1b194e..5d0d76d941 100644
> --- a/htl/Makefile
> +++ b/htl/Makefile
> @@ -204,7 +204,7 @@ $(inst_libdir)/libpthread_syms.a: $(srcdir)/libpthread_syms.a $(+force)
>  libc-link.so = $(common-objpfx)libc.so
>  
>  extra-B-pthread.so = -B$(common-objpfx)htl/
> -LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
> +LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,unique,-z,nodelete,-z,initfirst
>  
>  include ../Rules
>  
> diff --git a/iconvdata/Makefile b/iconvdata/Makefile
> index 55c527a5f7..ea5565eb40 100644
> --- a/iconvdata/Makefile
> +++ b/iconvdata/Makefile
> @@ -67,6 +67,7 @@ modules	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
>  ifeq ($(bind-now),yes)
>  LDFLAGS.so += -Wl,-z,now
>  endif
> +LDFLAGS.so += -Wl,-z,unique
>  
>  modules.so := $(addsuffix .so, $(modules))
>  
> diff --git a/nptl/Makefile b/nptl/Makefile
> index 8fb7fee6db..9090b88dec 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -349,7 +349,7 @@ else
>  tests-printers-libs := $(static-thread-library)
>  endif
>  
> -LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
> +LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,unique,-z,nodelete,-z,initfirst
>  
>  tests += tst-cancelx7 tst-cancelx17 tst-cleanupx4
>  
>
Florian Weimer Feb. 22, 2021, 9:19 p.m. UTC | #2
* Adhemerval Zanella via Libc-alpha:

> We have some options to fix it:
>
>   1. Bump the minimum supported binutils version to 2.36. It would be
>      a large change, since we usually do incremental changes over releases
>      (the binutils 2.25 change from 2.22 was done on glibc 2.26).
>
>   2. Add a configure check and enable RTLD_SHARED iff ld supports
>      -z unique.  It would require return EINVAL is RTLD_SHARED or
>      RTLD_ISOLATE if the configure check see the binutils do not
>      support it (and extend the check for the tests to return
>      UNSUPPORTED in such case).
>
>   3. Find a way to force add DF_GNU_1_UNIQUE on older binutils
>      (since its support is just a dynamic section existence)

(1) is fine, I think.  Moving from 2.25 (2015) to 2.26 (2016) isn't that
big of a change.

> The 3. is a hackery solution, but might work without incurring a toolchain
> requirement bump (however I am not this is a easy solution).

There's a thread about this:

  Creating arbitrary dynamic tags with BFD ld
  <https://sourceware.org/legacy-ml/binutils/2019-09/msg00285.html>
  <https://sourceware.org/legacy-ml/binutils/2019-09/msg00287.html>

(Search machine indexing of sourceware.org mailing lists is really poor
these days unfortunately.)

Thanks,
Florian
Adhemerval Zanella Feb. 22, 2021, 9:53 p.m. UTC | #3
On 22/02/2021 18:19, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> We have some options to fix it:
>>
>>   1. Bump the minimum supported binutils version to 2.36. It would be
>>      a large change, since we usually do incremental changes over releases
>>      (the binutils 2.25 change from 2.22 was done on glibc 2.26).
>>
>>   2. Add a configure check and enable RTLD_SHARED iff ld supports
>>      -z unique.  It would require return EINVAL is RTLD_SHARED or
>>      RTLD_ISOLATE if the configure check see the binutils do not
>>      support it (and extend the check for the tests to return
>>      UNSUPPORTED in such case).
>>
>>   3. Find a way to force add DF_GNU_1_UNIQUE on older binutils
>>      (since its support is just a dynamic section existence)
> 
> (1) is fine, I think.  Moving from 2.25 (2015) to 2.26 (2016) isn't that
> big of a change.

It is not to 2.26, but rather *2.36* (2021).

> 
>> The 3. is a hackery solution, but might work without incurring a toolchain
>> requirement bump (however I am not this is a easy solution).
> 
> There's a thread about this:
> 
>   Creating arbitrary dynamic tags with BFD ld
>   <https://sourceware.org/legacy-ml/binutils/2019-09/msg00285.html>
>   <https://sourceware.org/legacy-ml/binutils/2019-09/msg00287.html>
> 
> (Search machine indexing of sourceware.org mailing lists is really poor
> these days unfortunately.)

Interesting, but I can't get this to work.  I added an object:

$ cat elf/dynamic-notes.S 
#define DT_GNU_FLAGS_1   0x6ffffdf4
#define DF_GNU_1_UNIQUE  0x00000001

.section .dynamic, "a", %6
.dc.a   DT_GNU_FLAGS_1
.dc.a   DF_GNU_1_UNIQUE

And added a rule to just build it:

diff --git a/elf/Makefile b/elf/Makefile
index bccf31b1a9..d244ba79b3 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -105,7 +105,7 @@ ld-map              = $(common-objpfx)ld.map
 endif
 
 ifeq (yes,$(build-shared))
-extra-objs     = $(all-rtld-routines:%=%.os) sofini.os interp.os
+extra-objs     = $(all-rtld-routines:%=%.os) sofini.os interp.os dynamic-notes.os
 generated      += librtld.os dl-allobjs.os ld.so ldd
 install-others = $(inst_rtlddir)/$(rtld-installed-name)
 install-bin-script = ldd

And edit the shlib.lds manually:

$ grep dynamic shlib.lds 
  .dynamic        : { *dynamic-notes.os(.dynamic) *(.dynamic) }

But I can get a GNU_FLAGS_1 entry on dynamic sections.
Vivek Das Mohapatra Feb. 23, 2021, 12:17 a.m. UTC | #4
> We have some options to fix it:
>
>  1. Bump the minimum supported binutils version to 2.36. It would be
>     a large change, since we usually do incremental changes over releases

It's a large bump: OTOH is it the case that people are going to be
rolling out cutting edge glibc with old binutils? (Serious question,
the answer might be yes in whic case we do need to think about this).

>  2. Add a configure check and enable RTLD_SHARED iff ld supports
>     -z unique.  It would require return EINVAL is RTLD_SHARED or

Doable, but then we'd have glibc at the same version with different
capabilities/behaviours in the linker: Asking for pain imo.

>  3. Find a way to force add DF_GNU_1_UNIQUE on older binutils
>     (since its support is just a dynamic section existence)

I think this is doable, either with a linker script or by
using the spare dynamic tags added by ld (cf --spare-dynamic-sections)
and writing in the value we want in the first spare slot.

I'll have a look at adding this since it enables the feature with
minimal friction for distributions/users/etc.
Alan Modra Feb. 23, 2021, 3:26 a.m. UTC | #5
On Mon, Feb 22, 2021 at 06:53:07PM -0300, Adhemerval Zanella wrote:
> $ grep dynamic shlib.lds 
>   .dynamic        : { *dynamic-notes.os(.dynamic) *(.dynamic) }
> 
> But I can get a GNU_FLAGS_1 entry on dynamic sections.

I assume you meant "can't".  If you did get everything correct in your
script then the added user .dynamic should appear, and readelf will
show it.  However, _DYNAMIC will be defined at the start of the linker
generated .dynamic section.

If there was a problem in your script, then the user .dynamic section
is likely at the end of the linker generated .dynamic after a number
of DT_NULL entries.  readelf stops displaying at the first DT_NULL.
objdump -sj.dynamic to see.
Florian Weimer Feb. 23, 2021, 10 a.m. UTC | #6
* Adhemerval Zanella:

> On 22/02/2021 18:19, Florian Weimer wrote:
>> * Adhemerval Zanella via Libc-alpha:
>> 
>>> We have some options to fix it:
>>>
>>>   1. Bump the minimum supported binutils version to 2.36. It would be
>>>      a large change, since we usually do incremental changes over releases
>>>      (the binutils 2.25 change from 2.22 was done on glibc 2.26).
>>>
>>>   2. Add a configure check and enable RTLD_SHARED iff ld supports
>>>      -z unique.  It would require return EINVAL is RTLD_SHARED or
>>>      RTLD_ISOLATE if the configure check see the binutils do not
>>>      support it (and extend the check for the tests to return
>>>      UNSUPPORTED in such case).
>>>
>>>   3. Find a way to force add DF_GNU_1_UNIQUE on older binutils
>>>      (since its support is just a dynamic section existence)
>> 
>> (1) is fine, I think.  Moving from 2.25 (2015) to 2.26 (2016) isn't that
>> big of a change.
>
> It is not to 2.26, but rather *2.36* (2021).

Ugh, that's way too soon.

> But I can get a GNU_FLAGS_1 entry on dynamic sections.

Maybe we can rewrite the binaries after linking to add the flag if we
can't get BFD ld to produce it.

Thanks,
Florian
Adhemerval Zanella Feb. 23, 2021, 11:57 a.m. UTC | #7
On 23/02/2021 00:26, Alan Modra wrote:
> On Mon, Feb 22, 2021 at 06:53:07PM -0300, Adhemerval Zanella wrote:
>> $ grep dynamic shlib.lds 
>>   .dynamic        : { *dynamic-notes.os(.dynamic) *(.dynamic) }
>>
>> But I can get a GNU_FLAGS_1 entry on dynamic sections.
> 
> I assume you meant "can't".  If you did get everything correct in your
> script then the added user .dynamic should appear, and readelf will
> show it.  However, _DYNAMIC will be defined at the start of the linker
> generated .dynamic section.
> 
> If there was a problem in your script, then the user .dynamic section
> is likely at the end of the linker generated .dynamic after a number
> of DT_NULL entries.  readelf stops displaying at the first DT_NULL.
> objdump -sj.dynamic to see.
> 

My mistake here Alan, sorry for the noise. I could get a the GNU_FLAGS_1
added with a proper modified linker script and with the object I referenced.
Adhemerval Zanella Feb. 23, 2021, 11:58 a.m. UTC | #8
On 23/02/2021 07:00, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 22/02/2021 18:19, Florian Weimer wrote:
>>> * Adhemerval Zanella via Libc-alpha:
>>>
>>>> We have some options to fix it:
>>>>
>>>>   1. Bump the minimum supported binutils version to 2.36. It would be
>>>>      a large change, since we usually do incremental changes over releases
>>>>      (the binutils 2.25 change from 2.22 was done on glibc 2.26).
>>>>
>>>>   2. Add a configure check and enable RTLD_SHARED iff ld supports
>>>>      -z unique.  It would require return EINVAL is RTLD_SHARED or
>>>>      RTLD_ISOLATE if the configure check see the binutils do not
>>>>      support it (and extend the check for the tests to return
>>>>      UNSUPPORTED in such case).
>>>>
>>>>   3. Find a way to force add DF_GNU_1_UNIQUE on older binutils
>>>>      (since its support is just a dynamic section existence)
>>>
>>> (1) is fine, I think.  Moving from 2.25 (2015) to 2.26 (2016) isn't that
>>> big of a change.
>>
>> It is not to 2.26, but rather *2.36* (2021).
> 
> Ugh, that's way too soon.

Yeah, my take as well :/

> 
>> But I can get a GNU_FLAGS_1 entry on dynamic sections.
> 
> Maybe we can rewrite the binaries after linking to add the flag if we
> can't get BFD ld to produce it.

I didn't really checked my build environment, with some adjustment I 
could get the new dynamic section with Alan's trick.
Adhemerval Zanella Feb. 23, 2021, 12:02 p.m. UTC | #9
On 22/02/2021 21:17, Vivek Das Mohapatra wrote:
>> We have some options to fix it:
>>
>>  1. Bump the minimum supported binutils version to 2.36. It would be
>>     a large change, since we usually do incremental changes over releases
> 
> It's a large bump: OTOH is it the case that people are going to be
> rolling out cutting edge glibc with old binutils? (Serious question,
> the answer might be yes in whic case we do need to think about this).
> 
>>  2. Add a configure check and enable RTLD_SHARED iff ld supports
>>     -z unique.  It would require return EINVAL is RTLD_SHARED or
> 
> Doable, but then we'd have glibc at the same version with different
> capabilities/behaviours in the linker: Asking for pain imo.
> 
>>  3. Find a way to force add DF_GNU_1_UNIQUE on older binutils
>>     (since its support is just a dynamic section existence)
> 
> I think this is doable, either with a linker script or by
> using the spare dynamic tags added by ld (cf --spare-dynamic-sections)
> and writing in the value we want in the first spare slot.

In fact I now more inclined to use 3. now that I checked that Alan's
trick [1] does work.  The assembly file should be architecture
independent, so it is a matter of building, changing the shlib.lds
generation to add the new object and adding the new note on each required
library.

[1] https://sourceware.org/legacy-ml/binutils/2019-09/msg00287.html
Florian Weimer Feb. 23, 2021, 12:12 p.m. UTC | #10
* Adhemerval Zanella:

>>> But I can get a GNU_FLAGS_1 entry on dynamic sections.
>> 
>> Maybe we can rewrite the binaries after linking to add the flag if we
>> can't get BFD ld to produce it.
>
> I didn't really checked my build environment, with some adjustment I 
> could get the new dynamic section with Alan's trick.

This is good news, thanks for doing that experiment.

Florian
Adhemerval Zanella Feb. 23, 2021, 1:24 p.m. UTC | #11
On 23/02/2021 09:02, Adhemerval Zanella wrote:
> 
> 
> On 22/02/2021 21:17, Vivek Das Mohapatra wrote:
>>> We have some options to fix it:
>>>
>>>  1. Bump the minimum supported binutils version to 2.36. It would be
>>>     a large change, since we usually do incremental changes over releases
>>
>> It's a large bump: OTOH is it the case that people are going to be
>> rolling out cutting edge glibc with old binutils? (Serious question,
>> the answer might be yes in whic case we do need to think about this).
>>
>>>  2. Add a configure check and enable RTLD_SHARED iff ld supports
>>>     -z unique.  It would require return EINVAL is RTLD_SHARED or
>>
>> Doable, but then we'd have glibc at the same version with different
>> capabilities/behaviours in the linker: Asking for pain imo.
>>
>>>  3. Find a way to force add DF_GNU_1_UNIQUE on older binutils
>>>     (since its support is just a dynamic section existence)
>>
>> I think this is doable, either with a linker script or by
>> using the spare dynamic tags added by ld (cf --spare-dynamic-sections)
>> and writing in the value we want in the first spare slot.
> 
> In fact I now more inclined to use 3. now that I checked that Alan's
> trick [1] does work.  The assembly file should be architecture
> independent, so it is a matter of building, changing the shlib.lds
> generation to add the new object and adding the new note on each required
> library.
> 
> [1] https://sourceware.org/legacy-ml/binutils/2019-09/msg00287.html
> 

This patch below based on your tree could get the dynamic note on libc.so.
It has to explicit add the dynamic-note.os as an extra object (adding an
extra object on libc.so build will add on libc_pic.{a,os} and linker script
won't handle).

The shlib.lds would require some work to get the previous '.dynamic'
info dumped from compiler. Also it does not add the dynamic section on
other libraries than libc.so.

Alan pointed me out that _DYNAMIC can be in the script too, but I am not
sure it would be simpler in our build process.  And dynamic-notes.c could
also be used to add other dynamic section when required.

---

diff --git a/Makerules b/Makerules
index 82adffdc27..fc6061e12d 100644
--- a/Makerules
+++ b/Makerules
@@ -581,7 +581,8 @@ $(common-objpfx)shlib.lds: $(common-objpfx)config.make $(..)Makerules
                 PROVIDE(__start___libc_IO_vtables = .);\
                 __libc_IO_vtables : { *(__libc_IO_vtables) }\
                 PROVIDE(__stop___libc_IO_vtables = .);\
-                /DISCARD/ : { *(.gnu.glibc-stub.*) }@'
+                /DISCARD/ : { *(.gnu.glibc-stub.*) }@' \
+             -e 's/^.*\*(\.dynamic).*$$/   .dynamic : { *dynamic-notes.os(.dynamic) *(.dynamic) }/'
        test -s $@T
        mv -f $@T $@
 common-generated += shlib.lds
@@ -693,6 +694,7 @@ $(common-objpfx)linkobj/libc.so: link-libc-deps = # empty
 $(common-objpfx)libc.so: $(common-objpfx)libc_pic.os$(libc_pic_clean) \
                         $(elf-objpfx)sofini.os \
                         $(elf-objpfx)interp.os \
+                        $(elf-objpfx)dynamic-notes.os \
                         $(elf-objpfx)ld.so \
                         $(shlib-lds)
        $(build-shlib)
diff --git a/elf/Makefile b/elf/Makefile
index bccf31b1a9..e3c5937caf 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -105,7 +105,8 @@ ld-map              = $(common-objpfx)ld.map
 endif
 
 ifeq (yes,$(build-shared))
-extra-objs     = $(all-rtld-routines:%=%.os) sofini.os interp.os
+extra-objs     = $(all-rtld-routines:%=%.os) sofini.os interp.os \
+                 dynamic-notes.os
 generated      += librtld.os dl-allobjs.os ld.so ldd
 install-others = $(inst_rtlddir)/$(rtld-installed-name)
 install-bin-script = ldd
diff --git a/elf/dynamic-notes.c b/elf/dynamic-notes.c
new file mode 100644
index 0000000000..d0b487e970
--- /dev/null
+++ b/elf/dynamic-notes.c
@@ -0,0 +1,4 @@
+#include <link.h>
+
+const ElfW(Dyn) __dynamic_note __attribute__ ((section (".dynamic"))) =
+  { .d_tag = DT_GNU_FLAGS_1, .d_un.d_val = DF_GNU_1_UNIQUE };
Vivek Das Mohapatra Feb. 23, 2021, 6:46 p.m. UTC | #12
> This patch below based on your tree could get the dynamic note on libc.so.
> It has to explicit add the dynamic-note.os as an extra object (adding an
> extra object on libc.so build will add on libc_pic.{a,os} and linker script
> won't handle).

Thanks. Would you like this enabled for the necessary libraries
only when ld isn't new enough, or enabled unconditionally?
Adhemerval Zanella Feb. 23, 2021, 6:48 p.m. UTC | #13
On 23/02/2021 15:46, Vivek Das Mohapatra wrote:
>> This patch below based on your tree could get the dynamic note on libc.so.
>> It has to explicit add the dynamic-note.os as an extra object (adding an
>> extra object on libc.so build will add on libc_pic.{a,os} and linker script
>> won't handle).
> 
> Thanks. Would you like this enabled for the necessary libraries
> only when ld isn't new enough, or enabled unconditionally?
> 

I think it would be simpler to just this scheme which is independently of
ld version instead of using -z,unique. We might clean this up once we
set the minimum binutils version to 2.36.
Florian Weimer Feb. 23, 2021, 7:01 p.m. UTC | #14
* Adhemerval Zanella via Libc-alpha:

> On 23/02/2021 15:46, Vivek Das Mohapatra wrote:
>>> This patch below based on your tree could get the dynamic note on libc.so.
>>> It has to explicit add the dynamic-note.os as an extra object (adding an
>>> extra object on libc.so build will add on libc_pic.{a,os} and linker script
>>> won't handle).
>> 
>> Thanks. Would you like this enabled for the necessary libraries
>> only when ld isn't new enough, or enabled unconditionally?
>> 
>
> I think it would be simpler to just this scheme which is independently of
> ld version instead of using -z,unique. We might clean this up once we
> set the minimum binutils version to 2.36.

The downside of this scheme is that the injected values come first,
which may confuse some consumers (although it should not).  Using the
binutils option generates a more regular-looking dynamic segment.

Thanks,
Florian
Adhemerval Zanella Feb. 23, 2021, 7:06 p.m. UTC | #15
On 23/02/2021 16:01, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> On 23/02/2021 15:46, Vivek Das Mohapatra wrote:
>>>> This patch below based on your tree could get the dynamic note on libc.so.
>>>> It has to explicit add the dynamic-note.os as an extra object (adding an
>>>> extra object on libc.so build will add on libc_pic.{a,os} and linker script
>>>> won't handle).
>>>
>>> Thanks. Would you like this enabled for the necessary libraries
>>> only when ld isn't new enough, or enabled unconditionally?
>>>
>>
>> I think it would be simpler to just this scheme which is independently of
>> ld version instead of using -z,unique. We might clean this up once we
>> set the minimum binutils version to 2.36.
> 
> The downside of this scheme is that the injected values come first,
> which may confuse some consumers (although it should not).  Using the
> binutils option generates a more regular-looking dynamic segment.
> 

My understanding is only the final NULL entry is really position
dependent in dynamic sections scheme.  Our internal parsing assumes
it, for instance on elf_get_dynamic_info; and I think it should be 
a fair assumption that all external usage takes this in consideration.
diff mbox series

Patch

diff --git a/Makeconfig b/Makeconfig
index 0a4811b5e5..d0e52f26fd 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -398,6 +398,7 @@  LDFLAGS-lib.so += -Wl,-z,now
 # Extra flags for dynamically linked non-test main programs.
 link-extra-flags += -Wl,-z,now
 endif
+LDFLAGS-lib.so += -Wl,-z,unique
 
 # Command to run after every final link (executable or shared object).
 # This is invoked with $(call after-link,...), so it should operate on
diff --git a/Makerules b/Makerules
index ca9885436e..82adffdc27 100644
--- a/Makerules
+++ b/Makerules
@@ -635,7 +635,7 @@  build-shlib-objlist = $(build-module-helper-objlist) \
 # Don't try to use -lc when making libc.so itself.
 # Also omits crti.o and crtn.o, which we do not want
 # since we define our own `.init' section specially.
-LDFLAGS-c.so = -nostdlib -nostartfiles
+LDFLAGS-c.so = -nostdlib -nostartfiles -Wl,-z,unique
 # But we still want to link libc.so against $(libc.so-gnulib).
 LDLIBS-c.so += $(libc.so-gnulib)
 # Give libc.so an entry point and make it directly runnable itself.
diff --git a/htl/Makefile b/htl/Makefile
index c15c1b194e..5d0d76d941 100644
--- a/htl/Makefile
+++ b/htl/Makefile
@@ -204,7 +204,7 @@  $(inst_libdir)/libpthread_syms.a: $(srcdir)/libpthread_syms.a $(+force)
 libc-link.so = $(common-objpfx)libc.so
 
 extra-B-pthread.so = -B$(common-objpfx)htl/
-LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
+LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,unique,-z,nodelete,-z,initfirst
 
 include ../Rules
 
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 55c527a5f7..ea5565eb40 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -67,6 +67,7 @@  modules	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
 ifeq ($(bind-now),yes)
 LDFLAGS.so += -Wl,-z,now
 endif
+LDFLAGS.so += -Wl,-z,unique
 
 modules.so := $(addsuffix .so, $(modules))
 
diff --git a/nptl/Makefile b/nptl/Makefile
index 8fb7fee6db..9090b88dec 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -349,7 +349,7 @@  else
 tests-printers-libs := $(static-thread-library)
 endif
 
-LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
+LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,unique,-z,nodelete,-z,initfirst
 
 tests += tst-cancelx7 tst-cancelx17 tst-cleanupx4