From patchwork Tue Sep 23 19:27:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Caleb Sander Mateos X-Patchwork-Id: 120763 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 3C9C2385841F for ; Tue, 23 Sep 2025 19:32:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3C9C2385841F Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=purestorage.com header.i=@purestorage.com header.a=rsa-sha256 header.s=google2022 header.b=d934o8G/ X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-wm1-x363.google.com (mail-wm1-x363.google.com [IPv6:2a00:1450:4864:20::363]) by sourceware.org (Postfix) with ESMTPS id 5A0A73858406 for ; Tue, 23 Sep 2025 19:27:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5A0A73858406 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=purestorage.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=purestorage.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5A0A73858406 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::363 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758655636; cv=none; b=BPgu53EXJPE8g8OqF5YGZ7ol6pDe/XY+wBFA3BL27xBMPvdDOXhlZ6QrQUEfNE8k+TLmbB737sa9fj78NYMAUO4d5s5+sXSkN9jU9ndr/RHACbuZTNc/MZCiSDXQS63pkISL4ZJuX9Eo2ZAqDKSKZAjoZHMn8IuIXehIbAx1KL0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758655636; c=relaxed/simple; bh=THkkV03HI3RHqVSJf2Hi93ZTs0Jb7n/wBHLUH8o42uc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=cFYMRGk1WxphkKiJ1O81dc9gFOuiQgN2llQQn20YCaIpkFZM+0bIU9xQniCBi3vFKtPm9whqNB3S50cmKIrg3uMzNZ19bZnvXRxxtCz1gjM65b49ZIjKtCWaPSGF2f3fIBXTvZhBRQwQ973SNf4zOcm9/Isx4P1HATYHJHWRpds= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5A0A73858406 Received: by mail-wm1-x363.google.com with SMTP id 5b1f17b1804b1-46dd25efa05so3666605e9.0 for ; Tue, 23 Sep 2025 12:27:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1758655635; x=1759260435; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ruYLwkR8CnvD/Ya3N1VYTNk173KEEkY8OkbiSaT29Os=; b=d934o8G/m6bxfCbAiHhZfzPYiN+2m5DGwGoV2IfIsQPT0nKn9qJ11W7D1RQM2osWwU Q6P0kE7EzovmuHSeRws+6RXCaSBoqt3HqJjUCKJ9FiJH1IVzVB1xQp1gczv/ZR/VY3Tr H7TLnB9vL26uTt5kMuYUMutfVQWsUnnxKtA+VCCHweXLB3JS4wsXgkbEW+YiUq2If4WV egzM/gFR9Dk0vYcjb2IqGuNU2hBe1VUMJUa1/E4HzBlLyFCkFoO08c4/Wr2EnOhpQ5MG yz1kXQJgLh2LTar8qLiqNe2aUHDGGVylC8m2N98g+RBZNOe3WK8UjMBeLjogHAtL/9Xe CFhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758655635; x=1759260435; 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=ruYLwkR8CnvD/Ya3N1VYTNk173KEEkY8OkbiSaT29Os=; b=qT1fPlFw/NspLtgIMwqSPp/gdpwftbVIEK/hS7sb293FwCx3ukcrJFFy32dzInMFLs RspnTsaU2zZ44ga4zmAsl/y5nJ7ULh1oVB4/uEASQVwdx80Ll+A+KhObaThKmG10yalE xL6zgk5/bkgs7b1K6paSZCC5m/LHCK4dXdz40xfdtLK0VWiecr3a/gT0fxfIniZPjurL QMhs2eZgyOHTaAtjFYlqqrgqNbNbIoWISTGADzWE86v+7MWwoGUOje8lElx6qaa50taU LquXKj1RHW+jeJp/zNV1HgVPgwyaXiiZ1PXH32/e5dtdZrMt1jM1YLRAdzaY2IySEUBU Ncng== X-Gm-Message-State: AOJu0Yxnjz6xa8lW4dzw2luXghMzinMM9iM5SDKw6G8RYYWgzI9QX6vT JubJreOx4J7BDq9h3/7hiAWXtPtIdr9cCEUIjA9HwYDMrhuA6VBqtnaIgs4u5toMhoEZZlVWt8w +V4VZnjajVrL6JbxrXJSc28iHinHqzxbQQxXCnSvlCL6Dm+nf0f8xXklkibGfbKjS2GkBShftnx OnZY659416hWJ6kKnG34QlmnHevDMwbSxHGksnXzzrrKPyD97UfGl1LBYvpkciPl3Im8QWJxe3T InqtQ02sIRRls56 X-Gm-Gg: ASbGncuTTlH25XsxIx35ghQmdCHA5PKY2oqmRxf6Ty4jbD3/IG+Tq1DLi72VjpnXinP Ur5hep5Ij9AJONU9YD0O+SHO4kEpHQP4PzDU+LakMRPTaqeSTpn5tBeKVQb7Kq5xNg2Bfbhwh8m fPHdbMhaPHGIr+UXEABroRRZ7cA2kScyWlZTf0Fw3igBgJWLysXM4UHiWDhrhBfoLO/YfDJEvhh 1yv4HkFeJDMG6OUU4uNyoF/wJlsZ5RQyq76yaAVhtOy1+pHmUOkTADTF2LrNF3TGNlYIo4ylZYO T5pm8tDrTB4ZccwV4mB8rj5aHJ/1bxQbYrptRxW8/JLkX16I9ytm1t1kLQu+jTtrRtSm7SC0 X-Google-Smtp-Source: AGHT+IGwaRHWatzVXiPGN7cUOIR3s2BepYf38dlq4FJbQWXJn63nH5fevuyu1/+QGD4WwLuThNNz4PPagtvp X-Received: by 2002:a05:600c:3b11:b0:46c:d777:da15 with SMTP id 5b1f17b1804b1-46e1dac62acmr18246355e9.7.1758655634717; Tue, 23 Sep 2025 12:27:14 -0700 (PDT) Received: from c7-smtp-2023.dev.purestorage.com ([208.88.159.129]) by smtp-relay.gmail.com with ESMTPS id 5b1f17b1804b1-46e20646699sm6065905e9.6.2025.09.23.12.27.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Sep 2025 12:27:14 -0700 (PDT) X-Relaying-Domain: purestorage.com Received: from dev-csander.dev.purestorage.com (unknown [IPv6:2620:125:9007:640:ffff::1199]) by c7-smtp-2023.dev.purestorage.com (Postfix) with ESMTP id 677F3340280; Tue, 23 Sep 2025 13:27:13 -0600 (MDT) Received: by dev-csander.dev.purestorage.com (Postfix, from userid 1557716354) id 5EFBEE41C15; Tue, 23 Sep 2025 13:27:13 -0600 (MDT) From: Caleb Sander Mateos To: libc-alpha@sourceware.org Cc: Eric Mueller , Caleb Sander Mateos Subject: [PATCH RESEND 2/3] sysdeps: add rtld_rwlock_recursive Date: Tue, 23 Sep 2025 13:27:03 -0600 Message-ID: <20250923192704.2944469-3-csander@purestorage.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250923192704.2944469-1-csander@purestorage.com> References: <20250923192704.2944469-1-csander@purestorage.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_STOCKGEN, LOCAL_AUTHENTICATION_FAIL_SPF, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, 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.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org A subsequent commit will want to use a reader-writer lock in the runtime dynamic loader. Currently, only a full mutual exclusion lock is defined for rtld, rtld_lock_recursive. Add rtld_rwlock_*_recursive macros providing an similar interface except with "lock" split into "rdlock" and "wrlock": - __rtld_rwlock_define_recursive() to declare a rwlock - __rtld_rwlock_define_initialized_recursive() to define and initialize a rwlock - __rtld_rwlock_rdlock_recursive() to lock a rwlock for reading (shared) - __rtld_rwlock_wrlock_recursive() to lock a rwlock for writing (exclusive) - __rtld_rwlock_unlock_recursive() to unlock a rwlock locked for either reading or writing In sysdeps/nptl/libc-lockP.h and sysdeps/nptl/dl-mutex.c, map the rdlock, wrlock, and unlock macros to the corresponding pthread_rwlock functions. Initialize the pthread_rwlock with the PTHREAD_RWLOCK_PREFER_READER_NP lock kind in the define_initialized macro to allow the rwlock to be locked recursively for reading. Define the rtld_rwlock macros as aliases for the corresponding rtld_lock macros in sysdeps/mach/libc-lock.h, analogous to the libc_rwlock macros. Signed-off-by: Caleb Sander Mateos --- sysdeps/generic/ldsodefs.h | 3 +++ sysdeps/generic/libc-lock.h | 5 +++++ sysdeps/mach/libc-lock.h | 7 +++++++ sysdeps/nptl/dl-mutex.c | 24 ++++++++++++++++++++++++ sysdeps/nptl/dl-tls_init_tp.c | 9 +++++++++ sysdeps/nptl/libc-lockP.h | 26 ++++++++++++++++++++++++++ 6 files changed, 74 insertions(+) diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 31e9a6b600..f36e64ddba 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1457,10 +1457,13 @@ _dl_audit_objclose (struct link_map *l) no-op dummy implementation early. Similar to GL (dl_rtld_lock_recursive) and GL (dl_rtld_unlock_recursive) in !PTHREAD_IN_LIBC builds. */ extern int (*___rtld_mutex_lock) (pthread_mutex_t *) attribute_hidden; extern int (*___rtld_mutex_unlock) (pthread_mutex_t *lock) attribute_hidden; +extern int (*___rtld_rwlock_rdlock) (pthread_rwlock_t *) attribute_hidden; +extern int (*___rtld_rwlock_wrlock) (pthread_rwlock_t *) attribute_hidden; +extern int (*___rtld_rwlock_unlock) (pthread_rwlock_t *) attribute_hidden; /* Called after libc has been loaded, but before RELRO is activated. Used to initialize the function pointers to the actual implementations. */ void __rtld_mutex_init (void) attribute_hidden; diff --git a/sysdeps/generic/libc-lock.h b/sysdeps/generic/libc-lock.h index fafaf8c932..a7b0ee6c88 100644 --- a/sysdeps/generic/libc-lock.h +++ b/sysdeps/generic/libc-lock.h @@ -28,20 +28,22 @@ begins with a `*'), because its storage size will not be known outside of libc. */ #define __libc_lock_define(CLASS,NAME) #define __libc_lock_define_recursive(CLASS,NAME) #define __rtld_lock_define_recursive(CLASS,NAME) +#define __rtld_rwlock_define_recursive(CLASS,NAME) #define __libc_rwlock_define(CLASS,NAME) /* Define an initialized lock variable NAME with storage class CLASS. */ #define __libc_lock_define_initialized(CLASS,NAME) #define __libc_rwlock_define_initialized(CLASS,NAME) /* Define an initialized recursive lock variable NAME with storage class CLASS. */ #define __libc_lock_define_initialized_recursive(CLASS,NAME) #define __rtld_lock_define_initialized_recursive(CLASS,NAME) +#define __rtld_rwlock_define_initialized_recursive(CLASS,NAME) /* Initialize the named lock variable, leaving it in a consistent, unlocked state. */ #define __libc_lock_init(NAME) #define __rtld_lock_initialize(NAME) @@ -65,10 +67,12 @@ #define __libc_rwlock_wrlock(NAME) /* Lock the recursive named lock variable. */ #define __libc_lock_lock_recursive(NAME) #define __rtld_lock_lock_recursive(NAME) +#define __rtld_rwlock_rdlock_recursive(NAME) +#define __rtld_rwlock_wrlock_recursive(NAME) /* Try to lock the named lock variable. */ #define __libc_lock_trylock(NAME) 0 #define __libc_rwlock_tryrdlock(NAME) 0 #define __libc_rwlock_trywrlock(NAME) 0 @@ -81,10 +85,11 @@ #define __libc_rwlock_unlock(NAME) /* Unlock the recursive named lock variable. */ #define __libc_lock_unlock_recursive(NAME) #define __rtld_lock_unlock_recursive(NAME) +#define __rtld_rwlock_unlock_recursive(NAME) /* Define once control variable. */ #define __libc_once_define(CLASS, NAME) CLASS int NAME = 0 diff --git a/sysdeps/mach/libc-lock.h b/sysdeps/mach/libc-lock.h index fd590f1551..d02269039b 100644 --- a/sysdeps/mach/libc-lock.h +++ b/sysdeps/mach/libc-lock.h @@ -150,10 +150,17 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; #define __libc_rwlock_rdlock __libc_lock_lock #define __libc_rwlock_wrlock __libc_lock_lock #define __libc_rwlock_tryrdlock __libc_lock_trylock #define __libc_rwlock_trywrlock __libc_lock_trylock #define __libc_rwlock_unlock __libc_lock_unlock +#define __rtld_rwlock_define_recursive __rtld_lock_define_recursive +#define _RTLD_RWLOCK_RECURSIVE_INITIALIZER _RTLD_LOCK_RECURSIVE_INITIALIZER +#define __rtld_rwlock_define_initialized_recursive \ + __rtld_lock_define_initialized_recursive +#define __rtld_rwlock_rdlock_recursive __rtld_lock_lock_recursive +#define __rtld_rwlock_wrlock_recursive __rtld_lock_lock_recursive +#define __rtld_rwlock_unlock_recursive __rtld_lock_unlock_recursive struct __libc_cleanup_frame { void (*__fct) (void *); void *__argp; diff --git a/sysdeps/nptl/dl-mutex.c b/sysdeps/nptl/dl-mutex.c index 1e324e19bb..f5371326b2 100644 --- a/sysdeps/nptl/dl-mutex.c +++ b/sysdeps/nptl/dl-mutex.c @@ -22,10 +22,13 @@ #include #include __typeof (pthread_mutex_lock) *___rtld_mutex_lock attribute_relro; __typeof (pthread_mutex_unlock) *___rtld_mutex_unlock attribute_relro; +__typeof (pthread_rwlock_rdlock) *___rtld_rwlock_rdlock attribute_relro; +__typeof (pthread_rwlock_wrlock) *___rtld_rwlock_wrlock attribute_relro; +__typeof (pthread_rwlock_unlock) *___rtld_rwlock_unlock attribute_relro; void __rtld_mutex_init (void) { /* There is an implicit assumption here that the lock counters are @@ -48,6 +51,27 @@ __rtld_mutex_init (void) 0x7dd7aaaa, /* dl_new_hash output. */ FIRST_VERSION_libc_pthread_mutex_unlock_STRING, FIRST_VERSION_libc_pthread_mutex_unlock_HASH); assert (sym != NULL); ___rtld_mutex_unlock = DL_SYMBOL_ADDRESS (libc_map, sym); + + sym = _dl_lookup_direct (libc_map, "pthread_rwlock_rdlock", + 0x1534d41c, /* dl_new_hash output. */ + FIRST_VERSION_libc_pthread_rwlock_rdlock_STRING, + FIRST_VERSION_libc_pthread_rwlock_rdlock_HASH); + assert (sym != NULL); + ___rtld_rwlock_rdlock = DL_SYMBOL_ADDRESS (libc_map, sym); + + sym = _dl_lookup_direct (libc_map, "pthread_rwlock_wrlock", + 0x21dbf64f, /* dl_new_hash output. */ + FIRST_VERSION_libc_pthread_rwlock_wrlock_STRING, + FIRST_VERSION_libc_pthread_rwlock_wrlock_HASH); + assert (sym != NULL); + ___rtld_rwlock_wrlock = DL_SYMBOL_ADDRESS (libc_map, sym); + + sym = _dl_lookup_direct (libc_map, "pthread_rwlock_unlock", + 0x1ce94309, /* dl_new_hash output. */ + FIRST_VERSION_libc_pthread_rwlock_unlock_STRING, + FIRST_VERSION_libc_pthread_rwlock_unlock_HASH); + assert (sym != NULL); + ___rtld_rwlock_unlock = DL_SYMBOL_ADDRESS (libc_map, sym); } diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c index 47566dce4f..5c97983302 100644 --- a/sysdeps/nptl/dl-tls_init_tp.c +++ b/sysdeps/nptl/dl-tls_init_tp.c @@ -41,10 +41,16 @@ rtld_hidden_def (__nptl_initial_report_events) static int rtld_mutex_dummy (pthread_mutex_t *lock) { return 0; } + +static int +rtld_rwlock_dummy (pthread_rwlock_t *lock) +{ + return 0; +} #endif const unsigned int __rseq_flags; size_t _rseq_align attribute_hidden; @@ -59,10 +65,13 @@ __tls_pre_init_tp (void) INIT_LIST_HEAD (&GL (dl_stack_cache)); #ifdef SHARED ___rtld_mutex_lock = rtld_mutex_dummy; ___rtld_mutex_unlock = rtld_mutex_dummy; + ___rtld_rwlock_rdlock = rtld_rwlock_dummy; + ___rtld_rwlock_wrlock = rtld_rwlock_dummy; + ___rtld_rwlock_unlock = rtld_rwlock_dummy; #endif } void __tls_init_tp (void) diff --git a/sysdeps/nptl/libc-lockP.h b/sysdeps/nptl/libc-lockP.h index 1be3dd1ec1..904482be83 100644 --- a/sysdeps/nptl/libc-lockP.h +++ b/sysdeps/nptl/libc-lockP.h @@ -36,10 +36,11 @@ /* Mutex type. */ typedef int __libc_lock_t __LIBC_LOCK_ALIGNMENT; typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t; typedef pthread_rwlock_t __libc_rwlock_t; +typedef struct { pthread_rwlock_t rwlock; } __rtld_rwlock_recursive_t; /* Define a lock variable NAME with storage class CLASS. The lock must be initialized with __libc_lock_init before it can be used (or define it with __libc_lock_define_initialized, below). Use `extern' for CLASS to declare a lock defined in another module. In public structure @@ -50,10 +51,12 @@ typedef pthread_rwlock_t __libc_rwlock_t; CLASS __libc_lock_t NAME; #define __libc_rwlock_define(CLASS,NAME) \ CLASS __libc_rwlock_t NAME; #define __rtld_lock_define_recursive(CLASS,NAME) \ CLASS __rtld_lock_recursive_t NAME; +#define __rtld_rwlock_define_recursive(CLASS,NAME) \ + CLASS __rtld_rwlock_recursive_t NAME; /* Define an initialized lock variable NAME with storage class CLASS. For the C library we take a deeper look at the initializer. For this implementation all fields are initialized to zero. Therefore @@ -71,10 +74,15 @@ _Static_assert (LLL_LOCK_INITIALIZER == 0, "LLL_LOCK_INITIALIZER != 0"); #define __rtld_lock_define_initialized_recursive(CLASS,NAME) \ CLASS __rtld_lock_recursive_t NAME = _RTLD_LOCK_RECURSIVE_INITIALIZER; #define _RTLD_LOCK_RECURSIVE_INITIALIZER \ {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} +#define __rtld_rwlock_define_initialized_recursive(CLASS,NAME) \ + CLASS __rtld_rwlock_recursive_t NAME = _RTLD_RWLOCK_RECURSIVE_INITIALIZER; +#define _RTLD_RWLOCK_RECURSIVE_INITIALIZER \ + {PTHREAD_RWLOCK_INITIALIZER} + #define __rtld_lock_initialize(NAME) \ (void) ((NAME) = (__rtld_lock_recursive_t) _RTLD_LOCK_RECURSIVE_INITIALIZER) /* If we check for a weakly referenced symbol and then perform a normal jump to it te code generated for some platforms in case of @@ -124,16 +132,34 @@ _Static_assert (LLL_LOCK_INITIALIZER == 0, "LLL_LOCK_INITIALIZER != 0"); # define __rtld_lock_lock_recursive(NAME) \ ___rtld_mutex_lock (&(NAME).mutex) # define __rtld_lock_unlock_recursive(NAME) \ ___rtld_mutex_unlock (&(NAME).mutex) + +# define __rtld_rwlock_rdlock_recursive(NAME) \ + ___rtld_rwlock_rdlock (&(NAME).rwlock) + +# define __rtld_rwlock_wrlock_recursive(NAME) \ + ___rtld_rwlock_wrlock (&(NAME).rwlock) + +# define __rtld_rwlock_unlock_recursive(NAME) \ + ___rtld_rwlock_unlock (&(NAME).rwlock) #else /* Not in the dynamic loader. */ # define __rtld_lock_lock_recursive(NAME) \ __pthread_mutex_lock (&(NAME).mutex) # define __rtld_lock_unlock_recursive(NAME) \ __pthread_mutex_unlock (&(NAME).mutex) + +# define __rtld_rwlock_rdlock_recursive(NAME) \ + __pthread_rwlock_rdlock (&(NAME).rwlock) + +# define __rtld_rwlock_wrlock_recursive(NAME) \ + __pthread_rwlock_wrlock (&(NAME).rwlock) + +# define __rtld_rwlock_unlock_recursive(NAME) \ + __pthread_rwlock_unlock (&(NAME).rwlock) #endif /* Define once control variable. */ #if PTHREAD_ONCE_INIT == 0 /* Special case for static variables where we can avoid the initialization