From patchwork Sat May 11 10:08:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89947 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 B7F0238708E1 for ; Sat, 11 May 2024 10:09:38 +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 ESMTPS id 191F83858C41 for ; Sat, 11 May 2024 10:08:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 191F83858C41 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 191F83858C41 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=1715422135; cv=none; b=aqYC+0+TsTRYTqTJawmEQOh3Xq3b6tgNzstxMPpsbJd+ywOgP0MA7SSDbixwG6VoA2dMCnbzONVOfRy7U8e1PQuQ/JZ453ldZsdsoyj4O5U3nV7hX9INRAxJnJfUouHqSAJdaowAK45PGsGMO2mbDN+exTLvCLjg4dpRGj8OB/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422135; c=relaxed/simple; bh=5Y9PSUVforz4BLmMbTrrt8YKPD4as050r2cByA0tXIc=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=cwfWiBtx0gyzi++fCglV0BzwqSKd+FWevk+C248AjO7xDiLEGOv4zoFTCX0V2PUpbOo23zLCW+02qkQdMlYLtdJ8GzXjzeTg2zBQmc2tYblsb2582giXjZh07ViynHAC0WZIXtv/2bWHyMYatXNlY0JwU3hxd4nCyQdSFZCIC18= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422132; 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=hocNIUxR0fvxLrV49+tg7LKoOh/JA3kk9vmMDD5k8eo=; b=CzIGKJly67us9HY+jK/p/yhGAl6kF2IiKviOjJT2vsU4Lu/ozLJVAKtWFEAWOx3Qjb24It XOYv2IgkN1azZrEzCb79WTNYCbbWzBMQ32b3WLNI7AQ2b1uYsrQY9M61EHeeS6XX6WNzcw a878qD6HKkpSnURiVS49PzquUVkgWt8= Received: from mail-lf1-f71.google.com (mail-lf1-f71.google.com [209.85.167.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-371-JSXT1a_AM_u1xgyWqXSkFA-1; Sat, 11 May 2024 06:08:51 -0400 X-MC-Unique: JSXT1a_AM_u1xgyWqXSkFA-1 Received: by mail-lf1-f71.google.com with SMTP id 2adb3069b0e04-51fd3568b04so2548062e87.1 for ; Sat, 11 May 2024 03:08:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422129; x=1716026929; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2lQ87tPQQIbOqF1OMYg2i/duuBDkXwFbOIKl0VMRBKY=; b=kWHe9lC50gDNeSdx+17QkvA0gxaGoic3Ibz3a2m/Kc26jS8tgTT3EbCxr97Q8518pN Y0HOXVg/PG7YdM0aKosiUT3jGKIHVnVMgYCfzDZjbydXBgPmOmFhcSQHhd+HI6OGS9fV sJZh0OAnaoMwM1IXeOGTZYADRBco+zpvRy4jNsqD1+jOq6BwFe48Qg96/I6ECa391Zc6 UvwgsrkmhRnN3eTtwMFa6flw9OyO0227IDhJmXYIAZ3nB7Hgt+j3euFNXzd2Yi4ci8bi fyUJx/+K/+F1WwqmXmw6zfVwHI3kePxjJbwV3PE61L9m7fcJMEEo7fkH7VX1DuIgJFwp MAGw== X-Gm-Message-State: AOJu0YxMke0hex7czQ4wsW/XJOkqF4joYutAkvyCPVaXFz2jQSa8FJyl 5iEnt/ujobLjQ25e2SsESAXRCbGszH1fpiertz/AUvffiTBfFWJ3vu+ESHRViqH2hzhmdP097NI 1A++/suzKYj2mOrwuXBmyPw/ImOjMOVjupn4DwYctFn5UfUq/t3LRF9yVFYLlrRSdazMdsCCoXl HiToKpsp6a6JX4CdF1Knpvu+a9T5Og4t5KI4JJpLDJj0U= X-Received: by 2002:a05:6512:290:b0:522:32c0:bb6e with SMTP id 2adb3069b0e04-52232c0bbf6mr1542458e87.23.1715422128730; Sat, 11 May 2024 03:08:48 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEm1N0f5cBxKiPE9tXBRByNBRub/TQRN5+DG4bkmVWQ6z/2yec+BwtfU6XMDidZg0y1P1y/GA== X-Received: by 2002:a05:6512:290:b0:522:32c0:bb6e with SMTP id 2adb3069b0e04-52232c0bbf6mr1542435e87.23.1715422128039; Sat, 11 May 2024 03:08:48 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3502b8a791esm6608935f8f.64.2024.05.11.03.08.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:08:46 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 1/9] gdb/gdbserver: share I386_LINUX_XSAVE_XCR0_OFFSET definition Date: Sat, 11 May 2024 11:08:31 +0100 Message-Id: <8685cc8a396015661afd96b38cf5f68d41c05a8e.1715421687.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 Share the definition of I386_LINUX_XSAVE_XCR0_OFFSET between GDB and gdbserver. This commit moves the definition into gdbsupport/x86-xstate.h, which allows the #define to be shared. There should be no user visible changes after this commit. Approved-By: Felix Willgerodt --- gdb/i386-linux-tdep.h | 20 -------------------- gdbserver/linux-x86-low.cc | 21 --------------------- gdbsupport/x86-xstate.h | 20 ++++++++++++++++++++ 3 files changed, 20 insertions(+), 41 deletions(-) diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h index 5891747572b..07593c6a8ec 100644 --- a/gdb/i386-linux-tdep.h +++ b/gdb/i386-linux-tdep.h @@ -58,26 +58,6 @@ extern void i386_linux_report_signal_info (struct gdbarch *gdbarch, /* Return the target description according to XCR0. */ extern const struct target_desc *i386_linux_read_description (uint64_t xcr0); -/* Format of XSAVE extended state is: - struct - { - fxsave_bytes[0..463] - sw_usable_bytes[464..511] - xstate_hdr_bytes[512..575] - extended state regions (AVX, MPX, AVX512, PKRU, etc.) - }; - - Same memory layout will be used for the coredump NT_X86_XSTATE - representing the XSAVE extended state registers. - - The first 8 bytes of the sw_usable_bytes[464..467] is the OS enabled - extended state mask, which is the same as the extended control register - 0 (the XFEATURE_ENABLED_MASK register), XCR0. We can use this mask - together with the mask saved in the xstate_hdr_bytes to determine what - states the processor/OS supports and what state, used or initialized, - the process/thread is in. */ -#define I386_LINUX_XSAVE_XCR0_OFFSET 464 - extern int i386_linux_gregset_reg_offset[]; /* Return x86 siginfo type. */ diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc index 2603fb2ac5d..6de44aeb2d9 100644 --- a/gdbserver/linux-x86-low.cc +++ b/gdbserver/linux-x86-low.cc @@ -831,27 +831,6 @@ x86_target::low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction) static int use_xml; -/* Format of XSAVE extended state is: - struct - { - fxsave_bytes[0..463] - sw_usable_bytes[464..511] - xstate_hdr_bytes[512..575] - avx_bytes[576..831] - future_state etc - }; - - Same memory layout will be used for the coredump NT_X86_XSTATE - representing the XSAVE extended state registers. - - The first 8 bytes of the sw_usable_bytes[464..467] is the OS enabled - extended state mask, which is the same as the extended control register - 0 (the XFEATURE_ENABLED_MASK register), XCR0. We can use this mask - together with the mask saved in the xstate_hdr_bytes to determine what - states the processor/OS supports and what state, used or initialized, - the process/thread is in. */ -#define I386_LINUX_XSAVE_XCR0_OFFSET 464 - /* Does the current host support the GETFPXREGS request? The header file may or may not define it, and even if it is defined, the kernel will return EIO if it's running on a pre-SSE processor. */ diff --git a/gdbsupport/x86-xstate.h b/gdbsupport/x86-xstate.h index 89c1143fbe1..11b37544aa3 100644 --- a/gdbsupport/x86-xstate.h +++ b/gdbsupport/x86-xstate.h @@ -120,4 +120,24 @@ constexpr bool operator!= (const x86_xsave_layout &lhs, #define I387_MXCSR_INIT_VAL 0x1f80 +/* Format of XSAVE extended state is: + struct + { + fxsave_bytes[0..463] + sw_usable_bytes[464..511] + xstate_hdr_bytes[512..575] + extended state regions (AVX, MPX, AVX512, PKRU, etc.) + }; + + Same memory layout will be used for the coredump NT_X86_XSTATE + representing the XSAVE extended state registers. + + The first 8 bytes of the sw_usable_bytes[464..467] is the OS enabled + extended state mask, which is the same as the extended control register + 0 (the XFEATURE_ENABLED_MASK register), XCR0. We can use this mask + together with the mask saved in the xstate_hdr_bytes to determine what + states the processor/OS supports and what state, used or initialized, + the process/thread is in. */ +#define I386_LINUX_XSAVE_XCR0_OFFSET 464 + #endif /* COMMON_X86_XSTATE_H */ From patchwork Sat May 11 10:08:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89948 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 233AE38708C0 for ; Sat, 11 May 2024 10:09:39 +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 ESMTPS id 6B97B3858404 for ; Sat, 11 May 2024 10:08:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6B97B3858404 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 6B97B3858404 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=1715422136; cv=none; b=d+W3iDRfrOFpt6MOldt2ayQiIVZn/RVqVyX9IhWQBm6pxORjNNVyePmJb6VlqQSsR+An/NtAHBhijmbogI5D/x+qK4M3opuJIdPEdC+nQMJfTM1+XVbCtxOW7PUNHvNiToIoC5mk+HXCLgzfOzEmz53e9pxfky9QjuhtxkHitPU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422136; c=relaxed/simple; bh=Yvst0bcnmtYFoAay+PFgd60W17CeqjrTARDMF5hgSzg=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=Vl6CI0ph1zaHMk/BJ8Xa1I0YgCnL10ENCJugvBVDt0o+FH/fDJ29D205M9DXdEb7gAgiw/P7wcBEpATS2MDu7lcfFbZwkPUCCLbH6YPTrpQKTt2F1c2FhyZIAYyI2tPCnLAgfuNIrEcz4ZRj82T2KAFRwPysJvLS0/xNI9meS+g= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422134; 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=aPhdQkVUz+dr3FxKW6fZsG6q3nZxo7a/XW73wZ/ewvQ=; b=Pii2aJ1N+5mzSD0BRL+AyhU+R85bJf18f7msyxqqlbrz0Iilv52mUdVw/DMxyrRfhc5bmE 1jsMC8DTsIan0HwvSefVPyoyrz55/rwhvE8HPgssBsBUY9d6KXyyQS01wtrLCWk+BqNi3E FFb95F/lHT3tfdmLxuT2s0x9CkrRRH0= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-499-B63J26HLOYW4tjSqZtZ13g-1; Sat, 11 May 2024 06:08:53 -0400 X-MC-Unique: B63J26HLOYW4tjSqZtZ13g-1 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-34db1830d7cso1093258f8f.1 for ; Sat, 11 May 2024 03:08:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422131; x=1716026931; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aPhdQkVUz+dr3FxKW6fZsG6q3nZxo7a/XW73wZ/ewvQ=; b=tfnE71IWTlrJb9M87pTq3/+SLlwRF0qBdQw4KpW5bHHqaKWPiMu9hOFlL8Vd+xzPNL o1pPe64fTbGJuRyYePILThYvEUy6WGuF4AxmAcaIiWjlj8uD8MfVYrIIu3BtN8f7FRgi EZeEW0t7BUqaOBEL6rkaCJVHRYkAEugHTLau3tjCqUSF+sPeVedYKxYfMWuqnzB8r/Kq +yPtiBAJkjkUGSR/siAPuTiEWuE9h1PtLWS14HGOgQz87u61lsBuKu9ss8JgRF5yiUdn 7QRXSL4zWsSsiGYFJdDIGcgFCHFqt3FtlROZXcADufIZsXJ/CDzT8xPEbogidJpKrfgM ISeQ== X-Gm-Message-State: AOJu0YyNJyH2zfb1n64eNU5AjaIPlrkPpicXxhaGKiBHuwUY33o2JD7+ wBnYDphlPnTqjT4WC24DI8KMgypkanY/PMlfD0PXBpacqN1kIlO+TmDdPeOkSrXA3iUFv3gWKS+ uveXpX4nnnmTV12N1f7oA3WgPHrrjKkvugWFPc+S5U2s/Axss/tRMqwPvkd1EDHmB3OxiIFJT2D M7wJ5lyqi4hIutBar+KziPJwIi5Srd3kY+7WGhfKD4jug= X-Received: by 2002:adf:ef52:0:b0:34d:9d2c:8ea5 with SMTP id ffacd0b85a97d-350185d93b2mr7273689f8f.28.1715422131114; Sat, 11 May 2024 03:08:51 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEZX68++nuTEkQdMNOx3uLqvu1wjwvsZ8B8hT7gPgGGEzxMKjEOoKYviinmG65B1eLBW9sTew== X-Received: by 2002:adf:ef52:0:b0:34d:9d2c:8ea5 with SMTP id ffacd0b85a97d-350185d93b2mr7273667f8f.28.1715422130636; Sat, 11 May 2024 03:08:50 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3502b79bd40sm6674818f8f.4.2024.05.11.03.08.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:08:49 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 2/9] gdbserver/x86: move no-xml code earlier in x86_linux_read_description Date: Sat, 11 May 2024 11:08:32 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 is part of a series that aims to share more of the x86 target description reading/generation code between GDB and gdbserver. There are a huge number of similarities between the code in gdbserver's x86_linux_read_description function and GDB's x86_linux_nat_target::read_description function, and it is this similarity that I plan, in a later commit, to share between GDB and gdbserver. However, one thing that is different in x86_linux_read_description is the code inside the '!use_xml' block. This is the code that handles the case where gdbserver is not allowed to send an XML target description back to GDB. In this case gdbserver uses some predefined, fixed, target descriptions. First, it's worth noting that I suspect this code is not tested any more. I couldn't find anything in the testsuite that tries to disable XML target description support. And the idea of having a single "fixed" target description really doesn't work well when we think about all the various x86 extensions that exist. Part of me would like to rip out the no-xml support in gdbserver (at least for x86), and if a GDB connects that doesn't support XML target descriptions, gdbserver can just give an error and drop the connection. GDB has supported XML target descriptions for 16 years now, I think it would be reasonable for our shipped gdbserver to drop support for the old way of doing things. Anyway.... this commit doesn't do that. What I did notice was that, over time, the '!use_xml' block appears to have "drifted" within the x86_linux_read_description function; it's now not the first check we do. Instead we make some ptrace calls and return a target description generated based on the result of these ptrace calls. Surely it only makes sense to generate variable target descriptions if we can send these back to GDB? So in this commit I propose to move the '!use_xml' block earlier in the x86_linux_read_description function. The benefit of this is that this leaves the later half of x86_linux_read_description much more similar to the GDB function x86_linux_nat_target::read_description and sets us up for potentially sharing code between GDB and gdbserver in a later commit. Approved-By: John Baldwin Approved-By: Felix Willgerodt --- gdbserver/linux-x86-low.cc | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc index 6de44aeb2d9..e8ef3667eb4 100644 --- a/gdbserver/linux-x86-low.cc +++ b/gdbserver/linux-x86-low.cc @@ -869,6 +869,22 @@ x86_linux_read_description (void) #endif } + /* If we are not allowed to send an XML target description then we need + to use the hard-wired target descriptions. This corresponds to GDB's + default machine for x86. + + This check needs to occur before any returns statements that might + generate some alternative target descriptions. */ + if (!use_xml) + { +#ifdef __x86_64__ + if (machine == EM_X86_64) + return tdesc_amd64_linux_no_xml.get (); + else +#endif + return tdesc_i386_linux_no_xml.get (); + } + #if !defined __x86_64__ && defined HAVE_PTRACE_GETFPXREGS if (machine == EM_386 && have_ptrace_getfpxregs == -1) { @@ -885,17 +901,6 @@ x86_linux_read_description (void) } #endif - if (!use_xml) - { - /* Don't use XML. */ -#ifdef __x86_64__ - if (machine == EM_X86_64) - return tdesc_amd64_linux_no_xml.get (); - else -#endif - return tdesc_i386_linux_no_xml.get (); - } - if (have_ptrace_getregset == TRIBOOL_UNKNOWN) { uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))]; From patchwork Sat May 11 10:08:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89951 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 CA46638708CB for ; Sat, 11 May 2024 10:10:23 +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.133.124]) by sourceware.org (Postfix) with ESMTPS id D34F63870882 for ; Sat, 11 May 2024 10:08:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D34F63870882 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 D34F63870882 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422144; cv=none; b=oBWLXFjWhpiNoeyR9GesUJNcAT+dkbCSvaggzTDRgPE/c6Zo8sL+VRSVrsHKkyDZEkmQIgNoApewkzuhHCbEYMbD9Uo0J4BzEAIw2TvXeSAJ4yVIqgyNAC4+fwj9oty083sVK+RdHtHJCPQg4JDyuI6xc28AMOfhQjoxQNdK7tc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422144; c=relaxed/simple; bh=6EO2w7nUJEp10tVwP1HUlGZPDsg9gTYlChYOB7mTdc8=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=nKRx7C8IS4wt+8b3tc0V/mP6HpxTsGReiV9YhYCkJEtuSKw+DI/mqPo2BdcP3fN+41deeOeT7IbQLbgE+DjIzuS33VK1erqU+uYXUaoUCOjK/fRu22yhvqeQBXBg3ZtXWACcHBhose3IWwGYu3NLL8F1eEE02Dm2OpAp2mPIPnE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422137; 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=FA9MflsIZqClh4yOGr/Ei8Yse3gJoGW6ZGDDlNpdjqM=; b=gJ3vtiQhKeGmXH2ycHiPxePP9jqtj9P8hHt8O/SdZZjiIDWQKpCsCZ1wXhPRJRAXjxsKZp CGuebm612llzLa4UKE+FnmhHSN6he86ZPAdY83Ma7pZqtAEali7xoETYFHXd4JU9mFg/BW xXlJaJJhO7b9zv0n/jGvy6/L7rkXGN4= Received: from mail-lj1-f197.google.com (mail-lj1-f197.google.com [209.85.208.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-2-V6xdNqlVOXWJsBHhQ1V7zA-1; Sat, 11 May 2024 06:08:56 -0400 X-MC-Unique: V6xdNqlVOXWJsBHhQ1V7zA-1 Received: by mail-lj1-f197.google.com with SMTP id 38308e7fff4ca-2e233a3d4b0so30127761fa.3 for ; Sat, 11 May 2024 03:08:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422134; x=1716026934; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JlxV3JzwvF1U7dbmzbLEskz7Bbt/9pfgP3JN37+sgas=; b=tt12joaQhk8mZPdhuusjWqVaGrZ9Z5BLto4sjx2w+6cQ3FG1ETUKaUb3DjwZEIIRsX 4qqbOj5Koi/a6LtiDapMkvnDZBBnuFHnIGdyH33v1qTMqVZLFbx+t7LMebvkP+Hnlcfo H9BjaHQyqG7qHKCLYhjX5VYAQQxHqQYP+EfPxeHwmdnoY922eqOcR4xBpuUDhFdsDKuA 8rYfxA472dArei0YQCvNf0j73BBWtighRVaqIuzM13+ayJmb008kbQt/42P1vEd6TgN5 wj3sO+MLW40PqBYPzEV8UUYUzAcmdMu2niZDAnS7dyQnGEsn3qBdZjjiIcUOXymuqmJT oK/Q== X-Gm-Message-State: AOJu0Yy06Dkngh7tcctzQaKsLaBPK8ZGVlcfacckTWgu8vLCBE197xpI Uhk9BieOfXoEyEmCS1Mu6fMmXxuUC0A45QkwFOaszUIAR6OndMkZhfy0DFsSfEVlKhQNA0y45js 4k0laWBfI9MOLljmWYBU/pKeapzL2Kqz1bS3+yEhlmYRzfpqk1cheNR2qP1NLlxcHIncSGZZ5f7 4b4Sfethy6oq8hJHZ+zq17XHtmV9/W6h3cxXdaDJyHmgc= X-Received: by 2002:a2e:7015:0:b0:2e2:f6e6:ada2 with SMTP id 38308e7fff4ca-2e51fd2dd20mr33625201fa.8.1715422134020; Sat, 11 May 2024 03:08:54 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFmKwJnXzhqKAXjczyemLjDCrp8rMjQxrPh6THiBFG9iP/VOpXSCFtwZq0y/ZGSz/IiwS26pg== X-Received: by 2002:a2e:7015:0:b0:2e2:f6e6:ada2 with SMTP id 38308e7fff4ca-2e51fd2dd20mr33625021fa.8.1715422133328; Sat, 11 May 2024 03:08:53 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-41fccbe8f74sm94687465e9.8.2024.05.11.03.08.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:08:52 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 3/9] gdb/x86: move have_ptrace_getfpxregs global into gdb/nat directory Date: Sat, 11 May 2024 11:08:33 +0100 Message-Id: <95646b59108329cb1e168e7815d242c0292ab3c2.1715421687.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 have_ptrace_getfpxregs global tracks whether GDB or gdbserver is running on a kernel that supports the GETFPXREGS ptrace request. Currently this global is declared twice (once in GDB and once in gdbserver), I think it makes sense to move this global into the nat/ directory, and have a single declaration and definition. While moving this variable I have converted it to a tribool, as that was what it really was, if even used the same numbering as the tribool enum (-1, 0, 1). Where have_ptrace_getfpxregs was used I have updated in the obvious way. However, while making this change I noticed what I think is a bug in x86_linux_nat_target::read_description and x86_linux_read_description, both of these functions can be called multiple times, but in both cases we only end up calling i386_linux_read_description the first time through in the event that PTRACE_GETFPXREGS is not supported. This is because initially have_ptrace_getfpxregs will be TRIBOOL_UNKNOWN, but after the ptrace call fails we set have_ptrace_getfpxregs to TRIBOOL_FALSE. The next time we attempt to read the target description we'll skip the ptrace call, and so skip the call to i386_linux_read_description. I've not tried to address this preexisting bug in this commit, this is purely a refactor, there should be no user visible changes after this commit. In later commits I'll merge the gdbserver and GDB code together into the nat/ directory, and after that I'll try to address this bug. Reviewed-By: Felix Willgerodt --- gdb/Makefile.in | 2 +- gdb/configure.nat | 2 +- gdb/i386-linux-nat.c | 26 +++------------ gdb/{i386-linux-nat.h => nat/i386-linux.c} | 15 +++++---- gdb/nat/i386-linux.h | 37 ++++++++++++++++++++++ gdb/x86-linux-nat.c | 6 ++-- gdbserver/configure.srv | 1 + gdbserver/linux-x86-low.cc | 19 +++-------- 8 files changed, 62 insertions(+), 46 deletions(-) rename gdb/{i386-linux-nat.h => nat/i386-linux.c} (77%) create mode 100644 gdb/nat/i386-linux.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 234d0051f49..bdb8a3683b5 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1397,7 +1397,6 @@ HFILES_NO_SRCDIR = \ hppa-tdep.h \ i386-bsd-nat.h \ i386-darwin-tdep.h \ - i386-linux-nat.h \ i386-linux-tdep.h \ i386-tdep.h \ i387-tdep.h \ @@ -1594,6 +1593,7 @@ HFILES_NO_SRCDIR = \ nat/gdb_ptrace.h \ nat/gdb_thread_db.h \ nat/fork-inferior.h \ + nat/i386-linux.h \ nat/linux-btrace.h \ nat/linux-namespaces.h \ nat/linux-nat.h \ diff --git a/gdb/configure.nat b/gdb/configure.nat index 8b98511cef7..25268bb268b 100644 --- a/gdb/configure.nat +++ b/gdb/configure.nat @@ -256,7 +256,7 @@ case ${gdb_host} in NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \ nat/x86-xstate.o \ i386-linux-nat.o x86-linux-nat.o nat/linux-btrace.o \ - nat/x86-linux.o nat/x86-linux-dregs.o" + nat/x86-linux.o nat/x86-linux-dregs.o nat/i386-linux.o" ;; ia64) # Host: Intel IA-64 running GNU/Linux diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index 7278dd91ff0..bfe3fb84d0a 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -26,7 +26,7 @@ #include "gregset.h" #include "gdb_proc_service.h" -#include "i386-linux-nat.h" +#include "nat/i386-linux.h" #include "i387-tdep.h" #include "i386-tdep.h" #include "i386-linux-tdep.h" @@ -80,22 +80,6 @@ int have_ptrace_getregs = 0 #endif ; - -/* Does the current host support the GETFPXREGS request? The header - file may or may not define it, and even if it is defined, the - kernel will return EIO if it's running on a pre-SSE processor. - - My instinct is to attach this to some architecture- or - target-specific data structure, but really, a particular GDB - process can only run on top of one kernel at a time. So it's okay - for this to be a simple variable. */ -int have_ptrace_getfpxregs = -#ifdef HAVE_PTRACE_GETFPXREGS - -1 -#else - 0 -#endif -; /* Accessing registers through the U area, one at a time. */ @@ -388,14 +372,14 @@ fetch_fpxregs (struct regcache *regcache, int tid) { elf_fpxregset_t fpxregs; - if (! have_ptrace_getfpxregs) + if (have_ptrace_getfpxregs == TRIBOOL_FALSE) return 0; if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) { if (errno == EIO) { - have_ptrace_getfpxregs = 0; + have_ptrace_getfpxregs = TRIBOOL_FALSE; return 0; } @@ -415,14 +399,14 @@ store_fpxregs (const struct regcache *regcache, int tid, int regno) { elf_fpxregset_t fpxregs; - if (! have_ptrace_getfpxregs) + if (have_ptrace_getfpxregs == TRIBOOL_FALSE) return 0; if (ptrace (PTRACE_GETFPXREGS, tid, 0, &fpxregs) == -1) { if (errno == EIO) { - have_ptrace_getfpxregs = 0; + have_ptrace_getfpxregs = TRIBOOL_FALSE; return 0; } diff --git a/gdb/i386-linux-nat.h b/gdb/nat/i386-linux.c similarity index 77% rename from gdb/i386-linux-nat.h rename to gdb/nat/i386-linux.c index c3d32aff1be..64605be4fc5 100644 --- a/gdb/i386-linux-nat.h +++ b/gdb/nat/i386-linux.c @@ -1,6 +1,6 @@ /* Native-dependent code for GNU/Linux i386. - Copyright (C) 1999-2024 Free Software Foundation, Inc. + Copyright (C) 2024 Free Software Foundation, Inc. This file is part of GDB. @@ -17,10 +17,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef I386_LINUX_NAT_H -#define I386_LINUX_NAT_H 1 - -/* Does the current host support the GETFPXREGS request? */ -extern int have_ptrace_getfpxregs; +#include "nat/i386-linux.h" +/* See nat/i386-linux.h. */ +tribool have_ptrace_getfpxregs = +#ifdef HAVE_PTRACE_GETFPXREGS + TRIBOOL_UNKNOWN +#else + TRIBOOL_FALSE #endif +; diff --git a/gdb/nat/i386-linux.h b/gdb/nat/i386-linux.h new file mode 100644 index 00000000000..c93626b6439 --- /dev/null +++ b/gdb/nat/i386-linux.h @@ -0,0 +1,37 @@ +/* Native-dependent code for GNU/Linux i386. + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#ifndef NAT_I386_LINUX_H +#define NAT_I386_LINUX_H + +/* Does the current host support the GETFPXREGS request? The system header + file may or may not define it, but even if it is defined, the kernel + will return EIO if it's running on a pre-SSE processor. + + Initially this will be TRIBOOL_UNKNOWN and should be changed to + TRIBOOL_FALSE if the ptrace call is attempted and fails or changed to + TRIBOOL_TRUE if the ptrace call is attempted and succeeds. + + My instinct is to attach this to some architecture- or target-specific + data structure, but really, a particular GDB process can only run on top + of one kernel at a time. So it's okay - for this to be a global + variable. */ +extern tribool have_ptrace_getfpxregs; + +#endif /* NAT_I386_LINUX_H */ diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index a3d8ffb60f1..762151ff378 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -27,7 +27,7 @@ #include "x86-nat.h" #ifndef __x86_64__ -#include "i386-linux-nat.h" +#include "nat/i386-linux.h" #endif #include "x86-linux-nat.h" #include "i386-linux-tdep.h" @@ -147,13 +147,13 @@ x86_linux_nat_target::read_description () error (_("Can't debug 64-bit process with 32-bit GDB")); } #elif HAVE_PTRACE_GETFPXREGS - if (have_ptrace_getfpxregs == -1) + if (have_ptrace_getfpxregs == TRIBOOL_UNKNOWN) { elf_fpxregset_t fpxregs; if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) { - have_ptrace_getfpxregs = 0; + have_ptrace_getfpxregs = TRIBOOL_FALSE; have_ptrace_getregset = TRIBOOL_FALSE; return i386_linux_read_description (X86_XSTATE_X87_MASK); } diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 9e861a75088..8e882d2159b 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -109,6 +109,7 @@ case "${gdbserver_host}" in srv_tgtobj="${srv_tgtobj} nat/linux-btrace.o" srv_tgtobj="${srv_tgtobj} nat/x86-linux.o" srv_tgtobj="${srv_tgtobj} nat/x86-linux-dregs.o" + srv_tgtobj="${srv_tgtobj} nat/i386-linux.o" srv_linux_usrregs=yes srv_linux_regsets=yes srv_linux_thread_db=yes diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc index e8ef3667eb4..2d99a82f566 100644 --- a/gdbserver/linux-x86-low.cc +++ b/gdbserver/linux-x86-low.cc @@ -29,6 +29,8 @@ #ifdef __x86_64__ #include "nat/amd64-linux-siginfo.h" +#else +#include "nat/i386-linux.h" #endif #include "gdb_proc_service.h" @@ -831,17 +833,6 @@ x86_target::low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction) static int use_xml; -/* Does the current host support the GETFPXREGS request? The header - file may or may not define it, and even if it is defined, the - kernel will return EIO if it's running on a pre-SSE processor. */ -int have_ptrace_getfpxregs = -#ifdef HAVE_PTRACE_GETFPXREGS - -1 -#else - 0 -#endif -; - /* Get Linux/x86 target description from running target. */ static const struct target_desc * @@ -886,18 +877,18 @@ x86_linux_read_description (void) } #if !defined __x86_64__ && defined HAVE_PTRACE_GETFPXREGS - if (machine == EM_386 && have_ptrace_getfpxregs == -1) + if (machine == EM_386 && have_ptrace_getfpxregs == TRIBOOL_UNKNOWN) { elf_fpxregset_t fpxregs; if (ptrace (PTRACE_GETFPXREGS, tid, 0, (long) &fpxregs) < 0) { - have_ptrace_getfpxregs = 0; + have_ptrace_getfpxregs = TRIBOOL_FALSE; have_ptrace_getregset = TRIBOOL_FALSE; return i386_linux_read_description (X86_XSTATE_X87); } else - have_ptrace_getfpxregs = 1; + have_ptrace_getfpxregs = TRIBOOL_TRUE; } #endif From patchwork Sat May 11 10:08:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89950 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 18A2038708A6 for ; Sat, 11 May 2024 10:10:23 +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 ESMTPS id 4E8A13870879 for ; Sat, 11 May 2024 10:09:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4E8A13870879 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 4E8A13870879 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=1715422142; cv=none; b=HAODhNG/CpPM9vjUba/xFy1YITCxuPMG+bTIlY/tiIyJXWlC6ZCbeEq2t7f6xDNOkt/7NBKMR3KyDX8hh70jTm+fye5O7g9WthRsZChWaH3Vtrk0yp8SkvkHm/oCzhSRLYAk95tg3ZaK3TM/plJJZak92van2rq9I5tNOrFCbCY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422142; c=relaxed/simple; bh=qnCvlbll2Ks1a83d+MtZcCImE/tYmOzu1/fkk8zs9/A=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=XdomADFjAESC3WHhbVvywv8AhUylGCkywXslVYz1Y5OtHVpQMnOcqNUPMZXrI+OxojMANiX3nws/geONEURHzrmD2pwKm5HRYgNEXZ2+Y1r9ITSq+nd7wPV3JyJuSnBbP+rk2jtkpIpaoywuCJnZyOTWHLSYWrvfxISuCfivKTE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422139; 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=dKk0xRQF8UjVvY03T3b9YvS0c8m504L8/vDhlC69pcg=; b=i8KMT75KOalgYt5AaG1n3PEAm2pidb2ta8a1LJk6qu3WqM2LjtHcBHCPEoSZwlCmWzWhLC sBnWhBmc0HpQ0Vwx+xBOaE31fvT+rNzEynwe22zNm5hsR8tZndsJDVNxXVAoU2YbQjYUX1 bOb6a86qYFyTMBHDzwrA7sMBGWpJABA= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-607-sUdiiqIcOqmmoI7ZHwubZg-1; Sat, 11 May 2024 06:08:58 -0400 X-MC-Unique: sUdiiqIcOqmmoI7ZHwubZg-1 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-41fef7df68eso7445145e9.3 for ; Sat, 11 May 2024 03:08:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422137; x=1716026937; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dKk0xRQF8UjVvY03T3b9YvS0c8m504L8/vDhlC69pcg=; b=iUMMhIUdDTQvBip+mvKxIgZSUGJKicuDseVQbmQVXLKV1DyVyQPSV2p1HwpMGlBRXf 3UqHYYAJBiW96wSM3SV6P9+YXPgEPnif9QQ3odBAD/DeFjuBTc963QoE87vN+1DvQjIp OWmOrzYjJ/UjXfxdEBTLalyw2aLhG0IA1/wiR7OGwzaeiq7+epQGbbWb0aOpPZt5pPX2 /p1NMkevV6t34y9V0OsA8jAY47DtZyc5BpC2/lG3qhUDMeALHmwtf9MrDzvLOPKPkfMv zEtl9DCujuqmAdMOrnQGebhDoinzPKiNk9Iw8a95rBN87DDLww1PPvkR96kyEVebVtcP 3kXQ== X-Gm-Message-State: AOJu0YwYymm6NJ8da01ftQEAlzqMrvTSe3Aikej9seWyhaHOgp9FZMZf na4rPMOH4k3MdjfKBiBq6Mx8tfM9EG1qz6uvsG+hFYqd/utVh8lm4I142xg7gP4Dc0MbaTDKK7E OirhiW8QVbJ6HZbP0sLz+yw3G39R2cFHo/swVpVX4r8QhPOyCvy0gQTaOtAZHXoXvLbYaNzIrYm Q6FWjX1GFmb5diMYGPaHaQhld8pNvs4+9lTpBq5DjilyU= X-Received: by 2002:a05:600c:450e:b0:41c:8754:8796 with SMTP id 5b1f17b1804b1-41feac4960bmr33450305e9.30.1715422136714; Sat, 11 May 2024 03:08:56 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEkwb9PjJSYL9mX8i4JebADigcvri0G8S88FmqiTP2KTcnBnNUtngLgwNm2oki392sBJ6982A== X-Received: by 2002:a05:600c:450e:b0:41c:8754:8796 with SMTP id 5b1f17b1804b1-41feac4960bmr33450175e9.30.1715422136238; Sat, 11 May 2024 03:08:56 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-41fccfe1527sm91831615e9.44.2024.05.11.03.08.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:08:55 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 4/9] gdb: move have_ptrace_getregset declaration into gdb/nat directory Date: Sat, 11 May 2024 11:08:34 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 In a later commit I want to access have_ptrace_getregset from a .c file in the nat/ directory. To achieve this I need access to the declaration of have_ptrace_getregset. Currently have_ptrace_getregset is declared (and defined) twice, once in GDB and once in gdbserver. This commit moves the declaration into nat/linux-nat.h, but leaves the two definitions where they are. Now, in my later commit, I can pull in the declaration from nat/linux-nat.h. There should be no user visible changes after this commit. --- gdb/linux-nat.c | 2 +- gdb/linux-nat.h | 3 --- gdb/nat/linux-nat.h | 3 +++ gdbserver/linux-low.cc | 2 +- gdbserver/linux-low.h | 2 -- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 48ecd3627ca..a342e06fd53 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -243,7 +243,7 @@ PTRACE_PEEKTEXT/PTRACE_POKETEXT or process_vm_readv/process_vm_writev: struct linux_nat_target *linux_target; -/* Does the current host support PTRACE_GETREGSET? */ +/* See nat/linux-nat.h. */ enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN; /* When true, print debug messages relating to the linux native target. */ diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h index 4dcbe9e170a..fd393df5020 100644 --- a/gdb/linux-nat.h +++ b/gdb/linux-nat.h @@ -299,9 +299,6 @@ lwp_info_range all_lwps (); lwp_info_safe_range all_lwps_safe (); -/* Does the current host support PTRACE_GETREGSET? */ -extern enum tribool have_ptrace_getregset; - /* Called from the LWP layer to inform the thread_db layer that PARENT spawned CHILD. Both LWPs are currently stopped. This function does whatever is required to have the child LWP under the diff --git a/gdb/nat/linux-nat.h b/gdb/nat/linux-nat.h index d4a36cbb601..b9fba7924b9 100644 --- a/gdb/nat/linux-nat.h +++ b/gdb/nat/linux-nat.h @@ -36,6 +36,9 @@ struct arch_lwp_info; instead SIGTRAP with bit 7 set. */ #define SYSCALL_SIGTRAP (SIGTRAP | 0x80) +/* Does the current host support PTRACE_GETREGSET? */ +extern tribool have_ptrace_getregset; + /* Return the ptid of the current lightweight process. With NPTL threads and LWPs map 1:1, so this is equivalent to returning the ptid of the current thread. This function must be provided by diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc index ac7f9807ecc..266c7de8fb8 100644 --- a/gdbserver/linux-low.cc +++ b/gdbserver/linux-low.cc @@ -133,7 +133,7 @@ typedef struct } Elf64_auxv_t; #endif -/* Does the current host support PTRACE_GETREGSET? */ +/* See nat/linux-nat.h. */ enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN; /* Return TRUE if THREAD is the leader thread of the process. */ diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h index eaf87527338..273c04626b8 100644 --- a/gdbserver/linux-low.h +++ b/gdbserver/linux-low.h @@ -951,8 +951,6 @@ void thread_db_notice_clone (struct thread_info *parent_thr, ptid_t child_ptid); bool thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len); -extern enum tribool have_ptrace_getregset; - /* Search for the value with type MATCH in the auxv vector, with entries of length WORDSIZE bytes, of process with pid PID. If found, store the value in *VALP and return 1. If not found or if there is an error, From patchwork Sat May 11 10:08:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89949 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 786CD38708D1 for ; Sat, 11 May 2024 10:10: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.133.124]) by sourceware.org (Postfix) with ESMTPS id 4500D387087B for ; Sat, 11 May 2024 10:09:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4500D387087B 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 4500D387087B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422149; cv=none; b=iL3w2rXYmo5fHZTT3hZHS2eKvt6ozwwEF4Qbo/CdFtkQzy7TeAo47ZAim9Ezfk6Dix6xHt932HOVSQr8f4Jpe0EEzLi4qmTUKAWqwtDu/RXXN9O6dDH0e84nHGYW9aJiIWm0/EhGRgXcI9YRvuHWC7SMIAS18JmlzwIFQZTAFZM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422149; c=relaxed/simple; bh=Eg0e/D8jjSQd4227yIz/AZKcBTAwWsvE6grpgUf10Jo=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=lk0/huQ9cdaxjFWBrlaTWj34FdliutrTlUOaT1Te0UIq3J/9CTMTfyBuIvIi6XTNTQOO6cRpNbPFhJLeZ8Z3BeHYn8bgpkqfPadMaW25AqjQZrp9u0rd2+0/ZNM6myLQ19zTkbX4TwibRcg2olqmORd6NeLUezpV8lGUhCL+dLU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422146; 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=mYy9GjBU46G0QTv/thLVyVIg4b0pasrhjC6daDx7Uxo=; b=WoKRWIVObhZp6g6FmQ6kbvEUuWIycD2ylMh39TUyLNrk1w20O2LSj/eNEgm8f2kNQgSf26 C7RCMA8LcSposMqB2gNMUWr5xtrMwe3n0gdM6nBZpM/8cbv63EhI0D2COr9jH7J9PI2bjA 7bKIL8hpEg3Bilcd+lMNsLTJnPzuF8k= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-320-gHsjmnCpMl-cEd_7s1zuFw-1; Sat, 11 May 2024 06:09:00 -0400 X-MC-Unique: gHsjmnCpMl-cEd_7s1zuFw-1 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-34deefe9142so1574289f8f.0 for ; Sat, 11 May 2024 03:09:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422139; x=1716026939; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mYy9GjBU46G0QTv/thLVyVIg4b0pasrhjC6daDx7Uxo=; b=EmBtCA8CFmZDPRdbDPDHklqcQ9kwIHsBeEn8vY1Nzo8v6IvM7SU01jzGjh6WnfbzYU M8qQM7ta4WoZXGab+V04FZM0UimtzDRRihNs+Eu8rEchN8NUeq/bDAn3//kKPzV2EQHc 3wa9ggbdprtwj6tEVl5M4Sl1hajHWxiILMswsjcWIwe1adhsGyZY1AAxqeeLrswxkYax J+DvWAtkXUn+kRFM9FYFW34llVZ6byVo4YS33kPY2aikwyRdrnDfQtwaEJSbyYz9ZFhV f8AifsYym+7alq8P+AKOD4ZI5ksoE0QyPybMfYUcg64Bgx0D7rFzjZZDpn/387cldbo8 US4A== X-Gm-Message-State: AOJu0YyGhG7G+wYYDopDmrtcU1SHg/PKMxwLnRBT//WBFGh4APSX14VX qicxNhUcjInsNPAostyoVfgCSelLkBRbnmeaK1AhmqWAoTd4VlrmhJAC1YTg8CthRphQuUcRUTS Ud7OXB6Yhal6tXCKEifJnhSg7uhNN5VsZso977wNEGVECgPnvSYYKZP+8JNAQUIqX91zn9wxzv5 sHtk23FER/jVyjRg0Thsnx3LhJ/EIChFnssDL8mvXZ9zs= X-Received: by 2002:a5d:40c1:0:b0:34d:707c:a281 with SMTP id ffacd0b85a97d-3504a62fb28mr4161453f8f.6.1715422138732; Sat, 11 May 2024 03:08:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHG4TWVB7WPc0DfK3IAHB0oKbvQ3AvUE6ywA4/V0Zn8VzfEcV8K3L+Rrqj96HdsMRFxcV9CHA== X-Received: by 2002:a5d:40c1:0:b0:34d:707c:a281 with SMTP id ffacd0b85a97d-3504a62fb28mr4161436f8f.6.1715422138242; Sat, 11 May 2024 03:08:58 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3502b8a77easm6584152f8f.53.2024.05.11.03.08.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:08:57 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 5/9] gdb/x86: move reading of cs and ds state into gdb/nat directory Date: Sat, 11 May 2024 11:08:35 +0100 Message-Id: <2dade5f6a5663b6b141a60ca5b7cb90da62338e4.1715421687.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 patch is part of a series that has the aim sharing the x86 Linux target description creation code between GDB and gdbserver. Within GDB part of this process involves reading the cs and ds state from the 'struct user_regs_struct' using a ptrace call. This isn't done by gdbserver, which is part of the motivation for this whole series; the approach gdbserver takes is inferior to the approach GDB takes (gdbserver relies on reading the file being debugged, and extracting similar information from the file headers). This commit moves the reading of cs and ds, which is used to figure out if a thread is 32-bit or 64-bit (or in x32 mode), into the gdb/nat directory so that the code can be shared with gdbserver, but at this point I'm not actually using the code in gdbserver, that will come later. As such there should be no user visible changes after this commit, GDB continues to do things as it did before (reading cs/ds), while gdbserver continues to use its own approach (which doesn't require reading cs/ds). Approved-By: John Baldwin Reviewed-By: Felix Willgerodt --- gdb/nat/x86-linux.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ gdb/nat/x86-linux.h | 28 +++++++++++++++++++++++++++ gdb/x86-linux-nat.c | 45 ++++++++----------------------------------- 3 files changed, 83 insertions(+), 37 deletions(-) diff --git a/gdb/nat/x86-linux.c b/gdb/nat/x86-linux.c index 7a21c8f2c26..ad3ed3c2289 100644 --- a/gdb/nat/x86-linux.c +++ b/gdb/nat/x86-linux.c @@ -19,6 +19,8 @@ #include "x86-linux.h" #include "x86-linux-dregs.h" +#include "nat/gdb_ptrace.h" +#include /* Per-thread arch-specific data we want to keep. */ @@ -79,3 +81,48 @@ x86_linux_prepare_to_resume (struct lwp_info *lwp) { x86_linux_update_debug_registers (lwp); } + +#ifdef __x86_64__ +/* Value of CS segment register: + 64bit process: 0x33 + 32bit process: 0x23 */ +#define AMD64_LINUX_USER64_CS 0x33 + +/* Value of DS segment register: + LP64 process: 0x0 + X32 process: 0x2b */ +#define AMD64_LINUX_X32_DS 0x2b +#endif + +/* See nat/x86-linux.h. */ + +x86_linux_arch_size +x86_linux_ptrace_get_arch_size (int tid) +{ +#ifdef __x86_64__ + unsigned long cs; + unsigned long ds; + + /* Get CS register. */ + errno = 0; + cs = ptrace (PTRACE_PEEKUSER, tid, + offsetof (struct user_regs_struct, cs), 0); + if (errno != 0) + perror_with_name (_("Couldn't get CS register")); + + bool is_64bit = cs == AMD64_LINUX_USER64_CS; + + /* Get DS register. */ + errno = 0; + ds = ptrace (PTRACE_PEEKUSER, tid, + offsetof (struct user_regs_struct, ds), 0); + if (errno != 0) + perror_with_name (_("Couldn't get DS register")); + + bool is_x32 = ds == AMD64_LINUX_X32_DS; + + return x86_linux_arch_size (is_64bit, is_x32); +#else + return x86_linux_arch_size (false, false); +#endif +} diff --git a/gdb/nat/x86-linux.h b/gdb/nat/x86-linux.h index 822882173f9..15153ea277e 100644 --- a/gdb/nat/x86-linux.h +++ b/gdb/nat/x86-linux.h @@ -47,4 +47,32 @@ extern void x86_linux_delete_thread (struct arch_lwp_info *arch_lwp); extern void x86_linux_prepare_to_resume (struct lwp_info *lwp); +/* Return value from x86_linux_ptrace_get_arch_size function. Indicates if + a thread is 32-bit, 64-bit, or x32. */ + +struct x86_linux_arch_size +{ + explicit x86_linux_arch_size (bool is_64bit, bool is_x32) + : m_is_64bit (is_64bit), + m_is_x32 (is_x32) + { + /* Nothing. */ + } + + bool is_64bit () const + { return m_is_64bit; } + + bool is_x32 () const + { return m_is_x32; } + +private: + bool m_is_64bit = false; + bool m_is_x32 = false; +}; + +/* Use ptrace calls to figure out if thread TID is 32-bit, 64-bit, or + 64-bit running in x32 mode. */ + +extern x86_linux_arch_size x86_linux_ptrace_get_arch_size (int tid); + #endif /* NAT_X86_LINUX_H */ diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index 762151ff378..ed76c1760bc 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -90,18 +90,6 @@ x86_linux_nat_target::post_startup_inferior (ptid_t ptid) linux_nat_target::post_startup_inferior (ptid); } -#ifdef __x86_64__ -/* Value of CS segment register: - 64bit process: 0x33 - 32bit process: 0x23 */ -#define AMD64_LINUX_USER64_CS 0x33 - -/* Value of DS segment register: - LP64 process: 0x0 - X32 process: 0x2b */ -#define AMD64_LINUX_X32_DS 0x2b -#endif - /* Get Linux/x86 target description from running target. */ const struct target_desc * @@ -121,31 +109,14 @@ x86_linux_nat_target::read_description () tid = inferior_ptid.pid (); #ifdef __x86_64__ - { - unsigned long cs; - unsigned long ds; - - /* Get CS register. */ - errno = 0; - cs = ptrace (PTRACE_PEEKUSER, tid, - offsetof (struct user_regs_struct, cs), 0); - if (errno != 0) - perror_with_name (_("Couldn't get CS register")); - - is_64bit = cs == AMD64_LINUX_USER64_CS; - - /* Get DS register. */ - errno = 0; - ds = ptrace (PTRACE_PEEKUSER, tid, - offsetof (struct user_regs_struct, ds), 0); - if (errno != 0) - perror_with_name (_("Couldn't get DS register")); - - is_x32 = ds == AMD64_LINUX_X32_DS; - - if (sizeof (void *) == 4 && is_64bit && !is_x32) - error (_("Can't debug 64-bit process with 32-bit GDB")); - } + + x86_linux_arch_size arch_size = x86_linux_ptrace_get_arch_size (tid); + is_64bit = arch_size.is_64bit (); + is_x32 = arch_size.is_x32 (); + + if (sizeof (void *) == 4 && is_64bit && !is_x32) + error (_("Can't debug 64-bit process with 32-bit GDB")); + #elif HAVE_PTRACE_GETFPXREGS if (have_ptrace_getfpxregs == TRIBOOL_UNKNOWN) { From patchwork Sat May 11 10:08:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89952 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 7124538708CB for ; Sat, 11 May 2024 10:11:01 +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.133.124]) by sourceware.org (Postfix) with ESMTPS id DDBA33858C41 for ; Sat, 11 May 2024 10:09:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DDBA33858C41 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 DDBA33858C41 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422147; cv=none; b=l4Rq5zZr820Bb4EocZYug9qL7XdSc4jlSiTl6ZSLHiYcdPrZOBL1vTB7XYrvdvjYZjfc9KYRO0bPi48vBihBB451h48QR+vRu7sraArAeUAeg/uvYzkJts7i7SFsRwZuoBtqeLhiUrbHpO9kwRylMi2+19f2DFSK7SnNN5+r+WQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422147; c=relaxed/simple; bh=9Diia1TGB7M9tr/V9zOJ29zUoGLo682cMaasu8gp76s=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=a/0X33HuLoHTmmxbORMyWamJnmtlst2lnWxZHfWEDwhVjZODpJHq92UElPG4p2Y5kJyy8zsyOqo6YQ2w5/542C+m2urAMp1hOHLy6qpsjDOioeHsS953Z1ZQaqGgSUXMtm+8jl7HWIqxvE0KOIWPWZkO6L8ouIjOHMi7xH/YT8Q= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422145; 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=Kdi8zyO660x2jbUvey0z6P24eCeNTfLaEBp/iQZW12c=; b=c4eJChxO7aYaIun4DedHnUiG958JVU1DCxB6ZJ7F4C/iHH/fEGIOg4Ua/KvyO1HGf9Q+H/ xLosdgXaHZcEhcwFBpFpqBSE3KprRLCKinEU4kgOqC9GJqDKAgiYLiyvlPwcl1UTv2icRv t8qi6DwwplQ5VrOhuWVbZt3mD/53Itw= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-8--xpzwuSNMyK03sgGmGF1GQ-1; Sat, 11 May 2024 06:09:04 -0400 X-MC-Unique: -xpzwuSNMyK03sgGmGF1GQ-1 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-41ff6049fdbso7556055e9.0 for ; Sat, 11 May 2024 03:09:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422141; x=1716026941; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Kdi8zyO660x2jbUvey0z6P24eCeNTfLaEBp/iQZW12c=; b=mZ1p7l92IpkoDvwC1fcHHWg5BQPBuL02lHAzbps6YMhSnSu3Z1ndXc4cHC5iIuDkjA wcMyoWPc4eHxzDBm85v7e9lRqJZXfi1GkkrtXtwhwoV38j6JyW4jRZ1vvPqtTrxNcMrZ TXfF+pFOc1JLVeC2/TtnmtWtVEwvYcYMUHRLny6ZfOWAIYI7PVDqwwY7CwZ48pnviFEj A3KbPbJipVsmR/ZdjUYX1qLV7CfhZYSo81s5O/5Z1hiAXzk8xjIXyLtsXq9SNfpWXQlo YCnb1xAf1/1BrlLFIRoKGTQYRY+leHPSo1LmI0MjJ5WxdiZO3NeCXSIfIUlK6/L+max6 DS5Q== X-Gm-Message-State: AOJu0YxnM5R8yvCttqe1OLtzRmDZ97wG95TUOH6Z+YDesIEFzkkXVM5M nEgKtO3LwPRYKF1mCU+FE/4SJo+PDo/s4Zlhwucw76VhmllkvXdYYwzlfFN5gi5sDIBsgGIfCYM nKeL5RG1+3ra0lR7i92s2ZaCQM5LD31ZUWta0YHBVrpJOHNDUthJztLfGHJsqw9d8fmYJF4kTNR AFGzlx8d93wmuxrjQdgBj/38U3Z3+rzIk5w1oy4P64H6I= X-Received: by 2002:a7b:cb0f:0:b0:416:9b7f:7098 with SMTP id 5b1f17b1804b1-41feab4479bmr37517725e9.24.1715422141222; Sat, 11 May 2024 03:09:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEM+WD+jweWYYhJ0M1eH4lTvvkcKGHZ8SPcav/YxN7tepNk4qN6SmKyxQ9u/F7GYhEVBOnraQ== X-Received: by 2002:a7b:cb0f:0:b0:416:9b7f:7098 with SMTP id 5b1f17b1804b1-41feab4479bmr37517555e9.24.1715422140628; Sat, 11 May 2024 03:09:00 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-41f88110fedsm129879695e9.31.2024.05.11.03.08.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:08:59 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 6/9] gdb: move xcr0 == 0 check into i386_linux_core_read_description Date: Sat, 11 May 2024 11:08:36 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 Currently, in i386_linux_core_read_description, if GDB fails to extract an xcr0 value from the core file, then we will have a default zero value for the xcr0 variable, we still call the i386_linux_read_description function, which checks for this zero value and returns nullptr. Back in i386_linux_core_read_description we spot the nullptr return value from i386_linux_read_description and call i386_linux_read_description again, but this time passing a default value for xcr0. In the next commit I plan to rework i386_linux_read_description, and in so doing I will remove the check for xcr0 == 0, this is inline with how the amd64 code is written. However, this means that the 'xcr0 == 0' check needs to move up the stack to i386_linux_core_read_description, again, this brings the i386 code into line with the amd64 code. This is just a refactor in preparation for the next commit, there should be no user visible changes after this commit. Approved-By: Felix Willgerodt Approved-By: John Baldwin --- gdb/i386-linux-tdep.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index a78f03fac8d..511e43f3b6f 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -714,15 +714,16 @@ i386_linux_core_read_description (struct gdbarch *gdbarch, /* Linux/i386. */ x86_xsave_layout layout; uint64_t xcr0 = i386_linux_core_read_xsave_info (abfd, layout); - const struct target_desc *tdesc = i386_linux_read_description (xcr0); - if (tdesc != NULL) - return tdesc; + if (xcr0 == 0) + { + if (bfd_get_section_by_name (abfd, ".reg-xfp") != nullptr) + xcr0 = X86_XSTATE_SSE_MASK; + else + xcr0 = X86_XSTATE_X87_MASK; + } - if (bfd_get_section_by_name (abfd, ".reg-xfp") != NULL) - return i386_linux_read_description (X86_XSTATE_SSE_MASK); - else - return i386_linux_read_description (X86_XSTATE_X87_MASK); + return i386_linux_read_description (xcr0); } /* Similar to i386_supply_fpregset, but use XSAVE extended state. */ From patchwork Sat May 11 10:08:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89954 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 C7DDC38708A8 for ; Sat, 11 May 2024 10:11:37 +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.133.124]) by sourceware.org (Postfix) with ESMTPS id 564543870849 for ; Sat, 11 May 2024 10:09:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 564543870849 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 564543870849 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422154; cv=none; b=Mc262t6Fh/GmHro7ft3MLHnE0IR5Gq0PNmIX7fMilJsVvyXvEFCHk0nOjWGwJydvZNFuNFmDA+LD49Sje80E3SaDhw9xSmSyChiXRCuc6WMq/abgyVrN+K7ptuTmX3Q/Hk4YwW9u7jp/RZ+9L810dU/nQmxqIAcQBrZdnR82ar8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422154; c=relaxed/simple; bh=lJYad3VsGbzzfZA/sMg3CewluIwJJI9s/OPcjcPVlXk=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=O7DrBpq+kiGVRV2QuQ2HSJMebfp1m8OW3lnGhAUbgBPmu8TIr6db4/9vif4CGtp69Pze/bRkiQgDhqKGFWMxGH+MdDINbaMq/rNn9f724Q3U/OPda2/LucBzJxUxGy39YVwrF/7fyWdUM2xcv8cieOTF1czFD9jLlHw/IO0cH/8= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422148; 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=YZgjxwqrYwxx4ujbHIN56D5PaTkt4x542sts4tUgXzw=; b=TKX+jCPoJz9sD+A8Utv3q6mMt07XrcLcFimHcfuySjFEdMpEnLximHhLVNzKPGO5eslLk3 n27p8RQh9iFOZROKjYF2tzD5lxW+HbQPrJZ7TH1iimjwB9rCH7waI/gSCJ3Smg3Hxji36c HaFAYu+sPvVkvbxBiMAogS8COSbokvE= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-538-aLdw3r5NM4irvC86a5AbqQ-1; Sat, 11 May 2024 06:09:06 -0400 X-MC-Unique: aLdw3r5NM4irvC86a5AbqQ-1 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-34d7861a1f4so1513140f8f.1 for ; Sat, 11 May 2024 03:09:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422145; x=1716026945; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fdCS+nYpXuZ26MZ0rPy7dD5LZMN8x7HZpz2fveeA50k=; b=XEAz2+9bEOq4KO1XoSBvoCZqsK4N4j/5zIL2hwYEzV8mg3DWOuHlPYY6UG+iJFqU7U +00kZ88R1COGh9AgD+AgFl4hakVded0otTyypqipnM+9Da6YjT98J6FO4PNmoQH7COPW sJk0KdmCuCbzFWZDKnx+iXAVtDnhQ4VJyA2Mg7yAIkcDaua1nxMZJvlvGrquTIzFNyXk myhZzvPrbd6QXectDqKldx5gfe1wxlhe2NYQxVMDBqIl+vxtfdE6PUOcAuOKbf+ouS+H lFLObpbc4wLF748pYn/jMWQNoeHQvryI2iQJctclN4EFb7R2+Tkn4ruSnEnX7URpiiVO wFmA== X-Gm-Message-State: AOJu0Ywps+EBgR1wdcnHO2iwowxq2LCpzwhJl828Z6EH3irT2JaLKM5X 3AMG0zEY6Hc6aENyEYoO2vSvYCbGKFsNZIf1eek2Hy/Qb1s9enay7GIKbhRLISrsgK1Pv4H35lH JTfJZ+VFh0vLDPzYde2FzSnIFrZG9+x/MSnFWVhe3QFyeL+suBQJDS4p1a3CpIwxdDaX9uqFfIK PUHMAsqrPtoGD8S2X4ethNKtiy2EtfFV8iPkcvvzIPI0I= X-Received: by 2002:a5d:6451:0:b0:346:b581:ff57 with SMTP id ffacd0b85a97d-3504aa62eb4mr2896430f8f.68.1715422144023; Sat, 11 May 2024 03:09:04 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFb2tCwM3r15GY10gYrcmPJSngtfSWj2SKlTeKMf+TNqXODUikpJYbe0R036QiZ05WDNxyxYg== X-Received: by 2002:a5d:6451:0:b0:346:b581:ff57 with SMTP id ffacd0b85a97d-3504aa62eb4mr2896410f8f.68.1715422143149; Sat, 11 May 2024 03:09:03 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3502b8a7907sm6576467f8f.63.2024.05.11.03.09.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:09:02 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 7/9] gdb/gdbserver: share some code relating to target description creation Date: Sat, 11 May 2024 11:08:37 +0100 Message-Id: <3f2e66bab7bb82afcc7cd5297786807c6626f2d6.1715421687.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-6.7 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 is part of a series to share more of the x86 target description creation code between GDB and gdbserver. Unlike previous commits which were mostly refactoring, this commit is the first that makes a real change, though that change should mostly be for gdbserver; I've largely adopted the "GDB" way of doing things for gdbserver, and this fixes a real gdbserver bug. On a x86-64 Linux target, running the test: gdb.server/connect-with-no-symbol-file.exp results in two core files being created. Both of these core files are from the inferior process, created after gdbserver has detached. In this test a gdbserver process is started and then, after gdbserver has started, but before GDB attaches, we either delete the inferior executable, or change its permissions so it can't be read. Only after doing this do we attempt to connect with GDB. As GDB connects to gdbserver, gdbserver attempts to figure out the target description so that it can send the description to GDB, this involves a call to x86_linux_read_description. In x86_linux_read_description one of the first things we do is try to figure out if the process is 32-bit or 64-bit. To do this we look up the executable via the thread-id, and then attempt to read the architecture size from the executable. This isn't going to work if the executable has been deleted, or is no longer readable. And so, as we can't read the executable, we default to an i386 target and use an i386 target description. A consequence of using an i386 target description is that addresses are assumed to be 32-bits. Here's an example session that shows the problems this causes. This is run on an x86-64 machine, and the test binary (xx.x) is a standard 64-bit x86-64 binary: shell_1$ gdbserver --once localhost :54321 /tmp/xx.x shell_2$ gdb -q (gdb) set sysroot (gdb) shell chmod 000 /tmp/xx.x (gdb) target remote :54321 Remote debugging using :54321 warning: /tmp/xx.x: Permission denied. 0xf7fd3110 in ?? () (gdb) show architecture The target architecture is set to "auto" (currently "i386"). (gdb) p/x $pc $1 = 0xf7fd3110 (gdb) info proc mappings process 2412639 Mapped address spaces: Start Addr End Addr Size Offset Perms objfile 0x400000 0x401000 0x1000 0x0 r--p /tmp/xx.x 0x401000 0x402000 0x1000 0x1000 r-xp /tmp/xx.x 0x402000 0x403000 0x1000 0x2000 r--p /tmp/xx.x 0x403000 0x405000 0x2000 0x2000 rw-p /tmp/xx.x 0xf7fcb000 0xf7fcf000 0x4000 0x0 r--p [vvar] 0xf7fcf000 0xf7fd1000 0x2000 0x0 r-xp [vdso] 0xf7fd1000 0xf7fd3000 0x2000 0x0 r--p /usr/lib64/ld-2.30.so 0xf7fd3000 0xf7ff3000 0x20000 0x2000 r-xp /usr/lib64/ld-2.30.so 0xf7ff3000 0xf7ffb000 0x8000 0x22000 r--p /usr/lib64/ld-2.30.so 0xf7ffc000 0xf7ffe000 0x2000 0x2a000 rw-p /usr/lib64/ld-2.30.so 0xf7ffe000 0xf7fff000 0x1000 0x0 rw-p 0xfffda000 0xfffff000 0x25000 0x0 rw-p [stack] 0xff600000 0xff601000 0x1000 0x0 r-xp [vsyscall] (gdb) info inferiors Num Description Connection Executable * 1 process 2412639 1 (remote :54321) (gdb) shell cat /proc/2412639/maps 00400000-00401000 r--p 00000000 fd:03 45907133 /tmp/xx.x 00401000-00402000 r-xp 00001000 fd:03 45907133 /tmp/xx.x 00402000-00403000 r--p 00002000 fd:03 45907133 /tmp/xx.x 00403000-00405000 rw-p 00002000 fd:03 45907133 /tmp/xx.x 7ffff7fcb000-7ffff7fcf000 r--p 00000000 00:00 0 [vvar] 7ffff7fcf000-7ffff7fd1000 r-xp 00000000 00:00 0 [vdso] 7ffff7fd1000-7ffff7fd3000 r--p 00000000 fd:00 143904 /usr/lib64/ld-2.30.so 7ffff7fd3000-7ffff7ff3000 r-xp 00002000 fd:00 143904 /usr/lib64/ld-2.30.so 7ffff7ff3000-7ffff7ffb000 r--p 00022000 fd:00 143904 /usr/lib64/ld-2.30.so 7ffff7ffc000-7ffff7ffe000 rw-p 0002a000 fd:00 143904 /usr/lib64/ld-2.30.so 7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 7ffffffda000-7ffffffff000 rw-p 00000000 00:00 0 [stack] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] (gdb) Notice the difference between the mappings reported via GDB and those reported directly from the kernel via /proc/PID/maps, the addresses of every mapping is clamped to 32-bits for GDB, while the kernel reports real 64-bit addresses. Notice also that the $pc value is a 32-bit value. It appears to be within one of the mappings reported by GDB, but is outside any of the mappings reported from the kernel. And this is where the problem arises. When gdbserver detaches from the inferior we pass the inferior the address from which it should resume. Due to the 32/64 bit confusion we tell the inferior to resume from the 32-bit $pc value, which is not within any valid mapping, and so, as soon as the inferior resumes, it segfaults. If we look at how GDB (not gdbserver) figures out its target description then we see an interesting difference. GDB doesn't try to read the executable. Instead GDB uses ptrace to query the thread's state, and uses this to figure out the if the thread is 32 or 64 bit. If we update gdbserver to do it the "GDB" way then the above problem is resolved, gdbserver now sees the process as 64-bit, and when we detach from the inferior we give it the correct 64-bit address, and the inferior no longer segfaults. Now, I could just update the gdbserver code, but better, I think, to share one copy of the code between GDB and gdbserver in gdb/nat/. That is what this commit does. The cores of x86_linux_read_description from gdbserver and x86_linux_nat_target::read_description from GDB are moved into a new file gdb/nat/x86-linux-tdesc.c and combined into a single function x86_linux_tdesc_for_tid which is called from each location. This new function does things mostly the GDB way, some changes are needed to allow for the sharing; we now take some pointers for where the shared code can cache the xcr0 and xsave layout values. Another thing to note about this commit is how the functions i386_linux_read_description and amd64_linux_read_description are handled. For now I've left these function as implemented separately in GDB and gdbserver. I've moved the declarations of these functions into gdb/arch/{i386,amd64}-linux-tdesc.h, but the implementations are left where they are. A later commit in this series will make these functions shared too, but doing this is not trivial, so I've left that for a separate commit. Merging the declarations as I've done here ensures that everyone implements the function to the same API, and once these functions are shared (in a later commit) we'll want a shared declaration anyway. Reviewed-By: Felix Willgerodt Acked-By: John Baldwin --- gdb/Makefile.in | 3 + gdb/amd64-linux-tdep.c | 1 + gdb/amd64-linux-tdep.h | 6 -- gdb/arch/amd64-linux-tdesc.h | 30 +++++++ gdb/arch/i386-linux-tdesc.h | 29 +++++++ gdb/configure.nat | 5 +- gdb/i386-linux-tdep.c | 1 + gdb/i386-linux-tdep.h | 3 - gdb/nat/x86-linux-tdesc.c | 129 ++++++++++++++++++++++++++++++ gdb/nat/x86-linux-tdesc.h | 54 +++++++++++++ gdb/x86-linux-nat.c | 88 ++------------------- gdbserver/configure.srv | 2 + gdbserver/i387-fp.cc | 9 +-- gdbserver/i387-fp.h | 4 +- gdbserver/linux-amd64-ipa.cc | 1 + gdbserver/linux-i386-ipa.cc | 1 + gdbserver/linux-x86-low.cc | 147 ++++++++++------------------------- gdbserver/linux-x86-tdesc.cc | 2 + gdbserver/linux-x86-tdesc.h | 7 -- 19 files changed, 312 insertions(+), 210 deletions(-) create mode 100644 gdb/arch/amd64-linux-tdesc.h create mode 100644 gdb/arch/i386-linux-tdesc.h create mode 100644 gdb/nat/x86-linux-tdesc.c create mode 100644 gdb/nat/x86-linux-tdesc.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index bdb8a3683b5..13ca417706b 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1550,8 +1550,10 @@ HFILES_NO_SRCDIR = \ arch/aarch64-insn.h \ arch/aarch64-mte-linux.h \ arch/aarch64-scalable-linux.h \ + arch/amd64-linux-tdesc.h \ arch/arc.h \ arch/arm.h \ + arch/i386-linux-tdesc.h \ arch/i386.h \ arch/loongarch.h \ arch/ppc-linux-common.h \ @@ -1608,6 +1610,7 @@ HFILES_NO_SRCDIR = \ nat/x86-gcc-cpuid.h \ nat/x86-linux.h \ nat/x86-linux-dregs.h \ + nat/x86-linux-tdesc.h \ python/py-event.h \ python/py-events.h \ python/py-stopevent.h \ diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index c52b0436872..f9647dce1e6 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -42,6 +42,7 @@ #include "arch/amd64.h" #include "target-descriptions.h" #include "expop.h" +#include "arch/amd64-linux-tdesc.h" /* The syscall's XML filename for i386. */ #define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml" diff --git a/gdb/amd64-linux-tdep.h b/gdb/amd64-linux-tdep.h index 2003dcda78f..0ec49e7fe03 100644 --- a/gdb/amd64-linux-tdep.h +++ b/gdb/amd64-linux-tdep.h @@ -43,12 +43,6 @@ extern struct target_desc *tdesc_x32_linux; extern struct target_desc *tdesc_x32_avx_linux; extern struct target_desc *tdesc_x32_avx_avx512_linux; -/* Return the right amd64-linux target descriptions according to - XCR0_FEATURES_BIT and IS_X32. */ - -const target_desc *amd64_linux_read_description (uint64_t xcr0_features_bit, - bool is_x32); - /* Enum that defines the syscall identifiers for amd64 linux. Used for process record/replay, these will be translated into a gdb-canonical set of syscall ids in linux-record.c. */ diff --git a/gdb/arch/amd64-linux-tdesc.h b/gdb/arch/amd64-linux-tdesc.h new file mode 100644 index 00000000000..db425b60df6 --- /dev/null +++ b/gdb/arch/amd64-linux-tdesc.h @@ -0,0 +1,30 @@ +/* Target description related code for GNU/Linux x86-64. + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#ifndef ARCH_AMD64_LINUX_TDESC_H +#define ARCH_AMD64_LINUX_TDESC_H + +struct target_desc; + +/* Return the AMD64 target descriptions corresponding to XCR0 and IS_X32. */ + +extern const target_desc *amd64_linux_read_description (uint64_t xcr0, + bool is_x32); + +#endif /* ARCH_AMD64_LINUX_TDESC_H */ diff --git a/gdb/arch/i386-linux-tdesc.h b/gdb/arch/i386-linux-tdesc.h new file mode 100644 index 00000000000..0b736337a75 --- /dev/null +++ b/gdb/arch/i386-linux-tdesc.h @@ -0,0 +1,29 @@ +/* Target description related code for GNU/Linux i386. + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#ifndef ARCH_I386_LINUX_TDESC_H +#define ARCH_I386_LINUX_TDESC_H + +struct target_desc; + +/* Return the i386 target description corresponding to XCR0. */ + +extern const struct target_desc *i386_linux_read_description (uint64_t xcr0); + +#endif /* ARCH_I386_LINUX_TDESC_H */ diff --git a/gdb/configure.nat b/gdb/configure.nat index 25268bb268b..a30b07ef8c5 100644 --- a/gdb/configure.nat +++ b/gdb/configure.nat @@ -256,7 +256,8 @@ case ${gdb_host} in NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \ nat/x86-xstate.o \ i386-linux-nat.o x86-linux-nat.o nat/linux-btrace.o \ - nat/x86-linux.o nat/x86-linux-dregs.o nat/i386-linux.o" + nat/x86-linux.o nat/x86-linux-dregs.o nat/i386-linux.o \ + nat/x86-linux-tdesc.o" ;; ia64) # Host: Intel IA-64 running GNU/Linux @@ -322,7 +323,7 @@ case ${gdb_host} in NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \ nat/x86-xstate.o amd64-nat.o amd64-linux-nat.o x86-linux-nat.o \ nat/linux-btrace.o \ - nat/x86-linux.o nat/x86-linux-dregs.o \ + nat/x86-linux.o nat/x86-linux-dregs.o nat/x86-linux-tdesc.o \ nat/amd64-linux-siginfo.o" ;; sparc) diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 511e43f3b6f..6a7490680c1 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -40,6 +40,7 @@ #include "i387-tdep.h" #include "gdbsupport/x86-xstate.h" +#include "arch/i386-linux-tdesc.h" /* The syscall's XML filename for i386. */ #define XML_SYSCALL_FILENAME_I386 "syscalls/i386-linux.xml" diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h index 07593c6a8ec..e8691cd778e 100644 --- a/gdb/i386-linux-tdep.h +++ b/gdb/i386-linux-tdep.h @@ -55,9 +55,6 @@ extern void i386_linux_report_signal_info (struct gdbarch *gdbarch, struct ui_out *uiout, enum gdb_signal siggnal); -/* Return the target description according to XCR0. */ -extern const struct target_desc *i386_linux_read_description (uint64_t xcr0); - extern int i386_linux_gregset_reg_offset[]; /* Return x86 siginfo type. */ diff --git a/gdb/nat/x86-linux-tdesc.c b/gdb/nat/x86-linux-tdesc.c new file mode 100644 index 00000000000..b065928f8ba --- /dev/null +++ b/gdb/nat/x86-linux-tdesc.c @@ -0,0 +1,129 @@ +/* Target description related code for GNU/Linux x86 (i386 and x86-64). + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 "nat/x86-linux-tdesc.h" +#ifdef __x86_64__ +#include "arch/amd64.h" +#include "arch/amd64-linux-tdesc.h" +#endif +#include "arch/i386.h" +#include "arch/i386-linux-tdesc.h" + +#include "nat/x86-linux.h" +#include "nat/gdb_ptrace.h" +#include "nat/x86-xstate.h" +#include "gdbsupport/x86-xstate.h" + +#ifndef __x86_64__ +#include +#include "nat/i386-linux.h" +#endif + +#include +#include + +#ifndef IN_PROCESS_AGENT + +/* See nat/x86-linux-tdesc.h. */ + +const target_desc * +x86_linux_tdesc_for_tid (int tid, const char *error_msg, + uint64_t *xcr0_storage, + x86_xsave_layout *xsave_layout_storage) +{ +#ifdef __x86_64__ + + x86_linux_arch_size arch_size = x86_linux_ptrace_get_arch_size (tid); + bool is_64bit = arch_size.is_64bit (); + bool is_x32 = arch_size.is_x32 (); + + if (sizeof (void *) == 4 && is_64bit && !is_x32) + error ("%s", error_msg); + +#elif HAVE_PTRACE_GETFPXREGS + if (have_ptrace_getfpxregs == TRIBOOL_UNKNOWN) + { + elf_fpxregset_t fpxregs; + + if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) + { + have_ptrace_getfpxregs = TRIBOOL_FALSE; + have_ptrace_getregset = TRIBOOL_FALSE; + } + else + have_ptrace_getfpxregs = TRIBOOL_TRUE; + } + + if (have_ptrace_getfpxregs == TRIBOOL_FALSE) + return i386_linux_read_description (X86_XSTATE_X87_MASK); +#endif + + if (have_ptrace_getregset == TRIBOOL_UNKNOWN) + { + uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))]; + struct iovec iov; + + iov.iov_base = xstateregs; + iov.iov_len = sizeof (xstateregs); + + /* Check if PTRACE_GETREGSET works. */ + if (ptrace (PTRACE_GETREGSET, tid, + (unsigned int) NT_X86_XSTATE, &iov) < 0) + { + have_ptrace_getregset = TRIBOOL_FALSE; + *xcr0_storage = 0; + } + else + { + have_ptrace_getregset = TRIBOOL_TRUE; + + /* Get XCR0 from XSAVE extended state. */ + *xcr0_storage = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET + / sizeof (uint64_t))]; + +#ifdef __x86_64__ + /* No MPX on x32. */ + if (is_64bit && is_x32) + *xcr0_storage &= ~X86_XSTATE_MPX; +#endif /* __x86_64__ */ + + *xsave_layout_storage + = x86_fetch_xsave_layout (*xcr0_storage, x86_xsave_length ()); + } + } + + /* Check the native XCR0 only if PTRACE_GETREGSET is available. If + PTRACE_GETREGSET is not available then set xcr0_features_bits to + zero so that the "no-features" descriptions are returned by the + code below. */ + uint64_t xcr0_features_bits; + if (have_ptrace_getregset == TRIBOOL_TRUE) + xcr0_features_bits = *xcr0_storage & X86_XSTATE_ALL_MASK; + else + xcr0_features_bits = 0; + +#ifdef __x86_64__ + if (is_64bit) + return amd64_linux_read_description (xcr0_features_bits, is_x32); + else +#endif + return i386_linux_read_description (xcr0_features_bits); +} + +#endif /* !IN_PROCESS_AGENT */ diff --git a/gdb/nat/x86-linux-tdesc.h b/gdb/nat/x86-linux-tdesc.h new file mode 100644 index 00000000000..4035c49fc06 --- /dev/null +++ b/gdb/nat/x86-linux-tdesc.h @@ -0,0 +1,54 @@ +/* Target description related code for GNU/Linux x86 (i386 and x86-64). + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#ifndef NAT_X86_LINUX_TDESC_H +#define NAT_X86_LINUX_TDESC_H + +#include "gdbsupport/function-view.h" + +struct target_desc; +struct x86_xsave_layout; + +/* Return the target description for Linux thread TID. + + The storage pointed to by XCR0_STORAGE AND XSAVE_LAYOUT_STORAGE must + exist until the program (GDB or gdbserver) terminates, this storage is + used to cache the xcr0 and xsave layout values. The values pointed to + by these arguments are only updated at most once, the first time this + function is called. + + This function returns a target description based on the extracted xcr0 + value along with other characteristics of the thread identified by TID. + + This function can return nullptr if we encounter a machine configuration + for which a target_desc cannot be created. Ideally this would not be + the case, we should be able to create a target description for every + possible machine configuration. See amd64_linux_read_description and + i386_linux_read_description for cases when nullptr might be + returned. + + ERROR_MSG is using in an error() call if we try to create a target + description for a 64-bit process but this is a 32-bit build of GDB. */ + +extern const target_desc * +x86_linux_tdesc_for_tid (int tid, const char *error_msg, + uint64_t *xcr0_storage, + x86_xsave_layout *xsave_layout_storage); + +#endif /* NAT_X86_LINUX_TDESC_H */ diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index ed76c1760bc..7c97f84ef56 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -41,6 +41,7 @@ #include "nat/x86-linux.h" #include "nat/x86-linux-dregs.h" #include "nat/linux-ptrace.h" +#include "nat/x86-linux-tdesc.h" /* linux_nat_target::low_new_fork implementation. */ @@ -95,93 +96,18 @@ x86_linux_nat_target::post_startup_inferior (ptid_t ptid) const struct target_desc * x86_linux_nat_target::read_description () { - int tid; - int is_64bit = 0; -#ifdef __x86_64__ - int is_x32; -#endif - static uint64_t xcr0; - uint64_t xcr0_features_bits; + static uint64_t xcr0_storage; if (inferior_ptid == null_ptid) return this->beneath ()->read_description (); - tid = inferior_ptid.pid (); - -#ifdef __x86_64__ - - x86_linux_arch_size arch_size = x86_linux_ptrace_get_arch_size (tid); - is_64bit = arch_size.is_64bit (); - is_x32 = arch_size.is_x32 (); - - if (sizeof (void *) == 4 && is_64bit && !is_x32) - error (_("Can't debug 64-bit process with 32-bit GDB")); - -#elif HAVE_PTRACE_GETFPXREGS - if (have_ptrace_getfpxregs == TRIBOOL_UNKNOWN) - { - elf_fpxregset_t fpxregs; - - if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) - { - have_ptrace_getfpxregs = TRIBOOL_FALSE; - have_ptrace_getregset = TRIBOOL_FALSE; - return i386_linux_read_description (X86_XSTATE_X87_MASK); - } - } -#endif - - if (have_ptrace_getregset == TRIBOOL_UNKNOWN) - { - uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))]; - struct iovec iov; - - iov.iov_base = xstateregs; - iov.iov_len = sizeof (xstateregs); - - /* Check if PTRACE_GETREGSET works. */ - if (ptrace (PTRACE_GETREGSET, tid, - (unsigned int) NT_X86_XSTATE, &iov) < 0) - have_ptrace_getregset = TRIBOOL_FALSE; - else - { - have_ptrace_getregset = TRIBOOL_TRUE; - - /* Get XCR0 from XSAVE extended state. */ - xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET - / sizeof (uint64_t))]; - - m_xsave_layout = x86_fetch_xsave_layout (xcr0, x86_xsave_length ()); - } - } - - /* Check the native XCR0 only if PTRACE_GETREGSET is available. If - PTRACE_GETREGSET is not available then set xcr0_features_bits to - zero so that the "no-features" descriptions are returned by the - switches below. */ - if (have_ptrace_getregset == TRIBOOL_TRUE) - xcr0_features_bits = xcr0 & X86_XSTATE_ALL_MASK; - else - xcr0_features_bits = 0; + int tid = inferior_ptid.pid (); - if (is_64bit) - { -#ifdef __x86_64__ - return amd64_linux_read_description (xcr0_features_bits, is_x32); -#endif - } - else - { - const struct target_desc * tdesc - = i386_linux_read_description (xcr0_features_bits); - - if (tdesc == NULL) - tdesc = i386_linux_read_description (X86_XSTATE_SSE_MASK); - - return tdesc; - } + const char *error_msg + = _("Can't debug 64-bit process with 32-bit GDB"); - gdb_assert_not_reached ("failed to return tdesc"); + return x86_linux_tdesc_for_tid (tid, error_msg, &xcr0_storage, + &this->m_xsave_layout); } diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 8e882d2159b..538845b96d5 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -110,6 +110,7 @@ case "${gdbserver_host}" in srv_tgtobj="${srv_tgtobj} nat/x86-linux.o" srv_tgtobj="${srv_tgtobj} nat/x86-linux-dregs.o" srv_tgtobj="${srv_tgtobj} nat/i386-linux.o" + srv_tgtobj="${srv_tgtobj} nat/x86-linux-tdesc.o" srv_linux_usrregs=yes srv_linux_regsets=yes srv_linux_thread_db=yes @@ -372,6 +373,7 @@ case "${gdbserver_host}" in srv_tgtobj="${srv_tgtobj} nat/linux-btrace.o" srv_tgtobj="${srv_tgtobj} nat/x86-linux.o" srv_tgtobj="${srv_tgtobj} nat/x86-linux-dregs.o" + srv_tgtobj="${srv_tgtobj} nat/x86-linux-tdesc.o" srv_tgtobj="${srv_tgtobj} nat/amd64-linux-siginfo.o" srv_linux_usrregs=yes # This is for i386 progs. srv_linux_regsets=yes diff --git a/gdbserver/i387-fp.cc b/gdbserver/i387-fp.cc index 62cafd87204..4d8bcb5edfa 100644 --- a/gdbserver/i387-fp.cc +++ b/gdbserver/i387-fp.cc @@ -21,7 +21,7 @@ #include "nat/x86-xstate.h" /* Default to SSE. */ -static unsigned long long x86_xcr0 = X86_XSTATE_SSE_MASK; +static uint64_t x86_xcr0 = X86_XSTATE_SSE_MASK; static const int num_mpx_bnd_registers = 4; static const int num_mpx_cfg_registers = 2; @@ -944,9 +944,8 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) /* See i387-fp.h. */ -void -i387_set_xsave_mask (uint64_t xcr0, int len) +std::pair +i387_get_xsave_storage () { - x86_xcr0 = xcr0; - xsave_layout = x86_fetch_xsave_layout (xcr0, len); + return { &x86_xcr0, &xsave_layout }; } diff --git a/gdbserver/i387-fp.h b/gdbserver/i387-fp.h index 450466efb75..4ee21da8461 100644 --- a/gdbserver/i387-fp.h +++ b/gdbserver/i387-fp.h @@ -19,6 +19,8 @@ #ifndef GDBSERVER_I387_FP_H #define GDBSERVER_I387_FP_H +struct x86_xsave_layout; + void i387_cache_to_fsave (struct regcache *regcache, void *buf); void i387_fsave_to_cache (struct regcache *regcache, const void *buf); @@ -30,6 +32,6 @@ void i387_xsave_to_cache (struct regcache *regcache, const void *buf); /* Set the XSAVE mask and fetch the XSAVE layout via CPUID. */ -void i387_set_xsave_mask (uint64_t xcr0, int len); +std::pair i387_get_xsave_storage (); #endif /* GDBSERVER_I387_FP_H */ diff --git a/gdbserver/linux-amd64-ipa.cc b/gdbserver/linux-amd64-ipa.cc index a6346750f49..df5e6aca081 100644 --- a/gdbserver/linux-amd64-ipa.cc +++ b/gdbserver/linux-amd64-ipa.cc @@ -22,6 +22,7 @@ #include "tracepoint.h" #include "linux-x86-tdesc.h" #include "gdbsupport/x86-xstate.h" +#include "arch/amd64-linux-tdesc.h" /* fast tracepoints collect registers. */ diff --git a/gdbserver/linux-i386-ipa.cc b/gdbserver/linux-i386-ipa.cc index 8f14e0937d4..aa346fc9bc3 100644 --- a/gdbserver/linux-i386-ipa.cc +++ b/gdbserver/linux-i386-ipa.cc @@ -22,6 +22,7 @@ #include "tracepoint.h" #include "linux-x86-tdesc.h" #include "gdbsupport/x86-xstate.h" +#include "arch/i386-linux-tdesc.h" /* GDB register numbers. */ diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc index 2d99a82f566..1c3d55f17fc 100644 --- a/gdbserver/linux-x86-low.cc +++ b/gdbserver/linux-x86-low.cc @@ -29,10 +29,13 @@ #ifdef __x86_64__ #include "nat/amd64-linux-siginfo.h" +#include "arch/amd64-linux-tdesc.h" #else #include "nat/i386-linux.h" #endif +#include "arch/i386-linux-tdesc.h" + #include "gdb_proc_service.h" /* Don't include elf/common.h if linux/elf.h got included by gdb_proc_service.h. */ @@ -48,6 +51,7 @@ #include "nat/x86-linux.h" #include "nat/x86-linux-dregs.h" #include "linux-x86-tdesc.h" +#include "nat/x86-linux-tdesc.h" #ifdef __x86_64__ static target_desc_up tdesc_amd64_linux_no_xml; @@ -836,29 +840,12 @@ static int use_xml; /* Get Linux/x86 target description from running target. */ static const struct target_desc * -x86_linux_read_description (void) +x86_linux_read_description () { - unsigned int machine; - int is_elf64; - int xcr0_features; - int tid; - static uint64_t xcr0; - static int xsave_len; - struct regset_info *regset; - - tid = lwpid_of (current_thread); + int tid = lwpid_of (current_thread); - is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine); - - if (sizeof (void *) == 4) - { - if (is_elf64 > 0) - error (_("Can't debug 64-bit process with 32-bit GDBserver")); -#ifndef __x86_64__ - else if (machine == EM_X86_64) - error (_("Can't debug x86-64 process with 32-bit GDBserver")); -#endif - } + const char *error_msg + = _("Can't debug 64-bit process with 32-bit GDBserver"); /* If we are not allowed to send an XML target description then we need to use the hard-wired target descriptions. This corresponds to GDB's @@ -868,103 +855,53 @@ x86_linux_read_description (void) generate some alternative target descriptions. */ if (!use_xml) { + x86_linux_arch_size arch_size = x86_linux_ptrace_get_arch_size (tid); + bool is_64bit = arch_size.is_64bit (); + bool is_x32 = arch_size.is_x32 (); + + if (sizeof (void *) == 4 && is_64bit && !is_x32) + error ("%s", error_msg); + #ifdef __x86_64__ - if (machine == EM_X86_64) + if (is_64bit && !is_x32) return tdesc_amd64_linux_no_xml.get (); else #endif return tdesc_i386_linux_no_xml.get (); } -#if !defined __x86_64__ && defined HAVE_PTRACE_GETFPXREGS - if (machine == EM_386 && have_ptrace_getfpxregs == TRIBOOL_UNKNOWN) - { - elf_fpxregset_t fpxregs; - - if (ptrace (PTRACE_GETFPXREGS, tid, 0, (long) &fpxregs) < 0) - { - have_ptrace_getfpxregs = TRIBOOL_FALSE; - have_ptrace_getregset = TRIBOOL_FALSE; - return i386_linux_read_description (X86_XSTATE_X87); - } - else - have_ptrace_getfpxregs = TRIBOOL_TRUE; - } -#endif - - if (have_ptrace_getregset == TRIBOOL_UNKNOWN) - { - uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))]; - struct iovec iov; - - iov.iov_base = xstateregs; - iov.iov_len = sizeof (xstateregs); - - /* Check if PTRACE_GETREGSET works. */ - if (ptrace (PTRACE_GETREGSET, tid, - (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) - have_ptrace_getregset = TRIBOOL_FALSE; - else - { - have_ptrace_getregset = TRIBOOL_TRUE; - - /* Get XCR0 from XSAVE extended state. */ - xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET - / sizeof (uint64_t))]; - - /* No MPX on x32. */ - if (machine == EM_X86_64 && !is_elf64) - xcr0 &= ~X86_XSTATE_MPX; - - xsave_len = x86_xsave_length (); - - /* Use PTRACE_GETREGSET if it is available. */ - for (regset = x86_regsets; - regset->fill_function != NULL; regset++) - if (regset->get_request == PTRACE_GETREGSET) - regset->size = xsave_len; - else if (regset->type != GENERAL_REGS) - regset->size = 0; - } - } - - /* Check the native XCR0 only if PTRACE_GETREGSET is available. */ - xcr0_features = (have_ptrace_getregset == TRIBOOL_TRUE - && (xcr0 & X86_XSTATE_ALL_MASK)); + /* If have_ptrace_getregset is changed to true by calling + x86_linux_tdesc_for_tid then we will perform some additional + initialisation. */ + bool have_ptrace_getregset_is_unknown + = have_ptrace_getregset == TRIBOOL_UNKNOWN; - if (xcr0_features) - i387_set_xsave_mask (xcr0, xsave_len); + /* Get pointers to where we should store the xcr0 and xsave_layout + values. These will be filled in by x86_linux_tdesc_for_tid the first + time that the function is called. Subsequent calls will not modify + the stored values. */ + std::pair storage + = i387_get_xsave_storage (); - if (machine == EM_X86_64) - { -#ifdef __x86_64__ - const target_desc *tdesc = NULL; + const target_desc *tdesc + = x86_linux_tdesc_for_tid (tid, error_msg, storage.first, storage.second); - if (xcr0_features) - { - tdesc = amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK, - !is_elf64); - } - - if (tdesc == NULL) - tdesc = amd64_linux_read_description (X86_XSTATE_SSE_MASK, !is_elf64); - return tdesc; -#endif - } - else + if (have_ptrace_getregset_is_unknown + && have_ptrace_getregset == TRIBOOL_TRUE) { - const target_desc *tdesc = NULL; - - if (xcr0_features) - tdesc = i386_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK); - - if (tdesc == NULL) - tdesc = i386_linux_read_description (X86_XSTATE_SSE); - - return tdesc; + int xsave_len = x86_xsave_length (); + + /* Use PTRACE_GETREGSET if it is available. */ + for (regset_info *regset = x86_regsets; + regset->fill_function != nullptr; + regset++) + if (regset->get_request == PTRACE_GETREGSET) + regset->size = xsave_len; + else if (regset->type != GENERAL_REGS) + regset->size = 0; } - gdb_assert_not_reached ("failed to return tdesc"); + return tdesc; } /* Update all the target description of all processes; a new GDB diff --git a/gdbserver/linux-x86-tdesc.cc b/gdbserver/linux-x86-tdesc.cc index cd3b5d80e37..af3735aa895 100644 --- a/gdbserver/linux-x86-tdesc.cc +++ b/gdbserver/linux-x86-tdesc.cc @@ -23,8 +23,10 @@ #include "gdbsupport/x86-xstate.h" #ifdef __x86_64__ #include "arch/amd64.h" +#include "arch/amd64-linux-tdesc.h" #endif #include "x86-tdesc.h" +#include "arch/i386-linux-tdesc.h" /* Return the right x86_linux_tdesc index for a given XCR0. Return X86_TDESC_LAST if can't find a match. */ diff --git a/gdbserver/linux-x86-tdesc.h b/gdbserver/linux-x86-tdesc.h index f9561b129ae..576aaf5e165 100644 --- a/gdbserver/linux-x86-tdesc.h +++ b/gdbserver/linux-x86-tdesc.h @@ -46,11 +46,4 @@ int amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc); const struct target_desc *i386_get_ipa_tdesc (int idx); -#ifdef __x86_64__ -const struct target_desc *amd64_linux_read_description (uint64_t xcr0, - bool is_x32); -#endif - -const struct target_desc *i386_linux_read_description (uint64_t xcr0); - #endif /* GDBSERVER_LINUX_X86_TDESC_H */ From patchwork Sat May 11 10:08:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89953 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 316D838708F9 for ; Sat, 11 May 2024 10:11:07 +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 ESMTPS id DAA9938708B0 for ; Sat, 11 May 2024 10:10:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DAA9938708B0 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 DAA9938708B0 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=1715422234; cv=none; b=PGUAPcTXctl5ogmcfI9ez+THMwAga2hpoDcIYnX0F38z4FEhWB65FFVhGztbAMPckWeN7Ud14eoLKaDAipsX/Zp1fGRsmQOEvCNYPhgvLCVWG4zn5yXOjeHXJxv/Lsr1E1F96s1VgSz+Tp469c5EO9pLNbPidvX/F1x8JpDE368= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422234; c=relaxed/simple; bh=4CCOSetN07PDPYGjQJU6kQ3AfW66IsEwlUNWqiiguIw=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=dMajSwFOPEQ3ZTcK3+2g0aHeBXaawtvraQvKtfU29/Jg6wPKYXo/bm7xsMxDKKLOvMZpTCXJ9xUaxcmPySeechAsuhyKd0vpIcHsqiIn1fzmL4uE4yzz6ipL5KoJDk3d5kOCCOhowVzbkqcv2T+mSifox0aOS69GLPRcwaenZ50= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422230; 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=phQKwgKT2apwS7P2L6NLSOA+puX8pntsRAEmR8Ke5do=; b=hEfNl8qoxkNRhoj4cS0SNesZTtI9Ye1orw0Sjt/rL+BRkMEm1JWPzLRrSd4yDJj78ln2u8 ACK9fTjlgKbjCqKJoHLw+o2MgoZRy4vIo3k9lyVdSCg9G2SU493+xsaTqPYGOtVgwesqlB HKxJt6NvHA25xsNfwOW9+adrAcyp2Cg= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-139-PIEVWVctNyaNr2T-2wu5_A-1; Sat, 11 May 2024 06:09:08 -0400 X-MC-Unique: PIEVWVctNyaNr2T-2wu5_A-1 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-4200efb9ac6so3370465e9.2 for ; Sat, 11 May 2024 03:09:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422146; x=1716026946; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=phQKwgKT2apwS7P2L6NLSOA+puX8pntsRAEmR8Ke5do=; b=jcclC0XAyvB5oywHtW+I7Hs3LXnlu3J09APNnkeFK7a5pCD/tWplzvsKCfHBZSe9VH ycvocNX4mezHOvZPEp9++kXW4zY3rK+Bl3NhI1zhSisUZYGbIqHtVXj7a80aqQsbJR3C nH4ci18dj2hDf1dO8oyBDp3aHnlgTMFFWiYYkaKnuYyqwADITfIQKGGUyhbQ8ZIFgUIA VRhXGndy9gQ7CwxnTWBIvnHuPui0pKG2h7M9mZtO5basc66bYjKsIx44ZmSpORQO8rRe cxeEmk+mPZnPkVq1nvOxb4qU2I+bqHQk4yvZcFtj4r59EOretMg+I8FV58dQJiExuaiX BrVg== X-Gm-Message-State: AOJu0YwURV0xypokQ4NybENAXUSTXms5NDyQQHJISCb2kCLQU8UhcfAq Ld/8BcXnw/xSN+PfKGToKiRs+R7V/xqUh2j23qTcujgCXgzT41XL6o+TXSOuYuvblP/6bPrnUrK bjSUkjw86LfI/Y5FkM6mj+WqlG3oACVn/m7h3XVtvO3Aio6zLDo6ritqkpjekvLDZdFooRAWr8h LkhCX/aq19chWM4UIW6ayLW91SOsyxMi1+MnzD0iEdZ2g= X-Received: by 2002:a05:600c:1d83:b0:420:1157:95b4 with SMTP id 5b1f17b1804b1-4201157977dmr3076205e9.12.1715422145823; Sat, 11 May 2024 03:09:05 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGlRk6sc3gEMIAmte1jFjIqc7YG6QjIEJnF1efcPveKIY0je+AIj5X8+kMObLuGUm8c+sfovg== X-Received: by 2002:a05:600c:1d83:b0:420:1157:95b4 with SMTP id 5b1f17b1804b1-4201157977dmr3075985e9.12.1715422145048; Sat, 11 May 2024 03:09:05 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-41fccce25casm94063865e9.20.2024.05.11.03.09.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:09:04 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 8/9] gdbserver: update target description creation for x86/linux Date: Sat, 11 May 2024 11:08:38 +0100 Message-Id: <40f37b5589e9e440d9bf8fdf51f65fde653e55d3.1715421687.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 is part of a series which aims to share more of the target description creation between GDB and gdbserver for x86/Linux. After some refactoring earlier in this series the shared x86_linux_tdesc_for_tid function was added into nat/x86-linux-tdesc.c. However, this function still relies on amd64_linux_read_description and i386_linux_read_description which are implemented separately for both gdbserver and GDB. Given that at their core, all these functions do is: 1. take an xcr0 value as input, 2. mask out some feature bits, 3. look for a cached pre-generated target description and return it if found, 4. if no cached target description is found then call either amd64_create_target_description or i386_create_target_description to create a new target description, which is then added to the cache. Return the newly created target description. The inner functions amd64_create_target_description and i386_create_target_description are already shared between GDB and gdbserver (in the gdb/arch/ directory), so the only thing that the *_read_description functions really do is add the caching layer, and it feels like this really could be shared. However, we have a small problem. Despite using the same {amd64,i386}_create_target_description functions in both GDB and gdbserver to create the target descriptions, on the gdbserver side we cache target descriptions based on a reduced set of xcr0 feature bits. What this means is that, in theory, different xcr0 values can map to the same cache entry, which could result in the wrong target description being used. However, I'm not sure if this can actually happen in reality. Within gdbserver we already split the target description cache based on i386, amd64, and x32. I suspect within a given gdbserver session we'll only see at most one target description for each of these. The cache conflicting problem is caused by xcr0_to_tdesc_idx, which maps an xcr0 value to a enum x86_linux_tdesc value, and there are only 7 usable values in enum x86_linux_tdesc. In contrast, on the GDB side there are 64, 32, and 16 cache slots for i386, amd64, and x32 respectively. On the GDB side it is much more important to cache things correctly as a single GDB session might connect to multiple different remote targets, each of which might have slightly different x86 architectures. And so, if we want to merge the target description caching between GDB and gdbserver, then we need to first update gdbserver so that it caches in the same way as GDB, that is, it needs to adopt a mechanism that allows for the same number of cache slots of each of i386, amd64, and x32. In this way, when the caching is shared, GDB's behaviour will not change. Unfortunately it's a little more complex than that due to the in process agent (IPA). When the IPA is in use, gdbserver sends a target description index to the IPA, and the IPA uses this to find the correct target description to use, the IPA having first generated every possible target description. Interestingly, there is certainly a bug here which results from only having 7 values in enum x86_linux_tdesc. As multiple possible target descriptions in gdbserver map to the same enum x86_linux_tdesc value, then, when the enum x86_linux_tdesc value is sent to the IPA there is no way for gdbserver to know that the IPA will select the correct target description. This bug will get fixed by this commit. ** START OF AN ASIDE ** Back in the day I suspect this approach of sending a target description index made perfect sense. However since this commit: commit a8806230241d201f808d856eaae4d44088117b0c Date: Thu Dec 7 17:07:01 2017 +0000 Initialize target description early in IPA I think that passing an index was probably a bad idea. We used to pass the index, and then use that index to lookup which target description to instantiate and use, the target description was not generated until the index arrived. However, the above commit fixed an issue where we can't call malloc() within (certain parts of) the IPA (apparently), so instead we now pre-compute _every_ possible target description within the IPA. The index is only used to lookup which of the (many) pre-computed target descriptions to use. It would (I think) have been easier all around if the IPA just self-inspected, figured out its own xcr0 value, and used that to create the one target description that is required. So long as the xcr0 to target description code is shared (at compile time) with gdbserver, then we can be sure that the IPA will derive the same target description as gdbserver, and we would avoid all this index passing business, which has made this commit so very, very painful. I did look at how a process might derive its own xcr0 value, but I don't believe this is actually that simple, so for now I've just doubled down on the index passing approach. While reviewing earlier iterations of this patch there has been discussion about the possibility of removing the IPA from GDB. That would certainly make all of the code touched in this patch much simpler, but I don't really want to do that as part of this series. ** END OF AN ASIDE ** Currently then for x86/linux, gdbserver sends a number between 0 and 7 to the IPA, and the IPA uses this to create a target description. However, I am proposing that gdbserver should now create one of (up to) 64 different target descriptions for i386, so this 0 to 7 index isn't going to be good enough any more (amd64 and x32 have slightly fewer possible target descriptions, but still more than 8, so the problem is the same). For a while I wondered if I was going to have to try and find some backward compatible solution for this mess. But after seeing how lightly the IPA is actually documented, I wonder if it is not the case that there is a tight coupling between a version of gdbserver and a version of the IPA? At least I'm hoping so, and that's what I've assumed in this commit. In this commit I have thrown out the old IPA target description index numbering scheme, and switched to a completely new numbering scheme. Instead of the index that is passed being arbitrary, the index is instead calculated from the set of xcr0 features that are present on the target. Within the IPA we can then reverse this logic to recreate the xcr0 value based on the index, and from the xcr0 value we can choose the correct target description. With the gdbserver to IPA numbering scheme issue resolved I have then update the gdbserver versions of amd64_linux_read_description and i386_linux_read_description so that they cache target descriptions using the same set of xcr0 features as GDB itself. After this gdbserver should now always come up with the same target description as GDB does on any x86/Linux target. This commit does not introduce any new code sharing between GDB and gdbserver as previous commits in this series have done. Instead this commit is all about bringing GDB and gdbserver into alignment functionally so that the next commit(s) can merge the GDB and gdbserver versions of these functions. Notes On The Implementation --------------------------- Previously, within gdbserver, target descriptions were cached within arrays. These arrays were sized based on enum x86_linux_tdesc and xcr0_to_tdesc_idx returned the array (cache) index. Now we need different array lengths for each of i386, amd64, and x32. And the index to use within each array is calculated based on which xcr0 bits are set and valid for a particular target type. I really wanted to avoid having fixed array sizes, or having the set of relevant xcr0 bits encoded in multiple places. The solution I came up with was to create a single data structure which would contain a list of xcr0 bits along with flags to indicate which of the i386, amd64, and x32 targets the bit is relevant for. By making the table constexpr, and adding some constexpr helper functions, it is possible to calculate the sizes for the cache arrays at compile time, as well as the bit masks needed to each target type. During review it was pointed out[1] that possibly the failure to check the SSE and X87 bits for amd64/x32 targets might be an error, however, if this is the case then this is an issue that existed long before this patch. I'd really like to keep this patch focused on reworking the existing code and try to avoid changing how target descriptions are actually created, mostly out of fear that I'll break something. [1] https://inbox.sourceware.org/gdb-patches/MN2PR11MB4566070607318EE7E669A5E28E1B2@MN2PR11MB4566.namprd11.prod.outlook.com Approved-By: John Baldwin --- gdbserver/linux-amd64-ipa.cc | 43 +---- gdbserver/linux-i386-ipa.cc | 23 +-- gdbserver/linux-x86-low.cc | 24 ++- gdbserver/linux-x86-tdesc.cc | 335 ++++++++++++++++++++++++++--------- gdbserver/linux-x86-tdesc.h | 48 ++--- 5 files changed, 306 insertions(+), 167 deletions(-) diff --git a/gdbserver/linux-amd64-ipa.cc b/gdbserver/linux-amd64-ipa.cc index df5e6aca081..0c80812cc6f 100644 --- a/gdbserver/linux-amd64-ipa.cc +++ b/gdbserver/linux-amd64-ipa.cc @@ -164,47 +164,21 @@ supply_static_tracepoint_registers (struct regcache *regcache, #endif /* HAVE_UST */ -#if !defined __ILP32__ -/* Map the tdesc index to xcr0 mask. */ -static uint64_t idx2mask[X86_TDESC_LAST] = { - X86_XSTATE_X87_MASK, - X86_XSTATE_SSE_MASK, - X86_XSTATE_AVX_MASK, - X86_XSTATE_MPX_MASK, - X86_XSTATE_AVX_MPX_MASK, - X86_XSTATE_AVX_AVX512_MASK, - X86_XSTATE_AVX_MPX_AVX512_PKU_MASK, -}; -#endif - /* Return target_desc to use for IPA, given the tdesc index passed by gdbserver. */ const struct target_desc * get_ipa_tdesc (int idx) { - if (idx >= X86_TDESC_LAST) - { - internal_error ("unknown ipa tdesc index: %d", idx); - } + uint64_t xcr0 = x86_linux_tdesc_idx_to_xcr0 (idx); #if defined __ILP32__ - switch (idx) - { - case X86_TDESC_SSE: - return amd64_linux_read_description (X86_XSTATE_SSE_MASK, true); - case X86_TDESC_AVX: - return amd64_linux_read_description (X86_XSTATE_AVX_MASK, true); - case X86_TDESC_AVX_AVX512: - return amd64_linux_read_description (X86_XSTATE_AVX_AVX512_MASK, true); - default: - break; - } + bool is_x32 = true; #else - return amd64_linux_read_description (idx2mask[idx], false); + bool is_x32 = false; #endif - internal_error ("unknown ipa tdesc index: %d", idx); + return amd64_linux_read_description (xcr0, is_x32); } /* Allocate buffer for the jump pads. The branch instruction has a @@ -272,11 +246,10 @@ void initialize_low_tracepoint (void) { #if defined __ILP32__ - amd64_linux_read_description (X86_XSTATE_SSE_MASK, true); - amd64_linux_read_description (X86_XSTATE_AVX_MASK, true); - amd64_linux_read_description (X86_XSTATE_AVX_AVX512_MASK, true); + for (auto i = 0; i < x86_linux_x32_tdesc_count (); i++) + amd64_linux_read_description (x86_linux_tdesc_idx_to_xcr0 (i), true); #else - for (auto i = 0; i < X86_TDESC_LAST; i++) - amd64_linux_read_description (idx2mask[i], false); + for (auto i = 0; i < x86_linux_amd64_tdesc_count (); i++) + amd64_linux_read_description (x86_linux_tdesc_idx_to_xcr0 (i), false); #endif } diff --git a/gdbserver/linux-i386-ipa.cc b/gdbserver/linux-i386-ipa.cc index aa346fc9bc3..c1c3152fb04 100644 --- a/gdbserver/linux-i386-ipa.cc +++ b/gdbserver/linux-i386-ipa.cc @@ -245,28 +245,15 @@ initialize_fast_tracepoint_trampoline_buffer (void) } } -/* Map the tdesc index to xcr0 mask. */ -static uint64_t idx2mask[X86_TDESC_LAST] = { - X86_XSTATE_X87_MASK, - X86_XSTATE_SSE_MASK, - X86_XSTATE_AVX_MASK, - X86_XSTATE_MPX_MASK, - X86_XSTATE_AVX_MPX_MASK, - X86_XSTATE_AVX_AVX512_MASK, - X86_XSTATE_AVX_MPX_AVX512_PKU_MASK, -}; - /* Return target_desc to use for IPA, given the tdesc index passed by gdbserver. */ const struct target_desc * get_ipa_tdesc (int idx) { - if (idx >= X86_TDESC_LAST) - { - internal_error ("unknown ipa tdesc index: %d", idx); - } - return i386_linux_read_description (idx2mask[idx]); + uint64_t xcr0 = x86_linux_tdesc_idx_to_xcr0 (idx); + + return i386_linux_read_description (xcr0); } /* Allocate buffer for the jump pads. On i386, we can reach an arbitrary @@ -288,6 +275,6 @@ void initialize_low_tracepoint (void) { initialize_fast_tracepoint_trampoline_buffer (); - for (auto i = 0; i < X86_TDESC_LAST; i++) - i386_linux_read_description (idx2mask[i]); + for (auto i = 0; i < x86_linux_i386_tdesc_count (); i++) + i386_linux_read_description (x86_linux_tdesc_idx_to_xcr0 (i)); } diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc index 1c3d55f17fc..ab225c57fa2 100644 --- a/gdbserver/linux-x86-low.cc +++ b/gdbserver/linux-x86-low.cc @@ -2878,14 +2878,28 @@ x86_target::get_ipa_tdesc_idx () struct regcache *regcache = get_thread_regcache (current_thread, 0); const struct target_desc *tdesc = regcache->tdesc; + if (!use_xml) + { + /* If USE_XML is false then we should be using one of these target + descriptions, see x86_linux_read_description for where we choose + one of these. Both of these descriptions are created from this + fixed xcr0 value X86_XSTATE_SSE_MASK. */ + gdb_assert (tdesc == tdesc_i386_linux_no_xml.get () #ifdef __x86_64__ - return amd64_get_ipa_tdesc_idx (tdesc); -#endif + || tdesc == tdesc_amd64_linux_no_xml.get () +#endif /* __x86_64__ */ + ); + return x86_linux_xcr0_to_tdesc_idx (X86_XSTATE_SSE_MASK); + } - if (tdesc == tdesc_i386_linux_no_xml.get ()) - return X86_TDESC_SSE; + /* The xcr0 value and xsave layout value are cached when the target + description is read. Grab their cache location, and use the cached + value to calculate a tdesc index. */ + std::pair storage + = i387_get_xsave_storage (); + uint64_t xcr0 = *storage.first; - return i386_get_ipa_tdesc_idx (tdesc); + return x86_linux_xcr0_to_tdesc_idx (xcr0); } /* The linux target ops object. */ diff --git a/gdbserver/linux-x86-tdesc.cc b/gdbserver/linux-x86-tdesc.cc index af3735aa895..f5636898d71 100644 --- a/gdbserver/linux-x86-tdesc.cc +++ b/gdbserver/linux-x86-tdesc.cc @@ -28,96 +28,297 @@ #include "x86-tdesc.h" #include "arch/i386-linux-tdesc.h" -/* Return the right x86_linux_tdesc index for a given XCR0. Return - X86_TDESC_LAST if can't find a match. */ +/* A structure used to describe a single xstate feature bit that might, or + might not, be checked for when creating a target description for one of + i386, amd64, or x32. -static enum x86_linux_tdesc -xcr0_to_tdesc_idx (uint64_t xcr0, bool is_x32) + The different CPU/ABI types check for different xstate features when + creating a target description. + + We want to cache target descriptions, and this is currently done in + three separate caches, one each for i386, amd64, and x32. Additionally, + the caching we're discussing here is Linux only, and for Linux, the only + thing that has an impact on target description creation is the xcr0 + value. + + In order to ensure the cache functions correctly we need to filter out + only those xcr0 feature bits that are relevant, we can then cache target + descriptions based on the relevant feature bits. Two xcr0 values might + be different, but have the same relevant feature bits. In this case we + would expect the two xcr0 values to map to the same cache entry. */ + +struct x86_xstate_feature { + /* The xstate feature mask. This is a mask against an xcr0 value. */ + uint64_t feature; + + /* Is this feature checked when creating an i386 target description. */ + bool is_i386; + + /* Is this feature checked when creating an amd64 target description. */ + bool is_amd64; + + /* Is this feature checked when creating an x32 target description. */ + bool is_x32; +}; + +/* A constant table that describes all of the xstate features that are + checked when building a target description for i386, amd64, or x32. + + If in the future, due to simplifications or refactoring, this table ever + ends up with 'true' for every xcr0 feature on every target type, then this + is an indication that this table should probably be removed, and that the + rest of the code in this file can be simplified. */ + +static constexpr x86_xstate_feature x86_linux_all_xstate_features[] = { + /* Feature, i386, amd64, x32. */ + { X86_XSTATE_PKRU, true, true, true }, + { X86_XSTATE_AVX512, true, true, true }, + { X86_XSTATE_AVX, true, true, true }, + { X86_XSTATE_MPX, true, true, false }, + { X86_XSTATE_SSE, true, false, false }, + { X86_XSTATE_X87, true, false, false } +}; + +/* Return a compile time constant which is a mask of all the xstate features + that are checked for when building an i386 target description. */ + +static constexpr uint64_t +x86_linux_i386_xcr0_feature_mask () { - if (xcr0 & X86_XSTATE_PKRU) - { - if (is_x32) - { - /* No x32 MPX and PKU, fall back to avx_avx512. */ - return X86_TDESC_AVX_AVX512; - } - else - return X86_TDESC_AVX_MPX_AVX512_PKU; - } - else if (xcr0 & X86_XSTATE_AVX512) - return X86_TDESC_AVX_AVX512; - else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK) + uint64_t mask = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_i386) + mask |= entry.feature; + + return mask; +} + +/* Return a compile time constant which is a mask of all the xstate features + that are checked for when building an amd64 target description. */ + +static constexpr uint64_t +x86_linux_amd64_xcr0_feature_mask () +{ + uint64_t mask = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_amd64) + mask |= entry.feature; + + return mask; +} + +/* Return a compile time constant which is a mask of all the xstate features + that are checked for when building an x32 target description. */ + +static constexpr uint64_t +x86_linux_x32_xcr0_feature_mask () +{ + uint64_t mask = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_x32) + mask |= entry.feature; + + return mask; +} + +/* Return a compile time constant which is a count of the number of xstate + features that are checked for when building an i386 target description. */ + +static constexpr int +x86_linux_i386_tdesc_count_1 () +{ + uint64_t count = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_i386) + ++count; + + gdb_assert (count > 0); + + return (1 << count); +} + +/* Return a compile time constant which is a count of the number of xstate + features that are checked for when building an amd64 target description. */ + +static constexpr int +x86_linux_amd64_tdesc_count_1 () +{ + uint64_t count = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_amd64) + ++count; + + gdb_assert (count > 0); + + return (1 << count); +} + +/* Return a compile time constant which is a count of the number of xstate + features that are checked for when building an x32 target description. */ + +static constexpr int +x86_linux_x32_tdesc_count_1 () +{ + uint64_t count = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_x32) + ++count; + + gdb_assert (count > 0); + + return (1 << count); +} + +#ifdef IN_PROCESS_AGENT + +/* See linux-x86-tdesc.h. */ + +int +x86_linux_amd64_tdesc_count () +{ + return x86_linux_amd64_tdesc_count_1 (); +} + +/* See linux-x86-tdesc.h. */ + +int +x86_linux_x32_tdesc_count () +{ + return x86_linux_x32_tdesc_count_1 (); +} + +/* See linux-x86-tdesc.h. */ + +int +x86_linux_i386_tdesc_count () +{ + return x86_linux_i386_tdesc_count_1 (); +} + +#endif /* IN_PROCESS_AGENT */ + +/* Convert an xcr0 value into an integer. The integer will be passed to + the in-process-agent where it will then be passed to + x86_linux_tdesc_idx_to_xcr0 to get back the xcr0 value. */ + +int +x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0) +{ + /* The following table shows which features are checked for when creating + the target descriptions (see nat/x86-linux-tdesc.c), the feature order + represents the bit order within the generated index number. + + i386 | x87 sse mpx avx avx512 pkru + amd64 | mpx avx avx512 pkru + i32 | avx avx512 pkru + + The features are ordered so that for each mode (i386, amd64, i32) the + generated index will form a continuous range. */ + + int idx = 0; + + for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i) { - if (is_x32) /* No MPX on x32. */ - return X86_TDESC_AVX; - else - return X86_TDESC_AVX_MPX; + if ((xcr0 & x86_linux_all_xstate_features[i].feature) + == x86_linux_all_xstate_features[i].feature) + idx |= (1 << i); } - else if (xcr0 & X86_XSTATE_MPX) + + return idx; +} + +#ifdef IN_PROCESS_AGENT + +/* Convert an index number (as returned from x86_linux_xcr0_to_tdesc_idx) + into an xcr0 value which can then be used to create a target + description. */ + +uint64_t +x86_linux_tdesc_idx_to_xcr0 (int idx) +{ + uint64_t xcr0 = 0; + + for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i) { - if (is_x32) /* No MPX on x32. */ - return X86_TDESC_AVX; - else - return X86_TDESC_MPX; + if ((idx & (1 << i)) != 0) + xcr0 |= x86_linux_all_xstate_features[i].feature; } - else if (xcr0 & X86_XSTATE_AVX) - return X86_TDESC_AVX; - else if (xcr0 & X86_XSTATE_SSE) - return X86_TDESC_SSE; - else if (xcr0 & X86_XSTATE_X87) - return X86_TDESC_MMX; - else - return X86_TDESC_LAST; + + return xcr0; } +#endif /* IN_PROCESS_AGENT */ + #if defined __i386__ || !defined IN_PROCESS_AGENT -static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { }; +/* A cache of all possible i386 target descriptions. */ -/* Return the target description according to XCR0. */ +static struct target_desc *i386_tdescs[x86_linux_i386_tdesc_count_1 ()] = { }; + +/* See nat/x86-linux-tdesc.h. */ const struct target_desc * i386_linux_read_description (uint64_t xcr0) { - enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, false); + xcr0 &= x86_linux_i386_xcr0_feature_mask (); + int idx = x86_linux_xcr0_to_tdesc_idx (xcr0); - if (idx == X86_TDESC_LAST) - return NULL; + gdb_assert (idx >= 0 && idx < x86_linux_i386_tdesc_count_1 ()); - struct target_desc **tdesc = &i386_tdescs[idx]; + target_desc **tdesc = &i386_tdescs[idx]; - if (*tdesc == NULL) + if (*tdesc == nullptr) { *tdesc = i386_create_target_description (xcr0, true, false); init_target_desc (*tdesc, i386_expedite_regs); } - return *tdesc;; + return *tdesc; } #endif #ifdef __x86_64__ -static target_desc *amd64_tdescs[X86_TDESC_LAST] = { }; -static target_desc *x32_tdescs[X86_TDESC_LAST] = { }; +/* A cache of all possible amd64 target descriptions. */ + +static target_desc *amd64_tdescs[x86_linux_amd64_tdesc_count_1 ()] = { }; + +/* A cache of all possible x32 target descriptions. */ + +static target_desc *x32_tdescs[x86_linux_x32_tdesc_count_1 ()] = { }; + +/* See nat/x86-linux-tdesc.h. */ const struct target_desc * amd64_linux_read_description (uint64_t xcr0, bool is_x32) { - enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, is_x32); + if (is_x32) + xcr0 &= x86_linux_x32_xcr0_feature_mask (); + else + xcr0 &= x86_linux_amd64_xcr0_feature_mask (); + + int idx = x86_linux_xcr0_to_tdesc_idx (xcr0); - if (idx == X86_TDESC_LAST) - return NULL; + if (is_x32) + gdb_assert (idx >= 0 && idx < x86_linux_x32_tdesc_count_1 ()); + else + gdb_assert (idx >= 0 && idx < x86_linux_amd64_tdesc_count_1 ()); - struct target_desc **tdesc = NULL; + target_desc **tdesc = nullptr; if (is_x32) tdesc = &x32_tdescs[idx]; else tdesc = &amd64_tdescs[idx]; - if (*tdesc == NULL) + if (*tdesc == nullptr) { *tdesc = amd64_create_target_description (xcr0, is_x32, true, true); @@ -127,39 +328,3 @@ amd64_linux_read_description (uint64_t xcr0, bool is_x32) } #endif - -#ifndef IN_PROCESS_AGENT - -int -i386_get_ipa_tdesc_idx (const struct target_desc *tdesc) -{ - for (int i = 0; i < X86_TDESC_LAST; i++) - { - if (tdesc == i386_tdescs[i]) - return i; - } - - /* If none tdesc is found, return the one with minimum features. */ - return X86_TDESC_MMX; -} - -#if defined __x86_64__ -int -amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc) -{ - for (int i = 0; i < X86_TDESC_LAST; i++) - { - if (tdesc == amd64_tdescs[i]) - return i; - } - for (int i = 0; i < X86_TDESC_LAST; i++) - { - if (tdesc == x32_tdescs[i]) - return i; - } - - return X86_TDESC_SSE; -} - -#endif -#endif diff --git a/gdbserver/linux-x86-tdesc.h b/gdbserver/linux-x86-tdesc.h index 576aaf5e165..c06af21da48 100644 --- a/gdbserver/linux-x86-tdesc.h +++ b/gdbserver/linux-x86-tdesc.h @@ -21,29 +21,29 @@ #ifndef GDBSERVER_LINUX_X86_TDESC_H #define GDBSERVER_LINUX_X86_TDESC_H -/* Note: since IPA obviously knows what ABI it's running on (i386 vs x86_64 - vs x32), it's sufficient to pass only the register set here. This, - together with the ABI known at IPA compile time, maps to a tdesc. */ - -enum x86_linux_tdesc { - X86_TDESC_MMX = 0, - X86_TDESC_SSE = 1, - X86_TDESC_AVX = 2, - X86_TDESC_MPX = 3, - X86_TDESC_AVX_MPX = 4, - X86_TDESC_AVX_AVX512 = 5, - X86_TDESC_AVX_MPX_AVX512_PKU = 6, - X86_TDESC_LAST = 7, -}; - -#if defined __i386__ || !defined IN_PROCESS_AGENT -int i386_get_ipa_tdesc_idx (const struct target_desc *tdesc); -#endif - -#if defined __x86_64__ && !defined IN_PROCESS_AGENT -int amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc); -#endif - -const struct target_desc *i386_get_ipa_tdesc (int idx); +/* Convert an xcr0 value into an integer. The integer will be passed to + the in-process-agent where it will then be passed to + x86_linux_tdesc_idx_to_xcr0 to get back the xcr0 value. */ + +extern int x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0); + +#ifdef IN_PROCESS_AGENT + +/* Convert an index number (as returned from x86_linux_xcr0_to_tdesc_idx) + into an xcr0 value which can then be used to create a target + description. */ + +extern uint64_t x86_linux_tdesc_idx_to_xcr0 (int idx); + +/* Within the in-process-agent we need to pre-initialise all of the target + descriptions, to do this we need to know how many target descriptions + there are for each different target type. These functions return the + target description count for the relevant target. */ + +extern int x86_linux_amd64_tdesc_count (); +extern int x86_linux_x32_tdesc_count (); +extern int x86_linux_i386_tdesc_count (); + +#endif /* IN_PROCESS_AGENT */ #endif /* GDBSERVER_LINUX_X86_TDESC_H */ From patchwork Sat May 11 10:08:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 89955 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 7E70C38708B5 for ; Sat, 11 May 2024 10:12:07 +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.133.124]) by sourceware.org (Postfix) with ESMTPS id 5B58A386F81E for ; Sat, 11 May 2024 10:09:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5B58A386F81E 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 5B58A386F81E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422160; cv=none; b=uL6/olKDbshBV18JEMucLePjubSZEAzJup4NK8Upp6TP4rSWsCgKyB/HY7Zan+n48ozHA3KA3VpfbA5/Doo2/oqiIZUB4+BkN7267S3o8mgKjpOMXX5MzDySngCkdO36+1sR+Ku9w+gjOku96aPURW7umh3uYBgshV9372VaM+o= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715422160; c=relaxed/simple; bh=WmeqZmGDRsCSNTnFbE7XX5HplDA9oNWPRwkmp7AqaL8=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=OxWJhpC6toeqrJhTXe7wUy1zr3mAeby2muuPNcO8Prtn//IUUYh9NUHQviW/3vfKVlqPJ2EvRkcpPRjJho1VB1NF1YcMuP8GmSTgxUfzXCk3+1B8t/f4GceaKsTvKoVngPhPNlfZlLlclUwFAFoJiRuy5ytsiNfFRvb7aFbU+qg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715422154; 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=xjPwqnj2x2/i/eTjkPmtJDpNGOg4wZwqv8SXvoXhDzc=; b=abeYNPmvC12i/NEwwd04ZnqmEqze623kpTQBOhxPoGaPLvBTYflv7dE+GgmP8tFuJKPmM/ mlc4mJDSVFap3yp2ubk1kzDQBYqqNaCN7c5AZ0Bu7FyaPMAsDYHDB29XB4Kz+RXfH/fKwR 7nHy1+pX9i54qR1oRY+KseVTjbrXz9E= Received: from mail-lf1-f70.google.com (mail-lf1-f70.google.com [209.85.167.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-492-nLQMm8W_MNuo1Ua1hKDRmw-1; Sat, 11 May 2024 06:09:12 -0400 X-MC-Unique: nLQMm8W_MNuo1Ua1hKDRmw-1 Received: by mail-lf1-f70.google.com with SMTP id 2adb3069b0e04-51fa975896eso2433507e87.3 for ; Sat, 11 May 2024 03:09:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715422150; x=1716026950; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xjPwqnj2x2/i/eTjkPmtJDpNGOg4wZwqv8SXvoXhDzc=; b=UAP3cTtUgHmcNXTr8h2/+ee4+7BhPUk/unoIDXOp1wFWAcB45moSTCdi+tgaSpzEyi EzyGD6Tp2j5r45kgXL8sdOosmS3/UmUYX1IQh8ju+5+TilEXLmlHBxZzcFnDWhdOP0+J uS/o4kjaCuiJZX7gQWNg4spUyvPykU7vCOX6quSojqk5sIOpuBYCUjqtoBMuEYKez0Xo +ACbvfu9tKXRxsVsiHks9NvXAmRFjm8LEEt8fIRVvFZJPNCpTnKF42JTGP49mj3jwXxT F0a2K5r/06uVMdrmLPKqxzoTbVp2muAhDaxT8YE1Q5pynvG774ujjrx4rCZOq6SRr9IY m60g== X-Gm-Message-State: AOJu0YxG833sVmFML6ComOu6z0YTVvqtPFdGxQpsf2SJKP5bq2PtzTw1 PUUg+g2jnj8LtZ7Ka4aUhgULiSE+f3Gq0qm4oss+o8+nthWvbPwBA9JQzA1EERLrDp+dPvXayba 0Pv5PCAEoxPoYpDxmKM0rgai+v1BVfldF77ab5RWSqmj2b/2mvc+74NPh4sf/bBuKQPXfvtrKfL VUdSwgkTdfQojORK6HzPHlPEN5Ojfl/niqGvABKADtAl0= X-Received: by 2002:ac2:4e14:0:b0:522:4062:6e79 with SMTP id 2adb3069b0e04-52240626f95mr903941e87.31.1715422149548; Sat, 11 May 2024 03:09:09 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHhS1iE9TA0nD9dHljdvuLjiNOS4IDYN/q1pF82HNwbj31RHEnxrM1UvmOMOMD2T1L6GJNSrw== X-Received: by 2002:ac2:4e14:0:b0:522:4062:6e79 with SMTP id 2adb3069b0e04-52240626f95mr903909e87.31.1715422148294; Sat, 11 May 2024 03:09:08 -0700 (PDT) Received: from localhost (92.40.185.101.threembb.co.uk. [92.40.185.101]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3502baacfffsm6605141f8f.75.2024.05.11.03.09.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 May 2024 03:09:06 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , felix.willgerodt@intel.com, jhb@FreeBSD.org Subject: [PATCHv7 9/9] gdb/gdbserver: share x86/linux tdesc caching Date: Sat, 11 May 2024 11:08:39 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-8.6 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_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: 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 builds on the previous series of commits to share the target description caching code between GDB and gdbserver for x86/Linux targets. The objective of this commit is to move the four functions (2 each of) i386_linux_read_description and amd64_linux_read_description into the gdb/arch/ directory and combine them so we have just a single copy of each. Then GDB, gdbserver, and the in-process-agent (IPA) will link against these shared functions. One curiosity with this patch is the function x86_linux_post_init_tdesc. On the gdbserver side the two functions amd64_linux_read_description and i386_linux_read_description have some functionality that is not present on the GDB side, there is some additional configuration that is performed as each target description is created, to setup the expedited registers. To support this I've added the function x86_linux_post_init_tdesc. This function is called from the two *_linux_read_description functions, but is implemented separately for GDB and gdbserver. An alternative approach that avoids adding x86_linux_post_init_tdesc would be to have x86_linux_tdesc_for_tid return a non-const target description, then in x86_target::low_arch_setup we could inspect the target description to figure out if it is 64-bit or not, and modify the target description as needed. In the end I think that adding the x86_linux_post_init_tdesc function is the simpler solution. The contents of gdbserver/linux-x86-low.cc have moved to gdb/arch/x86-linux-tdesc-features.c, and gdbserver/linux-x86-tdesc.h has moved to gdb/arch/x86-linux-tdesc-features.h, this change leads to some updates in the #includes in the gdbserver/ directory. This commit also changes how target descriptions are cached. Previously both GDB and gdbserver used static C-style arrays to act as the tdesc cache. This was fine, except for two problems. Either the C-style arrays would need to be placed in x86-linux-tdesc-features.c, which would allow us to use the x86_linux_*_tdesc_count_1() functions to size the arrays for us, or we'd need to hard code the array sizes using separate #defines, which we'd then have to keep in sync with the rest of the code in x86-linux-tdesc-features.c. Given both of these problems I decided a better solution would be to just switch to using a std::unordered_map to act as the cache. This will resize automatically, and we can use the xcr0 value as the key. At first inspection, using xcr0 might seem to be a problem; after all the {i386,amd64}_create_target_description functions take more than just the xcr0 value. However, this patch is only for x86/Linux targets, and for x86/Linux all of the other flags passed to the tdesc creation functions have constant values and so are irrelevant when we consider tdesc caching. For testing I've done the following: - Built on x86-64 GNU/Linux for all targets, and just for the native target, - Build on i386 GNU/Linux for all targets, and just for the native target, - Build on a 64-bit, non-x86 GNU/Linux for all targets, just for the native target, and for targets x86_64-*-linux and i386-*-linux. --- gdb/Makefile.in | 5 + gdb/amd64-linux-tdep.c | 31 -- gdb/arch/amd64-linux-tdesc.c | 61 ++++ gdb/arch/i386-linux-tdesc.c | 51 +++ gdb/arch/x86-linux-tdesc-features.c | 267 +++++++++++++++ .../arch/x86-linux-tdesc-features.h | 49 ++- gdb/arch/x86-linux-tdesc.h | 37 +++ gdb/configure.nat | 6 +- gdb/configure.tgt | 11 +- gdb/i386-linux-tdep.c | 26 +- gdbserver/configure.srv | 9 + gdbserver/linux-amd64-ipa.cc | 2 +- gdbserver/linux-i386-ipa.cc | 2 +- gdbserver/linux-x86-low.cc | 2 +- gdbserver/linux-x86-tdesc.cc | 311 +----------------- 15 files changed, 489 insertions(+), 381 deletions(-) create mode 100644 gdb/arch/amd64-linux-tdesc.c create mode 100644 gdb/arch/i386-linux-tdesc.c create mode 100644 gdb/arch/x86-linux-tdesc-features.c rename gdbserver/linux-x86-tdesc.h => gdb/arch/x86-linux-tdesc-features.h (52%) create mode 100644 gdb/arch/x86-linux-tdesc.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 13ca417706b..7d912f00fb3 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -748,6 +748,7 @@ ALL_64_TARGET_OBS = \ arch/aarch64-insn.o \ arch/aarch64-mte-linux.o \ arch/aarch64-scalable-linux.o \ + arch/amd64-linux-tdesc.o \ arch/amd64.o \ arch/riscv.o \ bpf-tdep.o \ @@ -788,9 +789,11 @@ ALL_TARGET_OBS = \ arch/arm.o \ arch/arm-get-next-pcs.o \ arch/arm-linux.o \ + arch/i386-linux-tdesc.o \ arch/i386.o \ arch/loongarch.o \ arch/ppc-linux-common.o \ + arch/x86-linux-tdesc-features.o \ arm-bsd-tdep.o \ arm-fbsd-tdep.o \ arm-linux-tdep.o \ @@ -1559,6 +1562,8 @@ HFILES_NO_SRCDIR = \ arch/ppc-linux-common.h \ arch/ppc-linux-tdesc.h \ arch/riscv.h \ + arch/x86-linux-tdesc-features.h \ + arch/x86-linux-tdesc.h \ cli/cli-cmds.h \ cli/cli-decode.h \ cli/cli-script.h \ diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index f9647dce1e6..d7662cac572 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -1578,37 +1578,6 @@ amd64_linux_record_signal (struct gdbarch *gdbarch, return 0; } -const target_desc * -amd64_linux_read_description (uint64_t xcr0_features_bit, bool is_x32) -{ - static target_desc *amd64_linux_tdescs \ - [2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {}; - static target_desc *x32_linux_tdescs \ - [2/*AVX*/][2/*AVX512*/][2/*PKRU*/] = {}; - - target_desc **tdesc; - - if (is_x32) - { - tdesc = &x32_linux_tdescs[(xcr0_features_bit & X86_XSTATE_AVX) ? 1 : 0 ] - [(xcr0_features_bit & X86_XSTATE_AVX512) ? 1 : 0] - [(xcr0_features_bit & X86_XSTATE_PKRU) ? 1 : 0]; - } - else - { - tdesc = &amd64_linux_tdescs[(xcr0_features_bit & X86_XSTATE_AVX) ? 1 : 0] - [(xcr0_features_bit & X86_XSTATE_MPX) ? 1 : 0] - [(xcr0_features_bit & X86_XSTATE_AVX512) ? 1 : 0] - [(xcr0_features_bit & X86_XSTATE_PKRU) ? 1 : 0]; - } - - if (*tdesc == NULL) - *tdesc = amd64_create_target_description (xcr0_features_bit, is_x32, - true, true); - - return *tdesc; -} - /* Get Linux/x86 target description from core dump. */ static const struct target_desc * diff --git a/gdb/arch/amd64-linux-tdesc.c b/gdb/arch/amd64-linux-tdesc.c new file mode 100644 index 00000000000..794cd5c815d --- /dev/null +++ b/gdb/arch/amd64-linux-tdesc.c @@ -0,0 +1,61 @@ +/* Target description related code for GNU/Linux x86-64. + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 "arch/x86-linux-tdesc.h" +#include "arch/amd64-linux-tdesc.h" +#include "arch/amd64.h" +#include "arch/x86-linux-tdesc-features.h" + + +/* See arch/amd64-linux-tdesc.h. */ + +const struct target_desc * +amd64_linux_read_description (uint64_t xcr0, bool is_x32) +{ + /* The type used for the amd64 and x32 target description caches. */ + using tdesc_cache_type = std::unordered_map; + + /* Caches for the previously seen amd64 and x32 target descriptions, + indexed by the xcr0 value that created the target description. These + need to be static within this function to ensure they are initialised + before first use. */ + static tdesc_cache_type amd64_tdesc_cache, x32_tdesc_cache; + + tdesc_cache_type &tdesc_cache = is_x32 ? x32_tdesc_cache : amd64_tdesc_cache; + + xcr0 &= is_x32 + ? x86_linux_x32_xcr0_feature_mask () + : x86_linux_amd64_xcr0_feature_mask (); + + const auto it = tdesc_cache.find (xcr0); + if (it != tdesc_cache.end ()) + return it->second.get (); + + /* Create the previously unseen target description. */ + target_desc_up tdesc (amd64_create_target_description (xcr0, is_x32, + true, true)); + x86_linux_post_init_tdesc (tdesc.get (), true); + + /* Add to the cache, and return a pointer borrowed from the + target_desc_up. This is safe as the cache (and the pointers contained + within it) are not deleted until GDB exits. */ + target_desc *ptr = tdesc.get (); + tdesc_cache.emplace (xcr0, std::move (tdesc)); + return ptr; +} diff --git a/gdb/arch/i386-linux-tdesc.c b/gdb/arch/i386-linux-tdesc.c new file mode 100644 index 00000000000..78b0cef841e --- /dev/null +++ b/gdb/arch/i386-linux-tdesc.c @@ -0,0 +1,51 @@ +/* Target description related code for GNU/Linux i386. + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 "arch/x86-linux-tdesc.h" +#include "arch/i386-linux-tdesc.h" +#include "arch/i386.h" +#include "arch/x86-linux-tdesc-features.h" + +/* See arch/i386-linux-tdesc.h. */ + +const target_desc * +i386_linux_read_description (uint64_t xcr0) +{ + /* Cache of previously seen i386 target descriptions, indexed by the xcr0 + value that created the target description. This needs to be static + within this function to ensure it is initialised before first use. */ + static std::unordered_map i386_tdesc_cache; + + xcr0 &= x86_linux_i386_xcr0_feature_mask (); + + const auto it = i386_tdesc_cache.find (xcr0); + if (it != i386_tdesc_cache.end ()) + return it->second.get (); + + /* Create the previously unseen target description. */ + target_desc_up tdesc (i386_create_target_description (xcr0, true, false)); + x86_linux_post_init_tdesc (tdesc.get (), false); + + /* Add to the cache, and return a pointer borrowed from the + target_desc_up. This is safe as the cache (and the pointers contained + within it) are not deleted until GDB exits. */ + target_desc *ptr = tdesc.get (); + i386_tdesc_cache.emplace (xcr0, std::move (tdesc)); + return ptr; +} diff --git a/gdb/arch/x86-linux-tdesc-features.c b/gdb/arch/x86-linux-tdesc-features.c new file mode 100644 index 00000000000..55444d91bd5 --- /dev/null +++ b/gdb/arch/x86-linux-tdesc-features.c @@ -0,0 +1,267 @@ +/* Target description related code for GNU/Linux x86 (i386 and x86-64). + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 "arch/x86-linux-tdesc-features.h" + +/* A structure used to describe a single xstate feature bit that might, or + might not, be checked for when creating a target description for one of + i386, amd64, or x32. + + The different CPU/ABI types check for different xstate features when + creating a target description. + + We want to cache target descriptions, and this is currently done in + three separate caches, one each for i386, amd64, and x32. Additionally, + the caching we're discussing here is Linux only, and for Linux, the only + thing that has an impact on target description creation is the xcr0 + value. + + In order to ensure the cache functions correctly we need to filter out + only those xcr0 feature bits that are relevant, we can then cache target + descriptions based on the relevant feature bits. Two xcr0 values might + be different, but have the same relevant feature bits. In this case we + would expect the two xcr0 values to map to the same cache entry. */ + +struct x86_xstate_feature { + /* The xstate feature mask. This is a mask against an xcr0 value. */ + uint64_t feature; + + /* Is this feature checked when creating an i386 target description. */ + bool is_i386; + + /* Is this feature checked when creating an amd64 target description. */ + bool is_amd64; + + /* Is this feature checked when creating an x32 target description. */ + bool is_x32; +}; + +/* A constant table that describes all of the xstate features that are + checked when building a target description for i386, amd64, or x32. + + If in the future, due to simplifications or refactoring, this table ever + ends up with 'true' for every xcr0 feature on every target type, then this + is an indication that this table should probably be removed, and that the + rest of the code in this file can be simplified. */ + +static constexpr x86_xstate_feature x86_linux_all_xstate_features[] = { + /* Feature, i386, amd64, x32. */ + { X86_XSTATE_PKRU, true, true, true }, + { X86_XSTATE_AVX512, true, true, true }, + { X86_XSTATE_AVX, true, true, true }, + { X86_XSTATE_MPX, true, true, false }, + { X86_XSTATE_SSE, true, false, false }, + { X86_XSTATE_X87, true, false, false } +}; + +/* Return a compile time constant which is a mask of all the xstate features + that are checked for when building an i386 target description. */ + +static constexpr uint64_t +x86_linux_i386_xcr0_feature_mask_1 () +{ + uint64_t mask = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_i386) + mask |= entry.feature; + + return mask; +} + +/* Return a compile time constant which is a mask of all the xstate features + that are checked for when building an amd64 target description. */ + +static constexpr uint64_t +x86_linux_amd64_xcr0_feature_mask_1 () +{ + uint64_t mask = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_amd64) + mask |= entry.feature; + + return mask; +} + +/* Return a compile time constant which is a mask of all the xstate features + that are checked for when building an x32 target description. */ + +static constexpr uint64_t +x86_linux_x32_xcr0_feature_mask_1 () +{ + uint64_t mask = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_x32) + mask |= entry.feature; + + return mask; +} + +/* See arch/x86-linux-tdesc-features.h. */ + +uint64_t +x86_linux_amd64_xcr0_feature_mask () +{ + return x86_linux_amd64_xcr0_feature_mask_1 (); +} + +/* See arch/x86-linux-tdesc-features.h. */ + +uint64_t +x86_linux_x32_xcr0_feature_mask () +{ + return x86_linux_x32_xcr0_feature_mask_1 (); +} + +/* See arch/x86-linux-tdesc-features.h. */ + +uint64_t +x86_linux_i386_xcr0_feature_mask () +{ + return x86_linux_i386_xcr0_feature_mask_1 (); +} + +#ifdef GDBSERVER + +/* See arch/x86-linux-tdesc-features.h. */ + +int +x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0) +{ + /* The following table shows which features are checked for when creating + the target descriptions (see nat/x86-linux-tdesc.c), the feature order + represents the bit order within the generated index number. + + i386 | x87 sse mpx avx avx512 pkru + amd64 | mpx avx avx512 pkru + i32 | avx avx512 pkru + + The features are ordered so that for each mode (i386, amd64, i32) the + generated index will form a continuous range. */ + + int idx = 0; + + for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i) + { + if ((xcr0 & x86_linux_all_xstate_features[i].feature) + == x86_linux_all_xstate_features[i].feature) + idx |= (1 << i); + } + + return idx; +} + +#endif /* GDBSERVER */ + +#ifdef IN_PROCESS_AGENT + +/* Return a compile time constant which is a count of the number of xstate + features that are checked for when building an i386 target description. */ + +static constexpr int +x86_linux_i386_tdesc_count_1 () +{ + uint64_t count = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_i386) + ++count; + + gdb_assert (count > 0); + + return (1 << count); +} + +/* Return a compile time constant which is a count of the number of xstate + features that are checked for when building an amd64 target description. */ + +static constexpr int +x86_linux_amd64_tdesc_count_1 () +{ + uint64_t count = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_amd64) + ++count; + + gdb_assert (count > 0); + + return (1 << count); +} + +/* Return a compile time constant which is a count of the number of xstate + features that are checked for when building an x32 target description. */ + +static constexpr int +x86_linux_x32_tdesc_count_1 () +{ + uint64_t count = 0; + + for (const auto &entry : x86_linux_all_xstate_features) + if (entry.is_x32) + ++count; + + gdb_assert (count > 0); + + return (1 << count); +} + +/* See arch/x86-linux-tdesc-features.h. */ + +int +x86_linux_amd64_tdesc_count () +{ + return x86_linux_amd64_tdesc_count_1 (); +} + +/* See arch/x86-linux-tdesc-features.h. */ + +int +x86_linux_x32_tdesc_count () +{ + return x86_linux_x32_tdesc_count_1 (); +} + +/* See arch/x86-linux-tdesc-features.h. */ + +int +x86_linux_i386_tdesc_count () +{ + return x86_linux_i386_tdesc_count_1 (); +} + +/* See arch/x86-linux-tdesc-features.h. */ + +uint64_t +x86_linux_tdesc_idx_to_xcr0 (int idx) +{ + uint64_t xcr0 = 0; + + for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i) + { + if ((idx & (1 << i)) != 0) + xcr0 |= x86_linux_all_xstate_features[i].feature; + } + + return xcr0; +} + +#endif /* IN_PROCESS_AGENT */ diff --git a/gdbserver/linux-x86-tdesc.h b/gdb/arch/x86-linux-tdesc-features.h similarity index 52% rename from gdbserver/linux-x86-tdesc.h rename to gdb/arch/x86-linux-tdesc-features.h index c06af21da48..fb0017e46db 100644 --- a/gdbserver/linux-x86-tdesc.h +++ b/gdb/arch/x86-linux-tdesc-features.h @@ -1,7 +1,6 @@ -/* Low level support for x86 (i386 and x86-64), shared between gdbserver - and IPA. +/* Target description related code for GNU/Linux x86 (i386 and x86-64). - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2024 Free Software Foundation, Inc. This file is part of GDB. @@ -18,32 +17,46 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef GDBSERVER_LINUX_X86_TDESC_H -#define GDBSERVER_LINUX_X86_TDESC_H +#ifndef ARCH_X86_LINUX_TDESC_FEATURES_H +#define ARCH_X86_LINUX_TDESC_FEATURES_H -/* Convert an xcr0 value into an integer. The integer will be passed to - the in-process-agent where it will then be passed to - x86_linux_tdesc_idx_to_xcr0 to get back the xcr0 value. */ +#include "gdbsupport/x86-xstate.h" +#include "gdbsupport/gdb_assert.h" + +/* Return a mask of X86_STATE_* feature flags. The returned mask indicates + the set of features which are checked for when creating the target + description for each of amd64, x32, and i386. */ + +extern uint64_t x86_linux_amd64_xcr0_feature_mask (); +extern uint64_t x86_linux_x32_xcr0_feature_mask (); +extern uint64_t x86_linux_i386_xcr0_feature_mask (); + +#ifdef GDBSERVER + +/* Convert an xcr0 value into an integer. The integer will be passed from + gdbserver to the in-process-agent where it will then be passed through + x86_linux_tdesc_idx_to_xcr0 to get back the original xcr0 value. */ extern int x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0); +#endif /* GDBSERVER */ + #ifdef IN_PROCESS_AGENT +/* Return the maximum possible number of target descriptions for each of + amd64, x32, and i386. These are used by the in-process-agent to + generate every possible target description. */ + +extern int x86_linux_amd64_tdesc_count (); +extern int x86_linux_x32_tdesc_count (); +extern int x86_linux_i386_tdesc_count (); + /* Convert an index number (as returned from x86_linux_xcr0_to_tdesc_idx) into an xcr0 value which can then be used to create a target description. */ extern uint64_t x86_linux_tdesc_idx_to_xcr0 (int idx); -/* Within the in-process-agent we need to pre-initialise all of the target - descriptions, to do this we need to know how many target descriptions - there are for each different target type. These functions return the - target description count for the relevant target. */ - -extern int x86_linux_amd64_tdesc_count (); -extern int x86_linux_x32_tdesc_count (); -extern int x86_linux_i386_tdesc_count (); - #endif /* IN_PROCESS_AGENT */ -#endif /* GDBSERVER_LINUX_X86_TDESC_H */ +#endif /* ARCH_X86_LINUX_TDESC_FEATURES_H */ diff --git a/gdb/arch/x86-linux-tdesc.h b/gdb/arch/x86-linux-tdesc.h new file mode 100644 index 00000000000..152592fcf76 --- /dev/null +++ b/gdb/arch/x86-linux-tdesc.h @@ -0,0 +1,37 @@ +/* Target description related code for GNU/Linux x86 (i386 and x86-64). + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#ifndef ARCH_X86_LINUX_TDESC_H +#define ARCH_X86_LINUX_TDESC_H + +struct target_desc; + +/* This function is called from amd64_linux_read_description and + i386_linux_read_description after a new target description has been + created, TDESC is the new target description, IS_64BIT will be true + when called from amd64_linux_read_description, otherwise IS_64BIT will + be false. If the *_linux_read_description functions found a cached + target description then this function will not be called. + + Both GDB and gdbserver have their own implementations of this + function. */ + +extern void x86_linux_post_init_tdesc (target_desc *tdesc, bool is_64bit); + +#endif /* ARCH_X86_LINUX_TDESC_H */ diff --git a/gdb/configure.nat b/gdb/configure.nat index a30b07ef8c5..5d6669f34d7 100644 --- a/gdb/configure.nat +++ b/gdb/configure.nat @@ -257,7 +257,8 @@ case ${gdb_host} in nat/x86-xstate.o \ i386-linux-nat.o x86-linux-nat.o nat/linux-btrace.o \ nat/x86-linux.o nat/x86-linux-dregs.o nat/i386-linux.o \ - nat/x86-linux-tdesc.o" + nat/x86-linux-tdesc.o arch/i386-linux-tdesc.o \ + arch/x86-linux-tdesc-features.o" ;; ia64) # Host: Intel IA-64 running GNU/Linux @@ -324,7 +325,8 @@ case ${gdb_host} in nat/x86-xstate.o amd64-nat.o amd64-linux-nat.o x86-linux-nat.o \ nat/linux-btrace.o \ nat/x86-linux.o nat/x86-linux-dregs.o nat/x86-linux-tdesc.o \ - nat/amd64-linux-siginfo.o" + nat/amd64-linux-siginfo.o arch/x86-linux-tdesc-features.o \ + arch/i386-linux-tdesc.o arch/amd64-linux-tdesc.o" ;; sparc) # Host: GNU/Linux UltraSPARC diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 47a674201f9..8326c458eb1 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -320,10 +320,13 @@ i[34567]86-*-linux*) gdb_target_obs="i386-linux-tdep.o \ glibc-tdep.o \ solib-svr4.o symfile-mem.o \ - linux-tdep.o linux-record.o" + linux-tdep.o linux-record.o \ + arch/i386-linux-tdesc.o \ + arch/x86-linux-tdesc-features.o" if test "x$enable_64_bit_bfd" = "xyes"; then # Target: GNU/Linux x86-64 - gdb_target_obs="amd64-linux-tdep.o ${gdb_target_obs}" + gdb_target_obs="amd64-linux-tdep.o \ + arch/amd64-linux-tdesc.o ${gdb_target_obs}" fi ;; i[34567]86-*-gnu*) @@ -718,7 +721,9 @@ x86_64-*-linux*) # Target: GNU/Linux x86-64 gdb_target_obs="amd64-linux-tdep.o ${i386_tobjs} \ i386-linux-tdep.o glibc-tdep.o \ - solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o" + solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o \ + arch/i386-linux-tdesc.o arch/amd64-linux-tdesc.o \ + arch/x86-linux-tdesc-features.o" ;; x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) # Target: FreeBSD/amd64 diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 6a7490680c1..6debed21b89 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -41,6 +41,7 @@ #include "i387-tdep.h" #include "gdbsupport/x86-xstate.h" #include "arch/i386-linux-tdesc.h" +#include "arch/x86-linux-tdesc.h" /* The syscall's XML filename for i386. */ #define XML_SYSCALL_FILENAME_I386 "syscalls/i386-linux.xml" @@ -680,29 +681,12 @@ i386_linux_core_read_x86_xsave_layout (struct gdbarch *gdbarch, layout) != 0; } -/* See i386-linux-tdep.h. */ +/* See arch/x86-linux-tdesc.h. */ -const struct target_desc * -i386_linux_read_description (uint64_t xcr0) +void +x86_linux_post_init_tdesc (target_desc *tdesc, bool is_64bit) { - if (xcr0 == 0) - return NULL; - - static struct target_desc *i386_linux_tdescs \ - [2/*X87*/][2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {}; - struct target_desc **tdesc; - - tdesc = &i386_linux_tdescs[(xcr0 & X86_XSTATE_X87) ? 1 : 0] - [(xcr0 & X86_XSTATE_SSE) ? 1 : 0] - [(xcr0 & X86_XSTATE_AVX) ? 1 : 0] - [(xcr0 & X86_XSTATE_MPX) ? 1 : 0] - [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0] - [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; - - if (*tdesc == NULL) - *tdesc = i386_create_target_description (xcr0, true, false); - - return *tdesc; + /* Nothing. */ } /* Get Linux/x86 target description from core dump. */ diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 538845b96d5..e24e40e85c1 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -111,12 +111,16 @@ case "${gdbserver_host}" in srv_tgtobj="${srv_tgtobj} nat/x86-linux-dregs.o" srv_tgtobj="${srv_tgtobj} nat/i386-linux.o" srv_tgtobj="${srv_tgtobj} nat/x86-linux-tdesc.o" + srv_tgtobj="${srv_tgtobj} arch/x86-linux-tdesc-features.o" + srv_tgtobj="${srv_tgtobj} arch/i386-linux-tdesc.o" srv_linux_usrregs=yes srv_linux_regsets=yes srv_linux_thread_db=yes srv_linux_btrace=yes ipa_obj="linux-i386-ipa.o linux-x86-tdesc-ipa.o" ipa_obj="${ipa_obj} arch/i386-ipa.o" + ipa_obj="${ipa_obj} arch/x86-linux-tdesc-features-ipa.o" + ipa_obj="${ipa_obj} arch/i386-linux-tdesc-ipa.o" ;; i[34567]86-*-mingw*) srv_regobj="" srv_tgtobj="x86-low.o nat/x86-dregs.o win32-low.o" @@ -375,12 +379,17 @@ case "${gdbserver_host}" in srv_tgtobj="${srv_tgtobj} nat/x86-linux-dregs.o" srv_tgtobj="${srv_tgtobj} nat/x86-linux-tdesc.o" srv_tgtobj="${srv_tgtobj} nat/amd64-linux-siginfo.o" + srv_tgtobj="${srv_tgtobj} arch/x86-linux-tdesc-features.o" + srv_tgtobj="${srv_tgtobj} arch/amd64-linux-tdesc.o" + srv_tgtobj="${srv_tgtobj} arch/i386-linux-tdesc.o" srv_linux_usrregs=yes # This is for i386 progs. srv_linux_regsets=yes srv_linux_thread_db=yes srv_linux_btrace=yes ipa_obj="linux-amd64-ipa.o linux-x86-tdesc-ipa.o" ipa_obj="${ipa_obj} arch/amd64-ipa.o" + ipa_obj="${ipa_obj} arch/x86-linux-tdesc-features-ipa.o" + ipa_obj="${ipa_obj} arch/amd64-linux-tdesc-ipa.o" ;; x86_64-*-mingw*) srv_regobj="" srv_tgtobj="x86-low.o nat/x86-dregs.o" diff --git a/gdbserver/linux-amd64-ipa.cc b/gdbserver/linux-amd64-ipa.cc index 0c80812cc6f..89857f208b8 100644 --- a/gdbserver/linux-amd64-ipa.cc +++ b/gdbserver/linux-amd64-ipa.cc @@ -20,9 +20,9 @@ #include #include "tracepoint.h" -#include "linux-x86-tdesc.h" #include "gdbsupport/x86-xstate.h" #include "arch/amd64-linux-tdesc.h" +#include "arch/x86-linux-tdesc-features.h" /* fast tracepoints collect registers. */ diff --git a/gdbserver/linux-i386-ipa.cc b/gdbserver/linux-i386-ipa.cc index c1c3152fb04..8100c9f9840 100644 --- a/gdbserver/linux-i386-ipa.cc +++ b/gdbserver/linux-i386-ipa.cc @@ -20,9 +20,9 @@ #include #include "tracepoint.h" -#include "linux-x86-tdesc.h" #include "gdbsupport/x86-xstate.h" #include "arch/i386-linux-tdesc.h" +#include "arch/x86-linux-tdesc-features.h" /* GDB register numbers. */ diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc index ab225c57fa2..5b2dc68a1e8 100644 --- a/gdbserver/linux-x86-low.cc +++ b/gdbserver/linux-x86-low.cc @@ -35,6 +35,7 @@ #endif #include "arch/i386-linux-tdesc.h" +#include "arch/x86-linux-tdesc-features.h" #include "gdb_proc_service.h" /* Don't include elf/common.h if linux/elf.h got included by @@ -50,7 +51,6 @@ #include "nat/linux-nat.h" #include "nat/x86-linux.h" #include "nat/x86-linux-dregs.h" -#include "linux-x86-tdesc.h" #include "nat/x86-linux-tdesc.h" #ifdef __x86_64__ diff --git a/gdbserver/linux-x86-tdesc.cc b/gdbserver/linux-x86-tdesc.cc index f5636898d71..13c80762605 100644 --- a/gdbserver/linux-x86-tdesc.cc +++ b/gdbserver/linux-x86-tdesc.cc @@ -17,314 +17,19 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include "arch/x86-linux-tdesc.h" #include "tdesc.h" -#include "linux-x86-tdesc.h" -#include "arch/i386.h" -#include "gdbsupport/x86-xstate.h" -#ifdef __x86_64__ -#include "arch/amd64.h" -#include "arch/amd64-linux-tdesc.h" -#endif #include "x86-tdesc.h" -#include "arch/i386-linux-tdesc.h" - -/* A structure used to describe a single xstate feature bit that might, or - might not, be checked for when creating a target description for one of - i386, amd64, or x32. - - The different CPU/ABI types check for different xstate features when - creating a target description. - - We want to cache target descriptions, and this is currently done in - three separate caches, one each for i386, amd64, and x32. Additionally, - the caching we're discussing here is Linux only, and for Linux, the only - thing that has an impact on target description creation is the xcr0 - value. - - In order to ensure the cache functions correctly we need to filter out - only those xcr0 feature bits that are relevant, we can then cache target - descriptions based on the relevant feature bits. Two xcr0 values might - be different, but have the same relevant feature bits. In this case we - would expect the two xcr0 values to map to the same cache entry. */ - -struct x86_xstate_feature { - /* The xstate feature mask. This is a mask against an xcr0 value. */ - uint64_t feature; - - /* Is this feature checked when creating an i386 target description. */ - bool is_i386; - - /* Is this feature checked when creating an amd64 target description. */ - bool is_amd64; - - /* Is this feature checked when creating an x32 target description. */ - bool is_x32; -}; - -/* A constant table that describes all of the xstate features that are - checked when building a target description for i386, amd64, or x32. - - If in the future, due to simplifications or refactoring, this table ever - ends up with 'true' for every xcr0 feature on every target type, then this - is an indication that this table should probably be removed, and that the - rest of the code in this file can be simplified. */ - -static constexpr x86_xstate_feature x86_linux_all_xstate_features[] = { - /* Feature, i386, amd64, x32. */ - { X86_XSTATE_PKRU, true, true, true }, - { X86_XSTATE_AVX512, true, true, true }, - { X86_XSTATE_AVX, true, true, true }, - { X86_XSTATE_MPX, true, true, false }, - { X86_XSTATE_SSE, true, false, false }, - { X86_XSTATE_X87, true, false, false } -}; - -/* Return a compile time constant which is a mask of all the xstate features - that are checked for when building an i386 target description. */ - -static constexpr uint64_t -x86_linux_i386_xcr0_feature_mask () -{ - uint64_t mask = 0; - - for (const auto &entry : x86_linux_all_xstate_features) - if (entry.is_i386) - mask |= entry.feature; - - return mask; -} - -/* Return a compile time constant which is a mask of all the xstate features - that are checked for when building an amd64 target description. */ - -static constexpr uint64_t -x86_linux_amd64_xcr0_feature_mask () -{ - uint64_t mask = 0; - - for (const auto &entry : x86_linux_all_xstate_features) - if (entry.is_amd64) - mask |= entry.feature; - - return mask; -} - -/* Return a compile time constant which is a mask of all the xstate features - that are checked for when building an x32 target description. */ - -static constexpr uint64_t -x86_linux_x32_xcr0_feature_mask () -{ - uint64_t mask = 0; - - for (const auto &entry : x86_linux_all_xstate_features) - if (entry.is_x32) - mask |= entry.feature; - - return mask; -} - -/* Return a compile time constant which is a count of the number of xstate - features that are checked for when building an i386 target description. */ - -static constexpr int -x86_linux_i386_tdesc_count_1 () -{ - uint64_t count = 0; - - for (const auto &entry : x86_linux_all_xstate_features) - if (entry.is_i386) - ++count; - - gdb_assert (count > 0); - - return (1 << count); -} - -/* Return a compile time constant which is a count of the number of xstate - features that are checked for when building an amd64 target description. */ - -static constexpr int -x86_linux_amd64_tdesc_count_1 () -{ - uint64_t count = 0; - - for (const auto &entry : x86_linux_all_xstate_features) - if (entry.is_amd64) - ++count; - - gdb_assert (count > 0); - - return (1 << count); -} - -/* Return a compile time constant which is a count of the number of xstate - features that are checked for when building an x32 target description. */ - -static constexpr int -x86_linux_x32_tdesc_count_1 () -{ - uint64_t count = 0; - - for (const auto &entry : x86_linux_all_xstate_features) - if (entry.is_x32) - ++count; - - gdb_assert (count > 0); - - return (1 << count); -} - -#ifdef IN_PROCESS_AGENT - -/* See linux-x86-tdesc.h. */ - -int -x86_linux_amd64_tdesc_count () -{ - return x86_linux_amd64_tdesc_count_1 (); -} - -/* See linux-x86-tdesc.h. */ - -int -x86_linux_x32_tdesc_count () -{ - return x86_linux_x32_tdesc_count_1 (); -} - -/* See linux-x86-tdesc.h. */ - -int -x86_linux_i386_tdesc_count () -{ - return x86_linux_i386_tdesc_count_1 (); -} - -#endif /* IN_PROCESS_AGENT */ - -/* Convert an xcr0 value into an integer. The integer will be passed to - the in-process-agent where it will then be passed to - x86_linux_tdesc_idx_to_xcr0 to get back the xcr0 value. */ - -int -x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0) -{ - /* The following table shows which features are checked for when creating - the target descriptions (see nat/x86-linux-tdesc.c), the feature order - represents the bit order within the generated index number. - - i386 | x87 sse mpx avx avx512 pkru - amd64 | mpx avx avx512 pkru - i32 | avx avx512 pkru - - The features are ordered so that for each mode (i386, amd64, i32) the - generated index will form a continuous range. */ - - int idx = 0; - - for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i) - { - if ((xcr0 & x86_linux_all_xstate_features[i].feature) - == x86_linux_all_xstate_features[i].feature) - idx |= (1 << i); - } - - return idx; -} - -#ifdef IN_PROCESS_AGENT - -/* Convert an index number (as returned from x86_linux_xcr0_to_tdesc_idx) - into an xcr0 value which can then be used to create a target - description. */ - -uint64_t -x86_linux_tdesc_idx_to_xcr0 (int idx) -{ - uint64_t xcr0 = 0; - - for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i) - { - if ((idx & (1 << i)) != 0) - xcr0 |= x86_linux_all_xstate_features[i].feature; - } - - return xcr0; -} - -#endif /* IN_PROCESS_AGENT */ - -#if defined __i386__ || !defined IN_PROCESS_AGENT -/* A cache of all possible i386 target descriptions. */ +/* See arch/x86-linux-tdesc.h. */ -static struct target_desc *i386_tdescs[x86_linux_i386_tdesc_count_1 ()] = { }; - -/* See nat/x86-linux-tdesc.h. */ - -const struct target_desc * -i386_linux_read_description (uint64_t xcr0) +void +x86_linux_post_init_tdesc (target_desc *tdesc, bool is_64bit) { - xcr0 &= x86_linux_i386_xcr0_feature_mask (); - int idx = x86_linux_xcr0_to_tdesc_idx (xcr0); - - gdb_assert (idx >= 0 && idx < x86_linux_i386_tdesc_count_1 ()); - - target_desc **tdesc = &i386_tdescs[idx]; - - if (*tdesc == nullptr) - { - *tdesc = i386_create_target_description (xcr0, true, false); - - init_target_desc (*tdesc, i386_expedite_regs); - } - - return *tdesc; -} -#endif - #ifdef __x86_64__ - -/* A cache of all possible amd64 target descriptions. */ - -static target_desc *amd64_tdescs[x86_linux_amd64_tdesc_count_1 ()] = { }; - -/* A cache of all possible x32 target descriptions. */ - -static target_desc *x32_tdescs[x86_linux_x32_tdesc_count_1 ()] = { }; - -/* See nat/x86-linux-tdesc.h. */ - -const struct target_desc * -amd64_linux_read_description (uint64_t xcr0, bool is_x32) -{ - if (is_x32) - xcr0 &= x86_linux_x32_xcr0_feature_mask (); - else - xcr0 &= x86_linux_amd64_xcr0_feature_mask (); - - int idx = x86_linux_xcr0_to_tdesc_idx (xcr0); - - if (is_x32) - gdb_assert (idx >= 0 && idx < x86_linux_x32_tdesc_count_1 ()); - else - gdb_assert (idx >= 0 && idx < x86_linux_amd64_tdesc_count_1 ()); - - target_desc **tdesc = nullptr; - - if (is_x32) - tdesc = &x32_tdescs[idx]; + if (is_64bit) + init_target_desc (tdesc, amd64_expedite_regs); else - tdesc = &amd64_tdescs[idx]; - - if (*tdesc == nullptr) - { - *tdesc = amd64_create_target_description (xcr0, is_x32, true, true); - - init_target_desc (*tdesc, amd64_expedite_regs); - } - return *tdesc; -} - #endif + init_target_desc (tdesc, i386_expedite_regs); +}