From patchwork Sun Jun 8 01:03:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 894807 Delivered-To: patch@linaro.org Received: by 2002:a05:6000:ecd:b0:3a4:ee3f:8f15 with SMTP id ea13csp1177238wrb; Sat, 7 Jun 2025 18:12:56 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVdAgJ5VNsdh1k/IO8SJlMBu6fb+X3SxfQj9BWVORVVpu1Kse4d2Z6o1fMKSdinPuH/Wp0eAA==@linaro.org X-Google-Smtp-Source: AGHT+IEoGigUJzk1WoVQRiFwIgCLaTJ5AZrrPE9JajWQxbGN3aHf81w/oZfpz6CzwrnKo4FGuuDT X-Received: by 2002:a05:6214:c2f:b0:6f4:cdca:2a6e with SMTP id 6a1803df08f44-6fb0906fda5mr142228106d6.45.1749345176608; Sat, 07 Jun 2025 18:12:56 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1749345176; cv=pass; d=google.com; s=arc-20240605; b=NGK+k03OO/BXpp7difPuhKpPM7G9rVKnCvhN5fUaEK/lbqyOHyiROhxR2wSrIEcaz5 gIn8As0oPV8RILXWVwhEUrsNOyKLBA6JMyKzmy0tvglVlMYxiafOvglo3Hrjn1MNYmMW sZcYwbAkKXMnsWlzrgcJbWtxMetjLImeCb+9QHYse3NZUhGRUy2rCN+GV5817ZjKJpju aa4KFa+4FpVNvBeNmuK6JbkiBqPaqZigMwDzDolXZAiZGCL2/6lry8qW8XXO/3OGdUM6 vvlaQK6/elykY8lE6LaS49G+Me2aR+MY6bufP6z9/B6P6tbHUU2YtLyZwZwhmlOC/MPA tHtw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:dkim-filter:arc-filter:dmarc-filter:delivered-to :dkim-filter; bh=QP19AvrdeZh5N2+LhyeA749/sMr8NDEdjIDs0sp8lxs=; fh=72kqq0iQhigvR9Vv/oqX5ebs3Yyyw7XhzWxOOEPdupI=; b=REr4aUz4/eOSOfbeDpSn5/xMe1cT3mq6T7t+ydXIDEWKdx4fnhjb4Fo22pRKURXq2R EY64en+KPLYzHrBu3Brn9BLZYoIyJ3hlxc+OEqazdzlVk8HgWDB3Z7LsLeuNRIJ+mrl1 mtUVRf+YTwshS+yadM5Vl4mbM7IlM4bo7JxvEvUzWAJBQY63M/9rt+9bukUvvKv5Avgy BwfstfVtT0m27FH44NVefkZkibYTi+VBH+4Hety4C8TTZmxxJwZkJ6opDg0TUYhsdfBx FgGzZuJQI+4kLtXbH99HpUPYBNxYZLpKPAjKYcc2EAOwXiy9PJjadvKADG8r7gyk6HDe smNg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Zmgt/mhR"; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gdb-patches-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id 6a1803df08f44-6fb09b40d3esi47401366d6.483.2025.06.07.18.12.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 07 Jun 2025 18:12:56 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Zmgt/mhR"; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gdb-patches-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1F2D83858D26 for ; Sun, 8 Jun 2025 01:12:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1F2D83858D26 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=Zmgt/mhR X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-vs1-xe31.google.com (mail-vs1-xe31.google.com [IPv6:2607:f8b0:4864:20::e31]) by sourceware.org (Postfix) with ESMTPS id E32A33858C2C for ; Sun, 8 Jun 2025 01:03:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E32A33858C2C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E32A33858C2C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::e31 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749344639; cv=none; b=GSYiI3+YKzERDV8JZdB6N15JBkr1lbbPzViiFM7J9Eiyy7xgMoMrrhSy0M7QKCEtTEi9SZ4LznB7buWU8dTT/wiLKASpNBqdGanJ8Cry4DgyEXQipkwYoyOhsqq0qthRkgY5eaeQUbtY7e3fDgk49Fp+8WeN0t6LEQYfmlA9nfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749344639; c=relaxed/simple; bh=1Y7LAu7Y06QtZoO15Ql7jGFk5jOvUt67NBbORNMPOrU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=h7xneFczVqejFp5tCuMokI08dSYyvF0+OX0wjRUbtvtr66IBxI0Xrf6n1/ztvZsqAXOdpH7W/rpvbMj0k0V793B8L3dn3DmPWqgFhnizDCzfWchPMJlge/ZHsP5XuGZ2oQxoAyEQnLzjR/nsxoZUhSayJxDgYITArDw3JSfngTw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E32A33858C2C Received: by mail-vs1-xe31.google.com with SMTP id ada2fe7eead31-4e700699dffso1100481137.1 for ; Sat, 07 Jun 2025 18:03:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1749344638; x=1749949438; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=QP19AvrdeZh5N2+LhyeA749/sMr8NDEdjIDs0sp8lxs=; b=Zmgt/mhRLvElqvRpTMM+yHeAS7+ch2SkgQKTVknUIvX8aa4mr8OGAdZB2iRid31yhC DkixkH/ASNmo3ckloYS1EztNwmp8/1DseSFowq4IFgNExEjiij2TkSvzXiC8Epf5XImp I4eqgFpeCFYKvkj0mAQP4srScgfx3t2++hhESYMqBog61C8nIGuRgZs9KmBIz+Ti5GUW +Y9ms58oaSl5Kz8C4Rx+wc+ReiejPXGi8Y1rR7XRY0A3DkIl3O+4XpniHWdXQAzoKPNu nljBx5YxtYyUijvsI2TO4YhGjx9bU6pgAYs84T6ix8X7orfFd97PJ/KmpK/db+Us8Hfl ePug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749344638; x=1749949438; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QP19AvrdeZh5N2+LhyeA749/sMr8NDEdjIDs0sp8lxs=; b=I//INM0132p+kzwfWBnLBcRghysnHgPnrTfNEApNd56zUvhx1m4c/lQZyFFsydDota jQk/engPe44dzaTT/aXNqk1HjNEo3UL9aonA5iX+zesnlzAeS29TPwNAarLoJCAuYMyO AybkIggMp1cqeKHOBOzo8xmJtN7eIHU7Y5cD2LPlbyyLIc3tgedtk6k12BAx8/W1yKEv WeuOFoNE4bts4FO4jKUbkYHFdbeNTnxheApB1HdhD34bhl/kqO4STQkxtSeP1tPXl1vb 5BEZvWhmuNVfsh/I/AMjPtqA/X0JZ4KIhFtxVX3dPdThjCNDSKFYeE+YriySj4KAJ4Su PTZA== X-Gm-Message-State: AOJu0Yx4n9rVZfl7UebIc+eIOxuV6dxQcSEtShPSd63sY4NRq/jcDyXu XoAfcGW599uB1rO+UXAEYQqU3vjfyvP+K02XsdjE6l2KFfa4PzanyuwAuMtXkZma45Q8ksUqgFo Anx6a X-Gm-Gg: ASbGncv6GzCQmPeiIpYD9YNd+Z6jT2ahYreyZyCTvcAl0msfP6prl9b+uNXLHsk4z8b kFsxqgbmgaH3pHh6FCU2Xx+9XHReghlA1HSg2dnG2gVghkUM9qcbCjJxrBUcW19ZVWCU4b+Fh9O IrFskbYL8+6lc7ZSrGLgtg3HfmFzJuUrcNHhtXNvAi85J3YPAZdSf5c3m/EACx7bX6OqMqELoa+ jvNjSyzYKy7nGYudGg22Nrnqrvonlxmgi+u3H8ogBZ/IqWYF4hduYcy8Ittdirb6FECy1ikXfoM 9K8BcnV1wHpakRq6luDTlBnmEEJYf2DCLhgc7GxmiRU2ZgtsQoNSXZADVPLChBGlXR/Qx6D5 X-Received: by 2002:a05:6102:510a:b0:4e5:a398:b6fa with SMTP id ada2fe7eead31-4e7728ce45bmr7712863137.3.1749344638128; Sat, 07 Jun 2025 18:03:58 -0700 (PDT) Received: from localhost ([2804:14d:7e39:88d6:8cb1:1e8e:e951:f687]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-87ec5da036fsm1985127241.18.2025.06.07.18.03.57 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 07 Jun 2025 18:03:57 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Subject: [PATCH 5/8] GDB: aarch64-linux: Implement GCS support in displaced stepping Date: Sat, 7 Jun 2025 22:03:16 -0300 Message-ID: <20250608010338.2234530-6-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250608010338.2234530-1-thiago.bauermann@linaro.org> References: <20250608010338.2234530-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org When doing displaced step on a branch and link instruction with the Guarded Control Stack enabled, it's necessary to manually push and pop the GCS entry for the function call since GDB writes a simple branch instruction rather than a branch and link instruction in the displaced step buffer. Reviewed-By: Eli Zaretskii --- gdb/NEWS | 3 +++ gdb/aarch64-linux-tdep.c | 30 +++++++++++++++++++++++++ gdb/aarch64-tdep.c | 47 +++++++++++++++++++++++++++++++++++----- gdb/linux-tdep.h | 7 ++++++ 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index a82b7e3342c5..13a11134600f 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -48,6 +48,9 @@ * Add record full support for rv64gc architectures +* Debugging Linux programs that use AArch64 Guarded Control Stacks are now + supported. + * New commands maintenance check psymtabs diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index 24fb151311c4..812486e0d250 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -2534,6 +2534,32 @@ aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address) return true; } +/* Implement the "get_shadow_stack_pointer" gdbarch method. */ + +static std::optional +aarch64_linux_get_shadow_stack_pointer (gdbarch *gdbarch, regcache *regcache, + bool &shadow_stack_enabled) +{ + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + shadow_stack_enabled = false; + + if (!tdep->has_gcs ()) + return {}; + + uint64_t features_enabled; + enum register_status status = regcache->cooked_read (tdep->gcs_linux_reg_base, + &features_enabled); + if (status != REG_VALID) + error (_("Can't read $gcs_features_enabled.")); + + CORE_ADDR gcspr; + status = regcache->cooked_read (tdep->gcs_reg_base, &gcspr); + if (status != REG_VALID) + error (_("Can't read $gcspr.")); + + shadow_stack_enabled = features_enabled & PR_SHADOW_STACK_ENABLE; + return gcspr; +} /* AArch64 Linux implementation of the report_signal_info gdbarch hook. Displays information about possible memory tag violations. */ @@ -3103,6 +3129,10 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) sections. */ set_gdbarch_use_target_description_from_corefile_notes (gdbarch, aarch64_use_target_description_from_corefile_notes); + + if (tdep->has_gcs ()) + set_gdbarch_get_shadow_stack_pointer (gdbarch, + aarch64_linux_get_shadow_stack_pointer); } #if GDB_SELF_TEST diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index d728f60e9e15..4f204f2e4208 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -1911,6 +1911,24 @@ aarch64_push_gcs_entry (regcache *regs, CORE_ADDR lr_value) regcache_cooked_write_unsigned (regs, tdep->gcs_reg_base, gcs_addr); } +/* Remove the newest entry from the Guarded Control Stack. */ + +static void +aarch64_pop_gcs_entry (regcache *regs) +{ + gdbarch *arch = regs->arch (); + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (arch); + CORE_ADDR gcs_addr; + + enum register_status status = regs->cooked_read (tdep->gcs_reg_base, + &gcs_addr); + if (status != REG_VALID) + error ("Can't read $gcspr."); + + /* Update GCSPR. */ + regcache_cooked_write_unsigned (regs, tdep->gcs_reg_base, gcs_addr + 8); +} + /* Implement the "shadow_stack_push" gdbarch method. */ static void @@ -3602,6 +3620,9 @@ struct aarch64_displaced_step_copy_insn_closure /* PC adjustment offset after displaced stepping. If 0, then we don't write the PC back, assuming the PC is already the right address. */ int32_t pc_adjust = 0; + + /* True if it's a branch instruction that saves the link register. */ + bool linked_branch = false; }; /* Data when visiting instructions for displaced stepping. */ @@ -3653,6 +3674,12 @@ aarch64_displaced_step_b (const int is_bl, const int32_t offset, /* Update LR. */ regcache_cooked_write_unsigned (dsd->regs, AARCH64_LR_REGNUM, data->insn_addr + 4); + dsd->dsc->linked_branch = true; + bool gcs_is_enabled; + gdbarch_get_shadow_stack_pointer (dsd->regs->arch (), dsd->regs, + gcs_is_enabled); + if (gcs_is_enabled) + aarch64_push_gcs_entry (dsd->regs, data->insn_addr + 4); } } @@ -3811,6 +3838,12 @@ aarch64_displaced_step_others (const uint32_t insn, aarch64_emit_insn (dsd->insn_buf, insn & 0xffdfffff); regcache_cooked_write_unsigned (dsd->regs, AARCH64_LR_REGNUM, data->insn_addr + 4); + dsd->dsc->linked_branch = true; + bool gcs_is_enabled; + gdbarch_get_shadow_stack_pointer (dsd->regs->arch (), dsd->regs, + gcs_is_enabled); + if (gcs_is_enabled) + aarch64_push_gcs_entry (dsd->regs, data->insn_addr + 4); } else aarch64_emit_insn (dsd->insn_buf, insn); @@ -3907,20 +3940,24 @@ aarch64_displaced_step_fixup (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, struct regcache *regs, bool completed_p) { + aarch64_displaced_step_copy_insn_closure *dsc + = (aarch64_displaced_step_copy_insn_closure *) dsc_; CORE_ADDR pc = regcache_read_pc (regs); - /* If the displaced instruction didn't complete successfully then all we - need to do is restore the program counter. */ + /* If the displaced instruction didn't complete successfully then we need + to restore the program counter, and perhaps the Guarded Control Stack. */ if (!completed_p) { + bool gcs_is_enabled; + gdbarch_get_shadow_stack_pointer (gdbarch, regs, gcs_is_enabled); + if (dsc->linked_branch && gcs_is_enabled) + aarch64_pop_gcs_entry (regs); + pc = from + (pc - to); regcache_write_pc (regs, pc); return; } - aarch64_displaced_step_copy_insn_closure *dsc - = (aarch64_displaced_step_copy_insn_closure *) dsc_; - displaced_debug_printf ("PC after stepping: %s (was %s).", paddress (gdbarch, pc), paddress (gdbarch, to)); diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h index 7083635b976c..21f46e2ef50d 100644 --- a/gdb/linux-tdep.h +++ b/gdb/linux-tdep.h @@ -26,6 +26,13 @@ struct inferior; struct regcache; +/* Flag which enables shadow stack in PR_SET_SHADOW_STACK_STATUS prctl. */ +#ifndef PR_SHADOW_STACK_ENABLE +#define PR_SHADOW_STACK_ENABLE (1UL << 0) +#define PR_SHADOW_STACK_WRITE (1UL << 1) +#define PR_SHADOW_STACK_PUSH (1UL << 2) +#endif + /* Enum used to define the extra fields of the siginfo type used by an architecture. */ enum linux_siginfo_extra_field_values