[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Update on the glibc segfault issue on Alpha

Hi Adhemerval!

On 1/3/23 13:09, Adhemerval Zanella Netto wrote:
Thanks, this commits helps narrow down the issue.  The 73fc4e28b9464f0e refactor did not
add the GL(dl_phdr) and GL(dl_phnum) for static case, relying on the __ehdr_start symbol
to get the correct values.

The issue is for some archs, alpha for instance, the hidden weak reference is not making
the static linker to define the __ehdr_start address correctly: it is being set to 0 and
thus GL(dl_phdr) and GL(dl_phnum) are set to invalid values.

And I am not sure if the hidden weak __ehdr_start does work on all architectures, so I
think it would be safer to just restore the previous behavior to setup GL(dl_phdr) and
GL(dl_phnum) for static and we can simplify __ehdr_start fallback case to not use
a weak ref (as for PIE). I am checking if the following patch trigger any regression,
at least for alpha it fixes the static failures:

diff --git a/csu/libc-start.c b/csu/libc-start.c
index 543560f36c..63a3eceaea 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -271,18 +271,10 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
           So we can set up _dl_phdr and _dl_phnum even without any
           information from auxv.  */

-      extern const ElfW(Ehdr) __ehdr_start
-       __attribute__ ((visibility ("hidden")));
-# else
-       __attribute__ ((weak, visibility ("hidden")));
-      if (&__ehdr_start != NULL)
-# endif
-        {
-          assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr));
-          GL(dl_phdr) = (const void *) &__ehdr_start + __ehdr_start.e_phoff;
-          GL(dl_phnum) = __ehdr_start.e_phnum;
-        }
+      extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+      assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr));
+      GL(dl_phdr) = (const void *) &__ehdr_start + __ehdr_start.e_phoff;
+      GL(dl_phnum) = __ehdr_start.e_phnum;

    __tunables_init (__environ);
diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h
index bf9374371e..5913c9d6e5 100644
--- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h
+++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h
@@ -56,6 +56,10 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values)
    if (GLRO(dl_sysinfo_dso) != NULL)
      GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO];
+#ifndef SHARED
+  GL(dl_phdr) = (void*) auxv_values[AT_PHDR];
+  GL(dl_phnum) = auxv_values[AT_PHENT];


I can confirm that this patch fixes the problem for me. I have uploaded a manually built glibc
package with the patch applied to Debian »unreleased« so that the buildds can resume building
packages again.

Would it be possible to backport this patch to 2.36 once it has been merged with the current
development tree? The reason is that I don't think that Debian is going to switch to anything
beyond 2.36 anytime soon due to the upcoming feature freeze in January.


 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

Reply to: