[3/5,PowerPC] Relocate stinfo->main

Message ID Ye4iHPb/sTm517LH@squeak.grove.modra.org
State Superseded
Headers
Series [PowerPC64] Use medium model toc accesses throughout |

Commit Message

Alan Modra Jan. 24, 2022, 3:50 a.m. UTC
  The previous 2 patches got us to the point of segfaulting when trying
to transfer to main.

start_addresses in sysdeps/powerpc/powerpc64/start.S is historical
baggage that should disappear.  Until someone does that, relocating
stinfo->main by hand is one solution to the fact that the field may be
unrelocated at the time it is accessed.  This is similar to what is
done for dynamic tags via the D_PTR macro.  The makefile change is
needed to pick up elf/dl-static-tls.h from dl-machine.h.
  

Comments

H.J. Lu Jan. 24, 2022, 4:48 a.m. UTC | #1
On Sun, Jan 23, 2022 at 7:51 PM Alan Modra via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> The previous 2 patches got us to the point of segfaulting when trying
> to transfer to main.
>
> start_addresses in sysdeps/powerpc/powerpc64/start.S is historical
> baggage that should disappear.  Until someone does that, relocating
> stinfo->main by hand is one solution to the fact that the field may be
> unrelocated at the time it is accessed.  This is similar to what is
> done for dynamic tags via the D_PTR macro.  The makefile change is
> needed to pick up elf/dl-static-tls.h from dl-machine.h.
>
> diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
> index fc7c29c695..93783cae00 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/Makefile
> +++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
> @@ -27,3 +27,9 @@ tests += $(tests-static)
>  tests += test-gettimebasefreq
>  tests += test-powerpc-linux-sysconf
>  endif
> +
> +ifeq ($(subdir),csu)
> +# to relocate stinfo->main
> +CPPFLAGS-libc-start.o += -I../elf
> +CPPFLAGS-libc-start.op += -I../elf
> +endif
> diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
> index bb97d16145..8f0d3a0eac 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
> +++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
> @@ -23,6 +23,10 @@
>  #ifndef SHARED
>  #include <hwcapinfo.h>
>  #endif
> +#if ENABLE_STATIC_PIE && !defined SHARED
> +/* For elf_machine_load_address.  */
> +#include <dl-machine.h>
> +#endif
>
>  /* The main work is done in the generic function.  */
>  #define LIBC_START_MAIN generic_start_main
> @@ -95,8 +99,15 @@ __libc_start_main_impl (int argc, char **argv,
>    __tcb_parse_hwcap_and_convert_at_platform ();
>  #endif
>
> -  return generic_start_main (stinfo->main, argc, argv, auxvec,
> -                            stinfo->init, stinfo->fini, rtld_fini,
> +  void *main = stinfo->main;
> +#if ENABLE_STATIC_PIE && !defined SHARED
> +  struct link_map *map = _dl_get_dl_main_map ();
> +  if (!map->l_relocated)
> +    main = (char *) main + elf_machine_load_address ();
> +#endif

Can you use __ehdr_start t here, similar to

https://gitlab.com/x86-glibc/glibc/-/commit/1df93c500d0f81d30d1b7e323153512a8768bb72#ffb950808032d5085fdf882753d7bf8889e6a3d7


> +  return generic_start_main (main, argc, argv, auxvec,
> +                            NULL, NULL, rtld_fini,
>                              stack_on_entry);
>  }
>  DEFINE_LIBC_START_MAIN_VERSION
>
> --
> Alan Modra
> Australia Development Lab, IBM



--
H.J.
  
Alan Modra Jan. 24, 2022, 6:51 a.m. UTC | #2
On Sun, Jan 23, 2022 at 08:48:44PM -0800, H.J. Lu wrote:
> On Sun, Jan 23, 2022 at 7:51 PM Alan Modra via Libc-alpha
> > +  void *main = stinfo->main;
> > +#if ENABLE_STATIC_PIE && !defined SHARED
> > +  struct link_map *map = _dl_get_dl_main_map ();
> > +  if (!map->l_relocated)
> > +    main = (char *) main + elf_machine_load_address ();
> > +#endif
> 
> Can you use __ehdr_start t here, similar to
> 
> https://gitlab.com/x86-glibc/glibc/-/commit/1df93c500d0f81d30d1b7e323153512a8768bb72#ffb950808032d5085fdf882753d7bf8889e6a3d7

That idea hadn't occurred to me.  Yes, that likely would have worked
too.  I used the old traditional way of calculating l_addr, which
happens to be quite cheap on powerpc64, but admittedly not so good on
powerpc32.
  

Patch

diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index fc7c29c695..93783cae00 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -27,3 +27,9 @@  tests += $(tests-static)
 tests += test-gettimebasefreq
 tests += test-powerpc-linux-sysconf
 endif
+
+ifeq ($(subdir),csu)
+# to relocate stinfo->main
+CPPFLAGS-libc-start.o += -I../elf
+CPPFLAGS-libc-start.op += -I../elf
+endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
index bb97d16145..8f0d3a0eac 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
@@ -23,6 +23,10 @@ 
 #ifndef SHARED
 #include <hwcapinfo.h>
 #endif
+#if ENABLE_STATIC_PIE && !defined SHARED
+/* For elf_machine_load_address.  */
+#include <dl-machine.h>
+#endif
 
 /* The main work is done in the generic function.  */
 #define LIBC_START_MAIN generic_start_main
@@ -95,8 +99,15 @@  __libc_start_main_impl (int argc, char **argv,
   __tcb_parse_hwcap_and_convert_at_platform ();
 #endif
 
-  return generic_start_main (stinfo->main, argc, argv, auxvec,
-			     stinfo->init, stinfo->fini, rtld_fini,
+  void *main = stinfo->main;
+#if ENABLE_STATIC_PIE && !defined SHARED
+  struct link_map *map = _dl_get_dl_main_map ();
+  if (!map->l_relocated)
+    main = (char *) main + elf_machine_load_address ();
+#endif
+
+  return generic_start_main (main, argc, argv, auxvec,
+			     NULL, NULL, rtld_fini,
 			     stack_on_entry);
 }
 DEFINE_LIBC_START_MAIN_VERSION