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;