diff options
Diffstat (limited to 'sysdeps/mach/hurd/i386')
-rw-r--r-- | sysdeps/mach/hurd/i386/Implies | 1 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/htl/Implies | 2 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/htl/pt-machdep.c | 82 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/htl/pt-setup.c | 110 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/libpthread.abilist | 151 |
5 files changed, 346 insertions, 0 deletions
diff --git a/sysdeps/mach/hurd/i386/Implies b/sysdeps/mach/hurd/i386/Implies index 94db5e92ef..eedc9eada9 100644 --- a/sysdeps/mach/hurd/i386/Implies +++ b/sysdeps/mach/hurd/i386/Implies @@ -1 +1,2 @@ mach/hurd/x86 +mach/hurd/i386/htl diff --git a/sysdeps/mach/hurd/i386/htl/Implies b/sysdeps/mach/hurd/i386/htl/Implies new file mode 100644 index 0000000000..7a0f99d772 --- /dev/null +++ b/sysdeps/mach/hurd/i386/htl/Implies @@ -0,0 +1,2 @@ +mach/hurd/htl +i386/htl diff --git a/sysdeps/mach/hurd/i386/htl/pt-machdep.c b/sysdeps/mach/hurd/i386/htl/pt-machdep.c new file mode 100644 index 0000000000..9b2083d2da --- /dev/null +++ b/sysdeps/mach/hurd/i386/htl/pt-machdep.c @@ -0,0 +1,82 @@ +/* Machine dependent pthreads code. Hurd/i386 version. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <errno.h> + +#include <mach.h> +#include <mach/i386/thread_status.h> +#include <mach/i386/mach_i386.h> +#include <mach/mig_errors.h> +#include <mach/thread_status.h> + +#define HURD_TLS_DESC_DECL(desc, tcb) \ + struct descriptor desc = \ + { /* low word: */ \ + 0xffff /* limit 0..15 */ \ + | (((unsigned int) (tcb)) << 16) /* base 0..15 */ \ + , /* high word: */ \ + ((((unsigned int) (tcb)) >> 16) & 0xff) /* base 16..23 */ \ + | ((0x12 | 0x60 | 0x80) << 8) /* access = ACC_DATA_W|ACC_PL_U|ACC_P */ \ + | (0xf << 16) /* limit 16..19 */ \ + | ((4 | 8) << 20) /* granularity = SZ_32|SZ_G */ \ + | (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */ \ + } + +int +__thread_set_pcsptp (thread_t thread, + int set_ip, void *ip, + int set_sp, void *sp, + int set_tp, void *tp) +{ + error_t err; + struct i386_thread_state state; + mach_msg_type_number_t state_count; + + state_count = i386_THREAD_STATE_COUNT; + + err = __thread_get_state (thread, i386_REGS_SEGS_STATE, + (thread_state_t) &state, &state_count); + if (err) + return err; + + if (set_sp) + state.uesp = (unsigned int) sp; + if (set_ip) + state.eip = (unsigned int) ip; + if (set_tp) + { + HURD_TLS_DESC_DECL (desc, tp); + int sel; + + asm ("mov %%gs, %w0": "=q" (sel):"0" (0)); + if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */ + err = __i386_set_ldt (thread, sel, &desc, 1); + else + err = __i386_set_gdt (thread, &sel, desc); + if (err) + return err; + state.gs = sel; + } + + err = __thread_set_state (thread, i386_REGS_SEGS_STATE, + (thread_state_t) &state, i386_THREAD_STATE_COUNT); + if (err) + return err; + + return 0; +} diff --git a/sysdeps/mach/hurd/i386/htl/pt-setup.c b/sysdeps/mach/hurd/i386/htl/pt-setup.c new file mode 100644 index 0000000000..a59f71b7be --- /dev/null +++ b/sysdeps/mach/hurd/i386/htl/pt-setup.c @@ -0,0 +1,110 @@ +/* Setup thread stack. Hurd/i386 version. + Copyright (C) 2000-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <stdint.h> +#include <assert.h> +#include <mach.h> + +#include <pt-internal.h> + +/* The stack layout used on the i386 is: + + ----------------- + | ARG | + ----------------- + | START_ROUTINE | + ----------------- + | 0 | + ----------------- + */ + +/* Set up the stack for THREAD, such that it appears as if + START_ROUTINE and ARG were passed to the new thread's entry-point. + Return the stack pointer for the new thread. */ +static void * +stack_setup (struct __pthread *thread, + void *(*start_routine) (void *), void *arg) +{ + error_t err; + uintptr_t *bottom, *top; + + /* Calculate the top of the new stack. */ + bottom = thread->stackaddr; + top = (uintptr_t *) ((uintptr_t) bottom + thread->stacksize + + ((thread->guardsize + __vm_page_size - 1) + / __vm_page_size) * __vm_page_size); + + if (start_routine != NULL) + { + /* And then the call frame. */ + top -= 3; + top = (uintptr_t *) ((uintptr_t) top & ~0xf); + top[2] = (uintptr_t) arg; /* Argument to START_ROUTINE. */ + top[1] = (uintptr_t) start_routine; + top[0] = (uintptr_t) thread; + *--top = 0; /* Fake return address. */ + } + + if (thread->guardsize) + { + err = __vm_protect (__mach_task_self (), (vm_address_t) bottom, + thread->guardsize, 0, 0); + assert_perror (err); + } + + return top; +} + +int +__pthread_setup (struct __pthread *thread, + void (*entry_point) (struct __pthread *, void *(*)(void *), + void *), void *(*start_routine) (void *), + void *arg) +{ + tcbhead_t *tcb; + error_t err; + mach_port_t ktid; + + thread->mcontext.pc = entry_point; + thread->mcontext.sp = stack_setup (thread, start_routine, arg); + + ktid = __mach_thread_self (); + if (thread->kernel_thread == ktid) + /* Fix up the TCB for the main thread. The C library has already + installed a TCB, which we want to keep using. This TCB must not + be freed so don't register it in the thread structure. On the + other hand, it's not yet possible to reliably release a TCB. + Leave the unused one registered so that it doesn't leak. The + only thing left to do is to correctly set the `self' member in + the already existing TCB. */ + tcb = THREAD_SELF; + else + { + err = __thread_set_pcsptp (thread->kernel_thread, + 1, thread->mcontext.pc, + 1, thread->mcontext.sp, + 1, thread->tcb); + assert_perror (err); + tcb = thread->tcb; + } + __mach_port_deallocate (__mach_task_self (), ktid); + + tcb->self = thread->kernel_thread; + + return 0; +} diff --git a/sysdeps/mach/hurd/i386/libpthread.abilist b/sysdeps/mach/hurd/i386/libpthread.abilist new file mode 100644 index 0000000000..e11569f176 --- /dev/null +++ b/sysdeps/mach/hurd/i386/libpthread.abilist @@ -0,0 +1,151 @@ +GLIBC_2.12 GLIBC_2.12 A +GLIBC_2.12 __mutex_lock_solid F +GLIBC_2.12 __mutex_unlock_solid F +GLIBC_2.12 __pthread_get_cleanup_stack F +GLIBC_2.12 __pthread_key_create F +GLIBC_2.12 __pthread_kill F +GLIBC_2.12 __pthread_mutex_transfer_np F +GLIBC_2.12 __pthread_spin_destroy F +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 +GLIBC_2.12 _pthread_mutex_destroy F +GLIBC_2.12 _pthread_mutex_init F +GLIBC_2.12 _pthread_mutex_lock F +GLIBC_2.12 _pthread_mutex_trylock F +GLIBC_2.12 _pthread_mutex_unlock F +GLIBC_2.12 _pthread_rwlock_destroy F +GLIBC_2.12 _pthread_rwlock_init F +GLIBC_2.12 _pthread_spin_lock F +GLIBC_2.12 cthread_detach F +GLIBC_2.12 cthread_fork F +GLIBC_2.12 cthread_getspecific F +GLIBC_2.12 cthread_keycreate F +GLIBC_2.12 cthread_setspecific F +GLIBC_2.12 flockfile F +GLIBC_2.12 ftrylockfile F +GLIBC_2.12 funlockfile F +GLIBC_2.12 pthread_atfork F +GLIBC_2.12 pthread_attr_destroy F +GLIBC_2.12 pthread_attr_getdetachstate F +GLIBC_2.12 pthread_attr_getguardsize F +GLIBC_2.12 pthread_attr_getinheritsched F +GLIBC_2.12 pthread_attr_getschedparam F +GLIBC_2.12 pthread_attr_getschedpolicy F +GLIBC_2.12 pthread_attr_getscope F +GLIBC_2.12 pthread_attr_getstack F +GLIBC_2.12 pthread_attr_getstackaddr F +GLIBC_2.12 pthread_attr_getstacksize F +GLIBC_2.12 pthread_attr_init F +GLIBC_2.12 pthread_attr_setdetachstate F +GLIBC_2.12 pthread_attr_setguardsize F +GLIBC_2.12 pthread_attr_setinheritsched F +GLIBC_2.12 pthread_attr_setschedparam F +GLIBC_2.12 pthread_attr_setschedpolicy F +GLIBC_2.12 pthread_attr_setscope F +GLIBC_2.12 pthread_attr_setstack F +GLIBC_2.12 pthread_attr_setstackaddr F +GLIBC_2.12 pthread_attr_setstacksize F +GLIBC_2.12 pthread_barrier_destroy F +GLIBC_2.12 pthread_barrier_init F +GLIBC_2.12 pthread_barrier_wait F +GLIBC_2.12 pthread_barrierattr_destroy F +GLIBC_2.12 pthread_barrierattr_getpshared F +GLIBC_2.12 pthread_barrierattr_init F +GLIBC_2.12 pthread_barrierattr_setpshared F +GLIBC_2.12 pthread_cancel F +GLIBC_2.12 pthread_cond_broadcast F +GLIBC_2.12 pthread_cond_destroy F +GLIBC_2.12 pthread_cond_init F +GLIBC_2.12 pthread_cond_signal F +GLIBC_2.12 pthread_cond_timedwait F +GLIBC_2.12 pthread_cond_wait F +GLIBC_2.12 pthread_condattr_destroy F +GLIBC_2.12 pthread_condattr_getclock F +GLIBC_2.12 pthread_condattr_getpshared F +GLIBC_2.12 pthread_condattr_init F +GLIBC_2.12 pthread_condattr_setclock F +GLIBC_2.12 pthread_condattr_setpshared F +GLIBC_2.12 pthread_create F +GLIBC_2.12 pthread_detach F +GLIBC_2.12 pthread_equal F +GLIBC_2.12 pthread_exit F +GLIBC_2.12 pthread_getattr_np F +GLIBC_2.12 pthread_getconcurrency F +GLIBC_2.12 pthread_getcpuclockid F +GLIBC_2.12 pthread_getschedparam F +GLIBC_2.12 pthread_getspecific F +GLIBC_2.12 pthread_join F +GLIBC_2.12 pthread_key_create F +GLIBC_2.12 pthread_key_delete F +GLIBC_2.12 pthread_kill F +GLIBC_2.12 pthread_mutex_destroy F +GLIBC_2.12 pthread_mutex_getprioceiling F +GLIBC_2.12 pthread_mutex_init F +GLIBC_2.12 pthread_mutex_lock F +GLIBC_2.12 pthread_mutex_setprioceiling F +GLIBC_2.12 pthread_mutex_timedlock F +GLIBC_2.12 pthread_mutex_transfer_np F +GLIBC_2.12 pthread_mutex_trylock F +GLIBC_2.12 pthread_mutex_unlock F +GLIBC_2.12 pthread_mutexattr_destroy F +GLIBC_2.12 pthread_mutexattr_getprioceiling F +GLIBC_2.12 pthread_mutexattr_getprotocol F +GLIBC_2.12 pthread_mutexattr_getpshared F +GLIBC_2.12 pthread_mutexattr_gettype F +GLIBC_2.12 pthread_mutexattr_init F +GLIBC_2.12 pthread_mutexattr_setprioceiling F +GLIBC_2.12 pthread_mutexattr_setprotocol F +GLIBC_2.12 pthread_mutexattr_setpshared F +GLIBC_2.12 pthread_mutexattr_settype F +GLIBC_2.12 pthread_once F +GLIBC_2.12 pthread_rwlock_destroy F +GLIBC_2.12 pthread_rwlock_init F +GLIBC_2.12 pthread_rwlock_rdlock F +GLIBC_2.12 pthread_rwlock_timedrdlock F +GLIBC_2.12 pthread_rwlock_timedwrlock F +GLIBC_2.12 pthread_rwlock_tryrdlock F +GLIBC_2.12 pthread_rwlock_trywrlock F +GLIBC_2.12 pthread_rwlock_unlock F +GLIBC_2.12 pthread_rwlock_wrlock F +GLIBC_2.12 pthread_rwlockattr_destroy F +GLIBC_2.12 pthread_rwlockattr_getpshared F +GLIBC_2.12 pthread_rwlockattr_init F +GLIBC_2.12 pthread_rwlockattr_setpshared F +GLIBC_2.12 pthread_self F +GLIBC_2.12 pthread_setcancelstate F +GLIBC_2.12 pthread_setcanceltype F +GLIBC_2.12 pthread_setconcurrency F +GLIBC_2.12 pthread_setschedparam F +GLIBC_2.12 pthread_setschedprio F +GLIBC_2.12 pthread_setspecific F +GLIBC_2.12 pthread_sigmask F +GLIBC_2.12 pthread_spin_destroy F +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 pthread_testcancel F +GLIBC_2.12 pthread_yield F +GLIBC_2.12 sem_close F +GLIBC_2.12 sem_destroy F +GLIBC_2.12 sem_getvalue F +GLIBC_2.12 sem_init F +GLIBC_2.12 sem_open F +GLIBC_2.12 sem_post F +GLIBC_2.12 sem_timedwait F +GLIBC_2.12 sem_trywait F +GLIBC_2.12 sem_unlink F +GLIBC_2.12 sem_wait F +GLIBC_2.2.6 GLIBC_2.2.6 A +GLIBC_2.2.6 _IO_flockfile F +GLIBC_2.2.6 _IO_ftrylockfile F +GLIBC_2.2.6 _IO_funlockfile F +GLIBC_2.21 GLIBC_2.21 A +GLIBC_2.21 pthread_hurd_cond_timedwait_np F +GLIBC_2.21 pthread_hurd_cond_wait_np F |