From patchwork Fri Aug 2 23:38:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95237 X-Patchwork-Delegate: mark@klomp.org 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 A7111385842C for ; Fri, 2 Aug 2024 23:39:13 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 1A3E53858D20 for ; Fri, 2 Aug 2024 23:39:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1A3E53858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1A3E53858D20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641944; cv=none; b=MD3IH34Yefj2HdMr2H5xHHpgtc7chjZzJAVvm/VYUqOCYFu6bIUystiJ/6p0qTnQOopzdoRPlscZc0XToHzvJHhEaj44x+oxax5Ni7G8PAmZVIDLowCrfPVSIpFU+DaBzyG28mW54DHDfGlIpkvOfU+rjyb1EhAklziIpLQwAO0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641944; c=relaxed/simple; bh=vW/rzugGpxsAGyIY4wDQnTCR1FHXBVsz9SxszNbIhxs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=lILQxCnlADCT4Y2PughI8kQAwZGW69y1qHZOVPhzaFYYTj0RXd4BCUlMXpGk7TOe0BT8TdNszW1rJqm+q8KtYatUcAMgDQaPmh+iFTShzRYe6acVSKQPGgtqh+dZ2fIeftpWncspnYOa5hP8c3qoV+ZXqYlJgCp2z3Xm4Gdxeqs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641942; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vGNBqBHNW+rTLAGDXUEWetsIrnfgGyIG6/1qg77kIg0=; b=fyLX+RmA2g37LFRFgfZtQ9GMYu2k+/cc4Iozj3kXajFNeR0qTTzOpXHwZcyIW/k97BNtNI unMC9P/dMyLDh0y2kMEQBF6eoLUgNWGDxp6ote3AHbMFm9+WD1VxSGmuvRu8n4/h4b3SXO 0WSROZyYLlci4zwhQNQZ31qpKQk5wgY= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-613-IEcfqRQaMiqXGqN2gWP4KQ-1; Fri, 02 Aug 2024 19:38:59 -0400 X-MC-Unique: IEcfqRQaMiqXGqN2gWP4KQ-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A3D221955D42; Fri, 2 Aug 2024 23:38:58 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D38B019560AA; Fri, 2 Aug 2024 23:38:56 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 01/10 v3] libelf: Fix deadlock in __libelf_readall Date: Fri, 2 Aug 2024 19:38:00 -0400 Message-ID: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 Apply locking during __libelf_readall. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard --- v3 changes: Update comments and change order or child lock aquisition. libelf/common.h | 24 ++++++++++++++---------- libelf/elf_readall.c | 4 ++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/libelf/common.h b/libelf/common.h index 9b2a856d..8e33a70e 100644 --- a/libelf/common.h +++ b/libelf/common.h @@ -89,30 +89,34 @@ allocate_elf (int fildes, void *map_address, int64_t offset, size_t maxsize, } -/* Acquire lock for the descriptor and all children. */ +/* Caller must hold a lock for ELF. If there are children then a lock + will be acquired for each of them (recursively). */ static void __attribute__ ((unused)) -libelf_acquire_all (Elf *elf) +libelf_acquire_all_children (Elf *elf) { - rwlock_wrlock (elf->lock); - if (elf->kind == ELF_K_AR) { Elf *child = elf->state.ar.children; while (child != NULL) { + rwlock_wrlock (child->lock); + if (child->ref_count != 0) - libelf_acquire_all (child); + libelf_acquire_all_children (child); + child = child->next; } } } -/* Release own lock and those of the children. */ + +/* Caller must hold a lock for ELF. If there are children then a lock + will be released for each of them (recursively). */ static void __attribute__ ((unused)) -libelf_release_all (Elf *elf) +libelf_release_all_children (Elf *elf) { if (elf->kind == ELF_K_AR) { @@ -121,12 +125,12 @@ libelf_release_all (Elf *elf) while (child != NULL) { if (child->ref_count != 0) - libelf_release_all (child); + libelf_release_all_children (child); + + rwlock_unlock (child->lock); child = child->next; } } - - rwlock_unlock (elf->lock); } diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c index d0f9a28c..4ef8fe97 100644 --- a/libelf/elf_readall.c +++ b/libelf/elf_readall.c @@ -84,7 +84,7 @@ __libelf_readall (Elf *elf) /* If this is an archive and we have derived descriptors get the locks for all of them. */ - libelf_acquire_all (elf); + libelf_acquire_all_children (elf); if (elf->maximum_size == ~((size_t) 0)) { @@ -141,7 +141,7 @@ __libelf_readall (Elf *elf) __libelf_seterrno (ELF_E_NOMEM); /* Free the locks on the children. */ - libelf_release_all (elf); + libelf_release_all_children (elf); } rwlock_unlock (elf->lock); From patchwork Fri Aug 2 23:38:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95238 X-Patchwork-Delegate: mark@klomp.org 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 ADCF8385840C for ; Fri, 2 Aug 2024 23:39:28 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 945CC385DDC0 for ; Fri, 2 Aug 2024 23:39:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 945CC385DDC0 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 945CC385DDC0 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641957; cv=none; b=tbrzw5Wr9ZB6RJT7ljq+2Bkp3uksT4qt4gqwzANXAT03Hs0tXKLbrwB4qXvgprDFm+Qk2IqgDRbzk9h07akcugQb0UPxDliAyjiZp5NdA4sgKvmKUf8+dAnO9liIP3kgG+4/PCtZDlR6eFxc9iiq0E9X8gwZNFVZmfgxapN2zL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641957; c=relaxed/simple; bh=BFX3JP0zY3V+UUO8fs8lxknZvlEiAhEDGXUuW+3jUE4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=aXpQv2wGk7shANOph65IN8StwPrCSS33EEJMYmsrtbhj2HeBC1zczAisY237nVM6PeHKxRKQPnB1vi5+E8CwVl9CW4+xNNtiyMNxq3w112fvrd0WOr3XDy4iVgWbawXPriu9RWWy+xO79SNzJMnlJLvl2FuRtUtYHSH/K5wYEvA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641955; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Hv+m+RXujaMirWZC2zFWEMJLLfGl56i0WKdevwR8Tls=; b=BzsTjNejqgdN0I7MDLSsP1G8FghxF6wAp8HklBaF+hElo8ERaDEQEvU2Bzdpr4EDgeE7MP 1hZwIiF9b6V5heXIgEutHQZ3oSUiU+8D2bAPlpkKWgqeihuFANMasIkVx/f27w2XVaJQh+ aMsMYrzYrlIjWJvr1nen4C7pX22REJs= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-404-udM5OJg7OrqXfJwvwa-npQ-1; Fri, 02 Aug 2024 19:39:13 -0400 X-MC-Unique: udM5OJg7OrqXfJwvwa-npQ-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3B32319560AA; Fri, 2 Aug 2024 23:39:12 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 942A419560AA; Fri, 2 Aug 2024 23:39:10 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 02/10 v3] libelf: Fix deadlock in elf_cntl Date: Fri, 2 Aug 2024 19:38:01 -0400 Message-ID: <20240802233847.690564-2-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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. Remove unnecessary early return. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard --- v3 changes: Remove unnecessary early return that would require locking to check condition. libelf/elf_cntl.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c index 04aa9132..da4ea999 100644 --- a/libelf/elf_cntl.c +++ b/libelf/elf_cntl.c @@ -42,19 +42,11 @@ elf_cntl (Elf *elf, Elf_Cmd cmd) if (elf == NULL) return -1; - if (elf->fildes == -1) - { - __libelf_seterrno (ELF_E_INVALID_HANDLE); - return -1; - } - - rwlock_wrlock (elf->lock); - switch (cmd) { case ELF_C_FDREAD: /* If not all of the file is in the memory read it now. */ - if (elf->map_address == NULL && __libelf_readall (elf) == NULL) + if (__libelf_readall (elf) == NULL) { /* We were not able to read everything. */ result = -1; @@ -64,7 +56,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 +67,5 @@ elf_cntl (Elf *elf, Elf_Cmd cmd) break; } - rwlock_unlock (elf->lock); - return result; } From patchwork Fri Aug 2 23:38:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95239 X-Patchwork-Delegate: mark@klomp.org 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 A8778385DDE9 for ; Fri, 2 Aug 2024 23:39:39 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id D605C3858C48 for ; Fri, 2 Aug 2024 23:39:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D605C3858C48 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D605C3858C48 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641968; cv=none; b=V+5Mv6XMViA8l9zcm2Elj8l4LYrfUY4upfb3qewTPjOx+BCPdYX+N3W9e65KFYjD5xnHEFKANoAQv7RVgm7mdmNvu3txX62Y5MKmhohlgC1WQH55TEHHqhsfFy/C2OPX6sAozNm3ibFhk38hlyvMgNDGfnh2BM7dhkBlGtE8jnU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641968; c=relaxed/simple; bh=RxwNe3wJ2+j8CHeSSqNXBPPz0IKll1FBxs+abaOZMro=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=vLChXuIgMcfoOkDc7Z0wMgqCy+f2gVCDk/mqZfohBBJ1++cbirFsuNOSU/cPXFP98vnKBWoJXC08GKoMW33oheH5Fi4NEdbYsTqIgldMtXQAgnDGKIynW+BBqiqYMVPu4l0Ctb9jVj+nDBt1tQqZF5vqx8L+mYuovryQ5tsLsos= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641963; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HKdJGOBErrfIQxCgg23ONC3On7fdfZBQuf8gHbl51aE=; b=civMdgvCrfS9ZYv4fTHa440KiJqdY/kkoVqs/erPMuIqlZBCken5tHdfVSB865bPwyoAeh +IL1hRJaRJIC+XwQ9EeEg/IiZGPFQa8coz6TSgeSRCY2Zs7DVM9EoDWRxo8SoR7ttOc28D /5QOfv1USnGB8JvWYmGWClQ/LTj/BgE= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-654-x66iSCx0NjCME2m9AvOwxw-1; Fri, 02 Aug 2024 19:39:19 -0400 X-MC-Unique: x66iSCx0NjCME2m9AvOwxw-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C6CAF1955F40; Fri, 2 Aug 2024 23:39:17 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A630319560AA; Fri, 2 Aug 2024 23:39:15 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 03/10 v3] lib: Add eu_tsearch, eu_tfind, eu_tdelete and eu_tdestroy Date: Fri, 2 Aug 2024 19:38:02 -0400 Message-ID: <20240802233847.690564-3-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 Add struct search_tree to hold tree root and lock. Add new eu_t* functions for ensuring synchronized tree access. Replace tsearch, tfind, etc with eu_t* equivalents. lib: * Makefile.am (libeu_a_SOURCES): Add eu-search.c. (noinst_HEADERS): Add eu-search.h and locks.h. * eu-config.h: Move rwlock macros to locks.h. * eu-search.c: New file containing tree search functions with locking. * eu-search.h: New file. * locks.h: New file containing rwlock macros previously in eu-config.h. libdw: * cfi.h (struct Dwarf_CFI_s): Change type of search tree members from void * to search_tree. * cie.c: Replace tree search functions with eu-search equivalents. * dwarf_begin_elf.c (valid_p): Initialize search trees. * dwarf_end.c (cu_free): Replace tree search functions with eu-search equivalents. * dwarf_getcfi.c (dwarf_getcfi): Initialize search trees. * dwarf_getlocations.c: Replace search tree functions with eu-search equivalents. (__libdw_intern_expression): Change type of cache parameter to search_tree *. * dwarf_getmacros.c: Replace tree search functions with eu-search equivalents. * dwarf_getsrclines.c: Ditto. * fde.c: Ditto. * frame-cache.c (__libdw_destroy_frame_cache): Initialize search trees. * libdwP.h (struct Dwarf): Change type of search tree members from void * to search_tree. (struct Dwarf_CU): Ditto. (__libdw_intern_expression): Change type of cache parameter to search_tree *. * libdw_find_split_unit.c: Replace tree search functions with eu-search equivalents. * libdw_findcu.c: Ditto. libdwfl: * cu.c: Ditto. * libdwflP.h (struct Dwfl_Module): Replace void *lazy_cu_root with search_tree lazy_cu_tree. libelf: * elf_begin.c (file_read_elf): Initialize rawchunck_tree. * elf_end.c (elf_end): Replace tree search function with eu-search equivalent. * elf_getdata_rawchunck.c: Ditto. * libelfP.h (struct Elf): Replace void * rawchuncks memeber with search_tree rawchunk_tree. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard --- v3 changes: Moved most locking code to another patch in this series. include "eu-search.h" and "locks.h" instead of and On Fri, Jul 19, 2024 at 8:51 AM Mark Wielaard wrote: > Is eu_tdestroy ever used now? > It looks like everything now uses eu_search_tree_fine. > Could still be a useful function to have, just checking. Yes the function less_lazy in libdwfl/cu.c uses it. > > +#define LOCKS_H 1 > > + > > +#ifdef USE_LOCKS > > +# include > > +# include > > Why the assert.h include? It's needed for assert_perror in the RWLOCK_CALL macro > > /* We know about all the CUs now, we don't need this table. */ > > - tdestroy (mod->lazy_cu_root, nofree); > > - mod->lazy_cu_root = NULL; > > + eu_tdestroy (&mod->lazy_cu_tree, nofree); > > } > > OK, a eu_tdestroy here, and then there is a eu_search_tree_fini in > __libdwfl_module_free, which will call eu_tdestroy again (on the now > NULL tree). Is that correct? Does [eu_]tdestroy handle NULL trees? Yes NULL is a valid (empty) tree. lib/Makefile.am | 5 ++- lib/eu-config.h | 30 +------------ lib/eu-search.c | 85 +++++++++++++++++++++++++++++++++++ lib/eu-search.h | 64 ++++++++++++++++++++++++++ lib/locks.h | 62 +++++++++++++++++++++++++ libdw/cfi.h | 6 +-- libdw/cie.c | 10 +++-- libdw/dwarf_begin_elf.c | 6 +-- libdw/dwarf_end.c | 15 +++---- libdw/dwarf_getcfi.c | 5 ++- libdw/dwarf_getlocation.c | 23 +++++----- libdw/dwarf_getmacros.c | 6 +-- libdw/dwarf_getsrclines.c | 8 ++-- libdw/fde.c | 6 +-- libdw/frame-cache.c | 8 ++-- libdw/libdwP.h | 16 ++++--- libdw/libdw_find_split_unit.c | 10 ++--- libdw/libdw_findcu.c | 18 ++++---- libdwfl/cu.c | 8 ++-- libdwfl/dwfl_module.c | 4 +- libdwfl/libdwflP.h | 3 +- libelf/elf_begin.c | 2 + libelf/elf_end.c | 13 +++--- libelf/elf_getdata_rawchunk.c | 12 ++--- libelf/libelfP.h | 10 +++-- 25 files changed, 317 insertions(+), 118 deletions(-) create mode 100644 lib/eu-search.c create mode 100644 lib/eu-search.h create mode 100644 lib/locks.h diff --git a/lib/Makefile.am b/lib/Makefile.am index b3bb929f..e324c18d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -34,10 +34,11 @@ 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 \ eu-config.h color.h printversion.h bpf.h \ - atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h + atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h \ + eu-search.h locks.h EXTRA_DIST = dynamicsizehash.c dynamicsizehash_concurrent.c diff --git a/lib/eu-config.h b/lib/eu-config.h index feb079db..0bf2aa76 100644 --- a/lib/eu-config.h +++ b/lib/eu-config.h @@ -29,35 +29,7 @@ #ifndef EU_CONFIG_H #define EU_CONFIG_H 1 -#ifdef USE_LOCKS -# 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 - the macros used expand to nothing for now. */ -# define rwlock_define(class,name) class int name -# define rwlock_init(lock) ((void) (lock)) -# define rwlock_fini(lock) ((void) (lock)) -# 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 "locks.h" #include /* gettext helper macros. */ diff --git a/lib/eu-search.c b/lib/eu-search.c new file mode 100644 index 00000000..fc31fe87 --- /dev/null +++ b/lib/eu-search.c @@ -0,0 +1,85 @@ +/* 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 "eu-search.h" + +void *eu_tsearch (const void *key, search_tree *tree, + int (*compare)(const void *, const void *)) +{ + rwlock_wrlock (tree->lock); + void *ret = tsearch (key, &tree->root, compare); + rwlock_unlock (tree->lock); + + return ret; +} + +void *eu_tfind (const void *key, search_tree *tree, + int (*compare)(const void *, const void *)) +{ + rwlock_rdlock (tree->lock); + void *ret = tfind (key, &tree->root, compare); + rwlock_unlock (tree->lock); + + return ret; +} + +void *eu_tdelete (const void *key, search_tree *tree, + int (*compare)(const void *, const void *)) +{ + rwlock_wrlock (tree->lock); + void *ret = tdelete (key, &tree->root, compare); + rwlock_unlock (tree->lock); + + return ret; +} + +void eu_tdestroy (search_tree *tree, void (*free_node)(void *)) +{ + rwlock_wrlock (tree->lock); + + tdestroy (tree->root, free_node); + tree->root = NULL; + + rwlock_unlock (tree->lock); +} + +void eu_search_tree_init (search_tree *tree) +{ + tree->root = NULL; + rwlock_init (tree->lock); +} + +void eu_search_tree_fini (search_tree *tree, void (*free_node)(void *)) +{ + eu_tdestroy (tree, free_node); + rwlock_fini (tree->lock); +} diff --git a/lib/eu-search.h b/lib/eu-search.h new file mode 100644 index 00000000..67b54c18 --- /dev/null +++ b/lib/eu-search.h @@ -0,0 +1,64 @@ +/* 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 +#include +#include + +typedef struct +{ + void *root; + rwlock_define (, lock); +} search_tree; + +/* Search TREE for KEY and add KEY if not found. Synchronized using + TREE's lock. */ +extern void *eu_tsearch (const void *key, search_tree *tree, + int (*compare)(const void *, const void *)); + +/* Search TREE for KEY. Synchronized with TREE's lock. */ +extern void *eu_tfind (const void *key, search_tree *tree, + int (*compare)(const void *, const void *)); + +/* Delete key from TREE. Synchronized with TREE's lock. */ +extern void *eu_tdelete (const void *key, search_tree *tree, + int (*compare)(const void *, const void *)); + +/* Free all nodes from TREE. */ +void eu_tdestroy (search_tree *tree, void (*free_node)(void *)); + +/* Initialize TREE's root and lock. */ +void eu_search_tree_init (search_tree *tree); + +/* Free all nodes from TREE as well as TREE's lock. */ +void eu_search_tree_fini (search_tree *tree, void (*free_node)(void *)); + +#endif diff --git a/lib/locks.h b/lib/locks.h new file mode 100644 index 00000000..90fe3f1b --- /dev/null +++ b/lib/locks.h @@ -0,0 +1,62 @@ +/* Configuration definitions. + Copyright (C) 2024 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 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 LOCKS_H +#define LOCKS_H 1 + +#ifdef USE_LOCKS +# 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 + the macros used expand to nothing for now. */ +# define rwlock_define(class,name) class int name +# define rwlock_init(lock) ((void) (lock)) +# define rwlock_fini(lock) ((void) (lock)) +# 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 */ + +#endif /* locks.h */ diff --git a/libdw/cfi.h b/libdw/cfi.h index 1b0d712f..bb9dc0df 100644 --- a/libdw/cfi.h +++ b/libdw/cfi.h @@ -90,13 +90,13 @@ struct Dwarf_CFI_s Dwarf_Off next_offset; /* Search tree for the CIEs, indexed by CIE_pointer (section offset). */ - void *cie_tree; + search_tree cie_tree; /* Search tree for the FDEs, indexed by PC address. */ - void *fde_tree; + search_tree fde_tree; /* Search tree for parsed DWARF expressions, indexed by raw pointer. */ - void *expr_tree; + search_tree expr_tree; /* Backend hook. */ struct ebl *ebl; diff --git a/libdw/cie.c b/libdw/cie.c index 1b0aae7c..9753d9b9 100644 --- a/libdw/cie.c +++ b/libdw/cie.c @@ -33,8 +33,8 @@ #include "cfi.h" #include "encoded-value.h" #include -#include #include +#include "eu-search.h" static int @@ -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,8 @@ 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 +190,8 @@ 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_begin_elf.c b/libdw/dwarf_begin_elf.c index ca2b7e2a..b4f3a83a 100644 --- a/libdw/dwarf_begin_elf.c +++ b/libdw/dwarf_begin_elf.c @@ -354,11 +354,11 @@ valid_p (Dwarf *result) result->fake_loc_cu->endp = (result->sectiondata[IDX_debug_loc]->d_buf + result->sectiondata[IDX_debug_loc]->d_size); - result->fake_loc_cu->locs = NULL; result->fake_loc_cu->address_size = elf_addr_size; result->fake_loc_cu->offset_size = 4; result->fake_loc_cu->version = 4; result->fake_loc_cu->split = NULL; + eu_search_tree_init (&result->fake_loc_cu->locs_tree); } } @@ -382,11 +382,11 @@ valid_p (Dwarf *result) result->fake_loclists_cu->endp = (result->sectiondata[IDX_debug_loclists]->d_buf + result->sectiondata[IDX_debug_loclists]->d_size); - result->fake_loclists_cu->locs = NULL; result->fake_loclists_cu->address_size = elf_addr_size; result->fake_loclists_cu->offset_size = 4; result->fake_loclists_cu->version = 5; result->fake_loclists_cu->split = NULL; + eu_search_tree_init (&result->fake_loclists_cu->locs_tree); } } @@ -415,11 +415,11 @@ valid_p (Dwarf *result) result->fake_addr_cu->endp = (result->sectiondata[IDX_debug_addr]->d_buf + result->sectiondata[IDX_debug_addr]->d_size); - result->fake_addr_cu->locs = NULL; result->fake_addr_cu->address_size = elf_addr_size; result->fake_addr_cu->offset_size = 4; result->fake_addr_cu->version = 5; result->fake_addr_cu->split = NULL; + eu_search_tree_init (&result->fake_addr_cu->locs_tree); } } diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c index ed8d27be..60a3e4fd 100644 --- a/libdw/dwarf_end.c +++ b/libdw/dwarf_end.c @@ -61,11 +61,10 @@ static void cu_free (void *arg) { struct Dwarf_CU *p = (struct Dwarf_CU *) arg; - - tdestroy (p->locs, noop_free); + eu_search_tree_fini (&p->locs_tree, noop_free); /* Only free the CU internals if its not a fake CU. */ - if(p != p->dbg->fake_loc_cu && p != p->dbg->fake_loclists_cu + if (p != p->dbg->fake_loc_cu && p != p->dbg->fake_loclists_cu && p != p->dbg->fake_addr_cu) { Dwarf_Abbrev_Hash_free (&p->abbrev_hash); @@ -102,17 +101,17 @@ dwarf_end (Dwarf *dwarf) /* The search tree for the CUs. NB: the CU data itself is allocated separately, but the abbreviation hash tables need to be handled. */ - tdestroy (dwarf->cu_tree, cu_free); - tdestroy (dwarf->tu_tree, cu_free); + eu_search_tree_fini (&dwarf->cu_tree, cu_free); + eu_search_tree_fini (&dwarf->tu_tree, cu_free); /* Search tree for macro opcode tables. */ - tdestroy (dwarf->macro_ops, noop_free); + eu_search_tree_fini (&dwarf->macro_ops_tree, noop_free); /* Search tree for decoded .debug_lines units. */ - tdestroy (dwarf->files_lines, noop_free); + eu_search_tree_fini (&dwarf->files_lines_tree, noop_free); /* And the split Dwarf. */ - tdestroy (dwarf->split_tree, noop_free); + eu_search_tree_fini (&dwarf->split_tree, noop_free); /* Free the internally allocated memory. */ for (size_t i = 0; i < dwarf->mem_stacks; i++) diff --git a/libdw/dwarf_getcfi.c b/libdw/dwarf_getcfi.c index afa8a460..a4497152 100644 --- a/libdw/dwarf_getcfi.c +++ b/libdw/dwarf_getcfi.c @@ -66,7 +66,10 @@ dwarf_getcfi (Dwarf *dbg) cfi->default_same_value = false; cfi->next_offset = 0; - cfi->cie_tree = cfi->fde_tree = cfi->expr_tree = NULL; + + eu_search_tree_init (&cfi->cie_tree); + eu_search_tree_init (&cfi->fde_tree); + eu_search_tree_init (&cfi->expr_tree); cfi->ebl = NULL; diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index 37b32fc1..ad1d46ca 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -31,11 +31,11 @@ #endif #include -#include #include #include #include +#include "eu-search.h" static bool @@ -137,9 +137,9 @@ 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) +store_implicit_value (Dwarf *dbg, search_tree *cache, Dwarf_Op *op) { if (dbg == NULL) return -1; @@ -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,8 @@ 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_tree, + loc_compare); if (unlikely (found == NULL)) { __libdw_seterrno (DWARF_E_NO_BLOCK); @@ -211,7 +212,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_tree, loc_compare); if (found == NULL) { @@ -235,7 +236,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_tree, loc_compare); } assert ((*found)->nloc == 1); @@ -253,7 +254,7 @@ int internal_function __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, unsigned int address_size, unsigned int ref_size, - void **cache, const Dwarf_Block *block, + search_tree *cache, const Dwarf_Block *block, bool cfap, bool valuep, Dwarf_Op **llbuf, size_t *listlen, int sec_index) { @@ -266,7 +267,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 +656,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); + eu_tsearch (newp, cache, loc_compare); /* We did it. */ return 0; @@ -677,7 +678,7 @@ getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block, cu->address_size, (cu->version == 2 ? cu->address_size : cu->offset_size), - &cu->locs, block, + &cu->locs_tree, block, false, false, llbuf, listlen, sec_index); } diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c index 2667eb45..f1c831fa 100644 --- a/libdw/dwarf_getmacros.c +++ b/libdw/dwarf_getmacros.c @@ -32,11 +32,11 @@ #include #include -#include #include #include #include +#include "eu-search.h" static int get_offset_from (Dwarf_Die *die, int name, Dwarf_Word *retp) @@ -317,7 +317,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_tree, macro_op_compare); if (found != NULL) return *found; @@ -329,7 +329,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_tree, macro_op_compare); if (unlikely (ret == NULL)) { diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index 987a86fd..da78db67 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -33,10 +33,10 @@ #include #include #include -#include #include "dwarf.h" #include "libdwP.h" +#include "eu-search.h" struct filelist @@ -1320,8 +1320,8 @@ get_lines_or_files (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, - files_lines_compare); + struct files_lines_s **found = eu_tfind (&fake, &dbg->files_lines_tree, + files_lines_compare); if (found == NULL) { /* This .debug_line is being read for the first time. */ @@ -1354,7 +1354,7 @@ get_lines_or_files (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_tree, files_lines_compare); if (found == NULL) { __libdw_seterrno (DWARF_E_NOMEM); diff --git a/libdw/fde.c b/libdw/fde.c index 73d551b6..a5167805 100644 --- a/libdw/fde.c +++ b/libdw/fde.c @@ -31,7 +31,7 @@ #endif #include "cfi.h" -#include +#include "eu-search.h" #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/libdw/frame-cache.c b/libdw/frame-cache.c index 683f7f17..6c89858a 100644 --- a/libdw/frame-cache.c +++ b/libdw/frame-cache.c @@ -60,10 +60,10 @@ void internal_function __libdw_destroy_frame_cache (Dwarf_CFI *cache) { - /* Most of the data is in our two search trees. */ - tdestroy (cache->fde_tree, free_fde); - tdestroy (cache->cie_tree, free_cie); - tdestroy (cache->expr_tree, free_expr); + /* Most of the data is in our three search trees. */ + eu_search_tree_fini (&cache->fde_tree, free_fde); + eu_search_tree_fini (&cache->cie_tree, free_cie); + eu_search_tree_fini (&cache->expr_tree, free_expr); if (cache->ebl != NULL && cache->ebl != (void *) -1l) ebl_closebackend (cache->ebl); diff --git a/libdw/libdwP.h b/libdw/libdwP.h index e55ff50a..ae9386f1 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -34,6 +34,7 @@ #include #include +#include "eu-search.h" /* Known location expressions already decoded. */ @@ -215,22 +216,22 @@ struct Dwarf size_t pubnames_nsets; /* Search tree for the CUs. */ - void *cu_tree; + search_tree cu_tree; Dwarf_Off next_cu_offset; /* Search tree and sig8 hash table for .debug_types type units. */ - void *tu_tree; + search_tree tu_tree; Dwarf_Off next_tu_offset; Dwarf_Sig8_Hash sig8_hash; /* Search tree for split Dwarf associated with CUs in this debug. */ - void *split_tree; + search_tree split_tree; /* Search tree for .debug_macro operator tables. */ - void *macro_ops; + search_tree macro_ops_tree; /* Search tree for decoded .debug_line units. */ - void *files_lines; + search_tree files_lines_tree; /* Address ranges read from .debug_aranges. */ Dwarf_Aranges *aranges; @@ -423,7 +424,7 @@ struct Dwarf_CU Dwarf_Files *files; /* Known location lists. */ - void *locs; + search_tree locs_tree; /* Base address for use with ranges and locs. Don't access directly, call __libdw_cu_base_address. */ @@ -912,7 +913,8 @@ extern int __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, unsigned int address_size, unsigned int ref_size, - void **cache, const Dwarf_Block *block, + search_tree *cache, + const Dwarf_Block *block, bool cfap, bool valuep, Dwarf_Op **llbuf, size_t *listlen, int sec_index) diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c index 8426a925..4005793b 100644 --- a/libdw/libdw_find_split_unit.c +++ b/libdw/libdw_find_split_unit.c @@ -32,9 +32,9 @@ #include "libdwP.h" #include "libelfP.h" +#include "eu-search.h" #include -#include #include #include #include @@ -57,8 +57,8 @@ 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, - __libdw_finddbg_cb) == NULL) + if (eu_tsearch (split->dbg, &cu->dbg->split_tree, + __libdw_finddbg_cb) == NULL) { /* Something went wrong. Don't link. */ __libdw_seterrno (DWARF_E_NOMEM); @@ -132,8 +132,8 @@ try_dwp_file (Dwarf_CU *cu) cu->unit_id8); if (split != NULL) { - if (tsearch (split->dbg, &cu->dbg->split_tree, - __libdw_finddbg_cb) == NULL) + if (eu_tsearch (split->dbg, &cu->dbg->split_tree, + __libdw_finddbg_cb) == NULL) { /* Something went wrong. Don't link. */ __libdw_seterrno (DWARF_E_NOMEM); diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index 6c7dcfb5..bfbad410 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -32,7 +32,7 @@ #endif #include -#include +#include "eu-search.h" #include "libdwP.h" static int @@ -101,7 +101,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) { Dwarf_Off *const offsetp = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset; - void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree; + search_tree *tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree; Dwarf_Off oldoff = *offsetp; uint16_t version; @@ -167,7 +167,6 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset; newp->files = NULL; newp->lines = NULL; - newp->locs = NULL; newp->split = (Dwarf_CU *) -1; newp->base_address = (Dwarf_Addr) -1; newp->addr_base = (Dwarf_Off) -1; @@ -177,6 +176,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->startp = data->d_buf + newp->start; newp->endp = data->d_buf + newp->end; + eu_search_tree_init (&newp->locs_tree); /* v4 debug type units have version == 4 and unit_type == DW_UT_type. */ if (debug_types) @@ -221,7 +221,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; @@ -236,13 +236,13 @@ struct Dwarf_CU * internal_function __libdw_findcu (Dwarf *dbg, Dwarf_Off start, bool v4_debug_types) { - void **tree = v4_debug_types ? &dbg->tu_tree : &dbg->cu_tree; + search_tree *tree = v4_debug_types ? &dbg->tu_tree : &dbg->cu_tree; Dwarf_Off *next_offset = v4_debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset; /* 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); if (found != NULL) return *found; @@ -270,7 +270,7 @@ struct Dwarf_CU * internal_function __libdw_findcu_addr (Dwarf *dbg, void *addr) { - void **tree; + search_tree *tree; Dwarf_Off start; if (addr >= dbg->sectiondata[IDX_debug_info]->d_buf && addr < (dbg->sectiondata[IDX_debug_info]->d_buf @@ -291,7 +291,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; @@ -306,7 +306,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; diff --git a/libdwfl/cu.c b/libdwfl/cu.c index 06684357..416773b3 100644 --- a/libdwfl/cu.c +++ b/libdwfl/cu.c @@ -30,10 +30,10 @@ # include #endif +#include "eu-search.h" #include "libdwflP.h" #include "libdwP.h" #include "memory-access.h" -#include static inline Dwarf_Arange * @@ -151,8 +151,7 @@ less_lazy (Dwfl_Module *mod) return; /* We know about all the CUs now, we don't need this table. */ - tdestroy (mod->lazy_cu_root, nofree); - mod->lazy_cu_root = NULL; + eu_tdestroy (&mod->lazy_cu_tree, nofree); } static inline Dwarf_Off @@ -198,7 +197,8 @@ 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_tree, + &compare_cukey); if (unlikely (found == NULL)) return DWFL_E_NOMEM; diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c index c4d872d4..b4ddf806 100644 --- a/libdwfl/dwfl_module.c +++ b/libdwfl/dwfl_module.c @@ -61,8 +61,7 @@ void internal_function __libdwfl_module_free (Dwfl_Module *mod) { - if (mod->lazy_cu_root != NULL) - tdestroy (mod->lazy_cu_root, nofree); + eu_search_tree_fini (&mod->lazy_cu_tree, nofree); if (mod->aranges != NULL) free (mod->aranges); @@ -200,6 +199,7 @@ dwfl_report_module (Dwfl *dwfl, const char *name, mod->low_addr = start; mod->high_addr = end; mod->dwfl = dwfl; + eu_search_tree_init (&mod->lazy_cu_tree); return use (mod, tailp, dwfl); } diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index d27bfdc2..e0055d65 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -40,6 +40,7 @@ #include "libdwP.h" /* We need its INTDECLs. */ #include "libdwelfP.h" +#include "eu-search.h" typedef struct Dwfl_Process Dwfl_Process; @@ -201,7 +202,7 @@ struct Dwfl_Module /* Known CU's in this module. */ struct dwfl_cu *first_cu, **cu; - void *lazy_cu_root; /* Table indexed by Dwarf_Off of CU. */ + search_tree lazy_cu_tree; /* Table indexed by Dwarf_Off of CU. */ struct dwfl_arange *aranges; /* Mapping of addresses in module to CUs. */ diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index 8a49f351..2b3b465f 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -439,6 +439,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, /* So far only one block with sections. */ elf->state.elf32.scns_last = &elf->state.elf32.scns; + eu_search_tree_init (&elf->state.elf32.rawchunk_tree); } else { @@ -536,6 +537,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, /* So far only one block with sections. */ elf->state.elf64.scns_last = &elf->state.elf64.scns; + eu_search_tree_init (&elf->state.elf64.rawchunk_tree); } return elf; diff --git a/libelf/elf_end.c b/libelf/elf_end.c index 80f4d13f..da8f3a20 100644 --- a/libelf/elf_end.c +++ b/libelf/elf_end.c @@ -126,13 +126,14 @@ elf_end (Elf *elf) case ELF_K_ELF: { - void *rawchunks + search_tree *rawchunk_tree = (elf->class == ELFCLASS32 - || (offsetof (struct Elf, state.elf32.rawchunks) - == offsetof (struct Elf, state.elf64.rawchunks)) - ? elf->state.elf32.rawchunks - : elf->state.elf64.rawchunks); - tdestroy (rawchunks, free_chunk); + || (offsetof (struct Elf, state.elf32.rawchunk_tree) + == offsetof (struct Elf, state.elf64.rawchunk_tree)) + ? &elf->state.elf32.rawchunk_tree + : &elf->state.elf64.rawchunk_tree); + + eu_search_tree_fini (rawchunk_tree, free_chunk); Elf_ScnList *list = (elf->class == ELFCLASS32 || (offsetof (struct Elf, state.elf32.scns) diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c index 1751878d..010fac90 100644 --- a/libelf/elf_getdata_rawchunk.c +++ b/libelf/elf_getdata_rawchunk.c @@ -33,12 +33,11 @@ #include #include -#include -#include #include #include "libelfP.h" #include "common.h" +#include "eu-search.h" static int chunk_compare (const void *a, const void *b) @@ -95,8 +94,9 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) key.offset = offset; key.data.d.d_size = size; key.data.d.d_type = type; - Elf_Data_Chunk **found = tsearch (&key, &elf->state.elf.rawchunks, - &chunk_compare); + Elf_Data_Chunk **found + = eu_tsearch (&key, &elf->state.elf.rawchunk_tree, &chunk_compare); + if (found == NULL) goto nomem; @@ -136,7 +136,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) if (rawchunk == NULL) { nomem: - tdelete (&key, &elf->state.elf.rawchunks, &chunk_compare); + eu_tdelete (&key, &elf->state.elf.rawchunk_tree, &chunk_compare); __libelf_seterrno (ELF_E_NOMEM); goto out; } @@ -147,7 +147,7 @@ elf_getdata_rawchunk (Elf *elf, int64_t offset, size_t size, Elf_Type type) != size)) { /* Something went wrong. */ - tdelete (&key, &elf->state.elf.rawchunks, &chunk_compare); + eu_tdelete (&key, &elf->state.elf.rawchunk_tree, &chunk_compare); free (rawchunk); __libelf_seterrno (ELF_E_READ_ERROR); goto out; diff --git a/libelf/libelfP.h b/libelf/libelfP.h index bdd2cc6a..a9213ab3 100644 --- a/libelf/libelfP.h +++ b/libelf/libelfP.h @@ -33,6 +33,7 @@ #include #include +#include "eu-search.h" #include #include @@ -323,7 +324,8 @@ struct Elf Elf_ScnList *scns_last; /* Last element in the section list. If NULL the data has not yet been read from the file. */ - void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ + search_tree rawchunk_tree; /* Tree and lock for elf_getdata_rawchunk + results. */ unsigned int scnincr; /* Number of sections allocate the last time. */ int ehdr_flags; /* Flags (dirty) for ELF header. */ @@ -342,7 +344,8 @@ struct Elf Elf_ScnList *scns_last; /* Last element in the section list. If NULL the data has not yet been read from the file. */ - void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ + search_tree rawchunk_tree; /* Tree and lock for + elf_getdata_rawchunk results. */ unsigned int scnincr; /* Number of sections allocate the last time. */ int ehdr_flags; /* Flags (dirty) for ELF header. */ @@ -367,7 +370,8 @@ struct Elf Elf_ScnList *scns_last; /* Last element in the section list. If NULL the data has not yet been read from the file. */ - void *rawchunks; /* Tree of elf_getdata_rawchunk results. */ + search_tree rawchunk_tree; /* Tree and lock for + elf_getdata_rawchunk results. */ unsigned int scnincr; /* Number of sections allocate the last time. */ int ehdr_flags; /* Flags (dirty) for ELF header. */ From patchwork Fri Aug 2 23:38:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95240 X-Patchwork-Delegate: mark@klomp.org 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 B10453858408 for ; Fri, 2 Aug 2024 23:39:42 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 97CAD3858D20 for ; Fri, 2 Aug 2024 23:39:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 97CAD3858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 97CAD3858D20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641968; cv=none; b=LTd39sXGONKxvhwRoi47Xz7VKsfExq89T6ZiSDDdt3NNNC93dBUpzeGThAJGJv1AXMtYlbOflOnRxCfG8NS9I90X/9pQSrlO9/Y6luutUSrtKgshYUprrWSKSlplqX8sdDPG/Lg5+EBwjiynoDTodqFtjfC2vT5aXc0S7wWj0ss= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641968; c=relaxed/simple; bh=MF/uRymrLEOm4egn4xP7lKJ3iNKd0st1ijY2kWV1buc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=MXHRCTj3bFpOhrj4dewFKDZZIWPAu1h3MQ4+VQ7ki9rJoLMhz4ZDjqYB7aNjgI6tTPHM0R43r83OysZZmZ1oBDxuuo0RBjiDztuH0mw2UjevXpfNd0IVOZeZ8zZvLksd2GrDMau474Noqlm4yQxTQ63wIWzKb70Q1WMJ4D2vdGw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641966; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yLIAAJ80UDFogbSg2tbvVwiVexQ3Ijb9RiWKMVQsF7E=; b=RYm+A52q6PlGyz9odJ2CleNrawEd5KZvav/BBfKnbHzfnq0JQ+M0Lf6rPe86GiO2lPXey0 TtZ37vhbM1dJsaqDZtuE2rNVcTbONR4NQ7uqXa5oA4n8PFqO2iBQKMniEIGPu08IzgEzN9 +IMAXzPe7ojfe2W5V1bFih23hW/beNA= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-437-7Ypu_qo7NACB_W03_Ha5jA-1; Fri, 02 Aug 2024 19:39:21 -0400 X-MC-Unique: 7Ypu_qo7NACB_W03_Ha5jA-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 106151955D42; Fri, 2 Aug 2024 23:39:20 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BA7BE1955D47; Fri, 2 Aug 2024 23:39:18 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 04/10 v3] libdw: Add rwlocks for Dwarf and Dwarf_CU Date: Fri, 2 Aug 2024 19:38:03 -0400 Message-ID: <20240802233847.690564-4-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 Add dwarf_lock for Dwarf as well as abbrev_lock for Dwarf_CU. * libdw/dwarf_begin_elf.c (dwarf_begin_elf): Init dwarf_lock. * libdw/dwarf_end.c (cu_free): Free abbrev_lock. (dwarf_end): Free dwarf_lock. * libdw/libdwP.h (struct Dwarf): Define dwarf_lock. (struct Dwarf_CU): Define abbrev_lock. * libdw/libdw_findcu.c (__libdw_intern_next_unit): Init abbrev_lock. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey --- v3 changes: New patch added in v3 that contains rwlock changes previously in patch 3/9 v2. libdw/dwarf_begin_elf.c | 1 + libdw/dwarf_end.c | 2 ++ libdw/libdwP.h | 7 +++++++ libdw/libdw_findcu.c | 1 + 4 files changed, 11 insertions(+) diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c index b4f3a83a..e4826dda 100644 --- a/libdw/dwarf_begin_elf.c +++ b/libdw/dwarf_begin_elf.c @@ -579,6 +579,7 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp) __libdw_seterrno (DWARF_E_NOMEM); /* no memory. */ return NULL; } + rwlock_init (result->dwarf_lock); result->mem_stacks = 0; result->mem_tails = NULL; diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c index 60a3e4fd..487d6ce7 100644 --- a/libdw/dwarf_end.c +++ b/libdw/dwarf_end.c @@ -68,6 +68,7 @@ cu_free (void *arg) && p != p->dbg->fake_addr_cu) { Dwarf_Abbrev_Hash_free (&p->abbrev_hash); + rwlock_fini (p->abbrev_lock); /* Free split dwarf one way (from skeleton to split). */ if (p->unit_type == DW_UT_skeleton @@ -127,6 +128,7 @@ dwarf_end (Dwarf *dwarf) if (dwarf->mem_tails != NULL) free (dwarf->mem_tails); pthread_rwlock_destroy (&dwarf->mem_rwl); + rwlock_fini (dwarf->dwarf_lock); /* Free the pubnames helper structure. */ free (dwarf->pubnames_sets); diff --git a/libdw/libdwP.h b/libdw/libdwP.h index ae9386f1..c95296e9 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -264,6 +264,10 @@ struct Dwarf allocations for this Dwarf. */ pthread_rwlock_t mem_rwl; + /* The dwarf_lock is a read-write lock designed to ensure thread-safe access + and modification of Dwarf objects. */ + rwlock_define(, dwarf_lock); + /* Internal memory handling. This is basically a simplified thread-local reimplementation of obstacks. Unfortunately the standard obstack implementation is not usable in libraries. */ @@ -447,6 +451,9 @@ struct Dwarf_CU Don't access directly, call __libdw_cu_locs_base. */ Dwarf_Off locs_base; + /* Synchronize Dwarf_Die abbrev access. */ + rwlock_define(, abbrev_lock); + /* Memory boundaries of this CU. */ void *startp; void *endp; diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index bfbad410..0f46d777 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -177,6 +177,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->startp = data->d_buf + newp->start; newp->endp = data->d_buf + newp->end; eu_search_tree_init (&newp->locs_tree); + rwlock_init (newp->abbrev_lock); /* v4 debug type units have version == 4 and unit_type == DW_UT_type. */ if (debug_types) From patchwork Fri Aug 2 23:38:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95241 X-Patchwork-Delegate: mark@klomp.org 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 2859D385DDC4 for ; Fri, 2 Aug 2024 23:39:55 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id CF2603858D26 for ; Fri, 2 Aug 2024 23:39:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CF2603858D26 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CF2603858D26 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641969; cv=none; b=i+JbcDiQdJB7oheRDos280qYoMagof6Z0qobWB8gmXSIqC2d0bCmPkxPh8xik72AZOd/pHAK1WKjjyW8bdW7NhZURXfDySFYD9fVoD//tVCd3RclolMTfLrkfv5Ob6StBJKXNgNo1sUOVcPs7xrCluyzxDsJYYCrPVFgksTyLGk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641969; c=relaxed/simple; bh=yR9JNBxky28gRJpNDpHNVAbLS4a2ErYy6S5FkkCSOlE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=GkhjZUQOkqrMhYEqoLiuMR+mF/MD2b60qDgtCW+nI5xPOCGAAQaSy7gL0/AUdzQ3ETfzIup/ikUQExpQq32UoeRfXlr7G3IvrC/fnlFssxlLD+tSUSo10czF7iGQ4vbf7/j/4gltyKIZr8FB7GiTGn7I79M6XvQTVzxFVOYmsIs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641967; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q0MyCOthBD9uI8wdgdzSqJt2p/XMAUgoD5A+SQF2B5A=; b=buF6+lNUVQb0GiMztJdVHnENxs9reYtvORkGo4JllKtiU2SusKgurELAgOYvO2nFBW1S2p jFs2xK2KnCktEFFZ40pThaXHR4IxKb3c3orcM2pI27tN/u+zqgDe4K8EoJ5nG6VWayK2AA 4OF9StXwA2/LvBp1a8IyFAMeM/cC218= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-314-Ll_0PwWLPHqkgdPhQKPKBg-1; Fri, 02 Aug 2024 19:39:24 -0400 X-MC-Unique: Ll_0PwWLPHqkgdPhQKPKBg-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 48CF219560B1; Fri, 2 Aug 2024 23:39:23 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id AF6ED19560AA; Fri, 2 Aug 2024 23:39:21 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 05/10 v3] libdw: make dwarf_getalt and dwarf_setalt thread-safe Date: Fri, 2 Aug 2024 19:38:04 -0400 Message-ID: <20240802233847.690564-5-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 (dwarf_getalt): Add locking. * libdw/dwarf_setalt.c (dwarf_setalt): Ditto. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard --- v3 changes: Check for NULL argument before acquiring lock. Assign result before releasing lock. Include dwarf_setalt.c changes that were previously included in patch 5/9 v2. libdw/dwarf_getalt.c | 31 +++++++++++++++++++++++++++---- libdw/dwarf_setalt.c | 3 +++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/libdw/dwarf_getalt.c b/libdw/dwarf_getalt.c index 0a12dfae..26433b81 100644 --- a/libdw/dwarf_getalt.c +++ b/libdw/dwarf_getalt.c @@ -160,15 +160,34 @@ find_debug_altlink (Dwarf *dbg) } } +/* find_debug_altlink() modifies "dbg->alt_dwarf". + dwarf_getalt() reads "main->alt_dwarf". + Mutual exclusion is enforced to prevent a race. */ + Dwarf * dwarf_getalt (Dwarf *main) { - /* Only try once. */ - if (main == NULL || main->alt_dwarf == (void *) -1) + if (main == NULL) return NULL; + rwlock_wrlock(main->dwarf_lock); + + /* Only try once. */ + if (main->alt_dwarf == (void *) -1) + { + rwlock_unlock (main->dwarf_lock); + return NULL; + } + + /* Assign result before releasing the lock. */ + Dwarf *result; + if (main->alt_dwarf != NULL) - return main->alt_dwarf; + { + result = main->alt_dwarf; + rwlock_unlock (main->dwarf_lock); + return result; + } find_debug_altlink (main); @@ -176,9 +195,13 @@ dwarf_getalt (Dwarf *main) if (main->alt_dwarf == NULL) { main->alt_dwarf = (void *) -1; + rwlock_unlock (main->dwarf_lock); return NULL; } - return main->alt_dwarf; + result = main->alt_dwarf; + rwlock_unlock (main->dwarf_lock); + + return result; } INTDEF (dwarf_getalt) diff --git a/libdw/dwarf_setalt.c b/libdw/dwarf_setalt.c index dc9b61cb..f98a457c 100644 --- a/libdw/dwarf_setalt.c +++ b/libdw/dwarf_setalt.c @@ -35,6 +35,8 @@ void dwarf_setalt (Dwarf *main, Dwarf *alt) { + rwlock_wrlock (main->dwarf_lock); + if (main->alt_fd != -1) { INTUSE(dwarf_end) (main->alt_dwarf); @@ -43,5 +45,6 @@ dwarf_setalt (Dwarf *main, Dwarf *alt) } main->alt_dwarf = alt; + rwlock_unlock (main->dwarf_lock); } INTDEF (dwarf_setalt) From patchwork Fri Aug 2 23:38:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95242 X-Patchwork-Delegate: mark@klomp.org 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 A07B53858C48 for ; Fri, 2 Aug 2024 23:40:00 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 753C33858289 for ; Fri, 2 Aug 2024 23:39:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 753C33858289 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 753C33858289 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641972; cv=none; b=HJLhPlQBtMQ47bHAaV2QE+Ci1m2MODXX9xmLuWDePkLv2ckQBmiOIAAYs7775nou2HAz78k51tW37fo563cx9mVLUsd6BxWSZSGWTde/FwIX6n0smMl7CwPMJv7uLEHf/j0as+oittCq3g8DIGPEEgyomXG8niGtSeQvEyJwg2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641972; c=relaxed/simple; bh=EjC6wtt8MjWFrMKaf48Q6Y9RCPnz9uz2NUC/RqKF46k=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=eZJup7SMvKsbk9DyBeLZysNE74N3eROmvQ9PqpdPPdEMUnhWJMWg/fDQlDk+XtWx6zEp/aPpAy0/m1ndDSk1HLFNoypDGGzJVz03pmZO9iotD96fYqxq8kdSgsWeFRrG00Gh8EIYBaqESp5jhtDW/gZFnzvCu75twc/2ajlvd+g= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641970; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TA1+yj5wj9W5f/Hzsh4CqAH3iK0ut0crvcFJHHfTuYs=; b=iNBNoeZVyVtZvsrbK77EKKsxb+NC65IfooZMWlxfe32OuTW1xynTOzNVP8qAHoyNTL1RfK HO7TXev0HdiHcK07wYQA5IS3xYT7OMLWjX6MZRYRlJ25XYhGlqJ1I0pH+jhFdyZEtOP/XP 9WplHDmeqNSvgC2s/Dw4RptzfH9yzvI= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-371-6N6cQVsYN9GotpcOe7zpdA-1; Fri, 02 Aug 2024 19:39:27 -0400 X-MC-Unique: 6N6cQVsYN9GotpcOe7zpdA-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4614F19560AA; Fri, 2 Aug 2024 23:39:26 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A818619560AA; Fri, 2 Aug 2024 23:39:24 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 06/10 v3] libdwP.h: Add locking to dwarf_formref_die and __libdw_dieabbrev Date: Fri, 2 Aug 2024 19:38:05 -0400 Message-ID: <20240802233847.690564-6-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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_formref_die.c (dwarf_formref_die): Add locking around call to __libdw_intern_next_unit. * libdw/libdwP.h (__libdw_dieabbrev): Add locking. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard v3 changes: Move dwarf_setalt.c changes to patch 5/9 v3. Set __libdw_dieabbrev result before releasing lock. --- libdw/dwarf_formref_die.c | 3 +++ libdw/libdwP.h | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c index 48ba8194..69d1bf1c 100644 --- a/libdw/dwarf_formref_die.c +++ b/libdw/dwarf_formref_die.c @@ -92,7 +92,10 @@ dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *result) bool scan_debug_types = false; do { + rwlock_wrlock(attr->cu->dbg->dwarf_lock); cu = __libdw_intern_next_unit (attr->cu->dbg, scan_debug_types); + rwlock_unlock(attr->cu->dbg->dwarf_lock); + if (cu == NULL) { if (scan_debug_types == false) diff --git a/libdw/libdwP.h b/libdw/libdwP.h index c95296e9..492cfe8c 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -801,15 +801,28 @@ static inline Dwarf_Abbrev * __nonnull_attribute__ (1) __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) { + if (unlikely (die->cu == NULL)) + { + die->abbrev = DWARF_END_ABBREV; + return DWARF_END_ABBREV; + } + + rwlock_wrlock (die->cu->abbrev_lock); + /* Do we need to get the abbreviation, or need to read after the code? */ if (die->abbrev == NULL || readp != NULL) { /* Get the abbreviation code. */ unsigned int code; const unsigned char *addr = die->addr; - if (unlikely (die->cu == NULL - || addr >= (const unsigned char *) die->cu->endp)) - return die->abbrev = DWARF_END_ABBREV; + + if (addr >= (const unsigned char *) die->cu->endp) + { + die->abbrev = DWARF_END_ABBREV; + rwlock_unlock (die->cu->abbrev_lock); + return DWARF_END_ABBREV; + } + get_uleb128 (code, addr, die->cu->endp); if (readp != NULL) *readp = addr; @@ -818,7 +831,11 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) if (die->abbrev == NULL) die->abbrev = __libdw_findabbrev (die->cu, code); } - return die->abbrev; + + Dwarf_Abbrev *result = die->abbrev; + rwlock_unlock (die->cu->abbrev_lock); + + return result; } /* Helper functions for form handling. */ From patchwork Fri Aug 2 23:38:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95243 X-Patchwork-Delegate: mark@klomp.org 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 B18013858C78 for ; Fri, 2 Aug 2024 23:40:10 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 6E8033858D3C for ; Fri, 2 Aug 2024 23:39:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6E8033858D3C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6E8033858D3C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641974; cv=none; b=LHQjmy9F/D3csksoQgUAzLdExcdEsYdcO6KY3GwX7hbThxxMaef1SvIjD1uTQzP/Zi+Bs+RGxDuwDqhhnagx+jvMdNdMQcthVQPBiZyV5Dcxu74ey6PLWq6MX35tFwgEov9dvNYt8Yeak/mWNany+5s+BHjQd7j0q1DB+zJ1la8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641974; c=relaxed/simple; bh=/WeXQJO9L/04WyRHn+KNZpnk1jOmyaqEtPa3mhKX6N0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=VKXMuRm8Lw7LORDQ3bdo6gEZmxLsQfH2hWWIIO0wX/SkLjC4e25gCtYV1dX8BAdsGhZbX6LcVbCFGXBiVZ/eqdRKjIXFQEbFNPWy2Ob5TqG9DxhBQIP9hRcwFEtnxAZeYrI8aN3wGOXJIfNdMoOzaTerLsa7qWJroAtnlPjT1OY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641971; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=z5OdZ1fRH+IaJMMloua5cTY+1KqZSM5AH1pmEEGgtmc=; b=X+aXDpU+DRWjuvhmt88SYJuvh34OEd3q5RABSVOmnVSI9y3GkJuTZKatoNq+oeXxi1br9v xmi1V7ffxdExuU5gwwSOjFxQlxATyW+iELNm2sBtLgPTNpCTOEj8zsa1kkl2FFD6P+pvu8 DE/2yH5u/lQA5o6sSm1LykUIwxSpfQ0= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-283-KjHkc4hMO2u4pJPERp-GZA-1; Fri, 02 Aug 2024 19:39:29 -0400 X-MC-Unique: KjHkc4hMO2u4pJPERp-GZA-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id DA2CA1956088; Fri, 2 Aug 2024 23:39:28 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3C99B19560AA; Fri, 2 Aug 2024 23:39:27 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 07/10 v3] libdw: Make libdw_find_split_unit thread-safe Date: Fri, 2 Aug 2024 19:38:06 -0400 Message-ID: <20240802233847.690564-7-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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/libdwP.h (struct Dwarf_CU): Add split_lock. * libdw/libdw_find_split_unit.c (__libdw_find_split_unit): Add locking. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard --- v3 changes: Move Dwarf split_lock code from patch 3/9 v2 to this patch. Assign return value before releasing lock. libdw/dwarf_end.c | 1 + libdw/libdwP.h | 3 +++ libdw/libdw_find_split_unit.c | 15 +++++++++++++-- libdw/libdw_findcu.c | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c index 487d6ce7..ee3ed74e 100644 --- a/libdw/dwarf_end.c +++ b/libdw/dwarf_end.c @@ -69,6 +69,7 @@ cu_free (void *arg) { Dwarf_Abbrev_Hash_free (&p->abbrev_hash); rwlock_fini (p->abbrev_lock); + rwlock_fini (p->split_lock); /* Free split dwarf one way (from skeleton to split). */ if (p->unit_type == DW_UT_skeleton diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 48c34871..8f942433 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -454,6 +454,9 @@ struct Dwarf_CU /* Synchronize Dwarf_Die abbrev access. */ rwlock_define(, abbrev_lock); + /* Synchronize split Dwarf access. */ + rwlock_define(, split_lock); + /* Memory boundaries of this CU. */ void *startp; void *endp; diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c index 4005793b..f4f34c5d 100644 --- a/libdw/libdw_find_split_unit.c +++ b/libdw/libdw_find_split_unit.c @@ -150,9 +150,18 @@ Dwarf_CU * internal_function __libdw_find_split_unit (Dwarf_CU *cu) { + /* Set result before releasing the lock. */ + Dwarf_CU *result; + + rwlock_wrlock(cu->split_lock); + /* Only try once. */ if (cu->split != (Dwarf_CU *) -1) - return cu->split; + { + result = cu->split; + rwlock_unlock(cu->split_lock); + return result; + } /* 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 @@ -207,5 +216,7 @@ __libdw_find_split_unit (Dwarf_CU *cu) if (cu->split == (Dwarf_CU *) -1) cu->split = NULL; - return cu->split; + result = cu->split; + rwlock_unlock(cu->split_lock); + return result; } diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index 0f46d777..c74e895e 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -178,6 +178,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->endp = data->d_buf + newp->end; eu_search_tree_init (&newp->locs_tree); rwlock_init (newp->abbrev_lock); + rwlock_init (newp->split_lock); /* v4 debug type units have version == 4 and unit_type == DW_UT_type. */ if (debug_types) From patchwork Fri Aug 2 23:38:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95244 X-Patchwork-Delegate: mark@klomp.org 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 DA9393858D20 for ; Fri, 2 Aug 2024 23:40:21 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 0EEBC385C6C7 for ; Fri, 2 Aug 2024 23:39:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0EEBC385C6C7 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0EEBC385C6C7 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641975; cv=none; b=skMDmKdUPtkP+AjRCgrWfktQewQW9sPvH1S/W7gLQUbCxhLqIlfR8lcyCgHmgR+hPPsb5nd77U6/bVJe9/7U+W/COZ2Uhx/xGBAy97B7y8T7WT8f6TPsSF/ujG/zwpTp/ScDGEQMRwZ19NeA0TUADPu+6sOVxF4wf19TS+7igxw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641975; c=relaxed/simple; bh=SJXv2t4OZbXh+NyO62LuV5zQymuScxzi2obA3tG3/oI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=n/GkP4JnuOpLUYGoyQiDg1MnS2CXB00iuaJmt2shCcSv9YDP+f1Z8DNNzxPIbcurSuBuxmiWMNVHjVlqSb/UPiXARaFDUR69cyTVGM+Mx3h+lNnKjTYGzvExR9+L/Dt3yDkABmP+Jgl1pWCm3yb7Wuu4rkVVFBfOJ4MbTS9BWmM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641973; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Qs7tutJvZtFjLNSc69xVY2l5Chogdf7MZhubQB4HYsE=; b=cZgwr02268nGSFiiWRWpNf2f6MRh2nylroW5Pyo2uU6GJx3S8R6C+Yrgwj3b7nnO44WsM6 bdiu9Te7pDhCQXC8fAIQWmaSKmWXWFCZ31FNh+UvMou1uROw7gP+0X/dr2/EFwUxUC9cCX RWQwrWZet8OHEQqzlTR/v496A/Th/24= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-411-pjxWqjUdO_yLdX8NfQu-0w-1; Fri, 02 Aug 2024 19:39:32 -0400 X-MC-Unique: pjxWqjUdO_yLdX8NfQu-0w-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A8CE8195608B; Fri, 2 Aug 2024 23:39:31 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 365DC1955D47; Fri, 2 Aug 2024 23:39:30 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 08/10 v3] libdw: Make libdw_findcu thread-safe Date: Fri, 2 Aug 2024 19:38:07 -0400 Message-ID: <20240802233847.690564-8-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 (__libdw_findcu): Add locking. Signed-off-by: Heather S. McIntyre Signed-off-by: Aaron Merey Signed-off-by: Mark Wielaard --- v3 changes: Fix indentation and move rwlock_init calls to other patches in this series. libdw/libdw_findcu.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index c74e895e..bbbbee5d 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -245,27 +245,39 @@ __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 = eu_tfind (&fake, tree, findcu_cb); + struct Dwarf_CU *result = NULL; if (found != NULL) return *found; + rwlock_wrlock (dbg->dwarf_lock); + if (start < *next_offset) + __libdw_seterrno (DWARF_E_INVALID_DWARF); + else { - __libdw_seterrno (DWARF_E_INVALID_DWARF); - return NULL; - } + /* No. Then read more CUs. */ + while (1) + { + struct Dwarf_CU *newp + = __libdw_intern_next_unit (dbg, v4_debug_types); - /* No. Then read more CUs. */ - while (1) - { - struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, v4_debug_types); - if (newp == NULL) - return NULL; + 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 (dbg->dwarf_lock); + return result; } struct Dwarf_CU * From patchwork Fri Aug 2 23:38:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95246 X-Patchwork-Delegate: mark@klomp.org 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 27BA43858D35 for ; Fri, 2 Aug 2024 23:40:59 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 9D5E1385DDDF for ; Fri, 2 Aug 2024 23:39:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9D5E1385DDDF Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9D5E1385DDDF Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641984; cv=none; b=DcF/mLfJJtT7TgXZxz2hQ0DTrJfRC408kmkajV92EIn9CjDHCPaedgsYI4f5Kd7KPQm+5Exxkw8JmeTZ19LQMO9Q7LiiO++lT/Kf2WN5b8Z3n/kONzZj/iWlHpJ7JSYvi4GfMltBWhSXhm6C1KxDEjQEINd4v9vlpJrS4KtM9P0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641984; c=relaxed/simple; bh=SHt6YF1rwoWFfuItPYiXrr7wfnxnzDucjwSyHrtVUL0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=oqfv9XOJkp41PIyuVyuI/AgzvJvRlNjsR7xRNRNT3P7mACdidBO20cUhWIIEABpadOdOCoeRPPN7aDlMXBZcUGRc0v3rcZaDP/cJE7kFjmJvIuLtYsajFkPSuh7S/py9cxrN1+6uTy7zniEybNOq4EKTL+KO1vMcU8TG9NC8u1M= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641979; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lPU94Eb5bSJIQlCasdlwjIP995AIiXNYGC9YWQtRb34=; b=E2W5BbwEZXw9hDzVJVB5UfHfXVMtTs5cdvdtTwdGSpd2JlVZ+BufnewLXvMEVAjBCWGR0d vF3VKjalwAthbdtnSWjiDX1BqaNmeFEBWGtxEpDTt8Gr2Nup0QE/NGOEXmxyruwRXKYDlI 8AGVuAXAT6LdRdhl662T/QGOWQZJNws= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-1-eyrf2gsgO0mGBA4XmZdIIQ-1; Fri, 02 Aug 2024 19:39:36 -0400 X-MC-Unique: eyrf2gsgO0mGBA4XmZdIIQ-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id EF45919560A2; Fri, 2 Aug 2024 23:39:34 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5FBFB19560AA; Fri, 2 Aug 2024 23:39:33 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 09/10 v3] tests: Add eu-search tests Date: Fri, 2 Aug 2024 19:38:08 -0400 Message-ID: <20240802233847.690564-9-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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: Aaron Merey Signed-off-by: Mark Wielaard --- No changes between v2 and v3. The elfutils testsuite (including the tests added in this patch) passes for me on the sourceware buildbots. However the buildbots do not configure elfutils with --enable-thread-safety. I think we should include this configure option when the buildbots run elfutils tests. Aaron tests/.gitignore | 4 + tests/Makefile.am | 19 ++- 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 ++++++++++++++++++++++ 7 files changed, 1129 insertions(+), 2 deletions(-) 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/.gitignore b/tests/.gitignore index 30f5800b..360c13a3 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -67,6 +67,10 @@ /elfstrtab /elf-print-reloc-syms /emptyfile +/eu_search_cfi +/eu_search_die +/eu_search_lines +/eu_search_macros /fillfile /find-prologues /funcretval diff --git a/tests/Makefile.am b/tests/Makefile.am index cfed54b7..1642d4e9 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 \ @@ -64,6 +68,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ msg_tst system-elf-libelf-test system-elf-gelf-test \ nvidia_extended_linemap_libdw elf-print-reloc-syms \ cu-dwp-section-info declfiles \ + 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 \ @@ -216,7 +221,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ run-readelf-dw-form-indirect.sh run-strip-largealign.sh \ run-readelf-Dd.sh run-dwfl-core-noncontig.sh run-cu-dwp-section-info.sh \ run-declfiles.sh \ - run-sysroot.sh + run-sysroot.sh run-eu-search-tests.sh if !BIARCH export ELFUTILS_DISABLE_BIARCH = 1 @@ -669,7 +674,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ testfile-dwp-4-cu-index-overflow.dwp.bz2 \ testfile-dwp-cu-index-overflow.source \ testfile-define-file.bz2 \ - testfile-sysroot.tar.bz2 run-sysroot.sh + testfile-sysroot.tar.bz2 run-sysroot.sh \ + run-eu-search-tests.sh if USE_VALGRIND @@ -849,6 +855,15 @@ nvidia_extended_linemap_libdw_LDADD = $(libelf) $(libdw) elf_print_reloc_syms_LDADD = $(libelf) cu_dwp_section_info_LDADD = $(libdw) declfiles_LDADD = $(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..6954ca79 --- /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 ("%dinclude %#" PRIx64 "\n", atomic_load (&level), w); + + atomic_fetch_add(&level, 1); + + include(dbg, w, DWARF_GETMACROS_START); + + atomic_fetch_sub(&level, 1); + + printf ("%d/include\n", atomic_load (&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 ("%dfile %s\n", atomic_load (&level), name); + atomic_fetch_add(&level, 1); + break; + } + + case DW_MACRO_end_file: + { + atomic_fetch_sub(&level, 1); + printf ("%d/file\n", atomic_load (&level)); + break; + } + + case DW_MACINFO_define: + case DW_MACRO_define_strp: + { + const char *value; + dwarf_macro_param2(macro, NULL, &value); + printf ("%d%s\n", atomic_load (&level), value); + break; + } + + case DW_MACINFO_undef: + case DW_MACRO_undef_strp: + break; + + default: + { + size_t paramcnt; + dwarf_macro_getparamcnt(macro, ¶mcnt); + printf ("%dopcode %u with %zd arguments\n", atomic_load (&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; +} 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 Fri Aug 2 23:38:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 95245 X-Patchwork-Delegate: mark@klomp.org 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 3A4BB3858289 for ; Fri, 2 Aug 2024 23:40:31 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id A76543858C78 for ; Fri, 2 Aug 2024 23:39:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A76543858C78 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A76543858C78 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641982; cv=none; b=BvNYxOriL8ICXlBqHOLbpvsm6yzO1t3UvpyYpTNuaZNSVTRIv7F9kC3yaJ+0KrcJv2meSZC/0i+sU8rX9F5m0NjOu7BcxfR7S0EenZ8q7ILRhX2uaONopsQmnDYQGoCFtSwcWqBahDIU9BZoNMqsvm1sNucfe3KnnjaY8YeBEAY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722641982; c=relaxed/simple; bh=P3YriNMsASpsI2YGFdCY6ICK5Dawp0q16rCso7OP/XA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=dT/Re3wE8G1jd1mncjP/o+BnuM6bpPE6ShcSvsyczUu2Zu6uN+HVspZOfKoL7xpNxpB+WUAmt0QJfO69y3p1V8vzgezNAqKDfGKaxiDiYD89leXFOHHdBhbUriUrbXNG8ymYWlsbGAn/sZAVvAhoIY5HCu+e1OFN4W5IvFnVmXQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722641980; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=czK3DE1TP/jAeM9QZh6VXoAaFNXJhOYcvtMZeTY2R34=; b=e9mJfuDxmd7H1IBbrIF0Y0ocATI8OluZ3nPxOHRdQeCpGOTYVuqMN7p7DVMgh1CO8t251n GNnTRsuYI7B6QW4GrZdYT9b8T+lMPHyuAmJA8WcefACm7tZs60oE3IhrQ1trVRZFqGkHHC VLZR4cdRDg/5m7a3UK4I2w+eh7f5B3Y= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-488-jxt99Mp9NXKIndSWAmoIjw-1; Fri, 02 Aug 2024 19:39:39 -0400 X-MC-Unique: jxt99Mp9NXKIndSWAmoIjw-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 27D511955D42; Fri, 2 Aug 2024 23:39:38 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.22.64.40]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7F9E01955D44; Fri, 2 Aug 2024 23:39:36 +0000 (UTC) From: Aaron Merey To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, johnmc@rice.edu, mark@klomp.org, Aaron Merey Subject: [PATCH 10/10 v3] configure: No longer mark --enable-thread-safety as EXPERIMENTAL Date: Fri, 2 Aug 2024 19:38:09 -0400 Message-ID: <20240802233847.690564-10-amerey@redhat.com> In-Reply-To: <20240802233847.690564-1-amerey@redhat.com> References: <20240802233847.690564-1-amerey@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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: Aaron Merey Signed-off-by: Mark Wielaard --- No changes between v2 and v3. PR31967 (datarace in elf_compress[_gnu]) was recently filed and this patch set does not address it. libdwfl requires additional locking. I think we should hold off on merging this patch and keep thread safety "experimental" until these issues are fixed. Aaron configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 24e68d94..2c885c8a 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.]) @@ -939,10 +937,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}