From patchwork Tue Feb 21 21:19:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 65429 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9506D385E443 for ; Tue, 21 Feb 2023 21:20:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9506D385E443 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677014405; bh=t+D6XXRVLTk9iV8AbFdaXoZeS/oOiWhFu4UUaGefAkg=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=WsULNGKfjiQhMrXpldl5rQaLV71HpfVuh9nBmXj0bTh0Dyub6yKnoz0jqrniaWHBx xvPO7Om3nT0qpDE2yMqFHq0DfBgSEaHP1Toh4Cnj/OEySU3Oob5G03/swbp4TRILjO G1SRFOCuAyOMe7aWVDw2NfvVtM7f+nAlLfkSxT0I= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lf1-x131.google.com (mail-lf1-x131.google.com [IPv6:2a00:1450:4864:20::131]) by sourceware.org (Postfix) with ESMTPS id C0B953858D37 for ; Tue, 21 Feb 2023 21:19:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C0B953858D37 Received: by mail-lf1-x131.google.com with SMTP id s20so7174160lfb.11 for ; Tue, 21 Feb 2023 13:19:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=t+D6XXRVLTk9iV8AbFdaXoZeS/oOiWhFu4UUaGefAkg=; b=z8yVVvQ5JpVs5hRGUVYB4DPJQ32ltv8IdpdbZxAa8VyBS5BAUkAgQ4gvGcTvT7wv7g tuM/fnhEVnSACSdUptQQiOSTNhUp3lqPNNRCJ/OBieuUL4ZO6fna8O0Y/Zfcv9/1Dw49 tICwN2KNR4lRzg2kyvWojCOUZY4WA8g+Rq0IJaG3Ykjgb1ujF2JcHnROQlqvFGvzR+iR cr1lDnk331cplYCejiM3TwA9wsewpUv3+786AWGJcUI5d6TnJ2aEjxfkMP3mdrJq0CFj Q9HEbUiOtRzP9ezsh+cDz9MUcPta9vILtRYLAzRWd4CenEkCo691Zqf4p4Swijkl76To gzfA== X-Gm-Message-State: AO0yUKUaoQ3OICsRh7qZOcr3b4NKxLProan0WsdVyPL1j/2ImABRi4sT QQjrD87xAlSdpuAL7fBdEfmSPoeUINc37Lif X-Google-Smtp-Source: AK7set/jyu6ylV5AwF2ZMHQI8mLYvhthy0N6294VL5eQdWEd1Gva9lAibl/NTb7EVcpdiKmSdTwHhQ== X-Received: by 2002:ac2:43ab:0:b0:4d8:6577:d2bf with SMTP id t11-20020ac243ab000000b004d86577d2bfmr2111218lfl.37.1677014377751; Tue, 21 Feb 2023 13:19:37 -0800 (PST) Received: from surface-pro-6.. ([2a00:1370:818c:4a57:d7b6:7913:7a86:3102]) by smtp.gmail.com with ESMTPSA id m17-20020a195211000000b00498f77cfa63sm1949097lfb.280.2023.02.21.13.19.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 13:19:37 -0800 (PST) To: bug-hurd@gnu.org, libc-alpha@sourceware.org Cc: =?utf-8?q?Fl=C3=A1vio_Cruz?= , Noah Goldstein , Samuel Thibault , Sergey Bugaev Subject: [PATCH v2 1/4] hurd: Simplify init-first.c further Date: Wed, 22 Feb 2023 00:19:29 +0300 Message-Id: <20230221211932.296459-2-bugaevc@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230221211932.296459-1-bugaevc@gmail.com> References: <20230221211932.296459-1-bugaevc@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sergey Bugaev via Libc-alpha From: Sergey Bugaev Reply-To: Sergey Bugaev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This drops all of the return address rewriting kludges. The only remaining hack is the jump out of a call stack while adjusting the stack pointer. Signed-off-by: Sergey Bugaev --- sysdeps/mach/hurd/dl-sysdep.c | 5 +- sysdeps/mach/hurd/i386/dl-machine.h | 7 - sysdeps/mach/hurd/i386/init-first.c | 200 ++++++++++------------------ 3 files changed, 75 insertions(+), 137 deletions(-) delete mode 100644 sysdeps/mach/hurd/i386/dl-machine.h diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index 9e591708..18b35ddb 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -207,6 +207,9 @@ _dl_sysdep_start (void **start_argptr, } } + extern void _dl_init_first (void *data); + _dl_init_first (argdata); + { extern void _dl_start_user (void); /* Unwind the stack to ARGDATA and simulate a return from _dl_start @@ -793,7 +796,7 @@ _dl_show_auxv (void) void weak_function -_dl_init_first (int argc, ...) +_dl_init_first (void *p) { /* This no-op definition only gets used if libc is not linked in. */ } diff --git a/sysdeps/mach/hurd/i386/dl-machine.h b/sysdeps/mach/hurd/i386/dl-machine.h deleted file mode 100644 index 40f2ff29..00000000 --- a/sysdeps/mach/hurd/i386/dl-machine.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Dynamic linker magic for Hurd/i386. - This file just gets us a call to _dl_first_init inserted - into the asm in sysdeps/i386/dl-machine.h that contains - the initializer code. */ - -#define RTLD_START_SPECIAL_INIT "call _dl_init_first@PLT; movl (%esp), %edx" -#include_next "dl-machine.h" diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c index a558da16..34e8dcc0 100644 --- a/sysdeps/mach/hurd/i386/init-first.c +++ b/sysdeps/mach/hurd/i386/init-first.c @@ -24,8 +24,6 @@ #include #include #include "hurdstartup.h" -#include "hurdmalloc.h" /* XXX */ -#include "../locale/localeinfo.h" #include #include @@ -87,68 +85,13 @@ posixland_init (int argc, char **argv, char **envp) __init_misc (argc, argv, envp); } - static void -init1 (int argc, char *arg0, ...) -{ - char **argv = &arg0; - char **envp = &argv[argc + 1]; - struct hurd_startup_data *d; - - while (*envp) - ++envp; - d = (void *) ++envp; - - if ((void *) d == argv[0]) - { - /* No Hurd data block to process. */ -#ifndef SHARED - __libc_enable_secure = 0; -#endif - return; - } - -#ifndef SHARED - __libc_enable_secure = d->flags & EXEC_SECURE; -#endif - - _hurd_init_dtable = d->dtable; - _hurd_init_dtablesize = d->dtablesize; - - { - /* Check if the stack we are now on is different from - the one described by _hurd_stack_{base,size}. */ - - char dummy; - const vm_address_t newsp = (vm_address_t) &dummy; - - if (d->stack_size != 0 && (newsp < d->stack_base - || newsp - d->stack_base > d->stack_size)) - /* The new stack pointer does not intersect with the - stack the exec server set up for us, so free that stack. */ - __vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size); - } - - if (d->portarray || d->intarray) - /* Initialize library data structures, start signal processing, etc. */ - _hurd_init (d->flags, argv, - d->portarray, d->portarraysize, - d->intarray, d->intarraysize); -} - - -static inline void init (int *data) { - /* data is the address of the argc parameter to _dl_init_first or - doinit1 in _hurd_stack_setup, so the array subscripts are - undefined. */ - DIAG_PUSH_NEEDS_COMMENT; - DIAG_IGNORE_NEEDS_COMMENT (10, "-Warray-bounds"); - 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 @@ -157,18 +100,18 @@ 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. */ if ((void *) d == argv[0] || d->phdr == 0) { + __libc_enable_secure = 0; /* With a new enough linker (binutils-2.23 or better), the magic __ehdr_start symbol will be available and __libc_start_main will have done this that way already. */ @@ -186,51 +129,39 @@ init (int *data) } else { + __libc_enable_secure = d->flags & EXEC_SECURE; _dl_phdr = (ElfW(Phdr) *) d->phdr; _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr)); assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0); } #endif - /* Call `init1' (above) with the user code as the return address, and the - argument data immediately above that on the stack. */ - - void *usercode, **ret_address; - - 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. */ - ret_address = (void **) __builtin_frame_address (0) + 1; - usercode = *ret_address; - /* GCC 4.4.6 also wants us to force loading USERCODE already here. */ - asm volatile ("# %0" : : "X" (usercode)); - *ret_address = &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. */ -} + if ((void *) d == argv[0]) + return; -/* These bits of inline assembler used to be located inside `init'. - However they were optimized away by gcc 2.95. */ + _hurd_init_dtable = d->dtable; + _hurd_init_dtablesize = d->dtablesize; -/* The return address of `init' above, was redirected to here, so at - this point our stack is unwound and callers' registers restored. - Only %ecx and %eax are call-clobbered and thus still have the - values we set just above. We have stashed in %eax the user code - return address. Push it on the top of the stack so it acts as - init1's return address, and then jump there. */ -asm ("call_init1:\n" - " push %eax\n" - " jmp *%ecx\n"); + { + /* Check if the stack we are now on is different from + the one described by _hurd_stack_{base,size}. */ + char dummy; + const vm_address_t newsp = (vm_address_t) &dummy; + + if (d->stack_size != 0 && (newsp < d->stack_base + || newsp - d->stack_base > d->stack_size)) + /* The new stack pointer does not intersect with the + stack the exec server set up for us, so free that stack. */ + __vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size); + } + + if (d->portarray || d->intarray) + /* Initialize library data structures, start signal processing, etc. */ + _hurd_init (d->flags, argv, + d->portarray, d->portarraysize, + d->intarray, d->intarraysize); +} /* Do the first essential initializations that must precede all else. */ static inline void @@ -242,7 +173,7 @@ first_init (void) #ifndef SHARED /* In the static case, we need to set up TLS early so that the stack protection guard can be read at gs:0x14 by the gcc-generated snippets. */ - _hurd_tls_init(&__init1_tcbhead); + _hurd_tls_init (&__init1_tcbhead); asm ("movw %%gs,%w0" : "=m" (__init1_desc)); #endif @@ -252,21 +183,15 @@ first_init (void) #ifdef SHARED /* This function is called specially by the dynamic linker to do early initialization of the shared C library before normal initializers - expecting a Posixoid environment can run. It gets called with the - stack set up just as the user will see it, so it can switch stacks. */ + expecting a Posixoid environment can run. */ void -_dl_init_first (int argc, ...) +_dl_init_first (void **p) { first_init (); - - /* If we use ``__builtin_frame_address (0) + 2'' here, GCC gets confused. */ - init (&argc); + init ((int *) p); } -#endif - -#ifdef SHARED /* The regular posixland initialization is what goes into libc's normal initializer. */ /* NOTE! The linker notices the magical name `_init' and sets the DT_INIT @@ -280,9 +205,10 @@ __libc_init_first (int argc, char **argv, char **envp) { /* Everything was done in the shared library initializer, _init. */ } -#else -strong_alias (posixland_init, __libc_init_first); +#else /* SHARED */ + +strong_alias (posixland_init, __libc_init_first); /* XXX This is all a crock and I am not happy with it. This poorly-named function is called by static-start.S, @@ -291,32 +217,48 @@ void inhibit_stack_protector _hurd_stack_setup (void) { - intptr_t caller = (intptr_t) __builtin_return_address (0); + /* This is the very first C code that runs in a statically linked + executable -- calling this function is the first thing that _start in + static-start.S does. Once this function returns, the unusual way that it + does (see below), _start jumps to _start1, the regular start-up code. + + _start1 expects the arguments, environment, and a Hurd data block to be + located at the top of the stack. The data may already be located there, + or we may need to receive it from the exec server. */ + void *caller = __builtin_extract_return_addr (__builtin_return_address (0)); + /* If the arguments and environment are already located on the stack, this is + where they are, just above our call frame. Note that this may not be a + valid pointer in case we're supposed to receive the arguments from the exec + server, so we can not dereference it yet. */ + void **p = (void **) __builtin_frame_address (0) + 2; + + /* Init the essential things. */ + first_init (); void doinit (intptr_t *data) { - /* This function gets called with the argument data at TOS. */ - void doinit1 (int argc, ...) - { - /* If we use ``__builtin_frame_address (0) + 2'' here, GCC gets - confused. */ - init ((int *) &argc); - } - - /* Push the user return address after the argument data, and then - jump to `doinit1' (above), so it is as if __libc_init_first's - caller had called `doinit1' with the argument data already on the - stack. */ - *--data = caller; + init ((int *) data); asm volatile ("movl %0, %%esp\n" /* Switch to new outermost stack. */ - "movl $0, %%ebp\n" /* Clear outermost frame pointer. */ - "jmp *%1" : : "r" (data), "r" (&doinit1)); - /* NOTREACHED */ + "xorl %%ebp, %%ebp\n" /* Clear outermost frame pointer. */ + "jmp *%1" : : "r" (data), "r" (caller)); + __builtin_unreachable (); } - first_init (); - - _hurd_startup ((void **) __builtin_frame_address (0) + 2, &doinit); + /* _hurd_startup () will attempt to receive the data block from the exec + server; or if that is not possible, will take the data from the pointer + we pass it here. The important point here is that the data + _hurd_startup () collects may be allocated in its stack frame (with + alloca), which is why _hurd_startup () does not return the normal way. + Instead, it invokes a callback (which is not expected to return normally + either). + + Our callback not only passes the data pointer to init (), but also jumps + out of the call stack back to our caller (i.e. to _start1), while setting + the stack pointer to the data (which is somewhere on teh current stack + anyway). This way, _start1 find the data on the top of the stack, just as + it expects to. */ + _hurd_startup (p, &doinit); + __builtin_unreachable (); } #endif From patchwork Tue Feb 21 21:19:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 65430 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6C0233858005 for ; Tue, 21 Feb 2023 21:20:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6C0233858005 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677014409; bh=ZH6AOvocsh/qDaHaXXo3hhuKnkAuH8BhUrA3ifp3vAU=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=gbgqQA6yHd4n73czPBn5k59vZ7bK6B7rrPEn10q3hwDfKzA8yiA4xCctHAzcpsdiQ OEuK9ZvKOmW9QxFrLhgmhPFNw9IMPeQST+8YK+IGTGL6QVzLlZoIvdfOBjHSZZmT3T ffnCRBNcpmzVM85p5rFyDtvc+4cHkB8KN3A/fKqo= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) by sourceware.org (Postfix) with ESMTPS id 61B053858D39 for ; Tue, 21 Feb 2023 21:19:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 61B053858D39 Received: by mail-lf1-x12d.google.com with SMTP id w27so7512127lfu.4 for ; Tue, 21 Feb 2023 13:19:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZH6AOvocsh/qDaHaXXo3hhuKnkAuH8BhUrA3ifp3vAU=; b=iLiFj2ppHm5fwu3daIaKT7UWfyHqduIEWlsH4IDcGzMMlTHJZa2rPEdnzB5t+W8v1I SMdQk2E7YnCNVTG3eo9LC+6/Az3KrYcMWRo3ygfyWJHrP/lE1Hall3SfFPIzsSqOwvca G43KrjxPfAoqvhhJzmy9VQ3nSq3iJr2YX1nEJpRUeDtK8zOKWdZswPtWFBrC6+6hseC+ hayexKxj/Kt577z27gkXGPHuf1/gF6/TfGVgJqrcGxD3zpSVrEow2ll4nW/DMjmtNl/a fKotbIWA7Zhg+DpH2bdVSzyygSANUXX44WZAHjUTzO4G0Jh0mAGhMdaTvTT8O+4sCLqy O1mA== X-Gm-Message-State: AO0yUKUgRl31gyIG/7DJeCNi4e/y+PiWMmu64GMpfX+jQvlen8ZQefxO rjwlc8F6soIn/FYaUB4v8ho= X-Google-Smtp-Source: AK7set+cocoqvkzoQ6QQVOW/GbChPAYrTA0tcNBBa51GdmW1uYCuTt4ajiHp99n+L2mv12J2s144MQ== X-Received: by 2002:a05:6512:104f:b0:4d8:86c1:477f with SMTP id c15-20020a056512104f00b004d886c1477fmr1912654lfb.20.1677014378831; Tue, 21 Feb 2023 13:19:38 -0800 (PST) Received: from surface-pro-6.. ([2a00:1370:818c:4a57:d7b6:7913:7a86:3102]) by smtp.gmail.com with ESMTPSA id m17-20020a195211000000b00498f77cfa63sm1949097lfb.280.2023.02.21.13.19.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 13:19:38 -0800 (PST) To: bug-hurd@gnu.org, libc-alpha@sourceware.org Cc: =?utf-8?q?Fl=C3=A1vio_Cruz?= , Noah Goldstein , Samuel Thibault , Sergey Bugaev Subject: [PATCH v2 2/4] hurd: Generalize init-first.c to support x86_64 Date: Wed, 22 Feb 2023 00:19:30 +0300 Message-Id: <20230221211932.296459-3-bugaevc@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230221211932.296459-1-bugaevc@gmail.com> References: <20230221211932.296459-1-bugaevc@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sergey Bugaev via Libc-alpha From: Sergey Bugaev Reply-To: Sergey Bugaev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Signed-off-by: Sergey Bugaev --- sysdeps/mach/hurd/{i386 => x86}/init-first.c | 6 ++++++ 1 file changed, 6 insertions(+) rename sysdeps/mach/hurd/{i386 => x86}/init-first.c (97%) diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/x86/init-first.c similarity index 97% rename from sysdeps/mach/hurd/i386/init-first.c rename to sysdeps/mach/hurd/x86/init-first.c index 34e8dcc0..a187af82 100644 --- a/sysdeps/mach/hurd/i386/init-first.c +++ b/sysdeps/mach/hurd/x86/init-first.c @@ -238,9 +238,15 @@ _hurd_stack_setup (void) void doinit (intptr_t *data) { init ((int *) data); +# ifdef __x86_64__ + asm volatile ("movq %0, %%rsp\n" /* Switch to new outermost stack. */ + "xorq %%rbp, %%rbp\n" /* Clear outermost frame pointer. */ + "jmp *%1" : : "r" (data), "r" (caller)); +# else asm volatile ("movl %0, %%esp\n" /* Switch to new outermost stack. */ "xorl %%ebp, %%ebp\n" /* Clear outermost frame pointer. */ "jmp *%1" : : "r" (data), "r" (caller)); +# endif __builtin_unreachable (); } From patchwork Tue Feb 21 21:19:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 65432 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CCE573858289 for ; Tue, 21 Feb 2023 21:20:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CCE573858289 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677014448; bh=CTy4GUXjzAKnpsqjqD2mkVz2dtbA6Pkf10bgsqkMkWc=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Q7G1TxFYa3PCgiUM8VRgPYEFA4IMHWRKXFt0jPyIO6MXUVIyOVmm1FhJAy8m7CJLv Rg1vPK1qnBNK2MdLSXGk5D4RA7GCYnV3vT6few9+cak3ERffAqw9xHHA8nqqj1CC97 YtOOGRPh4OXvLsADfnlDR5Z0mFQmJG0A3BwpjQ5w= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [IPv6:2a00:1450:4864:20::132]) by sourceware.org (Postfix) with ESMTPS id 94D4B3858C83 for ; Tue, 21 Feb 2023 21:19:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 94D4B3858C83 Received: by mail-lf1-x132.google.com with SMTP id w27so7512193lfu.4 for ; Tue, 21 Feb 2023 13:19:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CTy4GUXjzAKnpsqjqD2mkVz2dtbA6Pkf10bgsqkMkWc=; b=suoEmr5+1rIXRfKMxgCcfWH4PGz+SotEJ/0bYn8RP24uvPrQHEQaKWikaBHzMvelqL jGSH4XguhOK9I8tkcuYG8Vr6INCpPlk+/6xr0k3bjAm8JVrAtbSLdAgzJfGJhH4h/bQ5 29ienzTb3TeqamYu3iwN3ZZEd6rP0oWcAv/3e6hvw/TO+l+PS2gF3ZWNWPjJBzZQQAMP XZD3VqOJKcgxsS+FyyIBF4SrnOhB9bELYTHwunntZFSvzorI3kfpOvrI6dM3J3EOKdTy b+iUG2mZhPjtak69gxWyVdwkhUs7xGMS8a+oez1OnxgFXDk7Y6nBPBluhLL1NUl4jR5C rO4w== X-Gm-Message-State: AO0yUKVRw+QafTd4GbAZT2FqjXyOtAZjlsSGAONU5kpMLnqgktZ9IlR/ L9cEa8+zkZ94KDM4ki7B1q0= X-Google-Smtp-Source: AK7set9eCbey1Stn5GaaqAJ3eIvWWwNpQfHH2xBpm2/xKPIztrLM0x7g+j/Su/dn2cOXWlIDVvdVXg== X-Received: by 2002:ac2:5603:0:b0:4d8:56db:1ce7 with SMTP id v3-20020ac25603000000b004d856db1ce7mr1765282lfd.12.1677014380020; Tue, 21 Feb 2023 13:19:40 -0800 (PST) Received: from surface-pro-6.. ([2a00:1370:818c:4a57:d7b6:7913:7a86:3102]) by smtp.gmail.com with ESMTPSA id m17-20020a195211000000b00498f77cfa63sm1949097lfb.280.2023.02.21.13.19.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 13:19:39 -0800 (PST) To: bug-hurd@gnu.org, libc-alpha@sourceware.org Cc: =?utf-8?q?Fl=C3=A1vio_Cruz?= , Noah Goldstein , Samuel Thibault , Sergey Bugaev Subject: [PATCH v2 3/4] hurd: Implement TLS for x86_64 Date: Wed, 22 Feb 2023 00:19:31 +0300 Message-Id: <20230221211932.296459-4-bugaevc@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230221211932.296459-1-bugaevc@gmail.com> References: <20230221211932.296459-1-bugaevc@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sergey Bugaev via Libc-alpha From: Sergey Bugaev Reply-To: Sergey Bugaev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Signed-off-by: Sergey Bugaev --- sysdeps/mach/hurd/x86/init-first.c | 14 +- sysdeps/mach/hurd/x86_64/tls.h | 215 +++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 sysdeps/mach/hurd/x86_64/tls.h diff --git a/sysdeps/mach/hurd/x86/init-first.c b/sysdeps/mach/hurd/x86/init-first.c index a187af82..04480ed3 100644 --- a/sysdeps/mach/hurd/x86/init-first.c +++ b/sysdeps/mach/hurd/x86/init-first.c @@ -41,8 +41,14 @@ extern char **__libc_argv attribute_hidden; extern char **_dl_argv; #ifndef SHARED -unsigned short __init1_desc; static tcbhead_t __init1_tcbhead; +# ifndef __x86_64__ +unsigned short __init1_desc; +# endif +#endif + +#ifdef __x86_64__ +unsigned char __libc_tls_initialized; #endif /* Things that want to be run before _hurd_init or much anything else. @@ -174,7 +180,13 @@ first_init (void) /* In the static case, we need to set up TLS early so that the stack protection guard can be read at gs:0x14 by the gcc-generated snippets. */ _hurd_tls_init (&__init1_tcbhead); + + /* Make sure __LIBC_NO_TLS () keeps evaluating to 1. */ +# ifdef __x86_64__ + __libc_tls_initialized = 0; +# else asm ("movw %%gs,%w0" : "=m" (__init1_desc)); +# endif #endif RUN_RELHOOK (_hurd_preinit_hook, ()); diff --git a/sysdeps/mach/hurd/x86_64/tls.h b/sysdeps/mach/hurd/x86_64/tls.h new file mode 100644 index 00000000..cf74e1f4 --- /dev/null +++ b/sysdeps/mach/hurd/x86_64/tls.h @@ -0,0 +1,215 @@ +/* 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 + . */ + +#ifndef _X86_64_TLS_H +#define _X86_64_TLS_H + + +/* Some things really need not be machine-dependent. */ +#include + + +#ifndef __ASSEMBLER__ +# include +# include +# include +# include + +/* 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"); + +extern unsigned char __libc_tls_initialized; + +# define __LIBC_NO_TLS() __builtin_expect (!__libc_tls_initialized, 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 + +/* Alignment requirement for TCB. + + Some processors such as Intel Atom pay a big penalty on every + access using a segment override if that segment's base is not + aligned to the size of a cache line. (See Intel 64 and IA-32 + Architectures Optimization Reference Manual, section 13.3.3.3, + "Segment Base".) On such machines, a cache line is 64 bytes. */ +# define TCB_ALIGNMENT 64 + + +# define TLS_INIT_TP(descr) _hurd_tls_init ((tcbhead_t *) (descr)) + +# define THREAD_SELF \ + (*(tcbhead_t * __seg_fs *) offsetof (tcbhead_t, tcb)) +/* Read member of the thread descriptor directly. */ +# define THREAD_GETMEM(descr, member) \ + (*(__typeof (descr->member) __seg_fs *) offsetof (tcbhead_t, member)) +/* Write member of the thread descriptor directly. */ +# define THREAD_SETMEM(descr, member, value) \ + (*(__typeof (descr->member) __seg_fs *) offsetof (tcbhead_t, member) = value) + + +/* Return the TCB address of a thread given its state. + Note: this is expensive. */ +static inline tcbhead_t * __attribute__ ((unused)) +THREAD_TCB (thread_t thread, + const void *all_state __attribute__ ((unused))) +{ + error_t err; + /* Fetch the target thread's state. */ + struct i386_fsgs_base_state state; + mach_msg_type_number_t state_count = i386_FSGS_BASE_STATE_COUNT; + err = __thread_get_state (thread, i386_FSGS_BASE_STATE, + (thread_state_t) &state, + &state_count); + assert_perror (err); + assert (state_count == i386_FSGS_BASE_STATE_COUNT); + return (tcbhead_t *) state.fs_base; +} + +/* 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) + + +/* 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)) + +/* Set up TLS in the new thread of a fork child, copying from the original. */ +static inline kern_return_t __attribute__ ((unused)) +_hurd_tls_fork (thread_t child, thread_t orig, + void *machine_state __attribute__ ((unused))) +{ + error_t err; + struct i386_fsgs_base_state state; + mach_msg_type_number_t state_count = i386_FSGS_BASE_STATE_COUNT; + err = __thread_get_state (orig, i386_FSGS_BASE_STATE, + (thread_state_t) &state, + &state_count); + if (err) + return err; + assert (state_count == i386_FSGS_BASE_STATE_COUNT); + + return __thread_set_state (child, i386_FSGS_BASE_STATE, + (thread_state_t) &state, + state_count); +} + +static inline kern_return_t __attribute__ ((unused)) +_hurd_tls_new (thread_t child, tcbhead_t *tcb) +{ + struct i386_fsgs_base_state state; + + tcb->tcb = tcb; + tcb->self = child; + + /* Install the TCB address into FS base. */ + state.fs_base = (uintptr_t) tcb; + state.gs_base = 0; + return __thread_set_state (child, i386_FSGS_BASE_STATE, + (thread_state_t) &state, + i386_FSGS_BASE_STATE_COUNT); +} + +static inline bool __attribute__ ((unused)) +_hurd_tls_init (tcbhead_t *tcb) +{ + error_t err; + thread_t self = __mach_thread_self (); + + /* We always at least start the sigthread anyway. */ + tcb->multiple_threads = 1; + + err = _hurd_tls_new (self, tcb); + __mach_port_deallocate (__mach_task_self (), self); + __libc_tls_initialized = 1; + return err == 0; +} + + +/* 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 */ From patchwork Tue Feb 21 21:19:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 65431 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5DBDF384DD0A for ; Tue, 21 Feb 2023 21:20:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5DBDF384DD0A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677014415; bh=hYZtb6/taK2PJl1UD1tF7FsgO0N/5WSUCwCWRIFruK0=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=xJsswfBbRnR7K0jPYKrPwSUtSiIXyiXQHDkujJYkX4LK38RUHJrXO682xyGg7PMqr IXDn6PGMnIIRcVuscO/WF9W461dJv7Hfg0N4bVOBBVALQZ4cWBtxA1vNAhu8+5qtzy RGQnk0OT/CIlB0d6+AaZ4adFSjPMZwbUXeVyZmRA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by sourceware.org (Postfix) with ESMTPS id 5529438582A1 for ; Tue, 21 Feb 2023 21:19:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5529438582A1 Received: by mail-lf1-x12c.google.com with SMTP id f41so7433585lfv.13 for ; Tue, 21 Feb 2023 13:19:44 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hYZtb6/taK2PJl1UD1tF7FsgO0N/5WSUCwCWRIFruK0=; b=UcMDdWzp+iUcjWkxMLV20S8CXEzNTf7TnjrETuKkVnPjyKucLCiI1a9XAMXu8MY7Yb d9VS0prqXk5Ek22rbU2iZBF/Irh6Bbnuf5YCuDnaOPevdfeWgv5tlqQijrtWxAVR91Vq r0X+5StZBMD2OjzDyTCbu1alM6OURN+26v+UiNQrNa8VSgOCMape9zyOzgEVfBdHRSZu bbodvnJ/zmlwHqZZ/IarqtO/fPivym0HMDEzMe8QstEjPhj9aJDVVEl5OW4w/eqhubUc QBVibO3JkgodQ1ze/f7xDsWhe1nrtGLMuxCbQX5DozPXSoO9EM2D5qy7RT66SRK7NfbN BZTQ== X-Gm-Message-State: AO0yUKUo4+deGFWqeB18HIp5Lk0QTwFvvTLx8qQpuqz5Uh2uyTsuHjaU qLNBjs7XtdWN5uxMPgaVuM4= X-Google-Smtp-Source: AK7set9xlPjnsoQ3+JW4853+nMUwThEP0rylsjK8C2InixrucHlLqBLWcvSVJPmsK8PQF8WIBlxCAA== X-Received: by 2002:ac2:5234:0:b0:4cb:4374:cc78 with SMTP id i20-20020ac25234000000b004cb4374cc78mr2103828lfl.26.1677014381249; Tue, 21 Feb 2023 13:19:41 -0800 (PST) Received: from surface-pro-6.. ([2a00:1370:818c:4a57:d7b6:7913:7a86:3102]) by smtp.gmail.com with ESMTPSA id m17-20020a195211000000b00498f77cfa63sm1949097lfb.280.2023.02.21.13.19.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 13:19:40 -0800 (PST) To: bug-hurd@gnu.org, libc-alpha@sourceware.org Cc: =?utf-8?q?Fl=C3=A1vio_Cruz?= , Noah Goldstein , Samuel Thibault , Sergey Bugaev Subject: [PATCH v2 4/4] htl: Add pthreadtypes-arch.h for x86_64 Date: Wed, 22 Feb 2023 00:19:32 +0300 Message-Id: <20230221211932.296459-5-bugaevc@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230221211932.296459-1-bugaevc@gmail.com> References: <20230221211932.296459-1-bugaevc@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sergey Bugaev via Libc-alpha From: Sergey Bugaev Reply-To: Sergey Bugaev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Signed-off-by: Sergey Bugaev --- sysdeps/x86_64/htl/bits/pthreadtypes-arch.h | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 sysdeps/x86_64/htl/bits/pthreadtypes-arch.h 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..1d402cc6 --- /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 + . */ + +#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 +#define __ONCE_ALIGNMENT + +#endif /* bits/pthreadtypes.h */