From patchwork Tue Oct 10 13:42:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77408 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 4442D3856DC6 for ; Tue, 10 Oct 2023 13:43:54 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 9E48B3858438 for ; Tue, 10 Oct 2023 13:43:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9E48B3858438 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 4D624300B302; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 112F734031B; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 01/16] lib: Add new once_define and once macros to eu-config.h Date: Tue, 10 Oct 2023 15:42:45 +0200 Message-ID: <20231010134300.53830-1-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * lib/eu-config.h New macros. [USE_LOCKS] (ONCE_CALL): (once_define, once) Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- lib/eu-config.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/eu-config.h b/lib/eu-config.h index 78a5c4fe..feb079db 100644 --- a/lib/eu-config.h +++ b/lib/eu-config.h @@ -33,13 +33,18 @@ # include # include # define rwlock_define(class,name) class pthread_rwlock_t name +# define once_define(class,name) class pthread_once_t name = PTHREAD_ONCE_INIT # define RWLOCK_CALL(call) \ ({ int _err = pthread_rwlock_ ## call; assert_perror (_err); }) +# define ONCE_CALL(call) \ + ({ int _err = pthread_ ## call; assert_perror (_err); }) # define rwlock_init(lock) RWLOCK_CALL (init (&lock, NULL)) # define rwlock_fini(lock) RWLOCK_CALL (destroy (&lock)) # define rwlock_rdlock(lock) RWLOCK_CALL (rdlock (&lock)) # define rwlock_wrlock(lock) RWLOCK_CALL (wrlock (&lock)) # define rwlock_unlock(lock) RWLOCK_CALL (unlock (&lock)) +# define once(once_control, init_routine) \ + ONCE_CALL (once (&once_control, init_routine)) #else /* Eventually we will allow multi-threaded applications to use the libraries. Therefore we will add the necessary locking although @@ -50,6 +55,8 @@ # define rwlock_rdlock(lock) ((void) (lock)) # define rwlock_wrlock(lock) ((void) (lock)) # define rwlock_unlock(lock) ((void) (lock)) +# define once_define(class,name) +# define once(once_control, init_routine) init_routine() #endif /* USE_LOCKS */ #include From patchwork Tue Oct 10 13:42:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77402 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 9934D3855587 for ; Tue, 10 Oct 2023 13:43:41 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 6F5ED3858C5E for ; Tue, 10 Oct 2023 13:43:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6F5ED3858C5E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 4FC45301BC17; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 137F534013F; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 02/16] libelf: Make elf_version thread-safe Date: Tue, 10 Oct 2023 15:42:46 +0200 Message-ID: <20231010134300.53830-2-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * elf_version.c (version_once): Define once. (initialize_version): New static function. (elf_version): Use initialize_version version_once. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libelf/elf_version.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libelf/elf_version.c b/libelf/elf_version.c index 6ec534ab..8296bb65 100644 --- a/libelf/elf_version.c +++ b/libelf/elf_version.c @@ -32,12 +32,21 @@ #endif #include +#include +/* Multiple threads may initialize __libelf_version. + pthread_once() ensures that __libelf_version is initialized only once. */ +once_define(static, version_once); /* Currently selected version. Should be EV_CURRENT. Will be EV_NONE if elf_version () has not been called yet. */ unsigned int __libelf_version = EV_NONE; +static void initialize_version(void) +{ + __libelf_version = EV_CURRENT; +} + unsigned int elf_version (unsigned int version) { @@ -49,7 +58,7 @@ elf_version (unsigned int version) /* Phew, we know this version. */ /* Signal that the version is now initialized. */ - __libelf_version = EV_CURRENT; + once(version_once, initialize_version); /* And return the last (or initial) version. */ return EV_CURRENT; From patchwork Tue Oct 10 13:42:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77403 X-Patchwork-Delegate: amerey@redhat.com 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 AC846385CC8A for ; Tue, 10 Oct 2023 13:43:41 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 9908B3858C2A for ; Tue, 10 Oct 2023 13:43:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9908B3858C2A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 582DB301BC1A; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 17BB434032D; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 03/16] libelf: Fix deadlock in __libelf_readall Date: Tue, 10 Oct 2023 15:42:47 +0200 Message-ID: <20231010134300.53830-3-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libelf/elf_readall.c (__libelf_readall): Move rwlock_unlock before libelf_acquire_all. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libelf/elf_readall.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c index d0f9a28c..2d62d447 100644 --- a/libelf/elf_readall.c +++ b/libelf/elf_readall.c @@ -84,6 +84,7 @@ __libelf_readall (Elf *elf) /* If this is an archive and we have derived descriptors get the locks for all of them. */ + rwlock_unlock(elf->lock); // lock will be reacquired next line libelf_acquire_all (elf); if (elf->maximum_size == ~((size_t) 0)) @@ -141,10 +142,8 @@ __libelf_readall (Elf *elf) __libelf_seterrno (ELF_E_NOMEM); /* Free the locks on the children. */ - libelf_release_all (elf); + libelf_release_all (elf); // lock is released } - rwlock_unlock (elf->lock); - return (char *) elf->map_address; } From patchwork Tue Oct 10 13:42:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77405 X-Patchwork-Delegate: amerey@redhat.com 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 B65F2385DC11 for ; Tue, 10 Oct 2023 13:43:45 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id B513A3858404 for ; Tue, 10 Oct 2023 13:43:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B513A3858404 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 5F187301FE87; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 1B31E3403A4; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 04/16] libelf: Fix deadlock in elf_cntl Date: Tue, 10 Oct 2023 15:42:48 +0200 Message-ID: <20231010134300.53830-4-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libelf/elf_cntl.c (elf_cntl): Move rwlock_wrlock, rwlock_unlock, inside case switch statements. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libelf/elf_cntl.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c index 04aa9132..64087c7d 100644 --- a/libelf/elf_cntl.c +++ b/libelf/elf_cntl.c @@ -48,13 +48,16 @@ elf_cntl (Elf *elf, Elf_Cmd cmd) return -1; } - rwlock_wrlock (elf->lock); + switch (cmd) { case ELF_C_FDREAD: + rwlock_rdlock (elf->lock); + int addr_isnull = elf->map_address == NULL; + rwlock_unlock(elf->lock); /* If not all of the file is in the memory read it now. */ - if (elf->map_address == NULL && __libelf_readall (elf) == NULL) + if (addr_isnull && __libelf_readall (elf) == NULL) { /* We were not able to read everything. */ result = -1; @@ -64,7 +67,9 @@ elf_cntl (Elf *elf, Elf_Cmd cmd) case ELF_C_FDDONE: /* Mark the file descriptor as not usable. */ + rwlock_wrlock (elf->lock); elf->fildes = -1; + rwlock_unlock (elf->lock); break; default: @@ -73,7 +78,5 @@ elf_cntl (Elf *elf, Elf_Cmd cmd) break; } - rwlock_unlock (elf->lock); - return result; } From patchwork Tue Oct 10 13:42:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77404 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 70AF4385CC98 for ; Tue, 10 Oct 2023 13:43:44 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id A93393858402 for ; Tue, 10 Oct 2023 13:43:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A93393858402 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 682BE301EC67; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 1E8FB3403B0; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 05/16] libelf: Fix elf_end deadlock Date: Tue, 10 Oct 2023 15:42:49 +0200 Message-ID: <20231010134300.53830-5-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libelf/elf_end.c (elf_end): Add rwlock_unlock before early return. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libelf/elf_end.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libelf/elf_end.c b/libelf/elf_end.c index 89727cb3..80f4d13f 100644 --- a/libelf/elf_end.c +++ b/libelf/elf_end.c @@ -82,7 +82,10 @@ elf_end (Elf *elf) elf->state.ar.ar_sym = NULL; if (elf->state.ar.children != NULL) - return 0; + { + rwlock_unlock(elf->lock); + return 0; + } } /* Remove this structure from the children list. */ From patchwork Tue Oct 10 13:42:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77406 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 588FD3858409 for ; Tue, 10 Oct 2023 13:43:48 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 3B7993858409 for ; Tue, 10 Oct 2023 13:43:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3B7993858409 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id D2DC9301FE80; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 224873403C4; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 06/16] libelf: Make elf32_getchdr and elf64_getchdr thread-safe Date: Tue, 10 Oct 2023 15:42:50 +0200 Message-ID: <20231010134300.53830-6-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libelf/elf32_getchdr.c: Move getchdr function to elf32_getchdr.h. * libelf/elf32_getchdr.h: New file. Add macro to create getchdr_wrlock. * libelf/elf32_updatenull.c: Change call from getchdr to getchdr_wrlock. * libelf/elf_getdata.c: Add elf_getdata_wrlock. * libelf/libelfP.h: Add internal function declarations. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libelf/elf32_getchdr.c | 46 +++-------------------------- libelf/elf32_getchdr.h | 61 +++++++++++++++++++++++++++++++++++++++ libelf/elf32_updatenull.c | 2 +- libelf/elf_getdata.c | 14 +++++++++ libelf/libelfP.h | 4 +++ 5 files changed, 84 insertions(+), 43 deletions(-) create mode 100644 libelf/elf32_getchdr.h diff --git a/libelf/elf32_getchdr.c b/libelf/elf32_getchdr.c index 982a614c..41591300 100644 --- a/libelf/elf32_getchdr.c +++ b/libelf/elf32_getchdr.c @@ -38,46 +38,8 @@ # define LIBELFBITS 32 #endif +#define ELF_WRLOCK_HELD 1 +#include "elf32_getchdr.h" -ElfW2(LIBELFBITS,Chdr) * -elfw2(LIBELFBITS,getchdr) (Elf_Scn *scn) -{ - ElfW2(LIBELFBITS,Shdr) *shdr = elfw2(LIBELFBITS,getshdr) (scn); - if (shdr == NULL) - return NULL; - - /* Must have SHF_COMPRESSED flag set. Allocated or no bits sections - can never be compressed. */ - if ((shdr->sh_flags & SHF_ALLOC) != 0) - { - __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS); - return NULL; - } - - if (shdr->sh_type == SHT_NULL - || shdr->sh_type == SHT_NOBITS) - { - __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE); - return NULL; - } - - if ((shdr->sh_flags & SHF_COMPRESSED) == 0) - { - __libelf_seterrno (ELF_E_NOT_COMPRESSED); - return NULL; - } - - /* This makes sure the data is in the correct format, so we don't - need to swap fields. */ - Elf_Data *d = elf_getdata (scn, NULL); - if (d == NULL) - return NULL; - - if (d->d_size < sizeof (ElfW2(LIBELFBITS,Chdr)) || d->d_buf == NULL) - { - __libelf_seterrno (ELF_E_INVALID_DATA); - return NULL; - } - - return (ElfW2(LIBELFBITS,Chdr) *) d->d_buf; -} +#define ELF_WRLOCK_HELD 0 +#include "elf32_getchdr.h" \ No newline at end of file diff --git a/libelf/elf32_getchdr.h b/libelf/elf32_getchdr.h new file mode 100644 index 00000000..04d47e7a --- /dev/null +++ b/libelf/elf32_getchdr.h @@ -0,0 +1,61 @@ +#undef ADD_ROUTINE_PREFIX +#undef ADD_ROUTINE_SUFFIX + +#if ELF_WRLOCK_HELD +#define CONCAT(x,y) x##y +#define ADD_ROUTINE_PREFIX(y) CONCAT(__,y) +#define ADD_ROUTINE_SUFFIX(x) x ## _wrlock +#define INTERNAL internal_function +#else +#define ADD_ROUTINE_PREFIX(y) y +#define ADD_ROUTINE_SUFFIX(x) x +#define INTERNAL +#endif + +ElfW2(LIBELFBITS,Chdr) * +INTERNAL +ADD_ROUTINE_PREFIX(elfw2(LIBELFBITS, ADD_ROUTINE_SUFFIX(getchdr))) (Elf_Scn *scn) +{ + + ElfW2(LIBELFBITS,Shdr) *shdr = ADD_ROUTINE_PREFIX(elfw2(LIBELFBITS, ADD_ROUTINE_SUFFIX(getshdr)))(scn); + + if (shdr == NULL) + return NULL; + + /* Must have SHF_COMPRESSED flag set. Allocated or no bits sections + can never be compressed. */ + if ((shdr->sh_flags & SHF_ALLOC) != 0) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS); + return NULL; + } + + if (shdr->sh_type == SHT_NULL + || shdr->sh_type == SHT_NOBITS) + { + __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE); + return NULL; + } + + if ((shdr->sh_flags & SHF_COMPRESSED) == 0) + { + __libelf_seterrno (ELF_E_NOT_COMPRESSED); + return NULL; + } + + /* This makes sure the data is in the correct format, so we don't + need to swap fields. */ + Elf_Data *d = ADD_ROUTINE_PREFIX(ADD_ROUTINE_SUFFIX(elf_getdata)) (scn, NULL); + if (d == NULL) + return NULL; + + if (d->d_size < sizeof (ElfW2(LIBELFBITS,Chdr)) || d->d_buf == NULL) + { + __libelf_seterrno (ELF_E_INVALID_DATA); + return NULL; + } + + return (ElfW2(LIBELFBITS,Chdr) *) d->d_buf; +} +#undef INTERNAL +#undef ELF_WRLOCK_HELD \ No newline at end of file diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c index c5d26b00..3594e8ba 100644 --- a/libelf/elf32_updatenull.c +++ b/libelf/elf32_updatenull.c @@ -407,7 +407,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) else { ElfW2(LIBELFBITS,Chdr) *chdr; - chdr = elfw2(LIBELFBITS,getchdr) (scn); + chdr = __elfw2(LIBELFBITS,getchdr_wrlock) (scn); if (unlikely (chdr == NULL)) return -1; sh_size = chdr->ch_size; diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c index 5ebd270f..7c3ac043 100644 --- a/libelf/elf_getdata.c +++ b/libelf/elf_getdata.c @@ -582,4 +582,18 @@ elf_getdata (Elf_Scn *scn, Elf_Data *data) return result; } + +Elf_Data * +internal_function +__elf_getdata_wrlock (Elf_Scn *scn, Elf_Data *data) +{ + Elf_Data *result; + + if (scn == NULL) + return NULL; + + result = __elf_getdata_rdlock (scn, data); + + return result; +} INTDEF(elf_getdata) diff --git a/libelf/libelfP.h b/libelf/libelfP.h index 96476064..ed061abb 100644 --- a/libelf/libelfP.h +++ b/libelf/libelfP.h @@ -514,6 +514,8 @@ extern Elf32_Shdr *__elf32_getshdr_rdlock (Elf_Scn *__scn) internal_function; extern Elf64_Shdr *__elf64_getshdr_rdlock (Elf_Scn *__scn) internal_function; extern Elf32_Shdr *__elf32_getshdr_wrlock (Elf_Scn *__scn) internal_function; extern Elf64_Shdr *__elf64_getshdr_wrlock (Elf_Scn *__scn) internal_function; +extern Elf32_Chdr *__elf32_getchdr_wrlock (Elf_Scn *__scn) internal_function; +extern Elf64_Chdr *__elf64_getchdr_wrlock (Elf_Scn *__scn) internal_function; extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index) attribute_hidden; extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn) @@ -523,6 +525,8 @@ extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data) attribute_hidden; extern Elf_Data *__elf_getdata_rdlock (Elf_Scn *__scn, Elf_Data *__data) internal_function; +extern Elf_Data *__elf_getdata_wrlock (Elf_Scn *__scn, Elf_Data *__data) + internal_function; extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data) attribute_hidden; /* Should be called to setup first section data element if From patchwork Tue Oct 10 13:42:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77409 X-Patchwork-Delegate: amerey@redhat.com 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 0B37F3861822 for ; Tue, 10 Oct 2023 13:44:00 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 8E46B3858426 for ; Tue, 10 Oct 2023 13:43:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8E46B3858426 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id D948F301FEB6; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 25EF43403D4; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 07/16] lib: Add eu_tsearch and eu_tfind Date: Tue, 10 Oct 2023 15:42:51 +0200 Message-ID: <20231010134300.53830-7-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * lib/eu-search.h: New file. Declarations for read/write locked eu_tsearch/eu_tfind. * lib/eu-search.c: New file. Definitions for read/write locked eu_tsearch/eu_tfind. * Makefile.am (libeu_a_SOURCES): Add eu-search.c. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- lib/Makefile.am | 2 +- lib/eu-search.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/eu-search.h | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 lib/eu-search.c create mode 100644 lib/eu-search.h diff --git a/lib/Makefile.am b/lib/Makefile.am index b3bb929f..ce8f3e1b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -34,7 +34,7 @@ AM_CPPFLAGS += -I$(srcdir)/../libelf noinst_LIBRARIES = libeu.a libeu_a_SOURCES = xasprintf.c xstrdup.c xstrndup.c xmalloc.c next_prime.c \ - crc32.c crc32_file.c \ + crc32.c crc32_file.c eu-search.c \ color.c error.c printversion.c noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \ diff --git a/lib/eu-search.c b/lib/eu-search.c new file mode 100644 index 00000000..a6b04f4f --- /dev/null +++ b/lib/eu-search.c @@ -0,0 +1,60 @@ +/* Definitions for thread-safe tsearch/tfind + Copyright (C) 2023 Rice University + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils 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 + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "eu-search.h" + +rwlock_define(static, search_find_lock); + +void *eu_tsearch(const void *key, void **rootp, + int (*compar)(const void *, const void *)) +{ + void *ret = NULL; + rwlock_wrlock(search_find_lock); + + ret = tsearch(key, rootp, compar); + + rwlock_unlock(search_find_lock); + return ret; +} + +void *eu_tfind(const void *key, void *const *rootp, + int (*compar)(const void *, const void *)) +{ + void *ret = NULL; + rwlock_rdlock(search_find_lock); + + ret = tfind(key, rootp, compar); + + rwlock_unlock(search_find_lock); + return ret; +} diff --git a/lib/eu-search.h b/lib/eu-search.h new file mode 100644 index 00000000..4ce0139a --- /dev/null +++ b/lib/eu-search.h @@ -0,0 +1,39 @@ +/* Calls for thread-safe tsearch/tfind + Copyright (C) 2023 Rice University + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils 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 + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifndef EU_SEARCH_H +#define EU_SEARCH_H 1 + +#include + +extern void *eu_tsearch(const void *key, void **rootp, + int (*compar)(const void *, const void *)); +extern void *eu_tfind(const void *key, void *const *rootp, + int (*compar)(const void *, const void *)); + +#endif From patchwork Tue Oct 10 13:42:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77407 X-Patchwork-Delegate: amerey@redhat.com 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 C2566385E038 for ; Tue, 10 Oct 2023 13:43:53 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 93AB4385842A for ; Tue, 10 Oct 2023 13:43:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 93AB4385842A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 0286E3022F18; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 296E63403F3; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 08/16] libcpu: Change calls for tsearch/tfind to eu_tsearch/eu_tfind. Date: Tue, 10 Oct 2023 15:42:52 +0200 Message-ID: <20231010134300.53830-8-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libcpu/Makefile.am: Add USE_LOCKS condition for -pthread. * libcpu/i386_parse.y: Add eu-search.h and remove search.h. Change calls for tsearch/tfind to eu_tsearch/eu_tfind. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libcpu/Makefile.am | 3 +++ libcpu/i386_parse.y | 48 ++++++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/libcpu/Makefile.am b/libcpu/Makefile.am index 4ba1be56..a51334b5 100644 --- a/libcpu/Makefile.am +++ b/libcpu/Makefile.am @@ -33,6 +33,9 @@ AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ if BUILD_STATIC AM_CFLAGS += $(fpic_CFLAGS) endif +if USE_LOCKS + AM_CFLAGS += -pthread +endif AM_CFLAGS += -fdollars-in-identifiers LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) -P$( #include #include -#include +#include #include #include #include @@ -269,12 +269,12 @@ mask: kMASK kBITFIELD kNUMBER struct synonym *newp = xmalloc (sizeof (*newp)); newp->from = $2; newp->to = $3; - if (tfind (newp, &synonyms, compare_syn) != NULL) + if (eu_tfind (newp, &synonyms, compare_syn) != NULL) error (0, 0, "%d: duplicate definition for synonym '%s'", i386_lineno, $2); - else if (tsearch ( newp, &synonyms, compare_syn) == NULL) - error (EXIT_FAILURE, 0, "tsearch"); + else if (eu_tsearch ( newp, &synonyms, compare_syn) == NULL) + error (EXIT_FAILURE, 0, "eu_tsearch"); } | ; @@ -308,12 +308,12 @@ instr: bytes ':' bitfieldopt kID bitfieldopt optargs newp->bytes = $1; newp->mnemonic = $4; if (newp->mnemonic != (void *) -1l - && tfind ($4, &mnemonics, + && eu_tfind ($4, &mnemonics, (int (*)(const void *, const void *)) strcmp) == NULL) { - if (tsearch ($4, &mnemonics, + if (eu_tsearch ($4, &mnemonics, (int (*)(const void *, const void *)) strcmp) == NULL) - error (EXIT_FAILURE, errno, "tsearch"); + error (EXIT_FAILURE, errno, "eu_tsearch"); ++nmnemonics; } @@ -339,15 +339,15 @@ instr: bytes ':' bitfieldopt kID bitfieldopt optargs infname, i386_lineno - 1, $5->name); struct suffix search = { .name = $5->name }; - if (tfind (&search, &suffixes, compare_suf) + if (eu_tfind (&search, &suffixes, compare_suf) == NULL) { struct suffix *ns = xmalloc (sizeof (*ns)); ns->name = $5->name; ns->idx = ++nsuffixes; - if (tsearch (ns, &suffixes, compare_suf) + if (eu_tsearch (ns, &suffixes, compare_suf) == NULL) - error (EXIT_FAILURE, errno, "tsearch"); + error (EXIT_FAILURE, errno, "eu_tsearch"); } } @@ -374,7 +374,7 @@ bitfieldopt: kBITFIELD struct known_bitfield search; search.name = $1; struct known_bitfield **res; - res = tfind (&search, &bitfields, bitfield_compare); + res = eu_tfind (&search, &bitfields, bitfield_compare); if (res == NULL) { error (0, 0, "%d: unknown bitfield '%s'", @@ -437,7 +437,7 @@ bit: '0' struct known_bitfield search; search.name = $1; struct known_bitfield **res; - res = tfind (&search, &bitfields, bitfield_compare); + res = eu_tfind (&search, &bitfields, bitfield_compare); if (res == NULL) { error (0, 0, "%d: unknown bitfield '%s'", @@ -497,7 +497,7 @@ argcomp: kBITFIELD struct known_bitfield search; search.name = $1; struct known_bitfield **res; - res = tfind (&search, &bitfields, bitfield_compare); + res = eu_tfind (&search, &bitfields, bitfield_compare); if (res == NULL) { if (strcmp ($1, "ax") == 0) @@ -575,7 +575,7 @@ new_bitfield (char *name, unsigned long int num) newp->bits = num; newp->tmp = 0; - if (tfind (newp, &bitfields, bitfield_compare) != NULL) + if (eu_tfind (newp, &bitfields, bitfield_compare) != NULL) { error (0, 0, "%d: duplicated definition of bitfield '%s'", i386_lineno, name); @@ -584,7 +584,7 @@ new_bitfield (char *name, unsigned long int num) return; } - if (tsearch (newp, &bitfields, bitfield_compare) == NULL) + if (eu_tsearch (newp, &bitfields, bitfield_compare) == NULL) error (EXIT_FAILURE, errno, "%d: cannot insert new bitfield '%s'", i386_lineno, name); } @@ -813,7 +813,7 @@ fillin_arg (struct bitvalue *bytes, struct argname *name, struct synonym search = { .from = fieldname }; - struct synonym **res = tfind (&search, &synonyms, compare_syn); + struct synonym **res = eu_tfind (&search, &synonyms, compare_syn); if (res != NULL) fieldname = (*res)->to; @@ -914,26 +914,26 @@ find_numbers (void) if (runp->operands[i].fct != NULL) { struct argstring search = { .str = runp->operands[i].fct }; - if (tfind (&search, &fct_names[i], compare_argstring) == NULL) + if (eu_tfind (&search, &fct_names[i], compare_argstring) == NULL) { struct argstring *newp = xmalloc (sizeof (*newp)); newp->str = runp->operands[i].fct; newp->idx = 0; - if (tsearch (newp, &fct_names[i], compare_argstring) == NULL) - error (EXIT_FAILURE, errno, "tsearch"); + if (eu_tsearch (newp, &fct_names[i], compare_argstring) == NULL) + error (EXIT_FAILURE, errno, "eu_tsearch"); ++nfct_names[i]; } if (runp->operands[i].str != NULL) { search.str = runp->operands[i].str; - if (tfind (&search, &strs[i], compare_argstring) == NULL) + if (eu_tfind (&search, &strs[i], compare_argstring) == NULL) { struct argstring *newp = xmalloc (sizeof (*newp)); newp->str = runp->operands[i].str; newp->idx = 0; - if (tsearch (newp, &strs[i], compare_argstring) == NULL) - error (EXIT_FAILURE, errno, "tsearch"); + if (eu_tsearch (newp, &strs[i], compare_argstring) == NULL) + error (EXIT_FAILURE, errno, "eu_tsearch"); ++nstrs[i]; } } @@ -1206,7 +1206,7 @@ instrtable_out (void) if (instr->operands[i].fct != NULL) { struct argstring search = { .str = instr->operands[i].fct }; - struct argstring **res = tfind (&search, &fct_names[i], + struct argstring **res = eu_tfind (&search, &fct_names[i], compare_argstring); assert (res != NULL); idx = (*res)->idx; @@ -1217,7 +1217,7 @@ instrtable_out (void) if (instr->operands[i].str != NULL) { struct argstring search = { .str = instr->operands[i].str }; - struct argstring **res = tfind (&search, &strs[i], + struct argstring **res = eu_tfind (&search, &strs[i], compare_argstring); assert (res != NULL); idx = (*res)->idx; From patchwork Tue Oct 10 13:42:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77415 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 2B92B385B522 for ; Tue, 10 Oct 2023 13:44:12 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id B59B03858017 for ; Tue, 10 Oct 2023 13:43:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B59B03858017 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 07BF33022F19; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 2CFD93403F4; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 09/16] src: Use eu-search in nm and findtextrel. Date: Tue, 10 Oct 2023 15:42:53 +0200 Message-ID: <20231010134300.53830-9-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * src/Makefile.am: Add USE_LOCKS condition for -pthread. * src/findtextrel.c: Add eu-search.h and remove search.h. Change calls of tsearch/tfind to eu_tsearch/eu_tfind. * src/nm.c: Likewise. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- src/Makefile.am | 3 +++ src/findtextrel.c | 10 +++++----- src/nm.c | 10 +++++----- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 10d59a48..fea5d43e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,6 +22,9 @@ DEFS += $(YYDEBUG) -DDEBUGPRED=@DEBUGPRED@ \ AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \ -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \ -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm +if USE_LOCKS + AM_CFLAGS += -pthread +endif AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw $(STACK_USAGE_NO_ERROR) diff --git a/src/findtextrel.c b/src/findtextrel.c index d3021a3a..5ac4c29a 100644 --- a/src/findtextrel.c +++ b/src/findtextrel.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -501,10 +501,10 @@ check_rel (size_t nsegments, struct segments segments[nsegments], /* There can be more than one relocation against one file. Try to avoid multiple messages. And yes, the code uses pointer comparison. */ - if (tfind (src, knownsrcs, ptrcompare) == NULL) + if (eu_tfind (src, knownsrcs, ptrcompare) == NULL) { printf (_("%s not compiled with -fpic/-fPIC\n"), src); - tsearch (src, knownsrcs, ptrcompare); + eu_tsearch (src, knownsrcs, ptrcompare); } return; } @@ -555,12 +555,12 @@ check_rel (size_t nsegments, struct segments segments[nsegments], if (sym->st_value + sym->st_size > addr) { /* It is this function. */ - if (tfind (lowstr, knownsrcs, ptrcompare) == NULL) + if (eu_tfind (lowstr, knownsrcs, ptrcompare) == NULL) { printf (_("\ the file containing the function '%s' is not compiled with -fpic/-fPIC\n"), lowstr); - tsearch (lowstr, knownsrcs, ptrcompare); + eu_tsearch (lowstr, knownsrcs, ptrcompare); } } else if (highidx == -1) diff --git a/src/nm.c b/src/nm.c index fbdee8e1..44c20fb2 100644 --- a/src/nm.c +++ b/src/nm.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -537,7 +537,7 @@ static int get_global (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global, void *arg __attribute__ ((unused))) { - tsearch (memcpy (xmalloc (sizeof (Dwarf_Global)), global, + eu_tsearch (memcpy (xmalloc (sizeof (Dwarf_Global)), global, sizeof (Dwarf_Global)), &global_root, global_compare); @@ -696,7 +696,7 @@ get_local_names (Dwarf *dbg) /* Check whether a similar local_name is already in the cache. That should not happen. But if it does, we don't want to leak memory. */ - struct local_name **tres = tsearch (newp, &local_root, + struct local_name **tres = eu_tsearch (newp, &local_root, local_compare); if (tres == NULL) error_exit (errno, _("cannot create search tree")); @@ -1387,7 +1387,7 @@ show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr, && global_root != NULL) { Dwarf_Global fake = { .name = symstr }; - Dwarf_Global **found = tfind (&fake, &global_root, + Dwarf_Global **found = eu_tfind (&fake, &global_root, global_compare); if (found != NULL) { @@ -1442,7 +1442,7 @@ show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr, .lowpc = sym->st_value, .highpc = sym->st_value, }; - struct local_name **found = tfind (&fake, &local_root, + struct local_name **found = eu_tfind (&fake, &local_root, local_compare); if (found != NULL) { From patchwork Tue Oct 10 13:42:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77412 X-Patchwork-Delegate: amerey@redhat.com 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 4AFF0385F00B for ; Tue, 10 Oct 2023 13:44:06 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id C27083857BB2 for ; Tue, 10 Oct 2023 13:43:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C27083857BB2 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 177423022F1A; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 304E13403F5; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 10/16] libdw: make dwarf_getalt thread-safe Date: Tue, 10 Oct 2023 15:42:54 +0200 Message-ID: <20231010134300.53830-10-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libdw/dwarf_getalt.c: Add lock for dbg->alt_dwarf/main->alt_dwarf. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libdw/dwarf_getalt.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/libdw/dwarf_getalt.c b/libdw/dwarf_getalt.c index 0a12dfae..e3894c8c 100644 --- a/libdw/dwarf_getalt.c +++ b/libdw/dwarf_getalt.c @@ -44,6 +44,10 @@ #include #include +/* find_debug_altlink() modifies "dbg->alt_dwarf". + dwarf_getalt() reads "main->alt_dwarf". + Mutual exclusion is enforced to prevent a race. */ +rwlock_define(static, alt_dwarf_lock); char * internal_function @@ -152,7 +156,9 @@ find_debug_altlink (Dwarf *dbg) Dwarf *alt = dwarf_begin (fd, O_RDONLY); if (alt != NULL) { + rwlock_wrlock(alt_dwarf_lock); dbg->alt_dwarf = alt; + rwlock_unlock(alt_dwarf_lock); dbg->alt_fd = fd; } else @@ -163,22 +169,33 @@ find_debug_altlink (Dwarf *dbg) Dwarf * dwarf_getalt (Dwarf *main) { + rwlock_rdlock(alt_dwarf_lock); + Dwarf *alt_dwarf_local = main->alt_dwarf; + rwlock_unlock(alt_dwarf_lock); + /* Only try once. */ - if (main == NULL || main->alt_dwarf == (void *) -1) + if (main == NULL || alt_dwarf_local == (void *) -1) return NULL; - if (main->alt_dwarf != NULL) - return main->alt_dwarf; + if (alt_dwarf_local != NULL) + return alt_dwarf_local; find_debug_altlink (main); + rwlock_rdlock(alt_dwarf_lock); + alt_dwarf_local = main->alt_dwarf; + rwlock_unlock(alt_dwarf_lock); + /* If we found nothing, make sure we don't try again. */ - if (main->alt_dwarf == NULL) + if (alt_dwarf_local == NULL) { + rwlock_wrlock(alt_dwarf_lock); main->alt_dwarf = (void *) -1; + rwlock_unlock(alt_dwarf_lock); + return NULL; } - return main->alt_dwarf; + return alt_dwarf_local; } INTDEF (dwarf_getalt) From patchwork Tue Oct 10 13:42:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77411 X-Patchwork-Delegate: amerey@redhat.com 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 5AAFA3861840 for ; Tue, 10 Oct 2023 13:44:01 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id D1C55385609B for ; Tue, 10 Oct 2023 13:43:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D1C55385609B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 1E42B3022F1B; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 33BA93403F6; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 11/16] libdw: Add locking around __libdw_dieabbrev for dwarf_hasattr Date: Tue, 10 Oct 2023 15:42:55 +0200 Message-ID: <20231010134300.53830-11-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libdw/dwarf_hasattr.c (dwarf_hasattr): Use die_abbrev_lock around __libdw_dieabbrev call. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libdw/dwarf_hasattr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libdw/dwarf_hasattr.c b/libdw/dwarf_hasattr.c index eca08394..92f8de68 100644 --- a/libdw/dwarf_hasattr.c +++ b/libdw/dwarf_hasattr.c @@ -34,6 +34,10 @@ #include #include "libdwP.h" +/* dwarf_hasattr() calls __libdw_dieabbrev() in libdwP.h. + __libdw_dieabbrev() reads/writes "die->abbrev". + Mutual exclusion is enforced around the call to __libdw_dieabbrev to prevent a race. */ +rwlock_define(static, die_abbrev_lock); int dwarf_hasattr (Dwarf_Die *die, unsigned int search_name) @@ -41,8 +45,13 @@ dwarf_hasattr (Dwarf_Die *die, unsigned int search_name) if (die == NULL) return 0; + rwlock_wrlock(die_abbrev_lock); + /* Find the abbreviation entry. */ Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); + + rwlock_unlock(die_abbrev_lock); + if (unlikely (abbrevp == DWARF_END_ABBREV)) { __libdw_seterrno (DWARF_E_INVALID_DWARF); From patchwork Tue Oct 10 13:42:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77410 X-Patchwork-Delegate: amerey@redhat.com 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 7F0F2385842A for ; Tue, 10 Oct 2023 13:44:00 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id A5B5C3858288 for ; Tue, 10 Oct 2023 13:43:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A5B5C3858288 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 238963022F1C; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 370B53403F7; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 12/16] libdw: Make libdw_find_split_unit thread-safe Date: Tue, 10 Oct 2023 15:42:56 +0200 Message-ID: <20231010134300.53830-12-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * (try_split_file): Use eu_tsearch. Add lock for cu->split. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libdw/libdw_find_split_unit.c | 43 +++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c index 533f8072..a288e9bd 100644 --- a/libdw/libdw_find_split_unit.c +++ b/libdw/libdw_find_split_unit.c @@ -34,13 +34,19 @@ #include "libelfP.h" #include -#include +#include #include #include #include #include #include +/* __libdw_link_skel_split() modifies "skel->split = split" + and "split->split = skel". + "cu->split" is read at multiple locations and conditionally updated. + Mutual exclusion is enforced to prevent a race. */ +rwlock_define(static, cu_split_lock); + static void try_split_file (Dwarf_CU *cu, const char *dwo_path) { @@ -57,7 +63,7 @@ try_split_file (Dwarf_CU *cu, const char *dwo_path) if (split->unit_type == DW_UT_split_compile && cu->unit_id8 == split->unit_id8) { - if (tsearch (split->dbg, &cu->dbg->split_tree, + if (eu_tsearch (split->dbg, &cu->dbg->split_tree, __libdw_finddbg_cb) == NULL) { /* Something went wrong. Don't link. */ @@ -65,9 +71,13 @@ try_split_file (Dwarf_CU *cu, const char *dwo_path) break; } + rwlock_wrlock(cu_split_lock); + /* Link skeleton and split compile units. */ __libdw_link_skel_split (cu, split); + rwlock_unlock(cu_split_lock); + /* We have everything we need from this ELF file. And we are going to close the fd to not run out of file descriptors. */ @@ -75,8 +85,13 @@ try_split_file (Dwarf_CU *cu, const char *dwo_path) break; } } + + rwlock_rdlock(cu_split_lock); + if (cu->split == (Dwarf_CU *) -1) dwarf_end (split_dwarf); + + rwlock_unlock(cu_split_lock); } /* Always close, because we don't want to run out of file descriptors. See also the elf_fcntl ELF_C_FDDONE call @@ -89,9 +104,13 @@ Dwarf_CU * internal_function __libdw_find_split_unit (Dwarf_CU *cu) { + rwlock_rdlock(cu_split_lock); + Dwarf_CU *cu_split_local = cu->split; + rwlock_unlock(cu_split_lock); + /* Only try once. */ - if (cu->split != (Dwarf_CU *) -1) - return cu->split; + if (cu_split_local != (Dwarf_CU *) -1) + return cu_split_local; /* We need a skeleton unit with a comp_dir and [GNU_]dwo_name attributes. The split unit will be the first in the dwo file and should have the @@ -116,7 +135,11 @@ __libdw_find_split_unit (Dwarf_CU *cu) free (dwo_path); } - if (cu->split == (Dwarf_CU *) -1) + rwlock_rdlock(cu_split_lock); + cu_split_local = cu->split; + rwlock_unlock(cu_split_lock); + + if (cu_split_local == (Dwarf_CU *) -1) { /* Try compdir plus dwo_name. */ Dwarf_Attribute compdir; @@ -138,9 +161,15 @@ __libdw_find_split_unit (Dwarf_CU *cu) } } + rwlock_wrlock(cu_split_lock); + /* If we found nothing, make sure we don't try again. */ if (cu->split == (Dwarf_CU *) -1) - cu->split = NULL; + { + cu->split = NULL; + cu_split_local = cu->split; + } - return cu->split; + rwlock_unlock(cu_split_lock); + return cu_split_local; } From patchwork Tue Oct 10 13:42:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77413 X-Patchwork-Delegate: amerey@redhat.com 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 AAD6638618D0 for ; Tue, 10 Oct 2023 13:44:06 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id A948038582A3 for ; Tue, 10 Oct 2023 13:43:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A948038582A3 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 2BF32301FE8A; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 3A6CB3403F8; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 13/16] libdw: Make libdw_findcu thread-safe Date: Tue, 10 Oct 2023 15:42:57 +0200 Message-ID: <20231010134300.53830-13-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libdw/libdw_findcu.c (findcu_cb): Use eu_tsearch. (__libdw_findcu): Use eu_tfind and next_tucu_offset_lock. (__libdw_findcu_addr): Use eu_tfind. (__libdw_find_split_dbg_addr): Likewise. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libdw/libdw_findcu.c | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index ed744231..e546fb0f 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -32,9 +32,13 @@ #endif #include -#include +#include #include "libdwP.h" +/* __libdw_findcu modifies "&dbg->next_tu_offset : &dbg->next_cu_offset". + May read or write, so mutual exclusion is enforced to prevent a race. */ +rwlock_define(static, next_tucu_offset_lock); + static int findcu_cb (const void *arg1, const void *arg2) { @@ -213,7 +217,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) Dwarf_Sig8_Hash_insert (&dbg->sig8_hash, unit_id8, newp); /* Add the new entry to the search tree. */ - if (tsearch (newp, tree, findcu_cb) == NULL) + if (eu_tsearch (newp, tree, findcu_cb) == NULL) { /* Something went wrong. Undo the operation. */ *offsetp = oldoff; @@ -234,28 +238,40 @@ __libdw_findcu (Dwarf *dbg, Dwarf_Off start, bool v4_debug_types) /* Maybe we already know that CU. */ struct Dwarf_CU fake = { .start = start, .end = 0 }; - struct Dwarf_CU **found = tfind (&fake, tree, findcu_cb); + struct Dwarf_CU **found = eu_tfind (&fake, tree, findcu_cb); + struct Dwarf_CU *result = NULL; + if (found != NULL) return *found; - if (start < *next_offset) - { - __libdw_seterrno (DWARF_E_INVALID_DWARF); - return NULL; - } + rwlock_wrlock(next_tucu_offset_lock); - /* No. Then read more CUs. */ - while (1) + if (start < *next_offset) + __libdw_seterrno (DWARF_E_INVALID_DWARF); + else { - struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, v4_debug_types); - if (newp == NULL) - return NULL; + /* No. Then read more CUs. */ + while (1) + { + struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, + v4_debug_types); + if (newp == NULL) + { + result = NULL; + break; + } - /* Is this the one we are looking for? */ - if (start < *next_offset || start == newp->start) - return newp; + /* Is this the one we are looking for? */ + if (start < *next_offset || start == newp->start) + { + result = newp; + break; + } + } } - /* NOTREACHED */ + + rwlock_unlock(next_tucu_offset_lock); + return result; } struct Dwarf_CU * @@ -283,7 +299,7 @@ __libdw_findcu_addr (Dwarf *dbg, void *addr) return NULL; struct Dwarf_CU fake = { .start = start, .end = 0 }; - struct Dwarf_CU **found = tfind (&fake, tree, findcu_cb); + struct Dwarf_CU **found = eu_tfind (&fake, tree, findcu_cb); if (found != NULL) return *found; @@ -298,7 +314,7 @@ __libdw_find_split_dbg_addr (Dwarf *dbg, void *addr) /* XXX Assumes split DWARF only has CUs in main IDX_debug_info. */ Elf_Data fake_data = { .d_buf = addr, .d_size = 0 }; Dwarf fake = { .sectiondata[IDX_debug_info] = &fake_data }; - Dwarf **found = tfind (&fake, &dbg->split_tree, __libdw_finddbg_cb); + Dwarf **found = eu_tfind (&fake, &dbg->split_tree, __libdw_finddbg_cb); if (found != NULL) return *found; From patchwork Tue Oct 10 13:42:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77416 X-Patchwork-Delegate: amerey@redhat.com 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 2C749386191E for ; Tue, 10 Oct 2023 13:44:18 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id C5BE53857713 for ; Tue, 10 Oct 2023 13:43:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C5BE53857713 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 85091301FE8B; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 3DDCF340402; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 14/16] libdw,libdwfl: Use eu-search for thread-safety Date: Tue, 10 Oct 2023 15:42:58 +0200 Message-ID: <20231010134300.53830-14-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * libdw/cie.c: Add eu-search.h and remove search.h. Change calls of tsearch/tfind to eu_tsearch/eu_tfind. * libdw/dwarf_getlocation.c: Likewise. * libdw/dwarf_getmacros.c: Likewise. * libdw/dwarf_getsrclines.c: Likewise. * libdw/fde.c: Likewise. * libdwfl/cu.c: Likewise. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- libdw/cie.c | 8 ++++---- libdw/dwarf_getlocation.c | 16 ++++++++-------- libdw/dwarf_getmacros.c | 6 +++--- libdw/dwarf_getsrclines.c | 6 +++--- libdw/fde.c | 6 +++--- libdwfl/cu.c | 4 ++-- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/libdw/cie.c b/libdw/cie.c index 1b0aae7c..758daef5 100644 --- a/libdw/cie.c +++ b/libdw/cie.c @@ -33,7 +33,7 @@ #include "cfi.h" #include "encoded-value.h" #include -#include +#include #include @@ -144,7 +144,7 @@ intern_new_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info) cie->initial_state = NULL; /* Add the new entry to the search tree. */ - if (tsearch (cie, &cache->cie_tree, &compare_cie) == NULL) + if (eu_tsearch (cie, &cache->cie_tree, &compare_cie) == NULL) { free (cie); __libdw_seterrno (DWARF_E_NOMEM); @@ -160,7 +160,7 @@ internal_function __libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset) { const struct dwarf_cie cie_key = { .offset = offset }; - struct dwarf_cie **found = tfind (&cie_key, &cache->cie_tree, &compare_cie); + struct dwarf_cie **found = eu_tfind (&cie_key, &cache->cie_tree, &compare_cie); if (found != NULL) return *found; @@ -189,7 +189,7 @@ internal_function __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info) { const struct dwarf_cie cie_key = { .offset = offset }; - struct dwarf_cie **found = tfind (&cie_key, &cache->cie_tree, &compare_cie); + struct dwarf_cie **found = eu_tfind (&cie_key, &cache->cie_tree, &compare_cie); if (found == NULL) /* We have not read this CIE yet. Enter it. */ (void) intern_new_cie (cache, offset, info); diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index 553fdc98..e26afe37 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -31,7 +31,7 @@ #endif #include -#include +#include #include #include @@ -137,7 +137,7 @@ loc_compare (const void *p1, const void *p2) /* For each DW_OP_implicit_value, we store a special entry in the cache. This points us directly to the block data for later fetching. - Returns zero on success, -1 on bad DWARF or 1 if tsearch failed. */ + Returns zero on success, -1 on bad DWARF or 1 if eu_tsearch failed. */ static int store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op) { @@ -154,7 +154,7 @@ store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op) block->addr = op; block->data = (unsigned char *) data; block->length = op->number; - if (unlikely (tsearch (block, cache, loc_compare) == NULL)) + if (unlikely (eu_tsearch (block, cache, loc_compare) == NULL)) return 1; return 0; } @@ -167,7 +167,7 @@ dwarf_getlocation_implicit_value (Dwarf_Attribute *attr, const Dwarf_Op *op, return -1; struct loc_block_s fake = { .addr = (void *) op }; - struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare); + struct loc_block_s **found = eu_tfind (&fake, &attr->cu->locs, loc_compare); if (unlikely (found == NULL)) { __libdw_seterrno (DWARF_E_NO_BLOCK); @@ -211,7 +211,7 @@ is_constant_offset (Dwarf_Attribute *attr, /* Check whether we already cached this location. */ struct loc_s fake = { .addr = attr->valp }; - struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare); + struct loc_s **found = eu_tfind (&fake, &attr->cu->locs, loc_compare); if (found == NULL) { @@ -235,7 +235,7 @@ is_constant_offset (Dwarf_Attribute *attr, newp->loc = result; newp->nloc = 1; - found = tsearch (newp, &attr->cu->locs, loc_compare); + found = eu_tsearch (newp, &attr->cu->locs, loc_compare); } assert ((*found)->nloc == 1); @@ -266,7 +266,7 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, /* Check whether we already looked at this list. */ struct loc_s fake = { .addr = block->data }; - struct loc_s **found = tfind (&fake, cache, loc_compare); + struct loc_s **found = eu_tfind (&fake, cache, loc_compare); if (found != NULL) { /* We already saw it. */ @@ -655,7 +655,7 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, newp->addr = block->data; newp->loc = result; newp->nloc = *listlen; - (void) tsearch (newp, cache, loc_compare); + (void) eu_tsearch (newp, cache, loc_compare); /* We did it. */ return 0; diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c index a3a78884..d150f05e 100644 --- a/libdw/dwarf_getmacros.c +++ b/libdw/dwarf_getmacros.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include @@ -293,7 +293,7 @@ cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff, Dwarf_Die *cudie) { Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index }; - Dwarf_Macro_Op_Table **found = tfind (&fake, &dbg->macro_ops, + Dwarf_Macro_Op_Table **found = eu_tfind (&fake, &dbg->macro_ops, macro_op_compare); if (found != NULL) return *found; @@ -305,7 +305,7 @@ cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff, if (table == NULL) return NULL; - Dwarf_Macro_Op_Table **ret = tsearch (table, &dbg->macro_ops, + Dwarf_Macro_Op_Table **ret = eu_tsearch (table, &dbg->macro_ops, macro_op_compare); if (unlikely (ret == NULL)) { diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index df003c5f..356284a0 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "dwarf.h" #include "libdwP.h" @@ -1138,7 +1138,7 @@ __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, Dwarf_Lines **linesp, Dwarf_Files **filesp) { struct files_lines_s fake = { .debug_line_offset = debug_line_offset }; - struct files_lines_s **found = tfind (&fake, &dbg->files_lines, + struct files_lines_s **found = eu_tfind (&fake, &dbg->files_lines, files_lines_compare); if (found == NULL) { @@ -1160,7 +1160,7 @@ __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, node->debug_line_offset = debug_line_offset; - found = tsearch (node, &dbg->files_lines, files_lines_compare); + found = eu_tsearch (node, &dbg->files_lines, files_lines_compare); if (found == NULL) { __libdw_seterrno (DWARF_E_NOMEM); diff --git a/libdw/fde.c b/libdw/fde.c index 73d551b6..55065528 100644 --- a/libdw/fde.c +++ b/libdw/fde.c @@ -31,7 +31,7 @@ #endif #include "cfi.h" -#include +#include #include #include "encoded-value.h" @@ -122,7 +122,7 @@ intern_fde (Dwarf_CFI *cache, const Dwarf_FDE *entry) fde->instructions += cie->fde_augmentation_data_size; /* Add the new entry to the search tree. */ - struct dwarf_fde **tres = tsearch (fde, &cache->fde_tree, &compare_fde); + struct dwarf_fde **tres = eu_tsearch (fde, &cache->fde_tree, &compare_fde); if (tres == NULL) { free (fde); @@ -252,7 +252,7 @@ __libdw_find_fde (Dwarf_CFI *cache, Dwarf_Addr address) /* Look for a cached FDE covering this address. */ const struct dwarf_fde fde_key = { .start = address, .end = 0 }; - struct dwarf_fde **found = tfind (&fde_key, &cache->fde_tree, &compare_fde); + struct dwarf_fde **found = eu_tfind (&fde_key, &cache->fde_tree, &compare_fde); if (found != NULL) return *found; diff --git a/libdwfl/cu.c b/libdwfl/cu.c index b1afb19a..71838011 100644 --- a/libdwfl/cu.c +++ b/libdwfl/cu.c @@ -33,7 +33,7 @@ #include "libdwflP.h" #include "libdwP.h" #include "memory-access.h" -#include +#include static inline Dwarf_Arange * @@ -198,7 +198,7 @@ intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu **result) struct dwfl_cu key; key.die.cu = die->cu; - struct dwfl_cu **found = tsearch (&key, &mod->lazy_cu_root, &compare_cukey); + struct dwfl_cu **found = eu_tsearch (&key, &mod->lazy_cu_root, &compare_cukey); if (unlikely (found == NULL)) return DWFL_E_NOMEM; From patchwork Tue Oct 10 13:42:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77417 X-Patchwork-Delegate: amerey@redhat.com 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 8EE9A3861918 for ; Tue, 10 Oct 2023 13:44:44 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 13064385B53C for ; Tue, 10 Oct 2023 13:43:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 13064385B53C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 8D9E43037F33; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 41DFE340403; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 15/16] tests: Add eu-search tests Date: Tue, 10 Oct 2023 15:42:59 +0200 Message-ID: <20231010134300.53830-15-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * tests/eu_search_cfi.c: New file. * tests/eu_search_die.c: New file. * tests/eu_search_lines.c: New file. * tests/eu_search_macros.c: New file. * tests/run-eu-search-tests.sh: New test. * tests/Makefile.am: Add USE_LOCKS condition for -pthread. (check_PROGRAMS): Add eu_search_cfi, eu_search_die, eu_search_lines, and eu_search_macros. (TESTS): Add run-eu-search-tests.sh (eu_search_cfi_LDADD): New variable. (eu_search_die_LDADD): New variable. (eu_search_lines_LDADD): New variable. (eu_search_macros_LDADD): New variable. (eu_search_cfi_LDFLAGS): New variable. Add -pthread if USE_LOCKS is not defined. (eu_search_die_LDFLAGS): Likewise. (eu_search_lines_LDFLAGS): Likewise. (eu_search_macros_LDFLAGS): Likewise. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- tests/Makefile.am | 16 ++- tests/eu_search_cfi.c | 234 +++++++++++++++++++++++++++++++ tests/eu_search_die.c | 262 +++++++++++++++++++++++++++++++++++ tests/eu_search_lines.c | 228 ++++++++++++++++++++++++++++++ tests/eu_search_macros.c | 216 +++++++++++++++++++++++++++++ tests/run-eu-search-tests.sh | 168 ++++++++++++++++++++++ 6 files changed, 1123 insertions(+), 1 deletion(-) create mode 100644 tests/eu_search_cfi.c create mode 100644 tests/eu_search_die.c create mode 100644 tests/eu_search_lines.c create mode 100644 tests/eu_search_macros.c create mode 100755 tests/run-eu-search-tests.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index 32b18e6e..a66b1033 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -32,6 +32,10 @@ else tests_rpath = no endif +if USE_LOCKS + AM_CFLAGS += -pthread +endif + check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ showptable update1 update2 update3 update4 test-nlist \ show-die-info get-files next-files get-lines next-lines \ @@ -63,6 +67,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ getphdrnum leb128 read_unaligned \ msg_tst system-elf-libelf-test system-elf-gelf-test \ nvidia_extended_linemap_libdw \ + eu_search_cfi eu_search_die eu_search_lines eu_search_macros \ $(asm_TESTS) asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ @@ -211,7 +216,8 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ $(asm_TESTS) run-disasm-bpf.sh run-low_high_pc-dw-form-indirect.sh \ run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \ run-readelf-dw-form-indirect.sh run-strip-largealign.sh \ - run-readelf-Dd.sh + run-readelf-Dd.sh \ + run-eu-search-tests.sh if !BIARCH export ELFUTILS_DISABLE_BIARCH = 1 @@ -804,6 +810,14 @@ getphdrnum_LDADD = $(libelf) $(libdw) leb128_LDADD = $(libelf) $(libdw) read_unaligned_LDADD = $(libelf) $(libdw) nvidia_extended_linemap_libdw_LDADD = $(libelf) $(libdw) +eu_search_cfi_LDFLAGS = $(if $(filter undefined,$(origin USE_LOCKS)),-pthread) $(AM_LDFLAGS) +eu_search_die_LDFLAGS = $(if $(filter undefined,$(origin USE_LOCKS)),-pthread) $(AM_LDFLAGS) +eu_search_lines_LDFLAGS = $(if $(filter undefined,$(origin USE_LOCKS)),-pthread) $(AM_LDFLAGS) +eu_search_macros_LDFLAGS = $(if $(filter undefined,$(origin USE_LOCKS)),-pthread) $(AM_LDFLAGS) +eu_search_cfi_LDADD = $(libeu) $(libelf) $(libdw) +eu_search_die_LDADD = $(libdw) +eu_search_lines_LDADD = $(libdw) $(libelf) +eu_search_macros_LDADD = $(libdw) # We want to test the libelf headers against the system elf.h header. # Don't include any -I CPPFLAGS. Except when we install our own elf.h. diff --git a/tests/eu_search_cfi.c b/tests/eu_search_cfi.c new file mode 100644 index 00000000..0b63b213 --- /dev/null +++ b/tests/eu_search_cfi.c @@ -0,0 +1,234 @@ +/*Test program for eu_search_cfi + Copyright (C) 2023 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + elfutils 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see. */ + +#include +#include +#include +#include ELFUTILS_HEADER(dw) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "system.h" +#include + +static void handle_section(char *name, const unsigned char e_ident[], Elf_Scn *scn, const bool is_eh); +static void *thread_work(void *arg); + +typedef struct +{ + char *name; + const unsigned char *e_ident; + Elf_Scn * scn; + bool is_eh; +} + +ThreadData; + +static void *thread_work(void *arg) +{ + ThreadData *data = (ThreadData*) arg; + handle_section(data->name, data->e_ident, data->scn, data->is_eh); + free(data); + return NULL; +} + +static void handle_section(char *name, const unsigned char e_ident[], + Elf_Scn *scn, const bool is_eh) +{ + if (is_eh) + printf(".eh_frame\n"); + else + printf(".debug_frame\n"); + + GElf_Shdr mem; + GElf_Shdr *shdr = gelf_getshdr(scn, &mem); + if (shdr == NULL) + error(EXIT_FAILURE, 0, "Couldn't get section header: %s", + elf_errmsg(-1)); + if ((shdr->sh_flags &SHF_COMPRESSED) != 0) + { + if (elf_compress(scn, 0, 0) < 0) + error(EXIT_FAILURE, 0, "Couldn't decompress section: %s", + elf_errmsg(-1)); + } + else if (name[0] == '.' && name[1] == 'z') + { + if (elf_compress_gnu(scn, 0, 0) < 0) + error(EXIT_FAILURE, 0, "Couldn't decompress section: %s", + elf_errmsg(-1)); + } + + Elf_Data *data = elf_getdata(scn, NULL); + if (data == NULL || data->d_buf == NULL) + error(EXIT_FAILURE, 0, "no section data"); + + int res; + Dwarf_Off off; + Dwarf_Off next_off = 0; + Dwarf_CFI_Entry entry; + while ((res = dwarf_next_cfi(e_ident, data, is_eh, off = next_off, &next_off, &entry)) == 0) + { + printf("[%" PRId64 "] ", off); + if (dwarf_cfi_cie_p(&entry)) + printf("CIE augmentation=\"%s\"\n", entry.cie.augmentation); + else + { + printf("FDE cie=[%" PRId64 "]\n", entry.fde.CIE_pointer); + + Dwarf_Off cie_off = entry.fde.CIE_pointer; + Dwarf_Off cie_off_next; + Dwarf_CFI_Entry cie_entry; + if (dwarf_next_cfi(e_ident, data, is_eh, cie_off, &cie_off_next, &cie_entry) != 0 || + !dwarf_cfi_cie_p(&cie_entry)) + error(EXIT_FAILURE, 0, "FDE doesn't point to CIE"); + } + } + + if (res < 0) + error(EXIT_FAILURE, 0, "dwarf_next_cfi failed: %s\n", + dwarf_errmsg(-1)); +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) + error(EXIT_FAILURE, 0, "need file name argument"); + + const char *file = argv[1]; + printf("%s\n", file); + + int fd = open(file, O_RDONLY); + if (fd == -1) + error(EXIT_FAILURE, errno, "cannot open input file `%s'", file); + + elf_version(EV_CURRENT); + + Elf *elf = elf_begin(fd, ELF_C_READ, NULL); + if (elf == NULL) + error(EXIT_FAILURE, 0, "cannot create ELF descriptor: %s", elf_errmsg(-1)); + + size_t esize; + const unsigned char *ident = (const unsigned char *) elf_getident(elf, &esize); + if (ident == NULL || esize < EI_NIDENT) + error(EXIT_FAILURE, 0, "no, or too small, ELF ident"); + + GElf_Ehdr ehdr; + if (gelf_getehdr(elf, &ehdr) == NULL) + error(EXIT_FAILURE, 0, "cannot get the ELF header: %s\n", elf_errmsg(-1)); + + size_t strndx = ehdr.e_shstrndx; + + int num_threads = 4; + pthread_t *threads = (pthread_t*) malloc(num_threads * sizeof(pthread_t)); + ThreadData **thread_data = (ThreadData**) malloc(num_threads * sizeof(ThreadData*)); + int thread_count = 0; + + if (!threads || !thread_data) + { + fprintf(stderr, "Failed to allocate memory for threads.\n"); + free(threads); + free(thread_data); + return 1; + } + + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn(elf, scn)) != NULL) + { + GElf_Shdr shdr; + if (gelf_getshdr(scn, &shdr) != NULL) + { + char *name = elf_strptr(elf, strndx, (size_t) shdr.sh_name); + if (name != NULL && shdr.sh_type == SHT_PROGBITS) + { + bool is_eh = false; + if (strcmp(name, ".eh_frame") == 0) + { + is_eh = true; + } + else if (strcmp(name, ".debug_frame") == 0 || strcmp(name, ".zdebug_frame") == 0) + { + is_eh = false; + } + else + { + continue; + } + + if (thread_count >= num_threads) + { + num_threads *= 2; + threads = realloc(threads, num_threads * sizeof(pthread_t)); + thread_data = realloc(thread_data, num_threads * sizeof(ThreadData*)); + } + + thread_data[thread_count] = malloc(sizeof(ThreadData)); + thread_data[thread_count]->name = name; + thread_data[thread_count]->e_ident = ident; + thread_data[thread_count]->scn = scn; + thread_data[thread_count]->is_eh = is_eh; + + if (pthread_create(&threads[thread_count], NULL, thread_work, thread_data[thread_count]) != 0) + { + perror("Failed to create thread"); + for (int j = 0; j < thread_count; j++) + { + pthread_cancel(threads[j]); + } + free(threads); + free(thread_data); + return 1; + } + else + { + thread_count++; + } + } + } + } + + for (int i = 0; i < thread_count; i++) + { + if (pthread_join(threads[i], NULL) != 0) + { + perror("Failed to join thread"); + free(threads); + free(thread_data); + return 1; + } + } + + for (int i = 0; i < thread_count; i++) + { + free(thread_data[i]); + } + + free(threads); + free(thread_data); + + elf_end(elf); + close(fd); + + return 0; +} \ No newline at end of file diff --git a/tests/eu_search_die.c b/tests/eu_search_die.c new file mode 100644 index 00000000..a7f75521 --- /dev/null +++ b/tests/eu_search_die.c @@ -0,0 +1,262 @@ +/*Test program for eu_search_die. + Copyright (C) 2023 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + elfutils 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see. */ +#include +#include ELFUTILS_HEADER(dw) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void *thread_work(void *arg); +static int check_die(Dwarf_Die *die); +static int check_dbg(Dwarf *dbg); + +/*The main Dwarf file. */ +static Dwarf * dwarf; + +typedef struct +{ + Dwarf * dbg; + Dwarf_Off start_offset; + Dwarf_Off end_offset; + int result; +} + +ThreadData; + +static void *thread_work(void *arg) +{ + ThreadData *data = (ThreadData*) arg; + data->result = check_dbg(data->dbg); + return NULL; +} + +static int check_die(Dwarf_Die *die) +{ + if (dwarf_tag(die) == DW_TAG_invalid) + { + printf("Invalid die\n"); + return -1; + } + + int res = 0; + void *addr = die->addr; + Dwarf_Die die2; + if (dwarf_die_addr_die(dwarf, addr, &die2) == NULL) + { + printf("Bad die addr die at offset %" PRIx64 "\n", dwarf_dieoffset(die)); + res = -1; + } + + if (dwarf_tag(die) != dwarf_tag(&die2)) + { + printf("Tags differ for die at offset %" PRIx64 "\n", dwarf_dieoffset(die)); + res = -1; + } + + if (dwarf_cuoffset(die) != dwarf_cuoffset(&die2)) + { + printf("CU offsets differ for die at offset %" PRIx64 "\n", dwarf_dieoffset(die)); + res = -1; + } + + Dwarf_Die child; + if (dwarf_child(die, &child) == 0) + res |= check_die(&child); + + Dwarf_Die sibling; + if (dwarf_siblingof(die, &sibling) == 0) + res |= check_die(&sibling); + + return res; +} + +static int check_dbg(Dwarf *dbg) +{ + int res = 0; + Dwarf_Off off = 0; + Dwarf_Off old_off = 0; + size_t hsize; + Dwarf_Off abbrev; + uint8_t addresssize; + uint8_t offsetsize; + + while (dwarf_nextcu(dbg, off, &off, &hsize, &abbrev, &addresssize, &offsetsize) == 0) + { + Dwarf_Die die; + if (dwarf_offdie(dbg, old_off + hsize, &die) != NULL) + { + printf("checking CU at %" PRIx64 "\n", old_off); + res |= check_die(&die); + } + + old_off = off; + } + + // Same for type... + Dwarf_Half version; + uint64_t typesig; + Dwarf_Off typeoff; + off = 0; + old_off = 0; + + while (dwarf_next_unit(dbg, off, &off, &hsize, &version, &abbrev, &addresssize, &offsetsize, &typesig, &typeoff) == 0) + { + Dwarf_Die die; + if (dwarf_offdie_types(dbg, old_off + hsize, &die) != NULL) + { + printf("checking TU at %" PRIx64 "\n", old_off); + res |= check_die(&die); + } + + // We should have seen this already, but double check... + if (dwarf_offdie_types(dbg, old_off + typeoff, &die) != NULL) + { + printf("checking Type DIE at %" PRIx64 "\n", old_off + hsize + typeoff); + res |= check_die(&die); + } + + old_off = off; + } + + Dwarf *alt = dwarf_getalt(dbg); + + if (alt != NULL) + { + printf("checking alt debug\n"); + res |= check_dbg(alt); + } + + // Split or Type Dwarf_Dies gotten through dwarf_get_units. + Dwarf_CU *cu = NULL; + Dwarf_Die subdie; + uint8_t unit_type; + while (dwarf_get_units(dbg, cu, &cu, NULL, &unit_type, NULL, &subdie) == 0) + { + if (dwarf_tag(&subdie) != DW_TAG_invalid) + { + printf("checking %" + PRIx8 " subdie\n", unit_type); + res |= check_die(&subdie); + } + } + + return res; +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + printf("No file given.\n"); + return -1; + } + + const char *name = argv[1]; + int fd = open(name, O_RDONLY); + if (fd < 0) + { + printf("Cannot open '%s': %s\n", name, strerror(errno)); + return -1; + } + + dwarf = dwarf_begin(fd, DWARF_C_READ); + if (dwarf == NULL) + { + printf("Not a Dwarf file '%s': %s\n", name, dwarf_errmsg(-1)); + close(fd); + return -1; + } + + printf("checking %s\n", name); + + int num_threads = 4; + pthread_t *threads = (pthread_t*) malloc(num_threads* sizeof(pthread_t)); + ThreadData *thread_data = (ThreadData*) malloc(num_threads* sizeof(ThreadData)); + + if (!threads || !thread_data) + { + fprintf(stderr, "Failed to allocate memory for threads.\n"); + free(threads); + free(thread_data); + return 1; + } + + Dwarf_Off total_off = 0; + Dwarf_Off unit_off = 0; + size_t hsize; + Dwarf_Off abbrev; + uint8_t addresssize; + uint8_t offsetsize; + + while (dwarf_nextcu(dwarf, unit_off, &unit_off, &hsize, &abbrev, &addresssize, &offsetsize) == 0) + { + thread_data[total_off % num_threads].start_offset = unit_off; + thread_data[total_off % num_threads].end_offset = unit_off + hsize; + total_off++; + } + + for (int i = 0; i < num_threads; i++) + { + thread_data[i].dbg = dwarf; + if (pthread_create(&threads[i], NULL, thread_work, (void*) &thread_data[i]) != 0) + { + perror("Failed to create thread"); + for (int j = 0; j < i; j++) + { + pthread_cancel(threads[j]); + } + free(threads); + free(thread_data); + return 1; + } + } + + for (int i = 0; i < num_threads; i++) + { + if (pthread_join(threads[i], NULL) != 0) + { + perror("Failed to join thread"); + free(threads); + free(thread_data); + return 1; + } + } + + int res = 0; + for (int i = 0; i < num_threads; i++) + { + res |= thread_data[i].result; + } + + free(threads); + free(thread_data); + + dwarf_end(dwarf); + close(fd); + + return res; +} \ No newline at end of file diff --git a/tests/eu_search_lines.c b/tests/eu_search_lines.c new file mode 100644 index 00000000..b7a875d8 --- /dev/null +++ b/tests/eu_search_lines.c @@ -0,0 +1,228 @@ +/*Test program for eu_search_lines. + Copyright (C) 2023 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + elfutils 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see. */ + +#include +#include +#include +#include +#include ELFUTILS_HEADER(dw) +#include +#include +#include +#include +#include + +typedef struct +{ + const char *filename; + int result; +} + +ThreadData; + +static void *thread_work(void *arg) +{ + ThreadData *data = (ThreadData*) arg; + + int fd = open(data->filename, O_RDONLY); + + Dwarf *dbg = dwarf_begin(fd, DWARF_C_READ); + if (dbg == NULL) + { + printf("%s not usable: %s\n", data->filename, dwarf_errmsg(-1)); + close(fd); + free(data); + pthread_exit(NULL); + } + + Dwarf_Off cuoff = 0; + Dwarf_Off old_cuoff = 0; + size_t hsize; + Dwarf_Off ao; + uint8_t asz; + uint8_t osz; + while (dwarf_nextcu(dbg, cuoff, &cuoff, &hsize, &ao, &asz, &osz) == 0) + { + printf("cuhl = %zu, o = %llu, asz = %hhu, osz = %hhu, ncu = %llu\n", + hsize, (unsigned long long int) ao, + asz, osz, (unsigned long long int) cuoff); + + // Get the DIE for the CU. + Dwarf_Die die; + if (dwarf_offdie(dbg, old_cuoff + hsize, &die) == NULL) + { + printf("%s: cannot get CU die\n", data->filename); + data->result = 1; + break; + } + + old_cuoff = cuoff; + + Dwarf_Lines * lb; + size_t nlb; + if (dwarf_getsrclines(&die, &lb, &nlb) != 0) + { + printf("%s: cannot get lines\n", data->filename); + data->result = 1; + break; + } + + printf(" %zu lines\n", nlb); + + for (size_t i = 0; i < nlb; ++i) + { + Dwarf_Line *l = dwarf_onesrcline(lb, i); + if (l == NULL) + { + printf("%s: cannot get individual line\n", data->filename); + data->result = 1; + break; + } + + Dwarf_Addr addr; + if (dwarf_lineaddr(l, &addr) != 0) + addr = 0; + const char *file = dwarf_linesrc(l, NULL, NULL); + int line; + if (dwarf_lineno(l, &line) != 0) + line = 0; + + printf("%" PRIx64 ": %s:%d:", (uint64_t) addr, file ? : "???", line); + + // Getting the file path through the Dwarf_Files should + // result in the same path. + Dwarf_Files * files; + size_t idx; + if (dwarf_line_file(l, &files, &idx) != 0) + { + printf("%s: cannot get file from line (%zd): %s\n", + data->filename, i, dwarf_errmsg(-1)); + data->result = 1; + break; + } + + const char *path = dwarf_filesrc(files, idx, NULL, NULL); + if ((path == NULL && file != NULL) || + (path != NULL && file == NULL) || + (strcmp(file, path) != 0)) + { + printf("%s: line %zd srcline (%s) != file srcline (%s)\n", + data->filename, i, file ? : "???", path ? : "???"); + data->result = 1; + break; + } + + int column; + if (dwarf_linecol(l, &column) != 0) + column = 0; + if (column >= 0) + printf("%d:", column); + + bool is_stmt; + if (dwarf_linebeginstatement(l, &is_stmt) != 0) + is_stmt = false; + bool end_sequence; + if (dwarf_lineendsequence(l, &end_sequence) != 0) + end_sequence = false; + bool basic_block; + if (dwarf_lineblock(l, &basic_block) != 0) + basic_block = false; + bool prologue_end; + if (dwarf_lineprologueend(l, &prologue_end) != 0) + prologue_end = false; + bool epilogue_begin; + if (dwarf_lineepiloguebegin(l, &epilogue_begin) != 0) + epilogue_begin = false; + + printf(" is_stmt:%s, end_seq:%s, bb:%s, prologue:%s, epilogue:%s\n", + is_stmt ? "yes" : "no", end_sequence ? "yes" : "no", + basic_block ? "yes" : "no", prologue_end ? "yes" : "no", + epilogue_begin ? "yes" : "no"); + } + } + + dwarf_end(dbg); + close(fd); + free(data); + + pthread_exit(NULL); +} + +int main(int argc, char *argv[]) +{ + int result = 0; + int cnt; + + if (argc < 2) + { + printf("Usage: %s[ ...]\n", argv[0]); + return 1; + } + + pthread_t *threads = (pthread_t*) malloc((argc - 1) *sizeof(pthread_t)); + ThreadData **thread_data = (ThreadData **) malloc((argc - 1) *sizeof(ThreadData*)); + + if (!threads || !thread_data) + { + fprintf(stderr, "Failed to allocate memory for threads.\n"); + free(threads); + free(thread_data); + return 1; + } + + for (cnt = 1; cnt < argc; ++cnt) + { + thread_data[cnt - 1] = (ThreadData*) malloc(sizeof(ThreadData)); + thread_data[cnt - 1]->filename = argv[cnt]; + thread_data[cnt - 1]->result = 0; + + if (pthread_create(&threads[cnt - 1], NULL, thread_work, thread_data[cnt - 1]) != 0) + { + perror("Failed to create thread"); + for (int j = 0; j < cnt; j++) + { + pthread_cancel(threads[j]); + } + free(threads); + free(thread_data); + return 1; + } + } + + for (cnt = 0; cnt < argc - 1; ++cnt) + { + if (pthread_join(threads[cnt], NULL) != 0) + { + perror("Failed to join thread"); + free(threads); + free(thread_data); + return 1; + } + + if (thread_data[cnt]->result != 0) + { + result = 1; + } + + free(thread_data[cnt]); + } + + free(threads); + free(thread_data); + + return result; +} \ No newline at end of file diff --git a/tests/eu_search_macros.c b/tests/eu_search_macros.c new file mode 100644 index 00000000..3dca828e --- /dev/null +++ b/tests/eu_search_macros.c @@ -0,0 +1,216 @@ +/*Test program for eu_search_macros + Copyright (C) 2023 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + elfutils 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see. */ + +#include +#include ELFUTILS_HEADER(dw) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void *thread_work(void *arg); +static int mac(Dwarf_Macro *macro, void *dbg); +static void include(Dwarf *dbg, Dwarf_Off macoff, ptrdiff_t token); + +typedef struct +{ + Dwarf * dbg; + Dwarf_Die * cudie; + bool new_style; +} + +ThreadData; + +static void *thread_work(void *arg) +{ + ThreadData *data = (ThreadData*) arg; + Dwarf *dbg = data->dbg; + Dwarf_Die *cudie = data->cudie; + bool new_style = data->new_style; + + for (ptrdiff_t off = new_style ? DWARF_GETMACROS_START : 0; + (off = dwarf_getmacros(cudie, mac, dbg, off));) + { + if (off == -1) + { + puts(dwarf_errmsg(dwarf_errno())); + break; + } + } + + return NULL; +} + +static void include(Dwarf *dbg, Dwarf_Off macoff, ptrdiff_t token) +{ + while ((token = dwarf_getmacros_off(dbg, macoff, mac, dbg, token)) != 0) + { + if (token == -1) + { + puts(dwarf_errmsg(dwarf_errno())); + break; + } + } +} + +static int +mac(Dwarf_Macro *macro, void *dbg) +{ + static atomic_int level = 0; + + unsigned int opcode; + dwarf_macro_opcode(macro, &opcode); + switch (opcode) + { + case DW_MACRO_import: + { + Dwarf_Attribute at; + int r = dwarf_macro_param(macro, 0, &at); + assert(r == 0); + + Dwarf_Word w; + r = dwarf_formudata(&at, &w); + assert(r == 0); + + printf ("%*sinclude %#" PRIx64 "\n", level, "", w); + + atomic_fetch_add(&level, 1); + + include(dbg, w, DWARF_GETMACROS_START); + + atomic_fetch_sub(&level, 1); + + printf ("%*s/include\n", level, ""); + break; + } + + case DW_MACRO_start_file: + { + Dwarf_Files * files; + size_t nfiles; + if (dwarf_macro_getsrcfiles(dbg, macro, &files, &nfiles) < 0) + printf("dwarf_macro_getsrcfiles: %s\n", dwarf_errmsg(dwarf_errno())); + + Dwarf_Word w = 0; + dwarf_macro_param2(macro, &w, NULL); + + const char *name = dwarf_filesrc (files, (size_t) w, NULL, NULL); + printf ("%*sfile %s\n", level, "", name); + atomic_fetch_add(&level, 1); + break; + } + + case DW_MACRO_end_file: + { + atomic_fetch_sub(&level, 1); + printf ("%*s/file\n", level, ""); + break; + } + + case DW_MACINFO_define: + case DW_MACRO_define_strp: + { + const char *value; + dwarf_macro_param2(macro, NULL, &value); + printf ("%*s%s\n", level, "", value); + break; + } + + case DW_MACINFO_undef: + case DW_MACRO_undef_strp: + break; + + default: + { + size_t paramcnt; + dwarf_macro_getparamcnt(macro, ¶mcnt); + printf ("%*sopcode %u with %zd arguments\n", level, "", opcode, paramcnt); + break; + } + } + + return DWARF_CB_ABORT; +} + +int main(int argc, char *argv[]) +{ + assert(argc >= 3); + const char *name = argv[1]; + ptrdiff_t cuoff = strtol(argv[2], NULL, 0); + bool new_style = argc > 3; + + int fd = open(name, O_RDONLY); + Dwarf *dbg = dwarf_begin(fd, DWARF_C_READ); + + Dwarf_Die cudie_mem, *cudie = dwarf_offdie(dbg, cuoff, &cudie_mem); + + int num_threads = 4; + pthread_t *threads = malloc(num_threads* sizeof(pthread_t)); + ThreadData *thread_data = malloc(num_threads* sizeof(ThreadData)); + + if (!threads || !thread_data) + { + fprintf(stderr, "Failed to allocate memory for threads.\n"); + free(threads); + free(thread_data); + return 1; + } + + for (int i = 0; i < num_threads; i++) + { + thread_data[i].dbg = dbg; + thread_data[i].cudie = cudie; + thread_data[i].new_style = new_style; + + if (pthread_create(&threads[i], NULL, thread_work, (void*) &thread_data[i]) != 0) + { + perror("Failed to create thread"); + for (int j = 0; j < i; j++) + { + pthread_cancel(threads[j]); + } + free(threads); + free(thread_data); + return 1; + } + } + + for (int i = 0; i < num_threads; i++) + { + if (pthread_join(threads[i], NULL) != 0) + { + perror("Failed to join thread"); + free(threads); + free(thread_data); + return 1; + } + } + + free(threads); + free(thread_data); + + dwarf_end(dbg); + + return 0; +} \ No newline at end of file diff --git a/tests/run-eu-search-tests.sh b/tests/run-eu-search-tests.sh new file mode 100755 index 00000000..84edc234 --- /dev/null +++ b/tests/run-eu-search-tests.sh @@ -0,0 +1,168 @@ +#! /bin/sh +# Copyright (C) 2015, 2018 Red Hat, Inc. +# This file is part of elfutils. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# elfutils 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. $srcdir/test-subr.sh + +# Extract the value of USE_ADDRESS_SANITIZER_TRUE from config.status +# Cannot use Helgrind and Address Sanitizer together. +# Test will be skipped if Address Sanitizer is enabled. +USE_ADDRESS_SANITIZER=$(grep 'USE_ADDRESS_SANITIZER_TRUE' ${abs_builddir}/../config.status | awk -F'=' '{print $2}') + +if [[ "$USE_ADDRESS_SANITIZER" == "\"#\"" ]]; then + echo "Address Sanitizer is disabled." +else + echo "Address Sanitizer is enabled. Skipping test." + exit 77 +fi + +# Extract the value of USE_MEMORY_SANITIZER_TRUE from config.status +# Cannot use Helgrind and Memory Sanitizer together. +# Test will be skipped if Memory Sanitizer is enabled. +USE_MEMORY_SANITIZER=$(grep 'USE_MEMORY_SANITIZER_TRUE' ${abs_builddir}/../config.status | awk -F'=' '{print $2}') + +if [[ "$USE_MEMORY_SANITIZER" == "\"#\"" ]]; then + echo "Memory Sanitizer is disabled." +else + echo "Memory Sanitizer is enabled. Skipping test." + exit 77 +fi + +# Extract the value of USE_LOCKS from config.h +# Test will only be run if USE_LOCKS is defined. Otherwise, skip. +USE_LOCKS=$(grep '^#define USE_LOCKS' ${abs_builddir}/../config.h | awk '{print $3}') + +if [[ "$USE_LOCKS" -eq 1 ]]; then + echo "USE_LOCKS is defined." +else + echo "USE_LOCKS is not defined. Skipping test." + exit 77 +fi + +# Disable valgrind if configured, since we are already using it here. +SAVED_VALGRIND_CMD="$VALGRIND_CMD" +unset VALGRIND_CMD + +echo "Begin tests..." + +# Begin data race test for parallelized dwarf-die-addr-die +# Tests thread safety for updated libdw_findcu.c and libdw_find_split_unit.c +testfiles testfile-debug-types +testfiles testfile_multi_main testfile_multi.dwz +testfiles testfilebazdbgppc64.debug +testfiles testfile-dwarf-4 testfile-dwarf-5 +testfiles testfile-splitdwarf-4 testfile-hello4.dwo testfile-world4.dwo +testfiles testfile-splitdwarf-5 testfile-hello5.dwo testfile-world5.dwo + +die_test_files=("testfile-debug-types" + "testfile_multi_main" "testfile_multi.dwz" + "testfilebazdbgppc64.debug" + "testfile-dwarf-4" "testfile-dwarf-5" + "testfile-splitdwarf-4" "testfile-hello4.dwo" "testfile-world4.dwo" + "testfile-splitdwarf-5" "testfile-hello5.dwo" "testfile-world5.dwo") + +echo -e "\nStarting data race test for dwarf-die-addr-die" + +for file in "${die_test_files[@]}"; do + helgrind_output=$(valgrind --tool=helgrind "${abs_builddir}/eu_search_die" "$file" 2>&1) + + if grep -q "ERROR SUMMARY: 0 errors" <<< "$helgrind_output"; then + echo "No data races found for $file. Test passed." + else + echo "Data races found for $file. Test failed." + echo "$helgrind_output" + exit 1 + fi +done + +# Begin data race test for parallelized next_cfi +# Tests thread safety for updated cie.c and fde.c +testfiles testfile11 testfile12 +testfiles testfilearm testfileaarch64 +testfiles testfileppc32 testfileppc64 + +cfi_test_files=("testfile11" "testfile12" + "testfilearm" "testfileaarch64" + "testfileppc32" "testfileppc64") + +echo -e "\nStarting data race test for next_cfi" + +for file in "${cfi_test_files[@]}"; do + + helgrind_output=$(valgrind --tool=helgrind "${abs_builddir}/eu_search_cfi" $file 2>&1) + + if grep -q "ERROR SUMMARY: 0 errors" <<< "$helgrind_output"; then + echo "No data races found for $file. Test passed." + else + echo "Data races found for $file. Test failed." + echo "$helgrind_output" + exit 1 + fi + +done + +# Begin data race test for parallelizd dwarf-getmacros +# Tests thread safety for updated dwarf_getmacros.c +testfiles testfile51 +testfiles testfile-macros +testfiles testfile-macros-0xff + +macro_test_files=("testfile51 0xb" + "testfile51 0x84" + "testfile-macrosm 0xb" + "testfile-macros-0xff 0xb") + +echo -e "\nStarting data race test for dwarf-getmacros" + +for file in "${macro_test_files[@]}"; do + + helgrind_output=$(valgrind --tool=helgrind "${abs_builddir}/eu_search_macros" $file 2>&1) + + if grep -q "ERROR SUMMARY: 0 errors" <<< "$helgrind_output"; then + echo "No data races found for $file. Test passed." + else + echo "Data races found for $file. Test failed." + echo "$helgrind_output" + exit 1 + fi + +done + +# Begin data race test for parallelized get-lines +# Tests thread safety for updated dwarf_getsrclines.c +testfiles testfile testfile2 testfilenolines + +lines_test_files=("testfile" "testfile2" "testfilenolines") + +echo -e "\nStarting data race test for get-lines" + +for file in "${lines_test_files[@]}"; do + + helgrind_output=$(valgrind --tool=helgrind "${abs_builddir}/eu_search_lines" $file 2>&1) + + if grep -q "ERROR SUMMARY: 0 errors" <<< "$helgrind_output"; then + echo "No data races found for $file. Test passed." + else + echo -e "$helgrind_output" + echo "Data races found for $file. Test failed." + exit 1 + fi + +done + +# This line is reached only if no data races were found in any test +# Exit with success status. +exit 0 \ No newline at end of file From patchwork Tue Oct 10 13:43:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 77414 X-Patchwork-Delegate: amerey@redhat.com 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 07E15386191E for ; Tue, 10 Oct 2023 13:44:09 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id CCD5E3856275 for ; Tue, 10 Oct 2023 13:43:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CCD5E3856275 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 96EC63037F36; Tue, 10 Oct 2023 15:43:35 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 451D3340404; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard Subject: [PATCH 16/16] configure: No longer mark --enable-thread-safety as EXPERIMENTAL Date: Tue, 10 Oct 2023 15:43:00 +0200 Message-ID: <20231010134300.53830-16-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, 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: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org From: Heather McIntyre * configure.ac (--enable-thread-safety): Remove experimental warning. Signed-off-by: Heather S. McIntyre Signed-off-by: Mark Wielaard --- configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 29ed32fe..be2103e2 100644 --- a/configure.ac +++ b/configure.ac @@ -79,12 +79,10 @@ AC_DEFINE_UNQUOTED(DEFAULT_AR_DETERMINISTIC, $default_ar_deterministic, AC_ARG_ENABLE([thread-safety], AS_HELP_STRING([--enable-thread-safety], - [enable thread safety of libraries EXPERIMENTAL]), + [enable thread safety of libraries]), use_locks=$enableval, use_locks=no) AM_CONDITIONAL(USE_LOCKS, test "$use_locks" = yes) AS_IF([test "$use_locks" = yes], [AC_DEFINE(USE_LOCKS)]) -AS_IF([test "$use_locks" = yes], - [AC_MSG_WARN([thread-safety is EXPERIMENTAL tests might fail.])]) AH_TEMPLATE([USE_LOCKS], [Defined if libraries should be thread-safe.]) @@ -907,10 +905,10 @@ AC_MSG_NOTICE([ Symbol versioning : ${enable_symbol_versioning} NOT RECOMMENDED FEATURES (should all be no) - Experimental thread safety : ${use_locks} install elf.h : ${install_elfh} OTHER FEATURES + Enable thread safety : ${use_locks} Deterministic archives by default : ${default_ar_deterministic} Native language support : ${USE_NLS} Extra Valgrind annotations : ${use_vg_annotations}