diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-11-11 10:35:10 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-11-11 20:41:25 +0000 |
commit | 9cec82de715b3ffc625a6c67d107a3fcb26af566 (patch) | |
tree | e66429ab410d9ef1510ac702a39ec439e956742f /sysdeps | |
parent | d482ebfa67850976485fdf061cd52427eb8a3cb7 (diff) | |
download | glibc-9cec82de715b3ffc625a6c67d107a3fcb26af566.tar.gz |
htl: Initialize later
Since htl does not actually need a stack switch, we can initialize it
like nptl is, avoiding all sorts of startup issues with ifunc.
More precisely, htl defines __pthread_initialize_minimal instead of the
elder _cthread_init_routine. We can then drop the stack switching dances.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/mach/hurd/htl/pt-sysdep.c | 19 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/init-first.c | 106 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/libc.abilist | 1 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/libpthread.abilist | 1 | ||||
-rw-r--r-- | sysdeps/mach/i386/sysdep.h | 10 | ||||
-rw-r--r-- | sysdeps/mach/sysdep.h | 8 |
6 files changed, 29 insertions, 116 deletions
diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.c b/sysdeps/mach/hurd/htl/pt-sysdep.c index 0963b44878..8ca549dd73 100644 --- a/sysdeps/mach/hurd/htl/pt-sysdep.c +++ b/sysdeps/mach/hurd/htl/pt-sysdep.c @@ -28,13 +28,6 @@ __thread struct __pthread *___pthread_self; -/* Forward. */ -static void *init_routine (void); - -/* OK, the name of this variable isn't really appropriate, but I don't - want to change it yet. */ -void *(*_cthread_init_routine) (void) = &init_routine; - static void reset_pthread_total (void) { @@ -45,7 +38,7 @@ reset_pthread_total (void) /* This function is called from the Hurd-specific startup code. It should return a new stack pointer for the main thread. The caller will switch to this new stack before doing anything serious. */ -static void * +static void _init_routine (void *stack) { struct __pthread *thread; @@ -54,7 +47,7 @@ _init_routine (void *stack) if (__pthread_threads != NULL) /* Already initialized */ - return 0; + return; /* Initialize the library. */ ___pthread_init (); @@ -96,14 +89,12 @@ _init_routine (void *stack) /* Make MiG code thread aware. */ __mig_init (thread->stackaddr); - - return thread->mcontext.sp; } -static void * -init_routine (void) +void +__pthread_initialize_minimal (void) { - return _init_routine (0); + _init_routine (__libc_stack_end); } #ifdef SHARED diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c index 5e66602d4b..6c35dc8104 100644 --- a/sysdeps/mach/hurd/i386/init-first.c +++ b/sysdeps/mach/hurd/i386/init-first.c @@ -46,9 +46,6 @@ extern int __libc_argc attribute_hidden; extern char **__libc_argv attribute_hidden; extern char **_dl_argv; -extern void *(*_cthread_init_routine) (void) __attribute__ ((weak)); -void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__)); - /* Things that want to be run before _hurd_init or much anything else. Importantly, these are called before anything tries to use malloc. */ DEFINE_HOOK (_hurd_preinit_hook, (void)); @@ -96,10 +93,6 @@ init1 (int argc, char *arg0, ...) ++envp; d = (void *) ++envp; - /* Initialize libpthread if linked in. */ - if (__pthread_initialize_minimal != NULL) - __pthread_initialize_minimal (); - if ((void *) d == argv[0]) /* No Hurd data block to process. */ return; @@ -145,7 +138,6 @@ init (int *data) int argc = *data; char **argv = (void *) (data + 1); char **envp = &argv[argc + 1]; - struct hurd_startup_data *d; /* Since the cthreads initialization code uses malloc, and the malloc initialization code needs to get at the environment, make @@ -154,11 +146,13 @@ init (int *data) stored. */ __environ = envp; +#ifndef SHARED + struct hurd_startup_data *d; + while (*envp) ++envp; d = (void *) ++envp; -#ifndef SHARED /* If we are the bootstrap task started by the kernel, then after the environment pointers there is no Hurd data block; the argument strings start there. */ @@ -190,79 +184,27 @@ init (int *data) __libc_setup_tls (); #endif - /* After possibly switching stacks, call `init1' (above) with the user - code as the return address, and the argument data immediately above - that on the stack. */ - - if (&_cthread_init_routine && _cthread_init_routine) - { - /* Initialize cthreads, which will allocate us a new stack to run on. */ - int *newsp = (*_cthread_init_routine) (); - struct hurd_startup_data *od; - - void switch_stacks (void); - - __libc_stack_end = newsp; - - /* Copy the argdata from the old stack to the new one. */ - newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data, - (char *) d - (char *) data); - -#ifdef SHARED - /* And readjust the dynamic linker's idea of where the argument - vector lives. */ - assert (_dl_argv == argv); - _dl_argv = (void *) (newsp + 1); -#endif - - /* Set up the Hurd startup data block immediately following - the argument and environment pointers on the new stack. */ - od = ((void *) newsp + ((char *) d - (char *) data)); - if ((void *) argv[0] == d) - /* We were started up by the kernel with arguments on the stack. - There is no Hurd startup data, so zero the block. */ - memset (od, 0, sizeof *od); - else - /* Copy the Hurd startup data block to the new stack. */ - *od = *d; - - /* Push the user code address on the top of the new stack. It will - be the return address for `init1'; we will jump there with NEWSP - as the stack pointer. */ - /* The following expression would typically be written as - ``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't - recognize that this read operation may alias the following write - operation, and thus is free to reorder the two, clobbering the - original return address. */ - *--newsp = *((int *) __builtin_frame_address (0) + 1); - /* GCC 4.4.6 also wants us to force loading *NEWSP already here. */ - asm volatile ("# %0" : : "X" (*newsp)); - *((void **) __builtin_frame_address (0) + 1) = &switch_stacks; - /* Force NEWSP into %eax and &init1 into %ecx, which are not restored - by function return. */ - asm volatile ("# a %0 c %1" : : "a" (newsp), "c" (&init1)); - } - else - { - int usercode; - - void call_init1 (void); - - /* The argument data is just above the stack frame we will unwind by - returning. Mutate our own return address to run the code below. */ - /* The following expression would typically be written as - ``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't - recognize that this read operation may alias the following write - operation, and thus is free to reorder the two, clobbering the - original return address. */ - usercode = *((int *) __builtin_frame_address (0) + 1); - /* GCC 4.4.6 also wants us to force loading USERCODE already here. */ - asm volatile ("# %0" : : "X" (usercode)); - *((void **) __builtin_frame_address (0) + 1) = &call_init1; - /* Force USERCODE into %eax and &init1 into %ecx, which are not - restored by function return. */ - asm volatile ("# a %0 c %1" : : "a" (usercode), "c" (&init1)); - } + /* Call `init1' (above) with the user code as the return address, and the + argument data immediately above that on the stack. */ + + int usercode; + + void call_init1 (void); + + /* The argument data is just above the stack frame we will unwind by + returning. Mutate our own return address to run the code below. */ + /* The following expression would typically be written as + ``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't + recognize that this read operation may alias the following write + operation, and thus is free to reorder the two, clobbering the + original return address. */ + usercode = *((int *) __builtin_frame_address (0) + 1); + /* GCC 4.4.6 also wants us to force loading USERCODE already here. */ + asm volatile ("# %0" : : "X" (usercode)); + *((void **) __builtin_frame_address (0) + 1) = &call_init1; + /* Force USERCODE into %eax and &init1 into %ecx, which are not + restored by function return. */ + asm volatile ("# a %0 c %1" : : "a" (usercode), "c" (&init1)); DIAG_POP_NEEDS_COMMENT; /* -Warray-bounds. */ } diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index e2ff0e8b9e..7a5eb66b85 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2333,4 +2333,3 @@ HURD_CTHREADS_0.3 __spin_lock_init F HURD_CTHREADS_0.3 __spin_lock_solid F HURD_CTHREADS_0.3 __spin_try_lock F HURD_CTHREADS_0.3 __spin_unlock F -HURD_CTHREADS_0.3 _cthread_exit_routine D 0x4 diff --git a/sysdeps/mach/hurd/i386/libpthread.abilist b/sysdeps/mach/hurd/i386/libpthread.abilist index a1e0a7183b..b9c9b75c28 100644 --- a/sysdeps/mach/hurd/i386/libpthread.abilist +++ b/sysdeps/mach/hurd/i386/libpthread.abilist @@ -10,7 +10,6 @@ GLIBC_2.12 __pthread_spin_init F GLIBC_2.12 __pthread_spin_lock F GLIBC_2.12 __pthread_spin_trylock F GLIBC_2.12 __pthread_spin_unlock F -GLIBC_2.12 _cthread_init_routine D 0x4 GLIBC_2.12 _cthreads_flockfile F GLIBC_2.12 _cthreads_ftrylockfile F GLIBC_2.12 _cthreads_funlockfile F diff --git a/sysdeps/mach/i386/sysdep.h b/sysdeps/mach/i386/sysdep.h index e849f120f9..c132b3a4c3 100644 --- a/sysdeps/mach/i386/sysdep.h +++ b/sysdeps/mach/i386/sysdep.h @@ -39,16 +39,6 @@ envp = p; \ } while (0) -#define CALL_WITH_SP(fn, info, sp) \ - do { \ - void **ptr = (void **) sp; \ - *--(__typeof (info) *) ptr = info; \ - ptr[-1] = ptr; \ - --ptr; \ - asm volatile ("movl %0, %%esp; call %1" : : \ - "g" (ptr), "m" (*(long int *) (fn)) : "%esp"); \ - } while (0) - #define RETURN_TO(sp, pc, retval) \ asm volatile ("movl %0, %%esp; jmp %*%1 # %2" \ : : "g" (sp), "r" (pc), "a" (retval)) diff --git a/sysdeps/mach/sysdep.h b/sysdeps/mach/sysdep.h index ba65015253..13ea04d980 100644 --- a/sysdeps/mach/sysdep.h +++ b/sysdeps/mach/sysdep.h @@ -62,14 +62,6 @@ #error SNARF_ARGS not defined by sysdeps/mach/MACHINE/sysdep.h #endif -/* Call the C function FN with no arguments, - on a stack starting at SP (as returned by *_cthread_init_routine). - You don't need to deal with FN returning; it shouldn't. */ -#ifndef CALL_WITH_SP -#define CALL_WITH_SP(fn, sp) -#error CALL_WITH_SP not defined by sysdeps/mach/MACHINE/sysdep.h -#endif - /* LOSE can be defined as the `halt' instruction or something similar which will cause the process to die in a characteristic way suggesting a bug. */ |