From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by sourceware.org (Postfix) with ESMTPS id ADFED384C005 for ; Wed, 17 Mar 2021 20:45:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org ADFED384C005 Received: by mail-qv1-xf35.google.com with SMTP id d10so2090368qve.7 for ; Wed, 17 Mar 2021 13:45:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=hHoRUzQ+NtNFWU1LGR9R6Eu2jbndwiGPIUVR3mpWlhg=; b=KaoMZ++TY+hFkUoyZGZgwosCVvogG6yF5goomPGAuRxs9pNi0OC6GEZDUFya3mPOSr 3/7jlJFagGCMyMDhhiC61qxmSEiyihXzwIFgzG+p+xJ0ywduUKO/Rm16Ps7k5OisL+Nx DuT0d9rnrkpldmTuTgRTtDWTzQwudM1CIfOue4vp5u8YDYxKXe3ZZ5wLVCv3MAF5WORZ VWWMAD1CflcDx09Yupj02X8fPi/+tMcxgecQoL+ewjERe3Xmid/aNNnL2WaHVu/khHJa Y1eKGHn9cOHqAJXmOE1xCOegO0u0Z5+/GXrQcYXgLzx0je0x5rOqwd8GBUwR2dtOtriO PA4Q== X-Gm-Message-State: AOAM5322y3HL6R4NAtVyZi3XRgT9UR3sb2XEeXF+wmamYoHac+aRbETU hffGlh3J9Dmb5ESaaOGjLDysg2ep7fhqzYxd X-Google-Smtp-Source: ABdhPJzPF/+yRE0+bC50YtNg9Cd0Immf/GZ/lbdLwGnDLtoDgrGiInNcsiE7tAKP9Ed5o9DYshNiOA== X-Received: by 2002:a05:6214:cad:: with SMTP id s13mr1012232qvs.53.1616013932246; Wed, 17 Mar 2021 13:45:32 -0700 (PDT) Received: from [192.168.1.4] ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id k24sm16486541qtu.35.2021.03.17.13.45.30 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 17 Mar 2021 13:45:31 -0700 (PDT) Subject: Re: [PATCH v3 10/37] csu: Move calling main out of __libc_start_main_impl To: libc-alpha@sourceware.org, Florian Weimer References: <3ec0825ceb5514f7f94d170f40cae12a3111a3fd.1615914631.git.fweimer@redhat.com> From: Adhemerval Zanella Message-ID: <5ef1e58c-ca0f-cb42-02a2-b2f7320630a8@linaro.org> Date: Wed, 17 Mar 2021 17:45:29 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: <3ec0825ceb5514f7f94d170f40cae12a3111a3fd.1615914631.git.fweimer@redhat.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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-List-Received-Date: Wed, 17 Mar 2021 20:45:34 -0000 On 16/03/2021 14:29, Florian Weimer via Libc-alpha wrote: > This code depends on whether glibc has unwinding support for > a particular port. LGTM. Reviewed-by: Adhemerval Zanella > --- > csu/libc-start.c | 74 ++-------------------- > sysdeps/generic/libc_start_call_main.h | 24 +++++++ > sysdeps/nptl/libc_start_call_main.h | 88 ++++++++++++++++++++++++++ > 3 files changed, 116 insertions(+), 70 deletions(-) > create mode 100644 sysdeps/generic/libc_start_call_main.h > create mode 100644 sysdeps/nptl/libc_start_call_main.h > > diff --git a/csu/libc-start.c b/csu/libc-start.c > index 05ff7afddf..8688cba76d 100644 > --- a/csu/libc-start.c > +++ b/csu/libc-start.c > @@ -58,12 +58,6 @@ uintptr_t __pointer_chk_guard_local > # endif > #endif > > -#ifdef HAVE_PTR_NTHREADS > -/* We need atomic operations. */ > -# include > -#endif > - > - > #ifndef SHARED > # include > # include > @@ -123,6 +117,9 @@ apply_irel (void) > # define ARCH_INIT_CPU_FEATURES() > #endif > > +/* Obtain the definition of __libc_start_call_main. */ > +#include > + > #ifdef SHARED > /* Initialization for dynamic executables. Find the main executable > link map and run its init functions. */ > @@ -245,9 +242,6 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), > void (*fini) (void), > void (*rtld_fini) (void), void *stack_end) > { > - /* Result of the 'main' function. */ > - int result; > - > #ifndef SHARED > char **ev = &argv[argc + 1]; > > @@ -413,68 +407,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), > #ifndef SHARED > _dl_debug_initialize (0, LM_ID_BASE); > #endif > -#ifdef HAVE_CLEANUP_JMP_BUF > - /* Memory for the cancellation buffer. */ > - struct pthread_unwind_buf unwind_buf; > - > - int not_first_call; > - DIAG_PUSH_NEEDS_COMMENT; > -#if __GNUC_PREREQ (7, 0) > - /* This call results in a -Wstringop-overflow warning because struct > - pthread_unwind_buf is smaller than jmp_buf. setjmp and longjmp > - do not use anything beyond the common prefix (they never access > - the saved signal mask), so that is a false positive. */ > - DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overflow="); > -#endif > - not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf); > - DIAG_POP_NEEDS_COMMENT; > - if (__glibc_likely (! not_first_call)) > - { > - struct pthread *self = THREAD_SELF; > - > - /* Store old info. */ > - unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf); > - unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup); > - > - /* Store the new cleanup handler info. */ > - THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf); > - > - /* Run the program. */ > - result = main (argc, argv, __environ MAIN_AUXVEC_PARAM); > - } > - else > - { > - /* Remove the thread-local data. */ > -# ifdef SHARED > - PTHFCT_CALL (ptr__nptl_deallocate_tsd, ()); > -# else > - extern void __nptl_deallocate_tsd (void) __attribute ((weak)); > - __nptl_deallocate_tsd (); > -# endif > - > - /* One less thread. Decrement the counter. If it is zero we > - terminate the entire process. */ > - result = 0; > -# ifdef SHARED > - unsigned int *ptr = __libc_pthread_functions.ptr_nthreads; > -# ifdef PTR_DEMANGLE > - PTR_DEMANGLE (ptr); > -# endif > -# else > - extern unsigned int __nptl_nthreads __attribute ((weak)); > - unsigned int *const ptr = &__nptl_nthreads; > -# endif > - > - if (! atomic_decrement_and_test (ptr)) > - /* Not much left to do but to exit the thread, not the process. */ > - __exit_thread (); > - } > -#else > - /* Nothing fancy, just call the function. */ > - result = main (argc, argv, __environ MAIN_AUXVEC_PARAM); > -#endif > > - exit (result); > + __libc_start_call_main (main, argc, argv MAIN_AUXVEC_PARAM); > } > > /* Starting with glibc 2.34, the init parameter is always NULL. Older Ok. > diff --git a/sysdeps/generic/libc_start_call_main.h b/sysdeps/generic/libc_start_call_main.h > new file mode 100644 > index 0000000000..8a06eec4a3 > --- /dev/null > +++ b/sysdeps/generic/libc_start_call_main.h > @@ -0,0 +1,24 @@ > +/* Invoking main from __libc_start. Generic version without unwinding. > + Copyright (C) 1998-2021 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 > + . */ > + > +_Noreturn static __always_inline void > +__libc_start_call_main (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), > + int argc, char **argv MAIN_AUXVEC_DECL) > +{ > + exit (main (argc, argv, __environ MAIN_AUXVEC_PARAM)); > +} Ok. > diff --git a/sysdeps/nptl/libc_start_call_main.h b/sysdeps/nptl/libc_start_call_main.h > new file mode 100644 > index 0000000000..5218e7ab1e > --- /dev/null > +++ b/sysdeps/nptl/libc_start_call_main.h > @@ -0,0 +1,88 @@ > +/* Invoking main from __libc_start_main. nptl version. > + Copyright (C) 1998-2021 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 > + . */ > + > +#include > + > +_Noreturn static void > +__libc_start_call_main (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), > + int argc, char **argv > +#ifdef LIBC_START_MAIN_AUXVEC_ARG > + , ElfW(auxv_t) *auxvec > +#endif > + ) > +{ > + int result; > + > + /* Memory for the cancellation buffer. */ > + struct pthread_unwind_buf unwind_buf; > + > + int not_first_call; > + DIAG_PUSH_NEEDS_COMMENT; > +#if __GNUC_PREREQ (7, 0) > + /* This call results in a -Wstringop-overflow warning because struct > + pthread_unwind_buf is smaller than jmp_buf. setjmp and longjmp > + do not use anything beyond the common prefix (they never access > + the saved signal mask), so that is a false positive. */ > + DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overflow="); > +#endif > + not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf); > + DIAG_POP_NEEDS_COMMENT; > + if (__glibc_likely (! not_first_call)) > + { > + struct pthread *self = THREAD_SELF; > + > + /* Store old info. */ > + unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf); > + unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup); > + > + /* Store the new cleanup handler info. */ > + THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf); > + > + /* Run the program. */ > + result = main (argc, argv, __environ MAIN_AUXVEC_PARAM); > + } > + else > + { > + /* Remove the thread-local data. */ > +# ifdef SHARED > + PTHFCT_CALL (ptr__nptl_deallocate_tsd, ()); > +# else > + extern void __nptl_deallocate_tsd (void) __attribute ((weak)); > + __nptl_deallocate_tsd (); > +# endif > + > + /* One less thread. Decrement the counter. If it is zero we > + terminate the entire process. */ > + result = 0; > +# ifdef SHARED > + unsigned int *ptr = __libc_pthread_functions.ptr_nthreads; > +# ifdef PTR_DEMANGLE > + PTR_DEMANGLE (ptr); > +# endif > +# else > + extern unsigned int __nptl_nthreads __attribute ((weak)); > + unsigned int *const ptr = &__nptl_nthreads; > +# endif > + > + if (! atomic_decrement_and_test (ptr)) > + /* Not much left to do but to exit the thread, not the process. */ > + __exit_thread (); > + } > + > + exit (result); > +} > Ok.