[3/5,PowerPC] Relocate stinfo->main
Commit Message
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
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.
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.
@@ -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
@@ -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