tls.h in particular is very unfinished. Signed-off-by: Sergey Bugaev <buga...@gmail.com> --- sysdeps/mach/hurd/x86_64/static-start.S | 27 +++ sysdeps/mach/hurd/x86_64/tls.h | 182 ++++++++++++++++++++ sysdeps/mach/hurd/x86_64/tlsdesc.sym | 22 +++ sysdeps/x86_64/htl/bits/pthreadtypes-arch.h | 36 ++++ sysdeps/x86_64/htl/machine-sp.h | 29 ++++ sysdeps/x86_64/htl/pt-machdep.h | 28 +++ 6 files changed, 324 insertions(+) create mode 100644 sysdeps/mach/hurd/x86_64/static-start.S create mode 100644 sysdeps/mach/hurd/x86_64/tls.h create mode 100644 sysdeps/mach/hurd/x86_64/tlsdesc.sym create mode 100644 sysdeps/x86_64/htl/bits/pthreadtypes-arch.h create mode 100644 sysdeps/x86_64/htl/machine-sp.h create mode 100644 sysdeps/x86_64/htl/pt-machdep.h
diff --git a/sysdeps/mach/hurd/x86_64/static-start.S b/sysdeps/mach/hurd/x86_64/static-start.S new file mode 100644 index 00000000..982d3d52 --- /dev/null +++ b/sysdeps/mach/hurd/x86_64/static-start.S @@ -0,0 +1,27 @@ +/* Startup code for statically linked Hurd/x86_64 binaries. + Copyright (C) 1998-2023 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + + .text + .globl _start +_start: + call _hurd_stack_setup + xorq %rdx, %rdx + jmp _start1 + +#define _start _start1 +#include <sysdeps/x86_64/start.S> diff --git a/sysdeps/mach/hurd/x86_64/tls.h b/sysdeps/mach/hurd/x86_64/tls.h new file mode 100644 index 00000000..027304d9 --- /dev/null +++ b/sysdeps/mach/hurd/x86_64/tls.h @@ -0,0 +1,182 @@ +/* Definitions for thread-local data handling. Hurd/x86_64 version. + Copyright (C) 2003-2023 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _X86_64_TLS_H +#define _X86_64_TLS_H + + +/* Some things really need not be machine-dependent. */ +#include <sysdeps/mach/hurd/tls.h> + + +#ifndef __ASSEMBLER__ +# include <dl-dtv.h> + +/* Type of the TCB. */ +typedef struct +{ + void *tcb; /* Points to this structure. */ + dtv_t *dtv; /* Vector of pointers to TLS data. */ + thread_t self; /* This thread's control port. */ + int __glibc_padding1; + int multiple_threads; + int gscope_flag; + uintptr_t sysinfo; + uintptr_t stack_guard; + uintptr_t pointer_guard; + long __glibc_padding2[2]; + int private_futex; + int __glibc_padding3; + /* Reservation of some values for the TM ABI. */ + void *__private_tm[4]; + /* GCC split stack support. */ + void *__private_ss; + /* The lowest address of shadow stack. */ + unsigned long long int ssp_base; + + /* Keep these fields last, so offsets of fields above can continue being + compatible with the x86_64 NPTL version. */ + mach_port_t reply_port; /* This thread's reply port. */ + struct hurd_sigstate *_hurd_sigstate; + + /* Used by the exception handling implementation in the dynamic loader. */ + struct rtld_catch *rtld_catch; +} tcbhead_t; + +/* GCC generates %fs:0x28 to access the stack guard. */ +_Static_assert (offsetof (tcbhead_t, stack_guard) == 0x28, + "stack guard offset"); +/* libgcc uses %fs:0x70 to access the split stack pointer. */ +_Static_assert (offsetof (tcbhead_t, __private_ss) == 0x70, + "split stack pointer offset"); + +/* FIXME */ +# define __LIBC_NO_TLS() 0 + +/* The TCB can have any size and the memory following the address the + thread pointer points to is unspecified. Allocate the TCB there. */ +# define TLS_TCB_AT_TP 1 +# define TLS_DTV_AT_TP 0 + +# define TCB_ALIGNMENT 64 + +# define TLS_INIT_TP(descr) 0 + +# if __GNUC_PREREQ (6, 0) + +# define THREAD_SELF \ + (*(tcbhead_t * __seg_fs *) offsetof (tcbhead_t, tcb)) +# define THREAD_GETMEM(descr, member) \ + (*(__typeof (descr->member) __seg_fs *) offsetof (tcbhead_t, member)) +# define THREAD_SETMEM(descr, member, value) \ + (*(__typeof (descr->member) __seg_fs *) offsetof (tcbhead_t, member) = value) + +# else + +# define THREAD_SELF \ + ({ tcbhead_t *__tcb; \ + asm ("movq %%fs:%c1,%0" : "=r" (__tcb) \ + : "i" (offsetof (tcbhead_t, tcb))); \ + __tcb; }) + +/* Read member of the thread descriptor directly. */ +# define THREAD_GETMEM(descr, member) \ + ({ __typeof (descr->member) __value; \ + _Static_assert (sizeof (__value) == 1 \ + || sizeof (__value) == 4 \ + || sizeof (__value) == 8, \ + "size of per-thread data"); \ + if (sizeof (__value) == 1) \ + asm volatile ("movb %%fs:%P2,%b0" \ + : "=q" (__value) \ + : "0" (0), "i" (offsetof (tcbhead_t, member))); \ + else if (sizeof (__value) == 4) \ + asm volatile ("movl %%fs:%P1,%0" \ + : "=r" (__value) \ + : "i" (offsetof (tcbhead_t, member))); \ + else /* 8 */ \ + asm volatile ("movq %%fs:%P1,%0" \ + : "=r" (__value) \ + : "i" (offsetof (tcbhead_t, member))); \ + __value; }) + +/* Write member of the thread descriptor directly. */ +# define THREAD_SETMEM(descr, member, value) \ + ({ \ + _Static_assert (sizeof (descr->member) == 1 \ + || sizeof (descr->member) == 4 \ + || sizeof (descr->member) == 8, \ + "size of per-thread data"); \ + if (sizeof (descr->member) == 1) \ + asm volatile ("movb %b0,%%fs:%P1" : \ + : "iq" (value), \ + "i" (offsetof (tcbhead_t, member))); \ + else if (sizeof (descr->member) == 4) \ + asm volatile ("movl %0,%%fs:%P1" : \ + : "ir" (value), \ + "i" (offsetof (tcbhead_t, member))); \ + else /* 8 */ \ + asm volatile ("movq %0,%%fs:%P1" : \ + : "ir" (value), \ + "i" (offsetof (tcbhead_t, member))); \ + }) +# endif /* __GNUC_PREREQ (6, 0) */ + +/* Set the stack guard field in TCB head. */ +# define THREAD_SET_STACK_GUARD(value) \ + THREAD_SETMEM (THREAD_SELF, stack_guard, value) +# define THREAD_COPY_STACK_GUARD(descr) \ + ((descr)->stack_guard \ + = THREAD_GETMEM (THREAD_SELF, stack_guard)) + +/* Set the pointer guard field in the TCB head. */ +# define THREAD_SET_POINTER_GUARD(value) \ + THREAD_SETMEM (THREAD_SELF, pointer_guard, value) +# define THREAD_COPY_POINTER_GUARD(descr) \ + ((descr)->pointer_guard \ + = THREAD_GETMEM (THREAD_SELF, pointer_guard)) + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(dtvp) THREAD_SETMEM (THREAD_SELF, dtv, dtvp) + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() THREAD_GETMEM (THREAD_SELF, dtv) + +/* Global scope switch support. */ +# define THREAD_GSCOPE_FLAG_UNUSED 0 +# define THREAD_GSCOPE_FLAG_USED 1 +# define THREAD_GSCOPE_FLAG_WAIT 2 + +# define THREAD_GSCOPE_SET_FLAG() \ + THREAD_SETMEM (THREAD_SELF, gscope_flag, THREAD_GSCOPE_FLAG_USED) + +# define THREAD_GSCOPE_RESET_FLAG() \ + ({ \ + int __flag; \ + asm volatile ("xchgl %0, %%fs:%P1" \ + : "=r" (__flag) \ + : "i" (offsetof (tcbhead_t, gscope_flag)), \ + "0" (THREAD_GSCOPE_FLAG_UNUSED)); \ + if (__flag == THREAD_GSCOPE_FLAG_WAIT) \ + lll_wake (THREAD_SELF->gscope_flag, LLL_PRIVATE); \ + }) + + + +#endif /* __ASSEMBLER__ */ +#endif /* x86_64/tls.h */ diff --git a/sysdeps/mach/hurd/x86_64/tlsdesc.sym b/sysdeps/mach/hurd/x86_64/tlsdesc.sym new file mode 100644 index 00000000..da3b96c1 --- /dev/null +++ b/sysdeps/mach/hurd/x86_64/tlsdesc.sym @@ -0,0 +1,22 @@ +#include <stddef.h> +#include <sysdep.h> +#include <tls.h> +#include <link.h> +#include <dl-tlsdesc.h> + +-- + +-- We have to override sysdeps/x86_64/tlsdesc.sym to adapt to our libpthread. + +-- Abuse tls.h macros to derive offsets relative to the thread register. + +DTV_OFFSET offsetof(tcbhead_t, dtv) + +TLSDESC_ARG offsetof(struct tlsdesc, arg) + +TLSDESC_GEN_COUNT offsetof(struct tlsdesc_dynamic_arg, gen_count) +TLSDESC_MODID offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module) +TLSDESC_MODOFF offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset) + +TI_MODULE_OFFSET offsetof(tls_index, ti_module) +TI_OFFSET_OFFSET offsetof(tls_index, ti_offset) diff --git a/sysdeps/x86_64/htl/bits/pthreadtypes-arch.h b/sysdeps/x86_64/htl/bits/pthreadtypes-arch.h new file mode 100644 index 00000000..c3ac991b --- /dev/null +++ b/sysdeps/x86_64/htl/bits/pthreadtypes-arch.h @@ -0,0 +1,36 @@ +/* Machine-specific pthread type layouts. Hurd x86_64 version. + Copyright (C) 2002-2023 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _BITS_PTHREADTYPES_ARCH_H +#define _BITS_PTHREADTYPES_ARCH_H 1 + +#define __SIZEOF_PTHREAD_MUTEX_T 32 +#define __SIZEOF_PTHREAD_ATTR_T 48 +#define __SIZEOF_PTHREAD_RWLOCK_T 48 +#define __SIZEOF_PTHREAD_BARRIER_T 40 +#define __SIZEOF_PTHREAD_MUTEXATTR_T 16 +#define __SIZEOF_PTHREAD_COND_T 40 +#define __SIZEOF_PTHREAD_CONDATTR_T 8 +#define __SIZEOF_PTHREAD_RWLOCKATTR_T 4 +#define __SIZEOF_PTHREAD_BARRIERATTR_T 4 +#define __SIZEOF_PTHREAD_ONCE_T 8 + +#define __LOCK_ALIGNMENT __attribute__ ((__aligned__(4))) +#define __ONCE_ALIGNMENT + +#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/x86_64/htl/machine-sp.h b/sysdeps/x86_64/htl/machine-sp.h new file mode 100644 index 00000000..7ae1c941 --- /dev/null +++ b/sysdeps/x86_64/htl/machine-sp.h @@ -0,0 +1,29 @@ +/* Machine-specific function to return the stack pointer. x86_64 version. + Copyright (C) 1994-2023 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _MACHINE_SP_H +#define _MACHINE_SP_H + +/* Return the current stack pointer. */ + +#define __thread_stack_pointer() ({ \ + register uintptr_t __sp__ asm("rsp"); \ + __sp__; \ +}) + +#endif /* machine-sp.h */ diff --git a/sysdeps/x86_64/htl/pt-machdep.h b/sysdeps/x86_64/htl/pt-machdep.h new file mode 100644 index 00000000..2e2846fa --- /dev/null +++ b/sysdeps/x86_64/htl/pt-machdep.h @@ -0,0 +1,28 @@ +/* Machine dependent pthreads internal defenitions. x86_64 version. + Copyright (C) 2000-2023 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _PT_MACHDEP_H +#define _PT_MACHDEP_H 1 + +struct pthread_mcontext +{ + void *pc; + void *sp; +}; + +#endif /* pt-machdep.h */ -- 2.39.1