From patchwork Thu Oct 10 02:16:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98621 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 527C138650F6 for ; Thu, 10 Oct 2024 02:27:09 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 A2B68385DDFF for ; Thu, 10 Oct 2024 02:26:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A2B68385DDFF 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 A2B68385DDFF 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=1728527184; cv=none; b=Ek2BuuVsx1ICB04NVWmBvNJdApBUSE05CFL0Fyx3Gafcntu5MsicpXkNu/PLR54TR82FikcBXkZ9XtNKVDEx4ewxvBhfc00Cz59SYLeApE54H1XEauWULfzG89VDmo28SjFQEKnoVf1EQw7I3E7YnXGnams8Mgnslt1DbMhmxI4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527184; c=relaxed/simple; bh=Tl6MOeGMkfxlNWl06MkA4v24pYKJ0XhjXFpIcIBpI9A=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=RoA3PUYSV4D3cryFKSpW5cWvaCxhjjzzvUHzBhyRdPTQGkpKylOXX4eiGF+hZmaRHUplUiOCGCrO44A6QE4q07DvwB/f0EkGx4kjUdGhTPLFa5gr3ngcnbcwBfGQ+Cr31E8jWd86G9d0WjbvPdhz4qwV7XbRRFIj/MAYLvRL6ms= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527179; 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=9QP3imvLapmnpdzHYQhZbenIeCxzs81N3tWhHWmdeFI=; b=KgPaYoAMQudlmd7NpE2/M+blxCUAlTsttMuTa2PAw/6eirlw4JCGN0l3c0Ajv7Vm7JBrTN X5Z4E8uH02ZxmX+LJmWQGoeABi3zlzifdcGVIw0oTGz2uPWsrSMYQIXJs0XCZsug4rNIsp sWUJ1dIMkxu7cWYgviIqBxMEQ6aVt6I= 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-473-W1Lc_sM-OYSmDRerdhP4LQ-1; Wed, 09 Oct 2024 22:26:18 -0400 X-MC-Unique: W1Lc_sM-OYSmDRerdhP4LQ-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 5C03419560B0 for ; Thu, 10 Oct 2024 02:26:15 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6791A19560A2; Thu, 10 Oct 2024 02:26:14 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 01/11] Don't attempt to find TLS address when target has no registers Date: Wed, 9 Oct 2024 19:16:04 -0700 Message-ID: <20241010022552.47637-2-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.7 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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org This commit fixes two bugs, one of which is Bug 25807 - that one is fixed by the change in findvar.c. I found it while testing on aarch64; it turned a KFAIL for gdb.threads/tls.exp: print a_thread_local into a FAIL due to a GDB internal error. In addition to the existing test just noted, I've also added a test to the new test case gdb.base/tls-nothreads.exp. It'll be tested, using different scenarios, up to 8 times: PASS: gdb.base/tls-nothreads.exp: default: force_internal_tls=false: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: default: force_internal_tls=true: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: static: force_internal_tls=false: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: static: force_internal_tls=true: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls=false: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls=true: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls=false: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls=true: after exit: print tls_tbss_1 There is a related problem that's fixed by the minsyms.c change. It can be observed when debugging a program without debugging symbols when the program is not executing. I've written a new test for this, but it's included in the new test case gdb.base/tls-nothreads.exp, found later in this series. Depending on the target, it'll be run up to 8 times for different targets. E.g., on aarch64, I'm seeing these PASSes, all of which test this change: PASS: gdb.base/tls-nothreads.exp: default: force_internal_tls=false: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: default: force_internal_tls=true: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: static: force_internal_tls=false: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: static: force_internal_tls=true: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls=false: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls=true: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls=false: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls=true: stripped: after exit: print (int) tls_tbss_1 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=25807 --- gdb/findvar.c | 7 ++++++- gdb/minsyms.c | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/gdb/findvar.c b/gdb/findvar.c index f7760aa61ca..a530e679c8a 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -485,7 +485,12 @@ language_defn::read_var_value (struct symbol *var, /* Determine address of TLS variable. */ if (obj_section && (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) - addr = target_translate_tls_address (obj_section->objfile, addr); + { + if (!target_has_registers ()) + error (_("Cannot read `%s' without registers"), + var->print_name ()); + addr = target_translate_tls_address (obj_section->objfile, addr); + } } break; diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 33eb9072e5f..a904bd96045 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -1684,7 +1684,13 @@ find_minsym_type_and_address (minimal_symbol *msymbol, { /* Skip translation if caller does not need the address. */ if (address_p != NULL) - *address_p = target_translate_tls_address (objfile, addr); + { + if (!target_has_registers ()) + error (_( + "Cannot determine address of TLS symbol `%s' without registers"), + bound_msym.minsym->print_name ()); + *address_p = target_translate_tls_address (objfile, addr); + } return builtin_type (objfile)->nodebug_tls_symbol; } From patchwork Thu Oct 10 02:16:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98620 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 3751638650E7 for ; Thu, 10 Oct 2024 02:27:03 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 A5C6D385E003 for ; Thu, 10 Oct 2024 02:26:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A5C6D385E003 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 A5C6D385E003 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=1728527183; cv=none; b=Xs7DlaSuPlUMyRfZwJrsEMFTgjwpBQ4b3IJvCiTfjQNauUH7RdFsN3mGbHpJDgu0GKkmYOihl6cJjo9QebZrhGnk2S/pT/r3ck0WTNZWIYsTE3F3HuqvtZRSrHJG6HjCc/Q2AIdmQaTuFGdBAwVMrimJ0io0b34razFf8zecOeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527183; c=relaxed/simple; bh=/xjatM3GzKfdNWlq4ZVSQ25BA7TIBI1LImJcEUh3JmU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=YmVTR6icUn2G+0OtJXCf7h/AOuaxvQB83sIvHPy74bxGBDnKcuWQ+9rNt39J4+Osu/ljIIt3nMksemub+D3Le2Epcu1hb/KA34XyVdOb78DfFRxPuX+XbVMuZapuTzkgTRqLkSknMvFKYf9WaUzIKb1chLDvEGQNAPKr6OUir6I= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527178; 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=ibMUVLjAjzoNerlX70etYfgrVfMRAp7rH8ZrL3jAb2Q=; b=PFH2ODmZM4wQ/TmVUF9GpfrA+PPBjm5mMnaU18oTDH9QOpbNSNzOYhTdgBKmRYDCKEUNEN M4xllAMhy/egfwRIP/y+jwcG4a2pbve473aqsu1ii7JbuuSZidYKIUeJVVIR9Q9P/3Yq3S nZY3MyDyYey+PmXz/CumzkmQehxs9Ag= 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-653-6HzpmLtbPsCnIEJBjn-x9Q-1; Wed, 09 Oct 2024 22:26:17 -0400 X-MC-Unique: 6HzpmLtbPsCnIEJBjn-x9Q-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 711571956083 for ; Thu, 10 Oct 2024 02:26:16 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9A0A619560A2; Thu, 10 Oct 2024 02:26:15 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 02/11] Allow TLS access to work in gdb.server/no-thread-db.exp Date: Wed, 9 Oct 2024 19:16:05 -0700 Message-ID: <20241010022552.47637-3-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.7 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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org The patches later in the series add GDB-internal TLS support for certain targets. This commit updates the "print foo" test in gdb.server/no-thread-db.exp to accept either a TLS failure (when libthread_db isn't available) or printing the correct answer, which will occur when GDB's internal TLS address resolution can be used. I'm making this change prior to the commits which actually add the GDB-internal TLS support in order to avoid tripping regression testers. --- gdb/testsuite/gdb.server/no-thread-db.exp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gdb/testsuite/gdb.server/no-thread-db.exp b/gdb/testsuite/gdb.server/no-thread-db.exp index 656fad1a560..baad81b0f8e 100644 --- a/gdb/testsuite/gdb.server/no-thread-db.exp +++ b/gdb/testsuite/gdb.server/no-thread-db.exp @@ -57,6 +57,8 @@ gdb_breakpoint ${srcfile}:[gdb_get_line_number "after tls assignment"] gdb_continue_to_breakpoint "after tls assignment" # Printing a tls variable should fail gracefully without a libthread_db. +# Alternately, the correct answer might be printed due GDB's internal +# TLS support for some targets. set re_exec "\[^\r\n\]*[file tail $binfile]" gdb_test "print foo" \ - "Cannot find thread-local storage for Thread \[^,\]+, executable file $re_exec:\[\r\n\]+Remote target failed to process qGetTLSAddr request" + "= 1|(?:Cannot find thread-local storage for Thread \[^,\]+, executable file $re_exec:\[\r\n\]+Remote target failed to process qGetTLSAddr request)" From patchwork Thu Oct 10 02:16:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98623 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 B1F42385E827 for ; Thu, 10 Oct 2024 02:27:36 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 BAC29385DDF3 for ; Thu, 10 Oct 2024 02:26:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BAC29385DDF3 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 BAC29385DDF3 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=1728527188; cv=none; b=eJaQUFaUjlxYsyvFzMIuX7QWVLh1Y4HfVNxCyP5dkeOruckX7PZgpTAEnIFYcAskFrlBE4aMEWrD48RK8htRX3DoydROIkRTo/uxPGZJvDdSFWGeh6mL4nCXGZMjbg1uMBwZ55/aYASRnwX1tDIbJ4TiUKkuuy7bYzdLa8zdOSQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527188; c=relaxed/simple; bh=8n8juZmLBF320DWeWPolBpVykGtakeZ0tFNYf1/ysyc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=N7Ul1YaXFNJoez05osjiDw3qKlvTvvu280OFbW4wKQMD+6tQGYg+1+YEluv5I0HZCstIo8Qidlkf+CDrtPhm0qx1SipsYBbj/OzM10j8ad09HrkWexD4OtejRq+Dac7851/LrqqZ+R5Xm6kNai+cKvSZNM9o4W5FfqJRK2z24r8= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527181; 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=cc4O0kxPGch1M1HyLEUizHYk4izJg/O0AFq3s9vbxaM=; b=FamJ3lsenXtZJB3wunE+k28CqoNTrNoOe5uMQ6b5XxIhdYe0oaIZCaZJdKnQkIUyGYDTOY oIzBZ6/8Og5r7W99OWl9n5uNQxTN1VPnopOs4isImiIl7Lk9+U2FYI9HhaNMQAJapKxXhP NIZiJpE9NCyDLjy/n/G8GomcxHFNbL8= 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-627-7jilrNfiMV-3d_rKXDqZzw-1; Wed, 09 Oct 2024 22:26:18 -0400 X-MC-Unique: 7jilrNfiMV-3d_rKXDqZzw-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 A6A0A19560AB for ; Thu, 10 Oct 2024 02:26:17 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CE32519560A2; Thu, 10 Oct 2024 02:26:16 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 03/11] Track and fetch TLS module ids for MUSL and GLIBC Date: Wed, 9 Oct 2024 19:16:06 -0700 Message-ID: <20241010022552.47637-4-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org This commit adds, to solib-svr4.h and solib-svr4.c, functions glibc_link_map_to_tls_module_id and musl_link_map_to_tls_module_id for use with callers in linux-tdep.c (which is not in this commit). It also adds a number of helper functions for implementing link map to module id support. It also renames existing function 'find_program_interpreter' to 'svr4_find_program_interpreter' and makes it visible to other source files within GDB. It will be used in the libc sniffing code in linux-tdep.c in a later commit in this series. The libc sniffer is needed in order to know which link map to module id function to call as the method for determining module ids differs between libc / dynamic linker implementations. These details are discussed in comments in the patch. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24548 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31563 --- gdb/solib-svr4.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++- gdb/solib-svr4.h | 12 +++ 2 files changed, 211 insertions(+), 4 deletions(-) diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 7999a8e6c7e..b331aac6122 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -405,6 +405,9 @@ struct svr4_info The special entry zero is reserved for a linear list to support gdbstubs that do not support namespaces. */ std::map> solib_lists; + + bool glibc_tls_slots_inited = false; + std::vector glibc_tls_slots; }; /* Per-program-space data key. */ @@ -586,10 +589,10 @@ read_program_header (int type, int *p_arch_size, CORE_ADDR *base_addr) return buf; } +/* See solib-svr4.h. */ -/* Return program interpreter string. */ -static std::optional -find_program_interpreter (void) +std::optional +svr4_find_program_interpreter () { /* If we have a current exec_bfd, use its section table. */ if (current_program_space->exec_bfd () @@ -1516,6 +1519,194 @@ svr4_fetch_objfile_link_map (struct objfile *objfile) return 0; } +/* Return true if bfd section BFD_SECT is a thread local section + (i.e. either named ".tdata" or ".tbss"), and false otherwise. */ + +static bool +is_thread_local_section (struct bfd_section *bfd_sect) +{ + return ((strcmp (bfd_sect->name, ".tdata") == 0 + || strcmp (bfd_sect->name, ".tbss") == 0) + && bfd_sect->size != 0); +} + +/* Return true if objfile OBJF contains a thread local section, and + false otherwise. */ + +static bool +has_thread_local_section (const objfile *objf) +{ + for (obj_section *objsec : objf->sections ()) + if (is_thread_local_section (objsec->the_bfd_section)) + return true; + return false; +} + +/* Return true if solib SO contains a thread local section, and false + otherwise. */ + +static bool +has_thread_local_section (const solib &so) +{ + for (const target_section &p : so.sections) + if (is_thread_local_section (p.the_bfd_section)) + return true; + return false; +} + +/* For the MUSL C library, given link map address LM_ADDR, return the + corresponding TLS module id, or 0 if not found. + + Background: Unlike the mechanism used by glibc (see below), the + scheme used by the MUSL C library is pretty simple. If the + executable contains TLS variables it gets module id 1. Otherwise, + the first shared object loaded which contains TLS variables is + assigned to module id 1. TLS-containing shared objects are then + assigned consecutive module ids, based on the order that they are + loaded. When unloaded via dlclose, module ids are reassigned as if + that module had never been loaded. */ + +int +musl_link_map_to_tls_module_id (CORE_ADDR lm_addr) +{ + /* When lm_addr is zero, the program is statically linked. Any TLS + variables will be in module id 1. */ + if (lm_addr == 0) + return 1; + + int mod_id = 0; + if (has_thread_local_section (current_program_space->symfile_object_file)) + mod_id++; + + struct svr4_info *info = get_svr4_info (current_program_space); + + /* Cause svr4_current_sos() to be run if it hasn't been already. */ + if (info->main_lm_addr == 0) + solib_add (NULL, 0, auto_solib_add); + + /* Handle case where lm_addr corresponds to the main program. + Return value is either 0, when there are no TLS variables, or 1, + when there are. */ + if (lm_addr == info->main_lm_addr) + return mod_id; + + /* Iterate through the shared objects, possibly incrementing the + module id, and returning mod_id should a match be found. */ + for (const solib &so : current_program_space->solibs ()) + { + if (has_thread_local_section (so)) + mod_id++; + + auto *li = gdb::checked_static_cast (so.lm_info.get ()); + if (li->lm_addr == lm_addr) + return mod_id; + } + return 0; +} + +/* For GLIBC, given link map address LM_ADDR, return the corresponding TLS + module id, or 0 if not found. */ + +int +glibc_link_map_to_tls_module_id (CORE_ADDR lm_addr) +{ + /* When lm_addr is zero, the program is statically linked. Any TLS + variables will be in module id 1. */ + if (lm_addr == 0) + return 1; + + /* Look up lm_addr in the TLS slot data structure. */ + struct svr4_info *info = get_svr4_info (current_program_space); + auto it = std::find (info->glibc_tls_slots.begin (), + info->glibc_tls_slots.end (), + lm_addr); + if (it == info->glibc_tls_slots.end ()) + return 0; + else + return 1 + it - info->glibc_tls_slots.begin (); +} + +/* Conditionally, based on whether the shared object, SO, contains TLS + variables, assign a link map address to a TLS module id slot. This + code is GLIBC-specific and may only work for specific GLIBC + versions. That said, it is known to work for (at least) GLIBC + versions 2.27 thru 2.40. + + Background: In order to implement internal TLS address lookup + code, it is necessary to find the module id that has been + associated with a specific link map address. In GLIBC, the TLS + module id is stored in struct link_map, in the member + 'l_tls_modid'. While the first several members of struct link_map + are part of the SVR4 ABI, the offset to l_tls_modid definitely is + not. Therefore, since we don't know the offset to l_tls_modid, we + cannot simply look it up - which is a shame, because things would + be so much more easy and obviously accurate, if we could access + l_tls_modid. + + GLIBC has a concept of TLS module id slots. These slots are + allocated consecutively as shared objects containing TLS variables + are loaded. When unloaded (e.g. via dlclose()), the corresponding + slot is marked as unused, but may be used again when later loading + a shared object. + + The functions tls_maybe_fill_slot and tls_maybe_erase_slot are + associated with the observers 'solib_loaded' and 'solib_unloaded'. + They (attempt to) track use of TLS module id slots in the same way + that GLIBC does, which will hopefully provide an accurate module id + when asked to provide it via glibc_link_map_to_tls_module_id(), + above. */ + +static void +tls_maybe_fill_slot (solib &so) +{ + struct svr4_info *info = get_svr4_info (current_program_space); + if (!info->glibc_tls_slots_inited) + { + /* Cause svr4_current_sos() to be run if it hasn't been already. */ + if (info->main_lm_addr == 0) + svr4_current_sos_direct (info); + + /* Quit early when main_lm_addr is still 0. */ + if (info->main_lm_addr == 0) + return; + + /* Also quit early when symfile_object_file is not yet known. */ + if (current_program_space->symfile_object_file == nullptr) + return; + + if (has_thread_local_section (current_program_space->symfile_object_file)) + info->glibc_tls_slots.push_back (info->main_lm_addr); + info->glibc_tls_slots_inited = true; + } + + if (has_thread_local_section (so)) + { + auto it = std::find (info->glibc_tls_slots.begin (), + info->glibc_tls_slots.end (), + 0); + auto *li = gdb::checked_static_cast (so.lm_info.get ()); + if (it == info->glibc_tls_slots.end ()) + info->glibc_tls_slots.push_back (li->lm_addr); + else + *it = li->lm_addr; + } +} + +/* Remove a link map address from the TLS module slot data structure. + As noted above, this code is GLIBC-specific. */ + +static void +tls_maybe_erase_slot (program_space *pspace, const solib &so) +{ + struct svr4_info *info = get_svr4_info (pspace); + auto *li = gdb::checked_static_cast (so.lm_info.get ()); + auto it = std::find (info->glibc_tls_slots.begin (), + info->glibc_tls_slots.end (), + li->lm_addr); + if (it != info->glibc_tls_slots.end ()) + *it = 0; +} + /* On some systems, the only way to recognize the link map entry for the main executable file is by looking at its name. Return non-zero iff SONAME matches one of the known main executable names. */ @@ -2305,7 +2496,7 @@ enable_break (struct svr4_info *info, int from_tty) /* Find the program interpreter; if not found, warn the user and drop into the old breakpoint at symbol code. */ std::optional interp_name_holder - = find_program_interpreter (); + = svr4_find_program_interpreter (); if (interp_name_holder) { const char *interp_name = (const char *) interp_name_holder->data (); @@ -3382,4 +3573,8 @@ _initialize_svr4_solib () { gdb::observers::free_objfile.attach (svr4_free_objfile_observer, "solib-svr4"); + + /* Set up observers for tracking GLIBC TLS module id slots. */ + gdb::observers::solib_loaded.attach (tls_maybe_fill_slot, "solib-svr4"); + gdb::observers::solib_unloaded.attach (tls_maybe_erase_slot, "solib-svr4"); } diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h index 579fe6d9843..6e25441f221 100644 --- a/gdb/solib-svr4.h +++ b/gdb/solib-svr4.h @@ -112,4 +112,16 @@ extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void); SVR4 run time loader. */ int svr4_in_dynsym_resolve_code (CORE_ADDR pc); +/* For the MUSL C library, given link map address LM_ADDR, return the + corresponding TLS module id, or 0 if not found. */ +int musl_link_map_to_tls_module_id (CORE_ADDR lm_addr); + +/* For GLIBC, given link map address LM_ADDR, return the corresponding TLS + module id, or 0 if not found. */ +int glibc_link_map_to_tls_module_id (CORE_ADDR lm_addr); + +/* Return program interpreter string. */ + +std::optional svr4_find_program_interpreter (); + #endif /* solib-svr4.h */ From patchwork Thu Oct 10 02:16:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98622 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 15FB0385EC29 for ; Thu, 10 Oct 2024 02:27:24 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 48777385332C for ; Thu, 10 Oct 2024 02:26:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 48777385332C 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 48777385332C 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=1728527188; cv=none; b=ck7m5WHLMQ+vTBcEzNUCPwAyIFCVlSW4NM+7NCqwAXg1WHyRsnGhL0h9I4O81Q+S+cUPridWNmIm60HhYEBb2gJIWLQWsfRl6+eKPIj9OpEwfnX7ncO2xt9AZHz7DtGWrVwope/kk6riXo485ZnIM44mbfZUVVz02d3UPtc/N2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527188; c=relaxed/simple; bh=iRgJbPI1kD4MJf0Aq04eP7j672ZYNBrjYilojkt1C8w=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=BD4ibMCPkk6xGu9Je2m35OjOr7FAYEKiJIpUUQq73scWKDtcnVwZiPmH8l/aeHGSbjRHksWMxU+VW71aAmX1FXELiRi/gTsMfNsaxsW4t13sxTCrRF1qmIJLPri+66K3ugcJC/n406M1Lo8x/q5siJn61aXkUZDSzTEkMTayOVE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527180; 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=jd6+Ms7yxmcodQJ+XMzu1/O2F+KdlmfmcztAKz0KrLQ=; b=FGNvI4Ju4C65ffhOgJPjdagSJXHSzVCL753gHC8rfv9R76nYkgyKP99BC1aIIas3W8GZgk ktxnwEzYdwgHoxVNUUZYwgBrcBlxY0lUqYEfRFdSWU/lgumRZJdkJHpaPTUhstOQDWH96B obVlgeGpyDslX8kek4L1wSsSFJiVrfg= 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-387-CEpsg-xkMDKcIZu5cvIM8w-1; Wed, 09 Oct 2024 22:26:19 -0400 X-MC-Unique: CEpsg-xkMDKcIZu5cvIM8w-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 DAEF91956048 for ; Thu, 10 Oct 2024 02:26:18 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0F1D119560A2; Thu, 10 Oct 2024 02:26:17 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 04/11] Implement internal TLS address lookup for Linux targets Date: Wed, 9 Oct 2024 19:16:07 -0700 Message-ID: <20241010022552.47637-5-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org This commit adds non-architecture-specific support for internal TLS address lookup for Linux targets. By "internal", I mean support which does not rely on libthread_db. Knowledge of how to traverse TLS data structures is contained in this commit along with the next commit containing architecture specific knowledge regarding TLS offsets, registers, and such. The new function 'linux_get_thread_local_address' is a gdbarch method. It should be passed as an argument to set_gdbarch_get_thread_local_address in architecture specific -linux-tdep.c files which wish to offer internal TLS support. The architecture specific tdep files need to define a get_tls_dtv_addr method - as the name suggests, it needs to return the address of the DTV (dynamic thread vector) via architecture specific means. This usually entails fetching the thread pointer via a register or registers assigned to this purpose, and then using that value to locate the address of the DTV from within the TCB (thread control block). Additionally, some architectures also need to provide a DTP offset, which is used by the MUSL C library to adjust the value obtained from a DTV entry to that of the start of the TLS block for a particular thread. This is provided, when necessary by a get_tls_dtp_offset method. Both methods, get_tls_dtv_addr and get_tls_dtp_offset are registered with data structures maintained by linux-tdep.c via the new function linux_register_tls_methods(). Thus, for example, on RISC-V, riscv_linux_init_abi() will make the following two calls, the first for registering the internal get_thread_local_address gdbarch method and the second for registering riscv-specific methods for obtaining the DTV address and DTP offset: set_gdbarch_get_thread_local_address (gdbarch, linux_get_thread_local_address); linux_register_tls_methods (info, gdbarch, riscv_linux_get_tls_dtv_addr, riscv_linux_get_tls_dtp_offset); Internal TLS support is provided for two C libraries, GLIBC, and MUSL. Details for accessing the various TLS data structures differ between these libraries. As a consequence, linux-tdep.h defines a new enum, linux_libc, with values linux_libc_unknown, linux_libc_musl, and linux_libc_glibc. A new static function libc_tls_sniffer uses heuristics to (try to) decide whether a program was linked against GLIBC or MUSL. Working out what the heuristics should be, especially for statically linked binaries, turned out to be harder than I thought it would be. There is also a new setting, force-internal-tls-address-lookup, which, when set to 'on', will (as the name suggests) force the internal TLS lookup mechanisms to be used. Otherwise, if thread_db support is available (via the thread stratum), that will be preferred since it should be more accurate. I expect that this setting will be mostly (only) used by test cases in the GDB test suite. The new test cases that are part of this series all use it, both on and off for all of the tests therein. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24548 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31563 --- gdb/linux-tdep.c | 209 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/linux-tdep.h | 36 ++++++++ 2 files changed, 245 insertions(+) diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 65ec221ef48..5c80ef50b78 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -48,6 +48,11 @@ #include #include +/* When true, force internal TLS address lookup instead of lookup via + the thread stratum. */ + +static bool force_internal_tls_address_lookup = false; + /* This enum represents the values that the user can choose when informing the Linux kernel about which memory mappings will be dumped in a corefile. They are described in the file @@ -198,6 +203,15 @@ struct linux_gdbarch_data { struct type *siginfo_type = nullptr; int num_disp_step_buffers = 0; + + /* Method for looking up TLS DTV. */ + get_tls_dtv_addr_ftype *get_tls_dtv_addr = nullptr; + + /* Method for looking up the TLS DTP offset. */ + get_tls_dtp_offset_ftype *get_tls_dtp_offset = nullptr; + + /* Cached libc value for TLS lookup purposes. */ + enum linux_libc libc = linux_libc_unknown; }; static const registry::key @@ -2744,6 +2758,172 @@ show_dump_excluded_mappings (struct ui_file *file, int from_tty, " flag is %s.\n"), value); } +/* For TLS lookup purposes, use heuristics to decide whether program + was linked against MUSL or GLIBC. */ + +static enum linux_libc +libc_tls_sniffer (struct gdbarch *gdbarch) +{ + /* Check for cached libc value. */ + linux_gdbarch_data *gdbarch_data = get_linux_gdbarch_data (gdbarch); + if (gdbarch_data->libc != linux_libc_unknown) + return gdbarch_data->libc; + + linux_libc libc = linux_libc_unknown; + + /* Fetch the program interpreter. */ + std::optional interp_name_holder + = svr4_find_program_interpreter (); + if (interp_name_holder) + { + /* A dynamically linked program linked against MUSL will have a + "ld-musl-" in its interpreter name. (Two examples of MUSL + interpreter names are "/lib/ld-musl-x86_64.so.1" and + "lib/ld-musl-aarch64.so.1".) If it's not found, assume GLIBC. */ + const char *interp_name = (const char *) interp_name_holder->data (); + if (strstr (interp_name, "/ld-musl-") != nullptr) + libc = linux_libc_musl; + else + libc = linux_libc_glibc; + gdbarch_data->libc = libc; + return libc; + } + + /* If there is no interpreter name, it's statically linked. For + programs with TLS data, a program statically linked against MUSL + will have the symbols 'main_tls' and 'builtin_tls'. If both of + these are present, assume that it was statically linked against + MUSL, otherwise assume GLIBC. */ + if (lookup_minimal_symbol (current_program_space, "main_tls").minsym + != nullptr + && lookup_minimal_symbol (current_program_space, "builtin_tls").minsym + != nullptr) + libc = linux_libc_musl; + else + libc = linux_libc_glibc; + gdbarch_data->libc = libc; + return libc; +} + +/* Implement gdbarch method, get_thread_local_address, for architectures + which provide a method for determining the DTV and possibly the DTP + offset. */ + +CORE_ADDR +linux_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, + CORE_ADDR lm_addr, CORE_ADDR offset) +{ + linux_gdbarch_data *gdbarch_data = get_linux_gdbarch_data (gdbarch); + + /* Use the target's get_thread_local_address method when: + + - No method has been provided for finding the TLS DTV. + + or + + - The thread stratum has been pushed (at some point) onto the + target stack, except when 'force_internal_tls_address_lookup' + has been set. + + The idea here is to prefer use of of the target's thread_stratum + method since it should be more accurate. */ + if (gdbarch_data->get_tls_dtv_addr == nullptr + || (find_target_at (thread_stratum) != nullptr + && !force_internal_tls_address_lookup)) + { + struct target_ops *target = current_inferior ()->top_target (); + return target->get_thread_local_address (ptid, lm_addr, offset); + } + else + { + /* Details, found below, regarding TLS layout is for the GNU C + library (glibc) and the MUSL C library (musl), circa 2024. + While some of this layout is defined by the TLS ABI, some of + it, such as how/where to find the DTV pointer in the TCB, is + not. A good source of ABI info for some architectures can be + found in "ELF Handling For Thread-Local Storage" by Ulrich + Drepper. That document is worth consulting even for + architectures not described there, since the general approach + and terminology is used regardless. + + Some architectures, such as aarch64, are not described in + that document, so some details had to ferreted out using the + glibc source code. Likewise, the MUSL source code was + consulted for details which differ from GLIBC. */ + enum linux_libc libc = libc_tls_sniffer (gdbarch); + int mod_id; + if (libc == linux_libc_glibc) + mod_id = glibc_link_map_to_tls_module_id (lm_addr); + else /* Assume MUSL. */ + mod_id = musl_link_map_to_tls_module_id (lm_addr); + if (mod_id == 0) + throw_error (TLS_GENERIC_ERROR, _("Unable to determine TLS module id")); + + /* Use the architecture specific DTV fetcher to obtain the DTV. */ + CORE_ADDR dtv_addr = gdbarch_data->get_tls_dtv_addr (gdbarch, ptid, libc); + + /* In GLIBC, The DTV (dynamic thread vector) is an array of + structs consisting of two fields, the first of which is a + pointer to the TLS block of interest. (The second field is a + pointer that assists with memory management, but that's not + of interest here.) Also, the 0th entry is the generation + number, but although it's a single scalar, the 0th entry is + padded to be the same size as all the rest. Thus each + element of the DTV array is two pointers in size. + + In MUSL, the DTV is simply an array of pointers. The 0th + entry is still the generation number, but contains no padding + aside from that which is needed to make it pointer sized. */ + int m; /* Multiplier, for size of DTV entry. */ + switch (libc) + { + case linux_libc_glibc: + m = 2; + break; + default: + m = 1; + break; + } + + /* Obtain TLS block address. Module ids start at 1, so there's + no need to adjust it to skip over the 0th entry of the DTV, + which is the generation number. */ + CORE_ADDR dtv_elem_addr + = dtv_addr + mod_id * m * (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + if (target_read_memory (dtv_elem_addr, buf.data (), buf.size ()) != 0) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch TLS block address")); + const struct builtin_type *builtin = builtin_type (gdbarch); + CORE_ADDR tls_block_addr = gdbarch_pointer_to_address + (gdbarch, builtin->builtin_data_ptr, + buf.data ()); + + /* When the TLS block addr is 0 or -1, this usually indicates that + the TLS storage hasn't been allocated yet. (In GLIBC, some + architectures use 0 while others use -1.) */ + if (tls_block_addr == 0 || tls_block_addr == (CORE_ADDR) -1) + throw_error (TLS_NOT_ALLOCATED_YET_ERROR, _("TLS not allocated yet")); + + /* MUSL (and perhaps other C libraries, though not GLIBC) have + TLS implementations for some architectures which, for some + reason, have DTV entries which must be negatively offset by + DTP_OFFSET in order to obtain the TLS block address. + DTP_OFFSET is a constant in the MUSL sources - these offsets, + when they're non-zero, seem to be either 0x800 or 0x8000, + and are present for riscv[32/64], powerpc[32/64], m68k, and + mips. + + Use the architecture specific get_tls_dtp_offset method, if + present, to obtain this offset. */ + ULONGEST dtp_offset + = gdbarch_data->get_tls_dtp_offset == nullptr + ? 0 + : gdbarch_data->get_tls_dtp_offset (gdbarch, ptid, libc); + + return tls_block_addr - dtp_offset + offset; + } +} + /* To be called from the various GDB_OSABI_LINUX handlers for the various GNU/Linux architectures and machine types. @@ -2787,6 +2967,20 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); } +/* See linux-tdep.h. */ + +void +linux_register_tls_methods (struct gdbarch_info info, struct gdbarch *gdbarch, + get_tls_dtv_addr_ftype *get_tls_dtv_addr, + get_tls_dtp_offset_ftype *get_tls_dtp_offset) +{ + gdb_assert (get_tls_dtv_addr != nullptr); + + linux_gdbarch_data *gdbarch_data = get_linux_gdbarch_data (gdbarch); + gdbarch_data->get_tls_dtv_addr = get_tls_dtv_addr; + gdbarch_data->get_tls_dtp_offset = get_tls_dtp_offset; +} + void _initialize_linux_tdep (); void _initialize_linux_tdep () @@ -2822,6 +3016,21 @@ VM_DONTDUMP flag (\"dd\" in /proc/PID/smaps) when generating the corefile. For\ more information about this file, refer to the manpage of proc(5) and core(5)."), NULL, show_dump_excluded_mappings, &setlist, &showlist); + + add_setshow_boolean_cmd ("force-internal-tls-address-lookup", class_obscure, + &force_internal_tls_address_lookup, _("\ +Set to force internal TLS address lookup."), _("\ +Show whether GDB is forced to use internal TLS address lookup."), _("\ +When resolving addresses for TLS (Thread Local Storage) variables,\n\ +GDB will attempt to use facilities provided by the thread library (i.e.\n\ +libthread_db). If those facilities aren't available, GDB will fall\n\ +back to using some internal (to GDB), but possibly less accurate\n\ +mechanisms to resolve the addresses for TLS variables. When this flag\n\ +is set, GDB will force use of the fall-back TLS resolution mechanisms.\n\ +This flag is used by some GDB tests to ensure that the internal fallback\n\ +code is exercised and working as expected. The default is to not force\n\ +the internal fall-back mechanisms to be used."), + NULL, NULL, &setlist, &showlist); } /* Fetch (and possibly build) an appropriate `link_map_offsets' for diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h index 66b03cabaa6..83f1538f033 100644 --- a/gdb/linux-tdep.h +++ b/gdb/linux-tdep.h @@ -88,6 +88,35 @@ extern void linux_displaced_step_restore_all_in_ptid (inferior *parent_inf, extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, int num_disp_step_buffers); +/* C library variants for TLS lookup. */ + +enum linux_libc +{ + linux_libc_unknown, + linux_libc_musl, + linux_libc_glibc +}; + +/* Function type for "get_tls_dtv_addr" method. */ + +typedef CORE_ADDR (get_tls_dtv_addr_ftype) (struct gdbarch *gdbarch, + ptid_t ptid, + enum linux_libc libc); + +/* Function type for "get_tls_dtp_offset" method. */ + +typedef CORE_ADDR (get_tls_dtp_offset_ftype) (struct gdbarch *gdbarch, + ptid_t ptid, + enum linux_libc libc); + +/* Register architecture specific methods for fetching the TLS DTV + and TLS DTP, used by linux_get_thread_local_address. */ + +extern void linux_register_tls_methods + (struct gdbarch_info info, struct gdbarch *gdbarch, + get_tls_dtv_addr_ftype *get_tls_dtv_addr, + get_tls_dtp_offset_ftype *get_tls_dtp_offset = nullptr); + extern int linux_is_uclinux (void); /* Fetch the AT_HWCAP entry from auxv data AUXV. Use TARGET and GDBARCH to @@ -117,4 +146,11 @@ extern CORE_ADDR linux_get_hwcap2 (); extern struct link_map_offsets *linux_ilp32_fetch_link_map_offsets (); extern struct link_map_offsets *linux_lp64_fetch_link_map_offsets (); +/* Used as a gdbarch method for get_thread_local_address when the tdep + file also defines a suitable method for obtaining the TLS DTV. + See linux_init_abi(), above. */ +CORE_ADDR +linux_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, + CORE_ADDR lm_addr, CORE_ADDR offset); + #endif /* linux-tdep.h */ From patchwork Thu Oct 10 02:16:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98624 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 73F0438650DB for ; Thu, 10 Oct 2024 02:28:08 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 B0838385E44D for ; Thu, 10 Oct 2024 02:26:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B0838385E44D 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 B0838385E44D 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=1728527189; cv=none; b=ZymBGyuYfcyxBKnSiIjIr64rvGF6CLfu3yAGO0pOv2dn5WgbXOqZOwldV1O4rxc4EM9+XkhRz6xGfYXO9+Df12OOkL9+MFxm2PGTGfibQ+7wzblc8/4ucdjiZSKD7KOAVJ0Q3R9szik/sQ5B5sw6FsknA0chFfHWQYzR7d9z+PM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527189; c=relaxed/simple; bh=e990kFo+Zf9vXtSvK1FOdAnpVOiq71XeaIvzoTxkkro=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=EZCxXoNFDy9HSmfq/8/HA2JlZYTheZba/3UFOIVYdvJXqhA959Im2sNDTpS6FDPczqfhWZIYry/rCTn1z/lzLmrPXtA261Oahz9kF5R09QpUWR2qjiARZ15VCBOrXPlOT7LRaQ/04nkyA534CMte6pK1Alm4pKKu3gXF2MWHJCI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527182; 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=2ZeUzHFnlgHZQaGcYTuk2rT2YcWv2X4Qz9btcTSsAG8=; b=fncn4fbUGM3YVoTX/hW1dcj0BE+VT9fjtlTx+k8MOCNT78/5dbdw6fFP5pTU6k4uBXKA2x 8swWSSRSjgteG+BFas0n0C7lroH+P3qB8sTICosLgxoY2KEgjHJC2Bzzv3Qmnebhdpuqv5 qhf2fh341/g8UdzrpDownsyVH6yCSkw= 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-81-_L5gbvgXOLG_OyqvlVa4MQ-1; Wed, 09 Oct 2024 22:26:21 -0400 X-MC-Unique: _L5gbvgXOLG_OyqvlVa4MQ-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 56B1119560AE for ; Thu, 10 Oct 2024 02:26:20 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4602F19560A2; Thu, 10 Oct 2024 02:26:19 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 05/11] Internal TLS support for aarch64, x86_64, riscv, ppc64, and s390x Date: Wed, 9 Oct 2024 19:16:08 -0700 Message-ID: <20241010022552.47637-6-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org For each architecture, aarch64, x86_64, riscv, ppc64, and s390x, this commit defines a suitable 'get_tls_dtv_addr' method and, when necessary, a 'get_tls_dtp_offset' method. It also registers linux_get_thread_local_address, defined in linux-tdep.c (in an earlier commit), as the get_thread_local_address gdbarch method. It also registers its architecture specific code using linux_register_tls_methods(). Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24548 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31563 Reviewed-By: Luis Machado --- gdb/aarch64-linux-tdep.c | 53 +++++++++++++++++++++++++++ gdb/amd64-linux-tdep.c | 37 +++++++++++++++++++ gdb/ppc-linux-tdep.c | 62 ++++++++++++++++++++++++++++++++ gdb/riscv-linux-tdep.c | 78 ++++++++++++++++++++++++++++++++++++++++ gdb/s390-linux-tdep.c | 43 ++++++++++++++++++++++ 5 files changed, 273 insertions(+) diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index c608a84bc71..b03c2162a1a 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -35,6 +35,7 @@ #include "target/target.h" #include "expop.h" #include "auxv.h" +#include "inferior.h" #include "regcache.h" #include "regset.h" @@ -2693,6 +2694,55 @@ aarch64_use_target_description_from_corefile_notes (gdbarch *gdbarch, return true; } +/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID. + Throw a suitable TLS error if something goes wrong. */ + +static CORE_ADDR +aarch64_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid, + linux_libc libc) +{ + /* On aarch64, the thread pointer is found in the tpidr register. */ + regcache *regcache + = get_thread_arch_regcache (current_inferior (), ptid, gdbarch); + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + target_fetch_registers (regcache, tdep->tls_regnum_base); + ULONGEST thr_ptr; + if (regcache->cooked_read (tdep->tls_regnum_base, &thr_ptr) != REG_VALID) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer")); + + CORE_ADDR dtv_ptr_addr; + switch (libc) + { + case linux_libc_musl: + /* MUSL: The DTV pointer is found at the very end of the pthread + struct which is located *before* the thread pointer. I.e. + the thread pointer will be just beyond the end of the struct, + so the address of the DTV pointer is found one pointer-size + before the thread pointer. */ + dtv_ptr_addr = thr_ptr - (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + break; + case linux_libc_glibc: + /* GLIBC: The thread pointer (tpidr) points at the TCB (thread control + block). On aarch64, this struct (tcbhead_t) is defined to + contain two pointers. The first is a pointer to the DTV and + the second is a pointer to private data. So the DTV pointer + address is the same as the thread pointer. */ + dtv_ptr_addr = thr_ptr; + break; + default: + throw_error (TLS_GENERIC_ERROR, _("Unknown aarch64 C library")); + break; + } + gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address")); + + const struct builtin_type *builtin = builtin_type (gdbarch); + CORE_ADDR dtv_addr = gdbarch_pointer_to_address + (gdbarch, builtin->builtin_data_ptr, buf.data ()); + return dtv_addr; +} + static void aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -2714,6 +2764,9 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); + set_gdbarch_get_thread_local_address (gdbarch, + linux_get_thread_local_address); + linux_register_tls_methods (info, gdbarch, aarch64_linux_get_tls_dtv_addr); /* Shared library handling. */ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 77de8211d86..7512448d987 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -34,6 +34,7 @@ #include "i386-linux-tdep.h" #include "linux-tdep.h" #include "gdbsupport/x86-xstate.h" +#include "inferior.h" #include "amd64-tdep.h" #include "solib-svr4.h" @@ -1767,6 +1768,39 @@ amd64_dtrace_parse_probe_argument (struct gdbarch *gdbarch, } } +/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID. + Throw a suitable TLS error if something goes wrong. */ + +static CORE_ADDR +amd64_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid, + enum linux_libc libc) +{ + /* On x86-64, the thread pointer is found in the fsbase register. */ + regcache *regcache + = get_thread_arch_regcache (current_inferior (), ptid, gdbarch); + target_fetch_registers (regcache, AMD64_FSBASE_REGNUM); + ULONGEST fsbase; + if (regcache->cooked_read (AMD64_FSBASE_REGNUM, &fsbase) != REG_VALID) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer")); + + /* The thread pointer (fsbase) points at the TCB (thread control + block). The first two members of this struct are both pointers, + where the first will be a pointer to the TCB (i.e. it points at + itself) and the second will be a pointer to the DTV (dynamic + thread vector). There are many other fields too, but the one + we care about here is the DTV pointer. Compute the address + of the DTV pointer, fetch it, and convert it to an address. */ + CORE_ADDR dtv_ptr_addr = fsbase + gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address")); + + const struct builtin_type *builtin = builtin_type (gdbarch); + CORE_ADDR dtv_addr = gdbarch_pointer_to_address + (gdbarch, builtin->builtin_data_ptr, buf.data ()); + return dtv_addr; +} + static void amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch, int num_disp_step_buffers) @@ -1797,6 +1831,9 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch, /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); + set_gdbarch_get_thread_local_address (gdbarch, + linux_get_thread_local_address); + linux_register_tls_methods (info, gdbarch, amd64_linux_get_tls_dtv_addr); /* GNU/Linux uses SVR4-style shared libraries. */ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 8a5eea765c2..42a4bc71263 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -2070,6 +2070,63 @@ ppc64_linux_gcc_target_options (struct gdbarch *gdbarch) return ""; } +/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID. + Throw a suitable TLS error if something goes wrong. */ + +static CORE_ADDR +ppc64_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid, + enum linux_libc libc) +{ + /* On ppc64, the thread pointer is found in r13. Fetch this + register. */ + regcache *regcache + = get_thread_arch_regcache (current_inferior (), ptid, gdbarch); + int thread_pointer_regnum = PPC_R0_REGNUM + 13; + target_fetch_registers (regcache, thread_pointer_regnum); + ULONGEST thr_ptr; + if (regcache->cooked_read (thread_pointer_regnum, &thr_ptr) != REG_VALID) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer")); + + /* The thread pointer (r13) is an address that is 0x7000 ahead of + the *end* of the TCB (thread control block). The field + holding the DTV address is at the very end of the TCB. + Therefore, the DTV pointer address can be found by + subtracting (0x7000+8) from the thread pointer. Compute the + address of the DTV pointer, fetch it, and convert it to an + address. */ + CORE_ADDR dtv_ptr_addr = thr_ptr - 0x7000 - 8; + gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address")); + + const struct builtin_type *builtin = builtin_type (gdbarch); + CORE_ADDR dtv_addr = gdbarch_pointer_to_address + (gdbarch, builtin->builtin_data_ptr, buf.data ()); + return dtv_addr; +} + +/* For internal TLS lookup, return the DTP offset, which is the offset + to subtract from a DTV entry, in order to obtain the address of the + TLS block. */ + +static ULONGEST +ppc_linux_get_tls_dtp_offset (struct gdbarch *gdbarch, ptid_t ptid, + linux_libc libc) +{ + if (libc == linux_libc_musl) + { + /* This value is DTP_OFFSET, which represents the value to + subtract from the DTV entry. For PPC, it can be found in + MUSL's arch/powerpc64/pthread_arch.h and + arch/powerpc32/pthread_arch.h. (Both values are the same.) + It represents the value to subtract from the DTV entry, once + it has been fetched from the DTV array. */ + return 0x8000; + } + else + return 0; +} + static displaced_step_prepare_status ppc_linux_displaced_step_prepare (gdbarch *arch, thread_info *thread, CORE_ADDR &displaced_pc) @@ -2283,6 +2340,11 @@ ppc_linux_init_abi (struct gdbarch_info info, set_gdbarch_gnu_triplet_regexp (gdbarch, ppc64_gnu_triplet_regexp); /* Set GCC target options. */ set_gdbarch_gcc_target_options (gdbarch, ppc64_linux_gcc_target_options); + /* Internal thread local address support. */ + set_gdbarch_get_thread_local_address (gdbarch, + linux_get_thread_local_address); + linux_register_tls_methods (info, gdbarch, ppc64_linux_get_tls_dtv_addr, + ppc_linux_get_tls_dtp_offset); } set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description); diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c index ff478cf4c28..31d90a32ce4 100644 --- a/gdb/riscv-linux-tdep.c +++ b/gdb/riscv-linux-tdep.c @@ -25,6 +25,7 @@ #include "tramp-frame.h" #include "trad-frame.h" #include "gdbarch.h" +#include "inferior.h" /* The following value is derived from __NR_rt_sigreturn in from the Linux source tree. */ @@ -173,6 +174,79 @@ riscv_linux_syscall_next_pc (const frame_info_ptr &frame) return pc + 4 /* Length of the ECALL insn. */; } +/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID. + Throw a suitable TLS error if something goes wrong. */ + +static CORE_ADDR +riscv_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid, + linux_libc libc) +{ + /* On RISC-V, the thread pointer is found in TP. */ + regcache *regcache + = get_thread_arch_regcache (current_inferior (), ptid, gdbarch); + int thread_pointer_regnum = RISCV_TP_REGNUM; + target_fetch_registers (regcache, thread_pointer_regnum); + ULONGEST thr_ptr; + if (regcache->cooked_read (thread_pointer_regnum, &thr_ptr) != REG_VALID) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer")); + + CORE_ADDR dtv_ptr_addr; + switch (libc) + { + case linux_libc_musl: + /* MUSL: The DTV pointer is found at the very end of the pthread + struct which is located *before* the thread pointer. I.e. + the thread pointer will be just beyond the end of the struct, + so the address of the DTV pointer is found one pointer-size + before the thread pointer. */ + dtv_ptr_addr + = thr_ptr - (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + break; + case linux_libc_glibc: + /* GLIBC: The thread pointer (TP) points just beyond the end of + the TCB (thread control block). On RISC-V, this struct + (tcbhead_t) is defined to contain two pointers. The first is + a pointer to the DTV and the second is a pointer to private + data. So the DTV pointer address is 16 bytes (i.e. the size of + two pointers) before thread pointer. */ + + dtv_ptr_addr + = thr_ptr - 2 * (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + break; + default: + throw_error (TLS_GENERIC_ERROR, _("Unknown RISC-V C library")); + break; + } + + gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address")); + + const struct builtin_type *builtin = builtin_type (gdbarch); + CORE_ADDR dtv_addr = gdbarch_pointer_to_address + (gdbarch, builtin->builtin_data_ptr, buf.data ()); + return dtv_addr; +} + +/* For internal TLS lookup, return the DTP offset, which is the offset + to subtract from a DTV entry, in order to obtain the address of the + TLS block. */ + +static ULONGEST +riscv_linux_get_tls_dtp_offset (struct gdbarch *gdbarch, ptid_t ptid, + linux_libc libc) +{ + if (libc == linux_libc_musl) + { + /* This value is DTP_OFFSET in MUSL's arch/riscv64/pthread_arch.h. + It represents the value to subtract from the DTV entry, once + it has been loaded. */ + return 0x800; + } + else + return 0; +} + /* Initialize RISC-V Linux ABI info. */ static void @@ -198,6 +272,10 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); + set_gdbarch_get_thread_local_address (gdbarch, + linux_get_thread_local_address); + linux_register_tls_methods (info, gdbarch, riscv_linux_get_tls_dtv_addr, + riscv_linux_get_tls_dtp_offset); set_gdbarch_iterate_over_regset_sections (gdbarch, riscv_linux_iterate_over_regset_sections); diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c index bc1db550d2e..17055d9f7b5 100644 --- a/gdb/s390-linux-tdep.c +++ b/gdb/s390-linux-tdep.c @@ -40,6 +40,7 @@ #include "target.h" #include "trad-frame.h" #include "xml-syscall.h" +#include "inferior.h" #include "features/s390-linux32v1.c" #include "features/s390-linux32v2.c" @@ -1123,6 +1124,45 @@ s390_init_linux_record_tdep (struct linux_record_tdep *record_tdep, record_tdep->ioctl_FIOQSIZE = 0x545e; } +/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID. + Throw a suitable TLS error if something goes wrong. */ + +static CORE_ADDR +s390_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid, + enum linux_libc libc) +{ + /* On S390, the thread pointer is found in two registers A0 and A1 + (or, using gdb naming, acr0 and acr1) A0 contains the top 32 + bits of the address and A1 contains the bottom 32 bits. */ + regcache *regcache + = get_thread_arch_regcache (current_inferior (), ptid, gdbarch); + target_fetch_registers (regcache, S390_A0_REGNUM); + target_fetch_registers (regcache, S390_A1_REGNUM); + ULONGEST thr_ptr_lo, thr_ptr_hi, thr_ptr; + if (regcache->cooked_read (S390_A0_REGNUM, &thr_ptr_hi) != REG_VALID + || regcache->cooked_read (S390_A1_REGNUM, &thr_ptr_lo) != REG_VALID) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer")); + thr_ptr = (thr_ptr_hi << 32) + thr_ptr_lo; + + /* The thread pointer points at the TCB (thread control block). The + first two members of this struct are both pointers, where the + first will be a pointer to the TCB (i.e. it points at itself) + and the second will be a pointer to the DTV (dynamic thread + vector). There are many other fields too, but the one we care + about here is the DTV pointer. Compute the address of the DTV + pointer, fetch it, and convert it to an address. */ + CORE_ADDR dtv_ptr_addr + = thr_ptr + gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + if (target_read_memory (dtv_ptr_addr, buf.data (), buf.size ()) != 0) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address")); + + const struct builtin_type *builtin = builtin_type (gdbarch); + CORE_ADDR dtv_addr = gdbarch_pointer_to_address + (gdbarch, builtin->builtin_data_ptr, buf.data ()); + return dtv_addr; +} + /* Initialize OSABI common for GNU/Linux on 31- and 64-bit systems. */ static void @@ -1151,6 +1191,9 @@ s390_linux_init_abi_any (struct gdbarch_info info, struct gdbarch *gdbarch) /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); + set_gdbarch_get_thread_local_address (gdbarch, + linux_get_thread_local_address); + linux_register_tls_methods (info, gdbarch, s390_linux_get_tls_dtv_addr); /* Support reverse debugging. */ set_gdbarch_process_record_signal (gdbarch, s390_linux_record_signal); From patchwork Thu Oct 10 02:16:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98626 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 53990385EC0E for ; Thu, 10 Oct 2024 02:28:28 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 E98D6385E82A for ; Thu, 10 Oct 2024 02:26:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E98D6385E82A 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 E98D6385E82A 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=1728527189; cv=none; b=l/o9m3d0Y7UxquzHwTuzLuibPm6eEivlOn/Xb6vyKmxAfdjG9JZjA1vonLLDbsY4vlQzAXMK3gyqOwvOsEmB/L4Y/fJpE3VmOa1ZpOKy0vXS+aOTOYt/VM9mLvAhQ3RQ29cdgHKDek55XaMTxm14/KiChGcfkwceoeqtuaxAFyg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527189; c=relaxed/simple; bh=2QqkLm6bDwRAOSzZITbwve82TIOa+YZXcMvOMLtTaz0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=eVg8Wija+LIpYIKbeVQ0k8quYFhuHQOXtx24c2N5nhwuIMEZE0RZt19ZMlaBNXYbJY6uKoCE5/fC95BothmophaXdgfOW5YYiAfMaaflcckcCW9OLtz6wBM1+9lnYr+dLaNG/yF2rEQTgoYJm5IO4K6S6zFDeH0/E6A9jCWQvRg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527183; 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=VI5P22AmzOdpr+wG9HWWjsmFqVC9Ff5bAy++P8/+9AY=; b=JmyFoy6o4j9P4JJv9agDB+sUIDicqmbnm0so7bJ6qdAahz8zsrRpXAfsS29C8D5JHEbIvJ nrPOPJIGrS2gjk0wI2CMcl4YJE0ZndZtOKEKmVB6Y3L2Dp4VIsKoQxXmWnpgK6xYKDjoD8 M2tciAdMnMp1w9zRCB+GLSAT9BvdXUk= 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-49-KR6JvDmPMfmDr7u4YcDlCw-1; Wed, 09 Oct 2024 22:26:22 -0400 X-MC-Unique: KR6JvDmPMfmDr7u4YcDlCw-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 8A48519560B4 for ; Thu, 10 Oct 2024 02:26:21 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B43DB19560A2; Thu, 10 Oct 2024 02:26:20 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 06/11] Internal, but disabled, TLS support for i386 Date: Wed, 9 Oct 2024 19:16:09 -0700 Message-ID: <20241010022552.47637-7-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, 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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org This commit shows how internal TLS address lookup support could be implemented for the i386 target. Unfortunately, it doesn't work due to I386_GSBASE_REGNUM being unavailable for Linux targets. I looked at trying to access the gsbase register via PTRACE_GET_THREAD_AREA, but did not understand it well enough to finish it. Since the i386 target is much less important than it used to be, I gave up working on it. I don't want to leave this disabled code in our sources, so I will delete it in the next commit, however, this commit will be in our git repo, so it'll be available for someone with sufficient interest in the i386 target to look at. --- gdb/i386-linux-tdep.c | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 9dec83ac753..8e9ffe984a3 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -753,6 +753,45 @@ i386_linux_displaced_step_copy_insn (struct gdbarch *gdbarch, return closure_; } +#if 0 +/* Disabled because fetching I386_GSBASE_REGNUM causes an internal + error. */ + +/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID. + Throw a suitable TLS error if something goes wrong. */ + +static CORE_ADDR +i386_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid, + enum linux_libc libc) +{ + /* On i386, the thread pointer is found in the gsbase register. */ + regcache *regcache + = get_thread_arch_regcache (current_inferior (), ptid, gdbarch); + target_fetch_registers (regcache, I386_GSBASE_REGNUM); + ULONGEST gsbase; + if (regcache->cooked_read (I386_GSBASE_REGNUM, &gsbase) != REG_VALID) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer")); + + /* The thread pointer (gsbase) points at the TCB (thread control + block). The first two members of this struct are both pointers, + where the first will be a pointer to the TCB (i.e. it points at + itself) and the second will be a pointer to the DTV (dynamic + thread vector). There are many other fields too, but the one + we care about here is the DTV pointer. Compute the address + of the DTV pointer, fetch it, and convert it to an address. */ + CORE_ADDR dtv_ptr_addr + = gsbase + gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + gdb_byte buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT]; + if (target_read_memory (dtv_ptr_addr, buf, sizeof buf) != 0) + throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address")); + + const struct builtin_type *builtin = builtin_type (gdbarch); + CORE_ADDR dtv_addr = gdbarch_pointer_to_address + (gdbarch, builtin->builtin_data_ptr, buf); + return dtv_addr; +} +#endif + static void i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -988,6 +1027,11 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); +#if 0 + set_gdbarch_get_thread_local_address (gdbarch, + linux_get_thread_local_address); + linux_register_tls_methods (info, gdbarch, i386_linux_get_tls_dtv_addr); +#endif /* Core file support. */ set_gdbarch_iterate_over_regset_sections From patchwork Thu Oct 10 02:16:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98625 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 0CE91385EC06 for ; Thu, 10 Oct 2024 02:28:11 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 2FBC0385E837 for ; Thu, 10 Oct 2024 02:26:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2FBC0385E837 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 2FBC0385E837 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=1728527189; cv=none; b=FyIMUhOjoHRdsLyBY/OExvFJpXWQncqNb+iKdhipK4aRAXL4d5VK5AkG2F9pD6o7OV3dVjYFgPkXc2Fg2NXWuP9erZrMgY87V88xxqqRpmnh/LycxtI1WfrbvMXqzRfmy7NYx3f2t+Qr27zWXxo+S/Hb5DcbQ4wqqOrAPAQbewk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527189; c=relaxed/simple; bh=1a1lVP45oDwVNMziL3le9cHM9WfPdazlOj54/6ewM7I=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=svR7zmFpy27Ie7Yq7G8YbFn505QoDjuUr/kfT3ZC4GzhqHftzTYySY2mk3egV3i3HkC7U0azzq8lGGILiWqzau8p1vEBtoTW9gAw44+Z4aN7rTAUoCNkgMUgNo30uqnG4scRTtNhBzDF40CdpkZLooYiuQi7cHhVEKQrTnYoaLc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527184; 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=/J7AJrLYKOfuFiKv47ry3kNrOQen9QeZj7OoeI+Efoo=; b=Wf1kKrWzaZaZbY81KB+LDEi7XdUJ6nKoAVgS1xVxTlnEa14kayPwWBmSQ8oJ0BwvTGdtMr hzql1QGZSGx/CAd7Qh5yslrCQA8zm9s1I/2H1wy8YQm1ipnR5aQUDOfbZckmP8OyHW1FkD /ge9TtsPtmZmg+oPPhyIvxNyUOJNoB8= 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-537-mSKSyc5AN5G9zxL7ti638g-1; Wed, 09 Oct 2024 22:26:23 -0400 X-MC-Unique: mSKSyc5AN5G9zxL7ti638g-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 BCE291956083 for ; Thu, 10 Oct 2024 02:26:22 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E6B5619560A2; Thu, 10 Oct 2024 02:26:21 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 07/11] Delete disabled i386 internal TLS support Date: Wed, 9 Oct 2024 19:16:10 -0700 Message-ID: <20241010022552.47637-8-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org As mentioned in the previous commit, this commit deletes the disabled code which could be used to implement internal TLS support for the i386 target. --- gdb/i386-linux-tdep.c | 44 ------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 8e9ffe984a3..9dec83ac753 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -753,45 +753,6 @@ i386_linux_displaced_step_copy_insn (struct gdbarch *gdbarch, return closure_; } -#if 0 -/* Disabled because fetching I386_GSBASE_REGNUM causes an internal - error. */ - -/* Fetch and return the TLS DTV (dynamic thread vector) address for PTID. - Throw a suitable TLS error if something goes wrong. */ - -static CORE_ADDR -i386_linux_get_tls_dtv_addr (struct gdbarch *gdbarch, ptid_t ptid, - enum linux_libc libc) -{ - /* On i386, the thread pointer is found in the gsbase register. */ - regcache *regcache - = get_thread_arch_regcache (current_inferior (), ptid, gdbarch); - target_fetch_registers (regcache, I386_GSBASE_REGNUM); - ULONGEST gsbase; - if (regcache->cooked_read (I386_GSBASE_REGNUM, &gsbase) != REG_VALID) - throw_error (TLS_GENERIC_ERROR, _("Unable to fetch thread pointer")); - - /* The thread pointer (gsbase) points at the TCB (thread control - block). The first two members of this struct are both pointers, - where the first will be a pointer to the TCB (i.e. it points at - itself) and the second will be a pointer to the DTV (dynamic - thread vector). There are many other fields too, but the one - we care about here is the DTV pointer. Compute the address - of the DTV pointer, fetch it, and convert it to an address. */ - CORE_ADDR dtv_ptr_addr - = gsbase + gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; - gdb_byte buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT]; - if (target_read_memory (dtv_ptr_addr, buf, sizeof buf) != 0) - throw_error (TLS_GENERIC_ERROR, _("Unable to fetch DTV address")); - - const struct builtin_type *builtin = builtin_type (gdbarch); - CORE_ADDR dtv_addr = gdbarch_pointer_to_address - (gdbarch, builtin->builtin_data_ptr, buf); - return dtv_addr; -} -#endif - static void i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -1027,11 +988,6 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); -#if 0 - set_gdbarch_get_thread_local_address (gdbarch, - linux_get_thread_local_address); - linux_register_tls_methods (info, gdbarch, i386_linux_get_tls_dtv_addr); -#endif /* Core file support. */ set_gdbarch_iterate_over_regset_sections From patchwork Thu Oct 10 02:16:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98629 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 93CB2385DDE2 for ; Thu, 10 Oct 2024 02:29:02 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 8873E385DDC4 for ; Thu, 10 Oct 2024 02:26:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8873E385DDC4 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 8873E385DDC4 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=1728527192; cv=none; b=vDvCqEcc+rv84D05FcWZcumv7Cnkp9iaTZcBu9i/3gR1ABppdUU4ydKM4KkWwu6BFkAmeuTA/PvXr50rePJxE+U6WwqTwpR/X0EyWtaCj2owCup1kgBS7cifb2fOMI7VeqJx8DfL331Ydoi1RkNE1accF0Bf6zy+yi4/eNCqkXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527192; c=relaxed/simple; bh=y23XrWT3kyl9LgBsgyoKRlI4wOeDnn0metu4AUInKUQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=q24Ct/C59+vkWUKaA8KUwEPjTu7KNw55A1s66cb6fqO9tTZzOKYmx9jo2gMfgw93IgxN9eOZA6dlVYf5hlHbO7GQD6nlI264GUzg0D38RSdBVtEyqyNzJLBQ7dVa3KGzEEHuNw8DGu5Bvx037EnP9jqvO9AqhxP+i9PPuoUWtA4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527186; 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=phBR+kPGNjBtn5QD/zu4GEad6PmEeIBPqw4SayZdPVE=; b=Fsye59gAQrRcAaM7mevliNDN9m4JWIp6mcuYqavRmvL+eP+Wx3y3VJYKDUSxQQAtZ38ZVP 0GFvWZc2H/isVhgJZaUV3RL+Oo9zHIlzG8cU9gFxae7bYmC6iDhKdLcylYfabwVyeARsHg tsDNl34Ew0CoxttsDJ7fK+wJCh+G7Ik= 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-587-5IKMB8XpPGimrMeKqJkl0w-1; Wed, 09 Oct 2024 22:26:24 -0400 X-MC-Unique: 5IKMB8XpPGimrMeKqJkl0w-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 1792A19560AA for ; Thu, 10 Oct 2024 02:26:24 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 25C9419560A2; Thu, 10 Oct 2024 02:26:22 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 08/11] New test - gdb.base/tls-nothreads.exp Date: Wed, 9 Oct 2024 19:16:11 -0700 Message-ID: <20241010022552.47637-9-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org This commit introduces a new test, gdb.base/tls-nothreads.exp. It has a test case, a C file, which has several TLS variables in the main program, which, once compiled and linked, should end up (in ELF files) in .tdata and .tbss. The test compiles the program in a number of different ways, making sure that each variable is accessible regardless of how it was compiled. Note that some of the compilation scenarios end up with a statically linked executable. Prior to this series of commits, accessing TLS variables from a statically linked program on Linux did not work. For certain targets (x86_64, aarch64, s390x, riscv, and ppc64), all on Linux, support has been added to GDB for accessing thread local storage in statically linked executables. This test is important for testing those build scenarios. But it's also important to make sure that GDB's internal TLS support works for other scenarios too. In order to accomplish that, the tests are also run in a mode which forces the internal support to be used. It also adds a new file, gdb.base/tls-common.exp.tcl, which includes some common definitions used by the three new TLS tests, including the one added by this commit. In particular, it sets a TCL variable, 'internal_tls_linux_targets' which list the targets mentioned earlier. This means that as internal TLS support is added for other targets, the target should be listed in just one file as opposed to three (or more if other tests using tls-common.exp.tcl are added). --- gdb/testsuite/gdb.base/tls-common.exp.tcl | 50 +++++ gdb/testsuite/gdb.base/tls-nothreads.c | 57 +++++ gdb/testsuite/gdb.base/tls-nothreads.exp | 249 ++++++++++++++++++++++ 3 files changed, 356 insertions(+) create mode 100644 gdb/testsuite/gdb.base/tls-common.exp.tcl create mode 100644 gdb/testsuite/gdb.base/tls-nothreads.c create mode 100644 gdb/testsuite/gdb.base/tls-nothreads.exp diff --git a/gdb/testsuite/gdb.base/tls-common.exp.tcl b/gdb/testsuite/gdb.base/tls-common.exp.tcl new file mode 100644 index 00000000000..7439e80e3e2 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-common.exp.tcl @@ -0,0 +1,50 @@ +# Copyright 2024 Free Software Foundation, Inc. +# This program 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. +# +# This program 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. + +# Require statement, variables and procs used by tls-nothreads.exp, +# tls-multiobj.exp, and tls-dlobj.exp. + +# The tests listed above are known to work for the targets listed on +# the 'require' line, below. +# +# At the moment, only the Linux target is listed, but, ideally, these +# tests should be run on other targets too. E.g, testing on FreeBSD +# shows many failures which should be addressed in some fashion before +# enabling it for that target. + +require {is_any_target "*-*-linux*"} + +# These are the targets which have support for internal TLS lookup: + +set internal_tls_linux_targets {"x86_64-*-linux*" "aarch64-*-linux*" + "riscv*-*-linux*" "powerpc64*-*-linux*" + "s390x*-*-linux*"} + +# The "set force-internal-tls-address-lookup" command is only +# available for certain Linux architectures. Don't attempt to force +# use of internal TLS support for architectures which don't support +# it. + +if [is_any_target {*}$internal_tls_linux_targets] { + set internal_tls_iters { false true } +} else { + set internal_tls_iters { false } +} + +# Set up a kfail with message KFAIL_MSG when KFAIL_COND holds, then +# issue gdb_test with command CMD and regular expression RE. + +proc gdb_test_with_kfail {cmd re kfail_cond kfail_msg} { + if [uplevel 1 [list expr $kfail_cond]] { + setup_kfail $kfail_msg *-*-* + } + gdb_test $cmd $re +} diff --git a/gdb/testsuite/gdb.base/tls-nothreads.c b/gdb/testsuite/gdb.base/tls-nothreads.c new file mode 100644 index 00000000000..b3aaa3383e7 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-nothreads.c @@ -0,0 +1,57 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program 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. + + This program 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 . */ + +__thread int tls_tbss_1; +__thread int tls_tbss_2; +__thread int tls_tbss_3; + +__thread int tls_tdata_1 = 21; +__thread int tls_tdata_2 = 22; +__thread int tls_tdata_3 = 23; + +volatile int data; + +void +use_it (int a) +{ + data = a; +} + +int +main (int argc, char **argv) +{ + use_it (-1); + + tls_tbss_1 = 24; /* main-breakpoint-1 */ + tls_tbss_2 = 25; + tls_tbss_3 = 26; + + tls_tdata_1 = 42; + tls_tdata_2 = 43; + tls_tdata_3 = 44; + + use_it (tls_tbss_1); + use_it (tls_tbss_2); + use_it (tls_tbss_3); + use_it (tls_tdata_1); + use_it (tls_tdata_2); + use_it (tls_tdata_3); + + use_it (100); /* main-breakpoint-2 */ + + return 0; +} diff --git a/gdb/testsuite/gdb.base/tls-nothreads.exp b/gdb/testsuite/gdb.base/tls-nothreads.exp new file mode 100644 index 00000000000..8860c3e753d --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-nothreads.exp @@ -0,0 +1,249 @@ +# Copyright 2024 Free Software Foundation, Inc. +# This program 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. +# +# This program 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. + +# Using different compilation/linking scenarios, attempt to access +# thread-local variables in a non-threaded program. Also test that +# GDB internal TLS lookup works correctly. + +source $srcdir/$subdir/tls-common.exp.tcl + +standard_testfile + +proc do_tests {force_internal_tls {do_kfail_tls_access 0}} { + clean_restart $::binfile + if ![runto_main] { + return + } + + if $force_internal_tls { + gdb_test_no_output "set force-internal-tls-address-lookup on" + } + + if { $do_kfail_tls_access && [istarget "*-*-linux*"] } { + # Turn off do_kfail_tls_access when libthread_db is loaded. + # This can happen for the default case when testing x86_64 + # w/ -m32 using glibc versions 2.34 or newer. + gdb_test_multiple "maint check libthread-db" "Check for loaded libthread_db" { + -re -wrap "libthread_db integrity checks passed." { + set do_kfail_tls_access 0 + pass $gdb_test_name + } + -re -wrap "No libthread_db loaded" { + pass $gdb_test_name + } + } + # Also turn off do_kfail_tls_access when connected to a + # gdbserver and we observe that accessing a TLS variable + # works. + if [target_is_gdbserver] { + gdb_test_multiple "print tls_tbss_1" "Check TLS accessibility when connected to a gdbserver" { + -re -wrap "= 0" { + set do_kfail_tls_access 0 + pass $gdb_test_name + } + -re -wrap "Remote target failed to process qGetTLSAddr request" { + pass $gdb_test_name + } + } + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"] + gdb_continue_to_breakpoint "main-breakpoint-1" + + set t $do_kfail_tls_access + set m "tls not available" + with_test_prefix "before assignments" { + gdb_test_with_kfail "print tls_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_tbss_3" ".* = 0" $t $m + + gdb_test_with_kfail "print tls_tdata_1" ".* = 21" $t $m + gdb_test_with_kfail "print tls_tdata_2" ".* = 22" $t $m + gdb_test_with_kfail "print tls_tdata_3" ".* = 23" $t $m + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"] + gdb_continue_to_breakpoint "main-breakpoint-2" + + with_test_prefix "after assignments" { + gdb_test_with_kfail "print tls_tbss_1" ".* = 24" $t $m + gdb_test_with_kfail "print tls_tbss_2" ".* = 25" $t $m + gdb_test_with_kfail "print tls_tbss_3" ".* = 26" $t $m + + gdb_test_with_kfail "print tls_tdata_1" ".* = 42" $t $m + gdb_test_with_kfail "print tls_tdata_2" ".* = 43" $t $m + gdb_test_with_kfail "print tls_tdata_3" ".* = 44" $t $m + } + + # Make a core file now, but save testing using it until the end + # in case core files are not supported. + set corefile ${::binfile}.core + set core_supported 0 + if { ![is_remote host] } { + set core_supported [gdb_gcore_cmd $corefile "save corefile"] + } + + # Now continue to end and see what happens when attempting to + # access a TLS variable when the program is no longer running. + gdb_continue_to_end + with_test_prefix "after exit" { + gdb_test "print tls_tbss_1" \ + "Cannot read `tls_tbss_1' without registers" + } + + with_test_prefix "stripped" { + set binfile_stripped "${::binfile}.stripped" + set objcopy [gdb_find_objcopy] + set cmd "$objcopy --strip-debug ${::binfile} $binfile_stripped" + if ![catch "exec $cmd" cmd_output] { + clean_restart $binfile_stripped + if ![runto_main] { + return + } + + if $force_internal_tls { + gdb_test_no_output "set force-internal-tls-address-lookup on" + } + + # While there are no debug (e.g. DWARF) symbols, there + # are minimal symbols, so we should be able to place a + # breakpoint in use_it and continue to it. Continuing + # twice should put us past the assignments, at which point + # we can see if the TLS variables are still accessible. + gdb_test "break use_it" "Breakpoint 2 at $::hex" + gdb_test "continue" "Breakpoint 2, $::hex in use_it.*" + gdb_test "continue" "Breakpoint 2, $::hex in use_it.*" "continue 2" + + # Note that a cast has been added in order to avoid the + # "...has unknown type; cast it to its declared type" + # problem. + gdb_test_with_kfail "print (int) tls_tbss_1" ".* = 24" $t $m + gdb_test_with_kfail "print (int) tls_tbss_2" ".* = 25" $t $m + gdb_test_with_kfail "print (int) tls_tbss_3" ".* = 26" $t $m + + gdb_test_with_kfail "print (int) tls_tdata_1" ".* = 42" $t $m + gdb_test_with_kfail "print (int) tls_tdata_2" ".* = 43" $t $m + gdb_test_with_kfail "print (int) tls_tdata_3" ".* = 44" $t $m + + # Get rid of the "use_it" breakpoint + gdb_test_no_output "del 2" + + # Continue to program exit + gdb_continue_to_end + + # TLS variables should not be accessible after program exit + # (This case initially caused GDB to crash during development + # of GDB-internal TLS lookup support.) + with_test_prefix "after exit" { + gdb_test "print (int) tls_tbss_1" \ + "Cannot determine address of TLS symbol `tls_tbss_1' without registers" + } + } + } + + # Finish test early if no core file was made. + if !$core_supported { + return + } + + clean_restart $::binfile + + set core_loaded [gdb_core_cmd $corefile "load corefile"] + if { $core_loaded == -1 } { + return + } + + with_test_prefix "core file" { + if $force_internal_tls { + gdb_test_no_output "set force-internal-tls-address-lookup on" + } + + gdb_test_with_kfail "print tls_tbss_1" ".* = 24" $t $m + gdb_test_with_kfail "print tls_tbss_2" ".* = 25" $t $m + gdb_test_with_kfail "print tls_tbss_3" ".* = 26" $t $m + + gdb_test_with_kfail "print tls_tdata_1" ".* = 42" $t $m + gdb_test_with_kfail "print tls_tdata_2" ".* = 43" $t $m + gdb_test_with_kfail "print tls_tdata_3" ".* = 44" $t $m + } +} + +# Certain linux target architectures implement support for internal +# TLS lookup which is used when thread stratum support (via +# libthread_db) is missing or when the linux-only GDB setting +# 'force-internal-tls-address-lookup' is 'on'. Thus for some +# of the testing scenarios, such as statically linked executables, +# this internal support will be used. Set 'do_kfail_tls_access' +# to 1 for those architectures which don't implement internal +# TLS support. +if {[istarget *-*-linux*] + && ![is_any_target {*}$internal_tls_linux_targets]} { + set do_kfail_tls_access 1 +} elseif {[istarget *-*-linux*] && [is_x86_like_target]} { + # This covers the case of x86_64 with -m32: + set do_kfail_tls_access 1 +} else { + set do_kfail_tls_access 0 +} + +set binprefix $binfile + +with_test_prefix "default" { + set binfile $binprefix-default + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + # Depending on glibc version, it might not be appropriate + # for do_kfail_tls_access to be set here. That will be + # handled in 'do_tests', disabling it if necessary. + # + # Specifically, glibc versions 2.34 and later have the + # thread library (and libthread_db availability) in + # programs not linked against libpthread.so + do_tests $force_internal_tls $do_kfail_tls_access + } + } +} + +with_test_prefix "static" { + set binfile $binprefix-static + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-static"}] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls $do_kfail_tls_access + } + } +} + +with_test_prefix "pthreads" { + set binfile $binprefix-pthreads + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls + } + } +} + +with_test_prefix "pthreads-static" { + set binfile $binprefix-pthreads-static + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-static"}] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls $do_kfail_tls_access + } + } +} From patchwork Thu Oct 10 02:16:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98627 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 9CDFD385EC0D for ; Thu, 10 Oct 2024 02:28:29 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 7F04B385EC11 for ; Thu, 10 Oct 2024 02:26:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7F04B385EC11 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 7F04B385EC11 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=1728527192; cv=none; b=bfSiEre8x3Qa5zi5auu87g2jRLjuVS9o9wa2MO8ws+5iPYwZL9kkdoQpx/L5nQkxsse/A8d0+K8SvlOVFGOmUFaOQjApPpX0p2zxLOy13qe902rQws7KvWxmUJvj6QsLDPza013R72gPO7yjzAmYsEOJCfjs3ctFS11dZYHzyPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527192; c=relaxed/simple; bh=nTDj/X+4XfRXePxrbl7fTYJzjvHf5nzarXPi7tXBpok=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=JlXAG/MCLDz2Fawi93F7flauUXDjR1PKzW8BWjHIkhMsPRoBk9A8KO4Adx/rEk1pZeE9gl1g+4SCzJi7RGSsPNUrFYexiRIOC9FQcM2/fRFtjAWDl+wlLG4YlAYxkMq/nfRnwxWQ9DPV9PlS21NxyeEkdx+zQuTDmx5uWDY6aqw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527188; 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=39/ZaJVMoowcPgXG/iPy82yneN+jlBhao180848yjkU=; b=hCHVx2KjQo2romYCLVq4mzLPFEa26AAxOTictweZyzGUBAzjwUfZvVkNlZkApzDO66s2lQ WnIB1PV42Y5p3BD1krfNEuYpZONGJuDhO8CXvViNvMuJkXNddxQXJ3cMmErFrvM1LyoPjg iAJ9U08Egzj3ghktE7dSvIi8OytTK0s= 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-349-9nAZACaAOtSXwNCW_ax8mA-1; Wed, 09 Oct 2024 22:26:26 -0400 X-MC-Unique: 9nAZACaAOtSXwNCW_ax8mA-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 4BFEE1956083 for ; Thu, 10 Oct 2024 02:26:25 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 750EC19560A2; Thu, 10 Oct 2024 02:26:24 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 09/11] New test - gdb.base/tls-multiobj.exp Date: Wed, 9 Oct 2024 19:16:12 -0700 Message-ID: <20241010022552.47637-10-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org This test exercises GDB's internal TLS support when both the main program and several shared libraries have TLS variables. It also tests existing (non-internal) TLS support too. It tests using two compilation scenarios, "default", in which libpthread is not linked with the program and libraries as well as one which does use libpthread. It tests link map address to module id mapping code in GDB in addition to the ability of GDB to traverse TLS data structures with several libraries in play. --- gdb/testsuite/gdb.base/tls-multiobj.c | 89 +++++++++ gdb/testsuite/gdb.base/tls-multiobj.exp | 231 ++++++++++++++++++++++++ gdb/testsuite/gdb.base/tls-multiobj1.c | 26 +++ gdb/testsuite/gdb.base/tls-multiobj2.c | 26 +++ gdb/testsuite/gdb.base/tls-multiobj3.c | 26 +++ 5 files changed, 398 insertions(+) create mode 100644 gdb/testsuite/gdb.base/tls-multiobj.c create mode 100644 gdb/testsuite/gdb.base/tls-multiobj.exp create mode 100644 gdb/testsuite/gdb.base/tls-multiobj1.c create mode 100644 gdb/testsuite/gdb.base/tls-multiobj2.c create mode 100644 gdb/testsuite/gdb.base/tls-multiobj3.c diff --git a/gdb/testsuite/gdb.base/tls-multiobj.c b/gdb/testsuite/gdb.base/tls-multiobj.c new file mode 100644 index 00000000000..10e67da54d8 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj.c @@ -0,0 +1,89 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program 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. + + This program 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 . */ + +__thread int tls_main_tbss_1; +__thread int tls_main_tbss_2; +__thread int tls_main_tdata_1 = 96; +__thread int tls_main_tdata_2 = 97; + +extern __thread int tls_lib1_tbss_1; +extern __thread int tls_lib1_tbss_2; +extern __thread int tls_lib1_tdata_1; +extern __thread int tls_lib1_tdata_2; + +extern __thread int tls_lib2_tbss_1; +extern __thread int tls_lib2_tbss_2; +extern __thread int tls_lib2_tdata_1; +extern __thread int tls_lib2_tdata_2; + +extern __thread int tls_lib3_tbss_1; +extern __thread int tls_lib3_tbss_2; +extern __thread int tls_lib3_tdata_1; +extern __thread int tls_lib3_tdata_2; + +extern void lib1_func (); +extern void lib2_func (); +extern void lib3_func (); + +volatile int data; + +void +use_it (int a) +{ + data = a; +} + +int +main (int argc, char **argv) +{ + use_it (-1); + + tls_main_tbss_1 = 51; /* main-breakpoint-1 */ + tls_main_tbss_2 = 52; + tls_main_tdata_1 = 53; + tls_main_tdata_2 = 54; + + tls_lib1_tbss_1 = 151; + tls_lib1_tbss_2 = 152; + tls_lib1_tdata_1 = 153; + tls_lib1_tdata_2 = 154; + + tls_lib2_tbss_1 = 251; + tls_lib2_tbss_2 = 252; + tls_lib2_tdata_1 = 253; + tls_lib2_tdata_2 = 254; + + tls_lib3_tbss_1 = 351; + tls_lib3_tbss_2 = 352; + tls_lib3_tdata_1 = 353; + tls_lib3_tdata_2 = 354; + + lib1_func (); + lib2_func (); + lib3_func (); + + /* Attempt to keep variables in the main program from being optimized + away. */ + use_it (tls_main_tbss_1); + use_it (tls_main_tbss_2); + use_it (tls_main_tdata_1); + use_it (tls_main_tdata_2); + + use_it (100); /* main-breakpoint-2 */ + + return 0; +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj.exp b/gdb/testsuite/gdb.base/tls-multiobj.exp new file mode 100644 index 00000000000..58dfff9ebf5 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj.exp @@ -0,0 +1,231 @@ +# Copyright 2024 Free Software Foundation, Inc. +# This program 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. +# +# This program 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. + +# Using different compilation/linking scenarios, attempt to access +# thread-local variables in a non-threaded program using multiple +# shared objects. + +source $srcdir/$subdir/tls-common.exp.tcl + +standard_testfile + +set lib1src "${srcdir}/${subdir}/${testfile}1.c" +set lib2src "${srcdir}/${subdir}/${testfile}2.c" +set lib3src "${srcdir}/${subdir}/${testfile}3.c" + +set lib1obj [standard_output_file "${testfile}1-lib.so"] +set lib2obj [standard_output_file "${testfile}2-lib.so"] +set lib3obj [standard_output_file "${testfile}3-lib.so"] + +proc do_tests {force_internal_tls {do_kfail_tls_access 0}} { + clean_restart $::binfile + if ![runto_main] { + return + } + + if $force_internal_tls { + gdb_test_no_output "set force-internal-tls-address-lookup on" + } + + if { $do_kfail_tls_access && [istarget "*-*-linux*"] } { + # Turn off do_kfail_tls_access when libthread_db is loaded. + # This can happen for the default case when testing x86_64 + # w/ -m32 using glibc versions 2.34 or newer. + gdb_test_multiple "maint check libthread-db" "Check for loaded libthread_db" { + -re -wrap "libthread_db integrity checks passed." { + set do_kfail_tls_access 0 + pass $gdb_test_name + } + -re -wrap "No libthread_db loaded" { + pass $gdb_test_name + } + } + # Also turn off do_kfail_tls_access when connected to a + # gdbserver and we observe that accessing a TLS variable + # works. + if [target_is_gdbserver] { + gdb_test_multiple "print tls_main_tbss_1" \ + "Check TLS accessibility when connected to a gdbserver" { + -re -wrap "= 0" { + set do_kfail_tls_access 0 + pass $gdb_test_name + } + -re -wrap "Remote target failed to process qGetTLSAddr request" { + pass $gdb_test_name + } + } + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"] + gdb_continue_to_breakpoint "main-breakpoint-1" + + set t $do_kfail_tls_access + set m "tls not available" + with_test_prefix "before assignments" { + gdb_test_with_kfail "print tls_main_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_main_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_main_tdata_1" ".* = 96" $t $m + gdb_test_with_kfail "print tls_main_tdata_2" ".* = 97" $t $m + + gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 196" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 197" $t $m + + gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 296" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 297" $t $m + + gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 396" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 397" $t $m + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"] + gdb_continue_to_breakpoint "main-breakpoint-2" + + with_test_prefix "after assignments" { + gdb_test_with_kfail "print tls_main_tbss_1" ".* = 51" $t $m + gdb_test_with_kfail "print tls_main_tbss_2" ".* = 52" $t $m + gdb_test_with_kfail "print tls_main_tdata_1" ".* = 53" $t $m + gdb_test_with_kfail "print tls_main_tdata_2" ".* = 54" $t $m + + gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 151" $t $m + gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 152" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 153" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 154" $t $m + + gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 251" $t $m + gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 252" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 253" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 254" $t $m + + gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 351" $t $m + gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 352" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 353" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 354" $t $m + } + + set corefile ${::binfile}.core + set core_supported 0 + if { ![is_remote host] } { + set core_supported [gdb_gcore_cmd $corefile "save corefile"] + } + + # Finish test early if no core file was made. + if !$core_supported { + return + } + + clean_restart $::binfile + + set core_loaded [gdb_core_cmd $corefile "load corefile"] + if { $core_loaded == -1 } { + return + } + + with_test_prefix "core file" { + if $force_internal_tls { + gdb_test_no_output "set force-internal-tls-address-lookup on" + } + + gdb_test_with_kfail "print tls_main_tbss_1" ".* = 51" $t $m + gdb_test_with_kfail "print tls_main_tbss_2" ".* = 52" $t $m + gdb_test_with_kfail "print tls_main_tdata_1" ".* = 53" $t $m + gdb_test_with_kfail "print tls_main_tdata_2" ".* = 54" $t $m + + gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 151" $t $m + gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 152" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 153" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 154" $t $m + + gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 251" $t $m + gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 252" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 253" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 254" $t $m + + gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 351" $t $m + gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 352" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 353" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 354" $t $m + } +} + +if { [gdb_compile_shlib $lib1src $lib1obj {debug}] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $lib2src $lib2obj {debug}] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $lib3src $lib3obj {debug}] != "" } { + untested "failed to compile shared object" + return -1 +} + +# Certain linux target architectures implement support for internal +# TLS lookup which is used when thread stratum support (via +# libthread_db) is missing or when the linux-only GDB setting +# 'force-internal-tls-address-lookup' is 'on'. Thus for some +# of the testing scenarios, such as statically linked executables, +# this internal support will be used. Set 'do_kfail_tls_access' +# to 1 for those architectures which don't implement internal +# tls support. +if {[istarget *-*-linux*] + && ![is_any_target {*}$internal_tls_linux_targets]} { + set do_kfail_tls_access 1 +} elseif {[istarget *-*-linux*] && [is_x86_like_target]} { + # This covers the case of x86_64 with -m32: + set do_kfail_tls_access 1 +} else { + set do_kfail_tls_access 0 +} + +set binprefix $binfile + +with_test_prefix "default" { + set binfile $binprefix-default + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ + [list debug shlib=${lib1obj} \ + shlib=${lib2obj} \ + shlib=${lib3obj}]] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + # Depending on glibc version, it might not be appropriate + # for do_kfail_tls_access to be set here. That will be + # handled in 'do_tests', disabling it if necessary. + # + # Specifically, glibc versions 2.34 and later have the + # thread library (and libthread_db availability) in + # programs not linked against libpthread.so + do_tests $force_internal_tls $do_kfail_tls_access + } + } +} + +with_test_prefix "pthreads" { + set binfile $binprefix-pthreads + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ + [list debug shlib=${lib1obj} \ + shlib=${lib2obj} \ + shlib=${lib3obj}]] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls + } + } +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj1.c b/gdb/testsuite/gdb.base/tls-multiobj1.c new file mode 100644 index 00000000000..86e72228b1b --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj1.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program 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. + + This program 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 . */ + +__thread int tls_lib1_tbss_1; +__thread int tls_lib1_tbss_2; +__thread int tls_lib1_tdata_1 = 196; +__thread int tls_lib1_tdata_2 = 197; + +void +lib1_func () +{ +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj2.c b/gdb/testsuite/gdb.base/tls-multiobj2.c new file mode 100644 index 00000000000..cea07092a5d --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj2.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program 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. + + This program 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 . */ + +__thread int tls_lib2_tbss_1; +__thread int tls_lib2_tbss_2; +__thread int tls_lib2_tdata_1 = 296; +__thread int tls_lib2_tdata_2 = 297; + +void +lib2_func () +{ +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj3.c b/gdb/testsuite/gdb.base/tls-multiobj3.c new file mode 100644 index 00000000000..bb0f2395fbf --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj3.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program 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. + + This program 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 . */ + +__thread int tls_lib3_tbss_1; +__thread int tls_lib3_tbss_2; +__thread int tls_lib3_tdata_1 = 396; +__thread int tls_lib3_tdata_2 = 397; + +void +lib3_func () +{ +} From patchwork Thu Oct 10 02:16:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98628 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 BBD0C385E836 for ; Thu, 10 Oct 2024 02:28:53 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 DA2363858417 for ; Thu, 10 Oct 2024 02:26:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DA2363858417 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 DA2363858417 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=1728527193; cv=none; b=r0Exh4ujfwfXiaazB6CqIDqtkBlN+Zo4jxF+rSbodvdlWiiiWKT4Bepf3ZdsSwuC9ik3OxJyS3EaVe7AqmPkHoEsdDif4YLgTCPi/ao6FWfvCZKsO75bU2HRIGoNUigCB5lS+4NE0mitvM/TzrDiuwQGtQZ5TPtuVAf3NRF/O2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527193; c=relaxed/simple; bh=M9X/xDjta1/RatgtA9Wxa3OgLkybsofcYbJZ90Ns/80=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=g4ISqC6kqyjgJ0C5dlEdTOgI6ZHXINLSpa5QCcqwP8Ct0dAtcLpQIK26zO4SXrTb8OsOy4nbPWSW4UsGCZJBZZSx9EJ2Bp0m2ks8LV+KtlVkXXsgsxb0kE2NhYa8YCBxkH1xNM9qUevzaTuzScYDgOR1xvPGxad0mz97y6mdid4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527188; 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=WesRdnojMTFH9JjtXDsPwacZxurDN9QjS9QgLn5m3OA=; b=D222gOQ3BTvs2Nj2VCKD08TC90BXHDxZApy0rrnGbPfZyYptvc8sbWLhKj2r5abZil0+SI dA6lL/uCiUkDKGZNrEXgn0/KDz2BFXoxaBoz93aL8xobEWn37oN5LoOnjUdLmVLqnCuBzg AKOfeQacLIK3574osds1z5NlgvDNaxg= 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-377-EXIbBgrKObGjn4fV-BFsoQ-1; Wed, 09 Oct 2024 22:26:27 -0400 X-MC-Unique: EXIbBgrKObGjn4fV-BFsoQ-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 7F35619560AA for ; Thu, 10 Oct 2024 02:26:26 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A892219560A2; Thu, 10 Oct 2024 02:26:25 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 10/11] New test - gdb.base/tls-dlobj.exp Date: Wed, 9 Oct 2024 19:16:13 -0700 Message-ID: <20241010022552.47637-11-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org This test exercises musl_link_map_to_tls_module_id() and glibc_link_map_to_tls_module_id(), both of which are in solib-svr4.c. Prior to writing this test, I had only written what is now named 'musl_link_map_to_tls_module_id' and it worked for both GLIBC and MUSL. Once I wrote this new test, tls-dlobj.exp, there were a number of tests which didn't work with GLIBC. This led me to write a GLIBC-specific link map to module id function, i.e, 'glibc_link_map_to_tls_module_id'. It only has one compilation scenario, in which the pthread(s) library is used - as noted in a comment, it became too much of a hassle to try to KFAIL things, though it certainly could have been done in much the same was as was done in gdb.base/multiobj.exp. It didn't seem that important to do so, however, since I believe that the other tests have adequate coverage for different compilation scenarios. --- gdb/testsuite/gdb.base/tls-dlobj-lib.c | 87 ++++++ gdb/testsuite/gdb.base/tls-dlobj.c | 310 ++++++++++++++++++++ gdb/testsuite/gdb.base/tls-dlobj.exp | 378 +++++++++++++++++++++++++ 3 files changed, 775 insertions(+) create mode 100644 gdb/testsuite/gdb.base/tls-dlobj-lib.c create mode 100644 gdb/testsuite/gdb.base/tls-dlobj.c create mode 100644 gdb/testsuite/gdb.base/tls-dlobj.exp diff --git a/gdb/testsuite/gdb.base/tls-dlobj-lib.c b/gdb/testsuite/gdb.base/tls-dlobj-lib.c new file mode 100644 index 00000000000..3f8ebc4f6a7 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-dlobj-lib.c @@ -0,0 +1,87 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program 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. + + This program 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 . */ + +/* This program needs to be compiled with preprocessor symbol set to + a small integer, e.g. "gcc -DN=1 ..." With N defined, the CONCAT2 + and CONCAT3 macros will construct suitable names for the global + variables and functions. */ + +#define CONCAT2(a,b) CONCAT2_(a,b) +#define CONCAT2_(a,b) a ## b + +#define CONCAT3(a,b,c) CONCAT3_(a,b,c) +#define CONCAT3_(a,b,c) a ## b ## c + +/* For N=1, this ends up being... + __thread int tls_lib1_tbss_1; + __thread int tls_lib1_tbss_2; + __thread int tls_lib1_tdata_1 = 196; + __thread int tls_lib1_tdata_2 = 197; */ + +__thread int CONCAT3(tls_lib, N, _tbss_1); +__thread int CONCAT3(tls_lib, N, _tbss_2); +__thread int CONCAT3(tls_lib, N, _tdata_1) = CONCAT2(N, 96); +__thread int CONCAT3(tls_lib, N, _tdata_2) = CONCAT2(N, 97); + +/* Substituting for N, define function: + + int get_tls_libN_var (int which) . */ + +int +CONCAT3(get_tls_lib, N, _var) (int which) +{ + switch (which) + { + case 0: + return -1; + case 1: + return CONCAT3(tls_lib, N, _tbss_1); + case 2: + return CONCAT3(tls_lib, N, _tbss_2); + case 3: + return CONCAT3(tls_lib, N, _tdata_1); + case 4: + return CONCAT3(tls_lib, N, _tdata_2); + } + return -1; +} + +/* Substituting for N, define function: + + void set_tls_libN_var (int which, int val) . */ + +void +CONCAT3(set_tls_lib, N, _var) (int which, int val) +{ + switch (which) + { + case 0: + break; + case 1: + CONCAT3(tls_lib, N, _tbss_1) = val; + break; + case 2: + CONCAT3(tls_lib, N, _tbss_2) = val; + break; + case 3: + CONCAT3(tls_lib, N, _tdata_1) = val; + break; + case 4: + CONCAT3(tls_lib, N, _tdata_2) = val; + break; + } +} diff --git a/gdb/testsuite/gdb.base/tls-dlobj.c b/gdb/testsuite/gdb.base/tls-dlobj.c new file mode 100644 index 00000000000..59b5320adf3 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-dlobj.c @@ -0,0 +1,310 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program 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. + + This program 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 + +typedef void (*setter_ftype) (int which, int val); + +__thread int tls_main_tbss_1; +__thread int tls_main_tbss_2; +__thread int tls_main_tdata_1 = 96; +__thread int tls_main_tdata_2 = 97; + +extern void set_tls_lib10_var (int which, int val); +extern void set_tls_lib11_var (int which, int val); + +volatile int data; + +static void +set_tls_main_var (int which, int val) +{ + switch (which) + { + case 1: + tls_main_tbss_1 = val; + break; + case 2: + tls_main_tbss_2 = val; + break; + case 3: + tls_main_tdata_1 = val; + break; + case 4: + tls_main_tdata_2 = val; + break; + } +} + +void +use_it (int a) +{ + data = a; +} + +static void * +load_dso (char *dso_name, int n, setter_ftype *setterp) +{ + char buf[80]; + void *sym; + void *handle = dlopen (dso_name, RTLD_NOW | RTLD_GLOBAL); + assert (handle != NULL); + sprintf (buf, "set_tls_lib%d_var", n); + sym = dlsym (handle, buf); + assert (sym != NULL); + *setterp = sym; + + /* Some libc implementations (for some architectures) refuse to + initialize TLS data structures (specifically, the DTV) without + first calling dlsym on one of the TLS symbols. */ + sprintf (buf, "tls_lib%d_tdata_1", n); + assert (dlsym (handle, buf) != NULL); + + return handle; +} + +#define str(N) str_(N) +#define str_(N) #N + +int +main (int argc, char **argv) +{ + int i, status; + setter_ftype s0, s1, s2, s3, s4, s10, s11; + void *h1 = load_dso (str(OBJ1), 1, &s1); + void *h2 = load_dso (str(OBJ2), 2, &s2); + void *h3 = load_dso (str(OBJ3), 3, &s3); + void *h4 = load_dso (str(OBJ4), 4, &s4); + s0 = set_tls_main_var; + s10 = set_tls_lib10_var; + s11 = set_tls_lib11_var; + + use_it (0); /* main-breakpoint-1 */ + + /* Set TLS variables in main program and all libraries. */ + for (i = 1; i <= 4; i++) + s0 (i, 10 + i); + for (i = 1; i <= 4; i++) + s1 (i, 110 + i); + for (i = 1; i <= 4; i++) + s2 (i, 210 + i); + for (i = 1; i <= 4; i++) + s3 (i, 310 + i); + for (i = 1; i <= 4; i++) + s4 (i, 410 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1010 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1110 + i); + + use_it (0); /* main-breakpoint-2 */ + + /* Unload lib2 and lib3. */ + status = dlclose (h2); + assert (status == 0); + status = dlclose (h3); + assert (status == 0); + + /* Set TLS variables in main program and in libraries which are still + loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 20 + i); + for (i = 1; i <= 4; i++) + s1 (i, 120 + i); + for (i = 1; i <= 4; i++) + s4 (i, 420 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1020 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1120 + i); + + use_it (0); /* main-breakpoint-3 */ + + /* Load lib3. */ + h3 = load_dso (str(OBJ3), 3, &s3); + + /* Set TLS vars again; currently, only lib2 is not loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 30 + i); + for (i = 1; i <= 4; i++) + s1 (i, 130 + i); + for (i = 1; i <= 4; i++) + s3 (i, 330 + i); + for (i = 1; i <= 4; i++) + s4 (i, 430 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1030 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1130 + i); + + use_it (0); /* main-breakpoint-4 */ + + /* Unload lib1 and lib4; load lib2. */ + status = dlclose (h1); + assert (status == 0); + status = dlclose (h4); + assert (status == 0); + h2 = load_dso (str(OBJ2), 2, &s2); + + /* Set TLS vars; currently, lib2 and lib3 are loaded, + lib1 and lib4 are not. */ + for (i = 1; i <= 4; i++) + s0 (i, 40 + i); + for (i = 1; i <= 4; i++) + s2 (i, 240 + i); + for (i = 1; i <= 4; i++) + s3 (i, 340 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1040 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1140 + i); + + use_it (0); /* main-breakpoint-5 */ + + /* Load lib4 and lib1. Unload lib2. */ + h4 = load_dso (str(OBJ4), 4, &s4); + h1 = load_dso (str(OBJ1), 1, &s1); + status = dlclose (h2); + assert (status == 0); + + /* Set TLS vars; currently, lib1, lib3, and lib4 are loaded; + lib2 is not loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 50 + i); + for (i = 1; i <= 4; i++) + s1 (i, 150 + i); + for (i = 1; i <= 4; i++) + s3 (i, 350 + i); + for (i = 1; i <= 4; i++) + s4 (i, 450 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1050 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1150 + i); + + use_it (0); /* main-breakpoint-6 */ + + /* Load lib2, unload lib1, lib3, and lib4; then load lib3 again. */ + h2 = load_dso (str(OBJ2), 2, &s2); + status = dlclose (h1); + assert (status == 0); + status = dlclose (h3); + assert (status == 0); + status = dlclose (h4); + assert (status == 0); + h3 = load_dso (str(OBJ3), 3, &s3); + + /* Set TLS vars; currently, lib2 and lib3 are loaded; + lib1 and lib4 are not loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 60 + i); + for (i = 1; i <= 4; i++) + s2 (i, 260 + i); + for (i = 1; i <= 4; i++) + s3 (i, 360 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1060 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1160 + i); + + use_it (0); /* main-breakpoint-7 */ + + /* Unload lib3 and lib2, then (re)load lib4, lib3, lib2, and lib1, + in that order. */ + status = dlclose (h3); + assert (status == 0); + status = dlclose (h2); + assert (status == 0); + h4 = load_dso (str(OBJ4), 4, &s4); + h3 = load_dso (str(OBJ3), 3, &s3); + h2 = load_dso (str(OBJ2), 2, &s2); + h1 = load_dso (str(OBJ1), 1, &s1); + + /* Set TLS vars; currently, lib1, lib2, lib3, and lib4 are all + loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 70 + i); + for (i = 1; i <= 4; i++) + s1 (i, 170 + i); + for (i = 1; i <= 4; i++) + s2 (i, 270 + i); + for (i = 1; i <= 4; i++) + s3 (i, 370 + i); + for (i = 1; i <= 4; i++) + s4 (i, 470 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1070 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1170 + i); + + use_it (0); /* main-breakpoint-8 */ + + /* Unload lib3, lib1, and lib4. */ + status = dlclose (h3); + assert (status == 0); + status = dlclose (h1); + assert (status == 0); + status = dlclose (h4); + assert (status == 0); + + /* Set TLS vars; currently, lib2 is loaded; lib1, lib3, and lib4 are + not. */ + for (i = 1; i <= 4; i++) + s0 (i, 80 + i); + for (i = 1; i <= 4; i++) + s2 (i, 280 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1080 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1180 + i); + + use_it (0); /* main-breakpoint-9 */ + + /* Load lib3, unload lib2, load lib4. */ + h3 = load_dso (str(OBJ3), 3, &s3); + status = dlclose (h2); + assert (status == 0); + h4 = load_dso (str(OBJ4), 4, &s4); + + /* Set TLS vars; currently, lib3 and lib4 are loaded; lib1 and lib2 + are not. */ + for (i = 1; i <= 4; i++) + s0 (i, 90 + i); + for (i = 1; i <= 4; i++) + s3 (i, 390 + i); + for (i = 1; i <= 4; i++) + s4 (i, 490 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1090 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1190 + i); + + use_it (0); /* main-breakpoint-10 */ + + /* Attempt to keep variables in the main program from being optimized + away. */ + use_it (tls_main_tbss_1); + use_it (tls_main_tbss_2); + use_it (tls_main_tdata_1); + use_it (tls_main_tdata_2); + + use_it (100); /* main-breakpoint-last */ + + return 0; +} diff --git a/gdb/testsuite/gdb.base/tls-dlobj.exp b/gdb/testsuite/gdb.base/tls-dlobj.exp new file mode 100644 index 00000000000..8b050ffd784 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-dlobj.exp @@ -0,0 +1,378 @@ +# Copyright 2024 Free Software Foundation, Inc. +# This program 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. +# +# This program 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. + +# Test that the GDB-internal TLS link map to module id mapping code +# works correctly when debugging a program which is linked against +# shared objects and which also loads and unloads other shared objects +# in different orders. For targets which have GDB-internal TLS +# support, it'll check both GDB-internal TLS support as well as that +# provided by a helper library such as libthread_db. + +source $srcdir/$subdir/tls-common.exp.tcl + +require allow_shlib_tests + +standard_testfile + +set libsrc "${srcdir}/${subdir}/${testfile}-lib.c" + +# These will be dlopen'd: +set lib1obj [standard_output_file "${testfile}1-lib.so"] +set lib2obj [standard_output_file "${testfile}2-lib.so"] +set lib3obj [standard_output_file "${testfile}3-lib.so"] +set lib4obj [standard_output_file "${testfile}4-lib.so"] + +# These will be dynamically linked with the main program: +set lib10obj [standard_output_file "${testfile}10-lib.so"] +set lib11obj [standard_output_file "${testfile}11-lib.so"] + +# Due to problems with some versions of glibc, we expect some tests to +# fail due to TLS storage not being allocated/initialized. Test +# command CMD using regular expression RE, and use XFAIL instead of +# FAIL when the relevant RE is matched and COND is true when evaluated +# in the upper level. + +proc gdb_test_with_xfail { cmd re cond} { + gdb_test_multiple $cmd $cmd { + -re -wrap $re { + pass $gdb_test_name + } + -re -wrap "The inferior has not yet allocated storage for thread-local variables.*" { + if [ uplevel 1 [list expr $cond]] { + xfail $gdb_test_name + } else { + fail $gdb_test_name + } + } + } +} + +proc do_tests {force_internal_tls} { + clean_restart $::binfile + if ![runto_main] { + return + } + + if $force_internal_tls { + gdb_test_no_output "set force-internal-tls-address-lookup on" + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"] + gdb_continue_to_breakpoint "main-breakpoint-1" + + with_test_prefix "before assignments" { + gdb_test "print tls_main_tbss_1" ".* = 0" + gdb_test "print tls_main_tbss_2" ".* = 0" + gdb_test "print tls_main_tdata_1" ".* = 96" + gdb_test "print tls_main_tdata_2" ".* = 97" + + # For these tests, where we're attempting to access TLS vars + # in a dlopen'd library, but before assignment to any of the + # vars, so it could happen that storage hasn't been allocated + # yet. But it might also work. (When testing against MUSL, + # things just work; GLIBC ends to produce the TLS error.) So + # accept either the right answer or a TLS error message. + + set tlserr "The inferior has not yet allocated storage for thread-local variables.*" + foreach n {1 2 3 4} { + gdb_test "print tls_lib${n}_tbss_1" \ + "0|${tlserr}" + gdb_test "print tls_lib${n}_tbss_2" \ + "0|${tlserr}" + gdb_test "print tls_lib${n}_tdata_1" \ + "96|${tlserr}" + gdb_test "print tls_lib${n}_tdata_2" \ + "97|${tlserr}" + } + foreach n {10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = 0" + gdb_test "print tls_lib${n}_tbss_2" ".* = 0" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}96" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}97" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"] + gdb_continue_to_breakpoint "main-breakpoint-2" + + with_test_prefix "at main-breakpoint-2" { + gdb_test "print tls_main_tbss_1" ".* = 11" + gdb_test "print tls_main_tbss_2" ".* = 12" + gdb_test "print tls_main_tdata_1" ".* = 13" + gdb_test "print tls_main_tdata_2" ".* = 14" + + foreach n {1 2 3 4 10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}11" + gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}12" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}13" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}14" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-3"] + gdb_continue_to_breakpoint "main-breakpoint-3" + + # At this point lib2 and lib3 have been unloaded. Also, TLS vars + # in remaining libraries have been changed. + + with_test_prefix "at main-breakpoint-3" { + gdb_test "print tls_main_tbss_1" ".* = 21" + gdb_test "print tls_main_tbss_2" ".* = 22" + gdb_test "print tls_main_tdata_1" ".* = 23" + gdb_test "print tls_main_tdata_2" ".* = 24" + + foreach n {1 4 10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}21" + gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}22" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}23" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}24" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-4"] + gdb_continue_to_breakpoint "main-breakpoint-4" + + # lib3 has been loaded again; lib2 is the only one not loaded. + + with_test_prefix "at main-breakpoint-4" { + gdb_test "print tls_main_tbss_1" ".* = 31" + gdb_test "print tls_main_tbss_2" ".* = 32" + gdb_test "print tls_main_tdata_1" ".* = 33" + gdb_test "print tls_main_tdata_2" ".* = 34" + + set cond { $n == 3 } + foreach n {1 3 4 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}31" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}32" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}33" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}34" $cond + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-5"] + gdb_continue_to_breakpoint "main-breakpoint-5" + + # lib2 and lib3 are loaded; lib1 and lib4 are not. + + with_test_prefix "at main-breakpoint-5" { + gdb_test "print tls_main_tbss_1" ".* = 41" + gdb_test "print tls_main_tbss_2" ".* = 42" + gdb_test "print tls_main_tdata_1" ".* = 43" + gdb_test "print tls_main_tdata_2" ".* = 44" + + set cond { $n == 2 || $n == 3 } + foreach n {2 3 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}41" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}42" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}43" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}44" $cond + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-6"] + gdb_continue_to_breakpoint "main-breakpoint-6" + + # lib1, lib3 and lib4 are loaded; lib2 is not loaded. + + with_test_prefix "at main-breakpoint-6" { + gdb_test "print tls_main_tbss_1" ".* = 51" + gdb_test "print tls_main_tbss_2" ".* = 52" + gdb_test "print tls_main_tdata_1" ".* = 53" + gdb_test "print tls_main_tdata_2" ".* = 54" + + set cond { $n == 1 || $n == 3 || $n == 4} + foreach n {1 3 4 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}51" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}52" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}53" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}54" $cond + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-7"] + gdb_continue_to_breakpoint "main-breakpoint-7" + + # lib2 and lib3 are loaded; lib1 and lib4 are not. + + with_test_prefix "at main-breakpoint-7" { + gdb_test "print tls_main_tbss_1" ".* = 61" + gdb_test "print tls_main_tbss_2" ".* = 62" + gdb_test "print tls_main_tdata_1" ".* = 63" + gdb_test "print tls_main_tdata_2" ".* = 64" + + set cond { $n == 2 || $n == 3 } + foreach n {2 3 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}61" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}62" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}63" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}64" $cond + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-8"] + gdb_continue_to_breakpoint "main-breakpoint-8" + + # lib1, lib2, lib3, and lib4 are all loaded. + + with_test_prefix "at main-breakpoint-8" { + gdb_test "print tls_main_tbss_1" ".* = 71" + gdb_test "print tls_main_tbss_2" ".* = 72" + gdb_test "print tls_main_tdata_1" ".* = 73" + gdb_test "print tls_main_tdata_2" ".* = 74" + + foreach n {1 2 3 4 10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}71" + gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}72" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}73" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}74" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-9"] + gdb_continue_to_breakpoint "main-breakpoint-9" + + # lib2 is loaded; lib1, lib3, and lib4 are not. + + with_test_prefix "at main-breakpoint-9" { + gdb_test "print tls_main_tbss_1" ".* = 81" + gdb_test "print tls_main_tbss_2" ".* = 82" + gdb_test "print tls_main_tdata_1" ".* = 83" + gdb_test "print tls_main_tdata_2" ".* = 84" + + foreach n {2 10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}81" + gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}82" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}83" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}84" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-10"] + gdb_continue_to_breakpoint "main-breakpoint-10" + + # lib3 and lib4 are loaded; lib1 and lib2 are not. + + with_test_prefix "at main-breakpoint-10" { + gdb_test "print tls_main_tbss_1" ".* = 91" + gdb_test "print tls_main_tbss_2" ".* = 92" + gdb_test "print tls_main_tdata_1" ".* = 93" + gdb_test "print tls_main_tdata_2" ".* = 94" + + set cond { $n == 3 || $n == 4 } + foreach n {3 4 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}91" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}92" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}93" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}94" $cond + } + } + + # gdb_interact + + set corefile ${::binfile}.core + set core_supported 0 + if { ![is_remote host] } { + set core_supported [gdb_gcore_cmd $corefile "save corefile"] + } + + # Finish test early if no core file was made. + if !$core_supported { + return + } + + clean_restart $::binfile + + set core_loaded [gdb_core_cmd $corefile "load corefile"] + if { $core_loaded == -1 } { + return + } + + with_test_prefix "core file" { + if $force_internal_tls { + gdb_test_no_output "set force-internal-tls-address-lookup on" + } + + gdb_test "print tls_main_tbss_1" ".* = 91" + gdb_test "print tls_main_tbss_2" ".* = 92" + gdb_test "print tls_main_tdata_1" ".* = 93" + gdb_test "print tls_main_tdata_2" ".* = 94" + + set cond { $n == 3 || $n == 4 } + foreach n {3 4 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}91" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}92" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}93" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}94" $cond + } + } +} + +# Build shared objects for dlopen: +if { [gdb_compile_shlib $libsrc $lib1obj [list debug additional_flags=-DN=1]] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $libsrc $lib2obj [list debug additional_flags=-DN=2]] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $libsrc $lib3obj [list debug additional_flags=-DN=3]] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $libsrc $lib4obj [list debug additional_flags=-DN=4]] != "" } { + untested "failed to compile shared object" + return -1 +} + +# Build shared objects to link against main program: +if { [gdb_compile_shlib $libsrc $lib10obj [list debug additional_flags=-DN=10]] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $libsrc $lib11obj [list debug additional_flags=-DN=11]] != "" } { + untested "failed to compile shared object" + return -1 +} + +# Use gdb_compile_pthreads to build and link the main program for +# testing. It's also possible to run the tests using plain old +# gdb_compile, but this adds complexity with setting up additional +# KFAILs. (When run using GLIBC versions earlier than 2.34, a program +# that's not dynamically linked against libpthread will lack a working +# libthread_db, and, therefore, won't be able to access thread local +# storage without GDB-internal TLS support. Additional complications +# arise from when testing on x86_64 with -m32, which tends to work +# okay on GLIBC 2.34 and newer, but not older versions. It gets messy +# to properly sort out all of these cases.) +# +# This test was originally written to do it both ways, i.e. with both +# both gdb_compile and gdb_compile_pthreads, but the point of this +# test is to check that the link map address to TLS module id mapping +# code works correctly in programs which use lots of dlopen and +# dlclose calls in various orders - and that can be done using just +# gdb_compile_pthreads. + +if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ + [list debug shlib_load \ + shlib=${lib10obj} \ + shlib=${lib11obj} \ + additional_flags=-DOBJ1=${lib1obj} \ + additional_flags=-DOBJ2=${lib2obj} \ + additional_flags=-DOBJ3=${lib3obj} \ + additional_flags=-DOBJ4=${lib4obj} \ + ]] != "" } { + untested "failed to compile" +} else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls + } +} From patchwork Thu Oct 10 02:16:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 98630 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 9AD72385E44D for ; Thu, 10 Oct 2024 02:29:29 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@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 191C5385E45B for ; Thu, 10 Oct 2024 02:26:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 191C5385E45B 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 191C5385E45B 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=1728527192; cv=none; b=PCCuCNGWdGvcWWxhaQuTo9mFiaCdEPmDousCvWHrDrwAU66zCL04U5WYNlq/4fZ59P7jbJIbLHtOuMaDzxzHQXdwXf9kOSGklDhLvvzILZEs9gkd+4eJdb54q9XoLtz4ozQ3q7UlhxRttp9C3SwfUDo+W6Ji4PzQ+AgxOh+XAS8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728527192; c=relaxed/simple; bh=Ohi1PaXC9EpoW42bOgM5JgTSVA/5i8VvG5yvDRXUgPM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=vIC65BVQ7igDybyBqPqNTSAU486aVrtlwy6GesNGx54aPpWsTBm+LnYUFLCurDmsnTb7TbOqO3NzlWEN420bDOJVAqpUdN70eqqabmVao/d+axi22NbDqhdFzn0VyDAMfQ7lKyrQo+LFHWPmBDBFLesX+GFMuD6uYEV80P+KoYI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728527189; 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=us38hLxpAs8jTVUR3s/fvo2NQsjRNADnIAGEvVAzmjg=; b=Ue2tyWhhhXDWNDmQKOACNMc3PrNpC6OYqhzvwvkZM4IAPrP4RSk8YpBLZkk4VSMsLl5blr UcfUsQ3BbwyvY0Ym5BKF2efgarQ755pDXuBK9LsgflND9jxnOJ8jyi5D0KeLBtGJC2Wgz8 f2YRIbO/wZOewDiJbERyG4Zudf4Br0g= 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-619-46pjV6VcNDSaqccrQqxr6A-1; Wed, 09 Oct 2024 22:26:28 -0400 X-MC-Unique: 46pjV6VcNDSaqccrQqxr6A-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 D2C6B195608B for ; Thu, 10 Oct 2024 02:26:27 +0000 (UTC) Received: from f41-1.lan (unknown [10.22.64.28]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id DBD0719560A2; Thu, 10 Oct 2024 02:26:26 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 11/11] Add TLS NEWS entry and document 'set force-internal-tls-address-lookup' command Date: Wed, 9 Oct 2024 19:16:14 -0700 Message-ID: <20241010022552.47637-12-kevinb@redhat.com> In-Reply-To: <20241010022552.47637-1-kevinb@redhat.com> References: <20241010022552.47637-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org --- gdb/NEWS | 20 ++++++++++++++++++++ gdb/doc/gdb.texinfo | 17 +++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/gdb/NEWS b/gdb/NEWS index 42668cbc057..dcb24eb5248 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -63,6 +63,26 @@ the return value from the latest "stepOut" command, when appropriate. +* GDB-internal TLS support + + ** Linux targets for the x86_64, aarch64, ppc64, s390x, and riscv + architectures now have GDB-internal support for TLS address + lookup in addition to that traditionally provided by the + libthread_db library. This internal support works for programs + linked against either the GLIBC or MUSL C libraries. For + programs linked against MUSL, this new internal support provides + new debug functionality, allowing access to TLS variables, due to + the fact that MUSL does not implement the libthread_db library. + Internal TLS support is also useful in cross-debugging + situations, debugging statically linked binaries, and debugging + programs linked against GLIBC 2.33 and earlier, but which are not + linked against libpthread. + + ** The command 'set force-internal-tls-address-lookup on' may be + used to force the internal TLS lookup mechanisms to be used. + Otherwise, TLS lookup via libthread_db will still be preferred, + when available. + * New commands set style line-number foreground COLOR diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 46ca62ec0c3..f0f98061a1f 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -4067,6 +4067,23 @@ only on some platforms. @item show libthread-db-search-path Display current libthread_db search path. +@kindex set force-internal-tls-address-lookup +@kindex show force-internal-tls-address-lookup +@cindex internal TLS lookup +Turns on or off forced use of @value{GDBN}-internal TLS (Thread Local +Storage) address lookup code. Use @code{on} to enable and @code{0} to +disable. + +When disabled, @value{GDBN} will attempt to use a helper +@code{libthread_db} library if possible, but will fall back to use of +its own internal TLS address lookup mechanisms if necessary. + +When enabled, @value{GDBN} will only use the @value{GDBN}'s internal +TLS address lookup mechanisms, if they exist. + +This command is only available on targets for which internal TLS +address lookup support exists. + @kindex set debug libthread-db @kindex show debug libthread-db @cindex debugging @code{libthread_db}