From patchwork Sun Jun 8 01:03:19 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: 894809 Delivered-To: patch@linaro.org Received: by 2002:a05:6000:ecd:b0:3a4:ee3f:8f15 with SMTP id ea13csp1177925wrb; Sat, 7 Jun 2025 18:16:06 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXX0HnmOt8lQ7/gwgnqDHF1VG904GItE+IecRuC+njoFMNynm7YHY1loJhcfQRapRKmrdj7Lw==@linaro.org X-Google-Smtp-Source: AGHT+IHi+4nsCk1//B9JaEtXybj/PfQMqwIQgRT2SyWg6lyNKctDVCfXYKIdrAh/n9lSWMIMENz1 X-Received: by 2002:a05:620a:1987:b0:7c5:d888:7098 with SMTP id af79cd13be357-7d2298db637mr1382709885a.44.1749345366175; Sat, 07 Jun 2025 18:16:06 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1749345366; cv=pass; d=google.com; s=arc-20240605; b=WgJw+q/QKdvenAvoUYdvJuXYG9pkWwZLCm04hFTCZTFkwr0I9McHH1bX+pHhzVYoD6 fA+SGxxZFDsOAllxpX/7aO/cWDsR3RgnrqEv/J3BieZUWbJApSOEAqlWcnuI20K/H8/A cGwTPzT8kxzbaode2cj33TzU7aRoMJN7LIasrLhpsUDVLtgBuLVx/BgJWeNea8zqnf/c 95GXsZ2Uqz3kXGUTvXGyrbfjtgnRwTZqe6bVDIrBGeHXjIRF/QlAGxe6yR86ZjoHbzvr qfQfQ+67089z1+uCqhhA/ZYIqyDuOtAKb8PsRwy/Eo4+XpQ7Ns7cDFhm1i75lwtqFh0X jvGg== 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=cbk+8QpY5sEVKFfP3xJwVJZCtGobl1/PKtxfghKaX1I=; fh=72kqq0iQhigvR9Vv/oqX5ebs3Yyyw7XhzWxOOEPdupI=; b=Pyt3XMBJNvkh6jGlIHY5W5WrLhn2oopDNVpPPzU/IgTBIv/PgZSKMwKAqb8b9dfLId GwlEqOQlJwLzzqD5/hyvIBTAumuXStYUXFgXtT/lzM53uhfAhyPzPHMDGAjFqZLAjS4b bfYkBGF/RXe/A89ccaFB9pMIHmNGs/2RelX5wesWKQyn3oq3o4PuQ9KvilCsY+FwkPtr lXKbrh/BcMn2HW+rEcNII4sEJqun5/9BerLdPQDUy70OJUoiMVH3vzJ//wOvn0qHkCME gSggWZfakGjZyXkBgvXxYZkYbNPMhAWMU4W6A0dBSy5F47l8Pf0LIrqdA+GCWadVF8ab 4gAw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mb9CRdqH; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 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. [8.43.85.97]) by mx.google.com with ESMTPS id af79cd13be357-7d24b3cba56si490183685a.82.2025.06.07.18.16.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 07 Jun 2025 18:16:06 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mb9CRdqH; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 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 B15C53858C51 for ; Sun, 8 Jun 2025 01:16:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B15C53858C51 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=mb9CRdqH X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-vs1-xe2d.google.com (mail-vs1-xe2d.google.com [IPv6:2607:f8b0:4864:20::e2d]) by sourceware.org (Postfix) with ESMTPS id 941733858D26 for ; Sun, 8 Jun 2025 01:04:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 941733858D26 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 941733858D26 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::e2d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749344648; cv=none; b=FI4MUppxhLL9bcYvHWRolgkxEJPbLW8lhu07p3N8x2LIPZuGJMV4ztI0P72PFH3DAVa970MrEEHbLQM1O99uvBTTo2xkL88AMDJ65jicXcQWucQjX+yGYgNUE0dq58nfgvDNT+ptZ7gyQrMmtbyERs3Ily1l702naQeXSgE1RY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749344648; c=relaxed/simple; bh=bfnvPu6tq7RAcb4byZ3RQdEGZw5j7WoI45XVTnu9QqQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=b37wbDZgXGycMZlRGW51Kk1xdBJwxMvh4dkX7fr+UPJCb4sdWBZ9CnXaIF6Be8cNhFxjjoQecCmKU6yxhwX0GRyvJDV85pXCzGMxjEpzYnX/IOVf4nZALIXOCsM9JP0CeqJgHMH7F9omnSLiPGTLaGJ3RdC3PpDMsG962FxMLeg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 941733858D26 Received: by mail-vs1-xe2d.google.com with SMTP id ada2fe7eead31-4e751947dd8so1065538137.2 for ; Sat, 07 Jun 2025 18:04:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1749344648; x=1749949448; 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=cbk+8QpY5sEVKFfP3xJwVJZCtGobl1/PKtxfghKaX1I=; b=mb9CRdqHG1fz2+Hrj+3Pab49MEPiA+YVL2mgrKuGZ+tVmNW4H3mUCnDppehYRtxZXz 9x0ahQOILwJdz9Ii0GsmwjRU/+p2tLXeGrrq/189N5TKqg8ddKITHjKS4JJjlAD6XFzF cj57H2hPxpOhncA2cMRYMWJpdf2v9TNQZdXIT5rzYhJxVfz6iniC4jkr63I3dqUPjjUa KuoqwFiDJrUvjWHqk6Up9gGC8Lr9cu4OTAoU7RxzS67XN1x5s16JTUrHQsqEPYU0sOM2 wam6TvOnZpCflgXm0oOFXw4U0YyGRJLQuq1lVurhEyAWhv40MeC0kMCyWw/nilxtko0b niSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749344648; x=1749949448; 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=cbk+8QpY5sEVKFfP3xJwVJZCtGobl1/PKtxfghKaX1I=; b=iYuKpFz8WsKlQxT5BOQawS4Klzl86e1w+JoIvNrHanWHz43ioX2sIpHS01E9P+dgE7 rPPWWtxwSESdBu+O0WMhq0zeEJGhD8P4h/87WrksVVT+K/zA8D8YLyWLr7y1BGc3j9+Y qesbHp58Po+Uc0NZzx8NmUeyh8+P4LNAP6JVhNtPsmdupd+yEt/5BvVkfIdLz1eQYI32 /pj2KlvdaFozkqmvjIFxIY6/XJkHBrdJNtUN/L32KhCslO2CRj4Qu4FhTSf6eNQUEFi5 qObAJAmWJjcPN19oQMKryXBO4ypgen+zxpGnT69hjgkhZ79kv4Rm4Y9aeqkDkSHkbhNB iATA== X-Gm-Message-State: AOJu0YzwV9lJQbn1DFSFN8kTsVue//Yz8Iy4ZpxZRQ8B/AK80fdUuS2q m8EOnqzFTkoTmP32zLUjlx2qrKPYZPkfB6O80O8GtGLwc8iBzPXmBE1OdNLo0r+A1rs8gCsQNgy kM+An X-Gm-Gg: ASbGnctQ5Cskpkb3bTTpdTxX82EEhpdEQ5HHNy+7ecsXDdMHZT0jBjCvyi26PtRdmul uavOPr02r8cZBnh/YKGPGGK3kCGtGwOcNGKh66HfNdxPlJorm8fEyUTU7FGHD7+qtX4IM+vKTBN FFfWhdzeeXfqsP+HhQ/wIBmUUjO3DwY77qElbG7eZFXgCjcO8GsoJXpuC6XatMb+xqYMFoE8DSU otLiaR9TE8/3S8aBHbW1bc2k2Q96MS2HAq8Xf162RBkI6OuVqZXXEOR6YiUpEO2ACGR4qdJh3Hv LSYYlC0kkAeFJKrOH9tKWo8KbMWLXnFdpRmdvKvbwbF+BWe88CGZEkBfOrPbcw== X-Received: by 2002:a05:6122:641b:10b0:529:2644:8c with SMTP id 71dfb90a1353d-530e48a0131mr4928875e0c.8.1749344647791; Sat, 07 Jun 2025 18:04:07 -0700 (PDT) Received: from localhost ([2804:14d:7e39:88d6:8cb1:1e8e:e951:f687]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-530e62f0c78sm3013947e0c.20.2025.06.07.18.04.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 07 Jun 2025 18:04:07 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Subject: [PATCH 8/8] GDB: testsuite: Add gdb.arch/aarch64-gcs-disp-step.exp testcase Date: Sat, 7 Jun 2025 22:03:19 -0300 Message-ID: <20250608010338.2234530-9-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 It exercises GCS with displaced stepping by putting the breakpoint on the bl instruction to force GDB to copy it to the displaced stepping buffer. In this case GDB needs to manually manage the Guarded Control Stack. --- .../gdb.arch/aarch64-gcs-disp-step.c | 140 ++++++++++++++++++ .../gdb.arch/aarch64-gcs-disp-step.exp | 90 +++++++++++ 2 files changed, 230 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.c create mode 100644 gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.exp diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.c b/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.c new file mode 100644 index 000000000000..3d895350ae42 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.c @@ -0,0 +1,140 @@ +/* This test program is part of GDB, the GNU debugger. + + Copyright 2025 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include +#include +#include +#include + +/* Feature check for Guarded Control Stack. */ +#ifndef HWCAP_GCS +#define HWCAP_GCS (1UL << 32) +#endif + +#ifndef PR_GET_SHADOW_STACK_STATUS +#define PR_GET_SHADOW_STACK_STATUS 74 +#define PR_SET_SHADOW_STACK_STATUS 75 +#define PR_SHADOW_STACK_ENABLE (1UL << 0) +#endif + +/* We need to use a macro to call prctl because after GCS is enabled, it's not + possible to return from the function which enabled it. This is because the + return address of the calling function isn't on the GCS. */ +#define my_syscall2(num, arg1, arg2) \ + ({ \ + register long _num __asm__("x8") = (num); \ + register long _arg1 __asm__("x0") = (long)(arg1); \ + register long _arg2 __asm__("x1") = (long)(arg2); \ + register long _arg3 __asm__("x2") = 0; \ + register long _arg4 __asm__("x3") = 0; \ + register long _arg5 __asm__("x4") = 0; \ + \ + __asm__ volatile("svc #0\n" \ + : "=r"(_arg1) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ + "r"(_arg5), "r"(_num) \ + : "memory", "cc"); \ + _arg1; \ + }) + +#define get_gcspr(void) \ + ({ \ + unsigned long *gcspr; \ + \ + /* Get GCSPR_EL0. */ \ + asm volatile("mrs %0, S3_3_C2_C5_1" : "=r"(gcspr) : : "cc"); \ + \ + gcspr; \ + }) + +static int __attribute__ ((noinline)) +function2 (void) +{ + return EXIT_SUCCESS; +} + +/* Put branch and link instructions being tested into their own functions so + that the program returns one level up in the stack after the displaced + stepped instruction. This tests that GDB doesn't leave the GCS out of sync + with the regular stack. */ + +static int __attribute__ ((noinline)) +function_bl (void) +{ + register int x0 __asm__("x0"); + + __asm__ ("bl function2\n" + : "=r"(x0) + : + : "x30"); + + return x0; +} + +static int __attribute__ ((noinline)) +function_blr (void) +{ + register int x0 __asm__("x0"); + + __asm__ ("blr %1\n" + : "=r"(x0) + : "r"(&function2) + : "x30"); + + return x0; +} + +int +main (void) +{ + if (!(getauxval (AT_HWCAP) & HWCAP_GCS)) + { + fprintf (stderr, "GCS support not found in AT_HWCAP\n"); + return EXIT_FAILURE; + } + + /* Force shadow stacks on, our tests *should* be fine with or + without libc support and with or without this having ended + up tagged for GCS and enabled by the dynamic linker. We + can't use the libc prctl() function since we can't return + from enabling the stack. */ + unsigned long gcs_mode; + int ret = my_syscall2 (__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to read GCS state: %d\n", ret); + return EXIT_FAILURE; + } + + if (!(gcs_mode & PR_SHADOW_STACK_ENABLE)) + { + gcs_mode = PR_SHADOW_STACK_ENABLE; + ret = my_syscall2 (__NR_prctl, PR_SET_SHADOW_STACK_STATUS, gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to configure GCS: %d\n", ret); + return EXIT_FAILURE; + } + } + + int ret1 = function_bl (); + int ret2 = function_blr (); + + /* Avoid returning, in case libc doesn't understand GCS. */ + exit (ret1 + ret2); +} diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.exp b/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.exp new file mode 100644 index 000000000000..10b09a4d980e --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.exp @@ -0,0 +1,90 @@ +# Copyright 2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test displaced stepping in a program that uses a Guarded Control Stack. + +require allow_aarch64_gcs_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return +} + +if ![runto_main] { + return +} + +gdb_test_no_output "set breakpoint auto-hw off" +gdb_test_no_output "set displaced-stepping on" + +# Get address of the branch and link instructions of interest. +set addr_bl 0 +set test "get address of bl instruction" +gdb_test_multiple "disassemble function_bl" $test -lbl { + -re "\r\n\\s+($hex) <\\+${decimal}>:\\s+bl\\s+${hex} (?=\r\n)" { + set addr_bl $expect_out(1,string) + exp_continue + } + -re "$::gdb_prompt \$" { + gdb_assert { $addr_bl != 0 } $test + } +} + +set addr_blr 0 +set test "get address of blr instruction" +gdb_test_multiple "disassemble function_blr" $test -lbl { + -re "\r\n\\s+($hex) <\\+${decimal}>:\\s+blr\\s+x${decimal}(?=\r\n)" { + set addr_blr $expect_out(1,string) + exp_continue + } + -re "$::gdb_prompt \$" { + gdb_assert { $addr_blr != 0 } $test + } +} + +if { $addr_bl == 0 || $addr_blr == 0 } { + return +} + +gdb_test "break *$addr_bl" \ + "Breakpoint $decimal at $hex: file .*aarch64-gcs-disp-step.c, line ${decimal}." \ + "set breakpoint at bl instruction" + +gdb_test "break *$addr_blr" \ + "Breakpoint $decimal at $hex: file .*aarch64-gcs-disp-step.c, line ${decimal}." \ + "set breakpoint at blr instruction" + +gdb_test "continue" \ + [multi_line \ + {Continuing\.} \ + "" \ + "Breakpoint $decimal, function_bl \\(\\) at .*aarch64-gcs-disp-step.c:${decimal}(?: \\\[GCS error\\\])?" \ + {[^\r\n]+"bl function2\\n"}] \ + "continue to breakpoint at bl" + +gdb_test "continue" \ + [multi_line \ + {Continuing\.} \ + "" \ + "Breakpoint $decimal, $hex in function_blr \\(\\) at .*aarch64-gcs-disp-step.c:${decimal}(?: \\\[GCS error\\\])?" \ + {[^\r\n]+"blr %1\\n"}] \ + "continue to breakpoint at blr" + +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "\\\[Inferior 1 \\(process $decimal\\) exited normally\\\]"] \ + "continue until inferior exits"