From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id KXraN/BVomrqEjwAWB0awg (envelope-from ) for ; Thu, 10 Sep 2026 03:02:08 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=ZB/EDAgr; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id DDEE91E091; Thu, 10 Sep 2026 03:02:08 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 4FA411E091 for ; Thu, 10 Sep 2026 03:02:07 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CA7434BB58D2 for ; Thu, 10 Sep 2026 07:02:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CA7434BB58D2 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=ZB/EDAgr Received: from mail-ot1-x32c.google.com (mail-ot1-x32c.google.com [IPv6:2607:f8b0:4864:20::32c]) by sourceware.org (Postfix) with ESMTPS id D69EB4BB3B81 for ; Thu, 10 Sep 2026 07:01:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D69EB4BB3B81 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 D69EB4BB3B81 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::32c ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1789023697; cv=none; b=wFNIhJyDWE6ANJNK+Azaz7MIe0WxhZ+atKEUI6U6Q70YQaiM9jXvRrbvPrMSMNAnsOXjsC6YGEsKOuPhkPiMeAw6HvQ8SHXydUcCY8hzOnXDdwARYSJJXC0E9TijurOtCBjM4/O8DwQDEJGOEiOD+UkdNx4rpPXNup9WPQ/Vmfg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1789023697; c=relaxed/simple; bh=Lk1NsMD+BM8ByexPvpXjGzsolhs3+SZRUYswCSyWHQc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=d/bKD/cTMgbV7TyCcm6gcmbzuNPczoJsOQAFqoT0MqURZanBrXd2t/P0FV7mYmtvv9AqvDjqhXkZNLFd99IBShr0L9amdUJ9JLKRTUSXHklMbkuhfDzy2e5NKUBLU3KzGm/M1okKCx/FQmavZs7U5Ns1ezWBvGxoIoe6Fl3ye6E= ARC-Authentication-Results: i=1; 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=ZB/EDAgr DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D69EB4BB3B81 Received: by mail-ot1-x32c.google.com with SMTP id 46e09a7af769-7f4f824de5dso2956722a34.2 for ; Thu, 10 Sep 2026 00:01:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1789023696; x=1789628496; darn=sourceware.org; h=content-transfer-encoding:content-type:mime-version:message-id:date :user-agent:references:in-reply-to:subject:cc:to:from:from:to:cc :subject:date:message-id:reply-to:content-type; bh=IQ/KK/I/CNG38T2k5IWpfjPmCjMlsN2UiRSiA+XFrdk=; b=ZB/EDAgr535Xu6v32Ff5WZ/Mvt3gQ0/+cpxjp497sc9hFJLO/tm2SAqfnlg10pudY/ RQ2xxQkA/t0tTElL9zLQhr5PaUGDyUurhuiwW0cCR2dljyXWRve3IG4jrzvnLU21ZZCB +MY10xumfwN6ce4PkVCcaRhscGKJXVemUu+IqxSERbhkohpMoZEVX4syFddXPz+zX1ar fJwnFsTRLMHKozV5f6+MYRvQG4vm41TywPSdSs15w5Nu46jXSQ1Ni2x1rXu4uJJDQrRb IKEppKTpfP+oTDOeOTvWijCDsTRFyz8s+cvQqKYcOGCSKDzqQBqfwLRqBgStEtqY3kGU A3UA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789023696; x=1789628496; h=content-transfer-encoding:content-type:mime-version:message-id:date :user-agent:references:in-reply-to:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=IQ/KK/I/CNG38T2k5IWpfjPmCjMlsN2UiRSiA+XFrdk=; b=lPj+rBYgKnqAcFNJcFAZyuFFlnZLyDI4zhzHgs5zdT/C5crSoAhoQagIiD+i7Pdm9+ NZFiK3tn1HW/El4HjufuBuDkb17cX0O19EX+FNRDzAU77Z0C8Cxea9GV8PceYsIsSzPd sFtfPMyFSucPs8Z0ReGR/3Ou2SDUx8Lb6cHrIF47rG4pJxcvA75GkoyJG58viWsBktFu 1tqLclSQJBACf7AeSkNHD9CrFNLXK+9v6364pNOOpy7adJQr299Nl8tU+1TUxH0ZJZIk c88NQ2bXMRK2y3Gm0qxl+Hl58mJQBumrQthiMidv+IiapSnwVx7TRF7LBuzhbaex3dnw dDKQ== X-Gm-Message-State: AFuF++n24M0PNz0T1QmAnnYPUQohhVV3YQVd60CBQR9a7I7if/nFbtFE pxw3kqJx/doPB9dQoFdyorjt7zk1d2gwXEezJNPN0p98lGwisrwoJM+vc8GNo98uq2w= X-Gm-Gg: AYBFou2Jct8W2DUZItuWwh5JzQmqGUQJohFAgT5SC3RDpEysgNEVb92erlZGcBYDDUE jnbucdsVNR+3zUErv8u49vv80SUhZk237Gh3SX2vgJc9hHvEy/bKZWEuBQ35lu/ivqHW/lbvnHY QofaC3GEQlkoZWqY9dBkMvuxJOJ9mZUucXC5RX4MjWvgs/1J2eUiupwfMLs5lFRaT2yqZcQpkot tgwXjQByHwqZeWlSpAqG21ozuVCvQzkldz/ELPPNJ1omvTOgvLv0bDiz54KiBrT2+HHyiXYYAfq B3fSXilXt6QCKmGwXjjt3UyaB6+QimBN/+kRyEeRVtQoQDpgNgd6KIkoxL2K2weHNpWRONWRrho S/sEpdSEwuP5tlkJiVgwLCIzKGeoJKF/xDjEfuA6AyiLLr08uHBW5J1fWMy5sFJeuOkIkW2LS/h isS5JWmGwsGqj7o8NKqpPAFhPSODrKgvDiiM5wPp2djuoj0s5AralEAc4CZ6utxScrmbFkIVOxF zQdFsMT2w== X-Received: by 2002:a05:6820:2007:b0:6be:d637:c914 with SMTP id 006d021491bc7-6bed637d0a3mr3581919eaf.63.1789023695826; Thu, 10 Sep 2026 00:01:35 -0700 (PDT) Received: from localhost ([2804:14d:7e39:8083:f04c:42e3:5943:38f6]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3397d6d1c16sm11538065eec.13.2026.09.10.00.01.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Sep 2026 00:01:35 -0700 (PDT) From: Thiago Jung Bauermann To: Cc: , , , , , , Subject: Re: [PATCH v4 1/5] gdb/aarch64: Add POR_EL0 register support for FEAT_S1POE In-Reply-To: <20260901091216.5711-2-srinath.parvathaneni@arm.com> (srinath parvathaneni's message of "Tue, 1 Sep 2026 09:12:12 +0000") References: <20260901091216.5711-1-srinath.parvathaneni@arm.com> <20260901091216.5711-2-srinath.parvathaneni@arm.com> User-Agent: mu4e 1.14.3; emacs 30.2 Date: Thu, 10 Sep 2026 07:01:32 +0000 Message-ID: <87bja5pp2r.fsf@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable 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~public-inbox=simark.ca@sourceware.org Some comment's below come from Luis' review of the v3 patch: https://inbox.sourceware.org/gdb-patches/29190e6c-7d33-4967-a21c-ed53cb1f43= e2@gmail.com/ writes: > Add support for the FEAT_S1POE POR_EL0 register on AArch64. > > This patch adds POR_EL0 to the AArch64 register set and reads/writes it > using the NT_ARM_POE ptrace regset. > > It also adds POE pseudo-registers por_p0 through por_p15, with each > pseudo-register mapping to a 4-bit field in POR_EL0, starting from the > least-significant nibble. > > POR_EL0 and the POE pseudo-registers are added to the "por" register > group, allowing them to be displayed together using the > "info registers por" command. > > With this change, POR_EL0 is accessible through: > > * info registers > * info registers por_el0 > * info registers por > * p $por_el0 > * p/x $por_el0 > * set $por_el0 =3D > > The individual POE fields can also be accessed and modified through > $por_p0 to $por_p15. > > Example: > (gdb) info register por_el0 > por_el0 0x7 [ P0=3Drwx ] > (gdb) set $por_el0=3D0xffffffff77777777 > (gdb) info registers por_el0 > por_el0 0xffffffff77777777 [ P15=3D??? P14=3D??? P13=3D??? P12=3D?= ?? > P11=3D??? P10=3D??? P9=3D??? P8=3D??? > P7=3Drwx P6=3Drwx P5=3Drwx P4=3Drwx > P3=3Drwx P2=3Drwx P1=3Drwx P0=3Drwx ] > (gdb) info registers por > por_el0 0xffffffff77777777 [ P15=3D??? P14=3D??? P13=3D??? P12=3D?= ?? > P11=3D??? P10=3D??? P9=3D??? P8=3D??? > P7=3Drwx P6=3Drwx P5=3Drwx P4=3Drwx > P3=3Drwx P2=3Drwx P1=3Drwx P0=3Drwx ] > por_p0 0x7 rwx > por_p1 0x7 rwx > por_p2 0x7 rwx > por_p3 0x7 rwx > por_p4 0x7 rwx > por_p5 0x7 rwx > por_p6 0x7 rwx > por_p7 0x7 rwx > por_p8 0xf ??? > por_p9 0xf ??? > por_p10 0xf ??? > por_p11 0xf ??? > por_p12 0xf ??? > por_p13 0xf ??? > por_p14 0xf ??? > por_p15 0xf ??? > > Individual POE pseudo-registers can be written independently, with the > corresponding 4-bit field in POR_EL0 updated accordingly. For example: > > (gdb) set $por_el0=3D0x7 > (gdb) info registers por_el0 > por_el0 0x0000000000000007 [ P0=3Drwx ] > (gdb) set $por_p1=3D0x7 > (gdb) info registers por_el0 > por_el0 0x0000000000000077 [ P1=3Drwx P0=3Drwx ] I like this output and the pseudo registers. Thanks! I'd like to see what Luis thinks of them, so I won't give an Approved-by. But assuming the nits below are fixed: Reviewed-by: Thiago Jung Bauermann > --- > gdb/Makefile.in | 2 + > gdb/aarch64-linux-nat.c | 64 ++++++++ > gdb/aarch64-tdep.c | 274 +++++++++++++++++++++++++++++++++++ > gdb/aarch64-tdep.h | 12 ++ > gdb/arch/aarch64-poe-linux.h | 29 ++++ > gdb/arch/aarch64.c | 4 + > gdb/arch/aarch64.h | 8 +- > gdb/features/Makefile | 1 + > gdb/features/aarch64-poe.c | 14 ++ > gdb/features/aarch64-poe.xml | 11 ++ > gdb/nat/aarch64-poe-linux.h | 29 ++++ > 11 files changed, 447 insertions(+), 1 deletion(-) > create mode 100644 gdb/arch/aarch64-poe-linux.h > create mode 100644 gdb/features/aarch64-poe.c > create mode 100644 gdb/features/aarch64-poe.xml > create mode 100644 gdb/nat/aarch64-poe-linux.h > v4-0001-PATCH-1-5-gdb-aarch64-Add-POR_EL0-register-suppor.patch: > diff --git a/gdb/Makefile.in b/gdb/Makefile.in > index c6bfc2949fc..0b5bf45545a 100644 > --- a/gdb/Makefile.in > +++ b/gdb/Makefile.in > @@ -1292,6 +1292,7 @@ HFILES_NO_SRCDIR =3D \ > arch/aarch32.h \ > arch/aarch64-fpmr-linux.h \ > arch/aarch64-gcs-linux.h \ > + arch/aarch64-poe-linux.h \ > arch/aarch64.h \ > arch/aarch64-insn.h \ > arch/aarch64-mte.h \ > @@ -1540,6 +1541,7 @@ HFILES_NO_SRCDIR =3D \ > namespace.h \ > nat/aarch64-fpmr-linux.h \ > nat/aarch64-gcs-linux.h \ > + nat/aarch64-poe-linux.h \ > nat/aarch64-hw-point.h \ > nat/aarch64-linux.h \ > nat/aarch64-linux-hw-point.h \ >From Luis: Let's keep these entries sorted alphabetically. > diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c > index 52ace4aab41..8e29c42908c 100644 > --- a/gdb/aarch64-linux-nat.c > +++ b/gdb/aarch64-linux-nat.c > @@ -34,6 +34,7 @@ > #include "arch/arm.h" > #include "nat/aarch64-fpmr-linux.h" > #include "nat/aarch64-gcs-linux.h" > +#include "nat/aarch64-poe-linux.h" > #include "nat/aarch64-linux.h" > #include "nat/aarch64-linux-hw-point.h" > #include "nat/aarch64-mte-linux-ptrace.h" > @@ -602,6 +603,54 @@ store_gcsregs_to_thread (regcache *regcache) > perror_with_name (_("Unable to store GCS registers")); > } >=20=20 > +/* Fill GDB's register array with the POE register value from the current > + thread. */ > + > +static void > +fetch_poeregs_from_thread (regcache *regcache) > +{ > + aarch64_gdbarch_tdep *tdep > + =3D gdbarch_tdep (regcache->arch ()); > + > + gdb_assert (tdep->has_poe ()); > + > + uint64_t user_poe; > + iovec iovec; > + > + iovec.iov_base =3D &user_poe; > + iovec.iov_len =3D sizeof (user_poe); > + > + int tid =3D get_ptrace_pid (regcache->ptid ()); > + if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_POE, &iovec) !=3D 0) > + perror_with_name (_("Unable to fetch POE register")); > + > + regcache->raw_supply (tdep->poe_regnum, &user_poe); > +} > + > +/* Store the NT_ARM_POE register contents from GDB's REGCACHE to the > + thread associated with REGCACHE. */ >From Luis: Wrong identation above. And also: Nit: Let's keep things consistent register contents or register value.=20 We should pick one and go with it. > +static void > +store_poeregs_to_thread (struct regcache *regcache) You can remove "struct" from the declaration. > +{ > + aarch64_gdbarch_tdep *tdep > + =3D gdbarch_tdep (regcache->arch ()); > + > + gdb_assert (tdep->has_poe ()); > + > + int tid =3D regcache->ptid ().lwp (); > + > + iovec iovec; > + uint64_t user_poe; > + iovec.iov_base =3D &user_poe; > + iovec.iov_len =3D sizeof (user_poe); > + > + regcache->raw_collect (tdep->poe_regnum, &user_poe); > + > + if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_POE, &iovec) !=3D 0) > + perror_with_name (_("Unable to store POE register")); > +} =E2=8B=AE > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c > index 950ad4f6aae..763321bdcb4 100644 > --- a/gdb/aarch64-tdep.c > +++ b/gdb/aarch64-tdep.c > @@ -164,6 +164,11 @@ static const char *const aarch64_gcs_register_names[= ] =3D { > "gcspr" > }; >=20=20 > +static const char *const aarch64_poe_register_names[] =3D { > + /* Permission Overlay Extension Register. */ > + "por_el0" > +}; > + > static const char *const aarch64_gcs_linux_register_names[] =3D { > /* Field in struct user_gcs. */ > "gcs_features_enabled", > @@ -2892,6 +2897,21 @@ is_w_pseudo_register (struct gdbarch *gdbarch, int= regnum) > return false; > } >=20=20 > +/* Return TRUE if REGNUM is a POE pseudo-register number. Return FALSE > + otherwise. */ > + > +static bool > +is_poe_pseudo_register (struct gdbarch *gdbarch, int regnum) You can remove "struct" from the declaration. > +{ > + aarch64_gdbarch_tdep *tdep =3D gdbarch_tdep (gdb= arch); > + > + if (tdep->poe_pseudo_base <=3D regnum > + && regnum < tdep->poe_pseudo_base + tdep->poe_pseudo_count) > + return true; > + > + return false; > +} =E2=8B=AE > +/* Display POE register POR_EL0 in the following format for the 'info re= gisters' > + and 'info all-registers' commands: > + [= ] */ > + > +static void > +aarch64_print_poe_register_info (struct ui_file *file, You can remove "struct" from the declaration. > + int regnum, const char *name, > + const frame_info_ptr &frame) > +{ > + value *val =3D value_of_register (regnum, get_next_frame_sentinel_okay= (frame)); > + ULONGEST por_el0 =3D (ULONGEST) value_as_long (val); > + gdb_printf (file, "%-14s 0x%s [ ", name, phex (por_el0, 8)); > + const int line_wrap_count =3D 36; > + > + for (int i =3D 15, line_wrap =3D 0; i >=3D 0; --i) > + { > + unsigned int perm =3D (por_el0 >> (i * 4)) & 0xf; > + if (perm) > + { > + if (line_wrap !=3D 0 && (line_wrap % 4) =3D=3D 0) > + gdb_printf (file, "\n%*s", line_wrap_count, ""); > + gdb_printf (file, "P%d=3D%s ", i, aarch64_perm_overlay_decode (perm)); > + line_wrap++; > + } > + } > + gdb_puts ("]\n", file); > +} > + > +/* Custom display for POE pseudo registers. */ > + > +static void > +aarch64_print_poe_pseudo_register_info (struct ui_file *file, int regnum, You can remove "struct" from the declaration. > + const char *name, > + const frame_info_ptr &frame) > +{ > + value *val =3D value_of_register (regnum, get_next_frame_sentinel_okay= (frame)); > + struct gdbarch *gdbarch =3D get_frame_arch (frame); You can remove "struct" from the declaration. > + unsigned int perm =3D extract_unsigned_integer (val->contents (), > + gdbarch_byte_order (gdbarch)); > + > + /* Extract only the least significant 4 bits. */ > + perm &=3D 0xf; > + > + gdb_printf (file, "%-14s 0x%-16x %s\n", name, (unsigned) perm, Is this cast necessary, considering perm is already an unsigned int? > + aarch64_perm_overlay_decode (perm)); > +} > + > +/* For 'info registers' and 'info all-registers', print POE POR_EL0 regi= ster and > + POE pseudo registers using the custom register printer and all other > + registers using the default register printer. */ > + > +static void > +aarch64_print_registers_info (struct gdbarch *gdbarch, > + struct ui_file *file, You can remove "struct" from the declarations above. > + const frame_info_ptr &frame, > + int regnum, > + bool print_all) > +{ > + const int numregs =3D gdbarch_num_cooked_regs (gdbarch); > + aarch64_gdbarch_tdep *tdep =3D gdbarch_tdep (gdb= arch); > + > + /* When no register is specified. */ > + if (regnum =3D=3D -1) > + { > + for (int i =3D 0; i < numregs; i++) > + { > + if (i =3D=3D tdep->poe_regnum) > + { > + aarch64_print_poe_register_info > + (file, i, gdbarch_register_name (gdbarch, i), frame); > + continue; > + } > + else if (is_poe_pseudo_register (gdbarch, i)) > + { > + aarch64_print_poe_pseudo_register_info > + (file, i, gdbarch_register_name (gdbarch, i), frame); > + continue; > + } > + default_print_registers_info (gdbarch, file, frame, i, print_all); > + } > + } > + /* When POE por_el0 register is specified. */ > + else if (regnum =3D=3D tdep->poe_regnum) > + aarch64_print_poe_register_info > + (file, regnum, gdbarch_register_name (gdbarch, regnum), frame); > + /* When individual POE pseudo register is specified. */ > + else if (is_poe_pseudo_register (gdbarch, regnum)) > + aarch64_print_poe_pseudo_register_info > + (file, regnum, gdbarch_register_name (gdbarch, regnum), frame); > + else > + default_print_registers_info (gdbarch, file, frame, regnum, print_al= l); > +} > + > /* Implement the "pseudo_register_reggroup_p" tdesc_arch_data method. */ >=20=20 > static bool > @@ -3161,6 +3318,8 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch = *gdbarch, int regnum, > return group =3D=3D all_reggroup || group =3D=3D vector_reggroup; > else if (is_sme_pseudo_register (gdbarch, regnum)) > return group =3D=3D all_reggroup || group =3D=3D vector_reggroup; > + else if (is_poe_pseudo_register (gdbarch, regnum)) > + return group =3D=3D all_reggroup || group =3D=3D reggroup_find (gdba= rch, "por"); > /* RA_STATE is used for unwinding only. Do not assign it to any group= s. */ > if (tdep->has_pauth () && regnum =3D=3D tdep->ra_sign_state_regnum) > return false; > @@ -3290,7 +3449,38 @@ aarch64_sme_pseudo_register_read (gdbarch *gdbarch= , const frame_info_ptr &next_f > za_value->contents_copy (result, dst_offset, src_offset, > offsets.chunk_size); > } > + return result; > +} > + > +/* Given REGNUM, a POE pseudo-register number, return its value in RESUL= T. */ > + > +static value * > +aarch64_poe_pseudo_register_read (gdbarch *gdbarch, > + const frame_info_ptr &next_frame, > + const int pseudo_reg_num) > +{ > + aarch64_gdbarch_tdep *tdep =3D gdbarch_tdep (gdb= arch); > + > + gdb_assert (tdep->has_poe ()); > + gdb_assert (tdep->poe_pseudo_base <=3D pseudo_reg_num); > + gdb_assert (pseudo_reg_num < tdep->poe_pseudo_base + tdep->poe_pseudo_= count); > + > + unsigned int pkey =3D pseudo_reg_num - tdep->poe_pseudo_base; > + unsigned int shift =3D pkey * 4; > + > + value *por_value =3D value_of_register (tdep->poe_regnum, next_frame); > + value *result =3D value::allocate_register (next_frame, pseudo_reg_num= ); >=20=20 > + ULONGEST por_el0 > + =3D extract_unsigned_integer (por_value->contents (), > + gdbarch_byte_order (gdbarch)); > + > + ULONGEST pseudo_reg_value =3D (por_el0 >> shift) & 0xf; > + > + store_unsigned_integer (result->contents_raw ().data (), > + result->type ()->length (), If you pass result->contents_raw () then you'll call the version of the function that accepts a gdb::array_view and won't need to pass the length parameter. I think that's simpler. > + gdbarch_byte_order (gdbarch), > + pseudo_reg_value); > return result; > } >=20=20 > @@ -3322,6 +3512,9 @@ aarch64_pseudo_read_value (gdbarch *gdbarch, const = frame_info_ptr &next_frame, > else if (is_sme_pseudo_register (gdbarch, pseudo_reg_num)) > return aarch64_sme_pseudo_register_read (gdbarch, next_frame, > pseudo_reg_num); > + else if (is_poe_pseudo_register (gdbarch, pseudo_reg_num)) > + return aarch64_poe_pseudo_register_read (gdbarch, next_frame, > + pseudo_reg_num); >=20=20 > /* Offset in the "pseudo-register space". */ > int pseudo_offset =3D pseudo_reg_num - gdbarch_num_regs (gdbarch); > @@ -3428,6 +3621,50 @@ aarch64_sme_pseudo_register_write (gdbarch *gdbarc= h, const frame_info_ptr &next_ > za_value->contents_raw ()); > } >=20=20 > +/* Given PSEUDO_REG_NUM, a POE pseudo-register number, store DATA in the > + corresponding field of POR_EL0. */ > + > +static void > +aarch64_poe_pseudo_register_write (gdbarch *gdbarch, > + const frame_info_ptr &next_frame, > + const int pseudo_reg_num, > + gdb::array_view data) > +{ > + aarch64_gdbarch_tdep *tdep > + =3D gdbarch_tdep (gdbarch); > + > + gdb_assert (tdep->has_poe ()); > + gdb_assert (tdep->poe_pseudo_base <=3D pseudo_reg_num); > + gdb_assert (pseudo_reg_num < tdep->poe_pseudo_base + tdep->poe_pseudo_= count); > + > + unsigned int pkey =3D pseudo_reg_num - tdep->poe_pseudo_base; > + unsigned int shift =3D pkey * 4; > + > + ULONGEST pseudo_reg_value > + =3D extract_unsigned_integer (data, gdbarch_byte_order (gdbarch)); > + > + if (pseudo_reg_value > 0xf) > + error (_("POE pseudo-register value must be between 0 and 15.")); > + > + /* Fetch the current POR_EL0 value. */ > + value *por_value =3D value_of_register (tdep->poe_regnum, next_frame); > + > + ULONGEST por_el0 > + =3D extract_unsigned_integer (por_value->contents (), > + gdbarch_byte_order (gdbarch)); > + > + ULONGEST mask =3D ULONGEST (0xf) << shift; > + > + por_el0 =3D (por_el0 & ~mask) | (pseudo_reg_value << shift); > + > + store_unsigned_integer (por_value->contents_writeable ().data (), > + por_value->type ()->length (), Same comment here about passing por_value->contents_writeable () and not needing to pass the length. > + gdbarch_byte_order (gdbarch), > + por_el0); > + > + put_frame_register (next_frame, tdep->poe_regnum, por_value->contents_= raw ()); > +} > + > /* Implement the "pseudo_register_write" gdbarch method. */ >=20=20 > static void > @@ -3464,6 +3701,12 @@ aarch64_pseudo_write (gdbarch *gdbarch, const fram= e_info_ptr &next_frame, > buf); > return; > } > + else if (is_poe_pseudo_register (gdbarch, pseudo_reg_num)) > + { > + aarch64_poe_pseudo_register_write (gdbarch, next_frame, pseudo_reg= _num, > + buf); > + return; > + } >=20=20 > /* Offset in the "pseudo-register space". */ > int pseudo_offset =3D pseudo_reg_num - gdbarch_num_regs (gdbarch); > @@ -4140,6 +4383,10 @@ aarch64_features_from_target_desc (const struct ta= rget_desc *tdesc) > features.fpmr =3D (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpm= r") > !=3D nullptr); >=20=20 > + /* Check for POE feature. */ > + features.poe =3D (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.poe") > + !=3D nullptr); > + > return features; > } >=20=20 > @@ -4560,6 +4807,24 @@ aarch64_gdbarch_init (struct gdbarch_info info, st= ruct gdbarch_list *arches) > fpmr_regnum, "fpmr"); > } >=20=20 > + int poe_regnum =3D -1; > + int first_poe_pseudo_regnum =3D -1; > + const struct tdesc_feature *feature_poe > + =3D tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.poe"); You can remove "struct" from the declaration. > + if (feature_poe !=3D nullptr) > + { > + poe_regnum =3D num_regs; > + for (i =3D 0; i < ARRAY_SIZE (aarch64_poe_register_names); i++) > + valid_p &=3D tdesc_numbered_register (feature_poe, tdesc_data.get (), > + poe_regnum + i, > + aarch64_poe_register_names[i]); > + > + /* POE pseudo-registers. */ > + first_poe_pseudo_regnum =3D num_pseudo_regs; > + num_pseudo_regs +=3D 16; > + num_regs++; > + } =E2=8B=AE > diff --git a/gdb/arch/aarch64-poe-linux.h b/gdb/arch/aarch64-poe-linux.h > new file mode 100644 > index 00000000000..8623fa43b54 > --- /dev/null > +++ b/gdb/arch/aarch64-poe-linux.h > @@ -0,0 +1,29 @@ > +/* Common Linux target-dependent definitions for AArch64 POE > + > + Copyright (C) 2026 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 GDB_ARCH_AARCH64_POE_LINUX_H > +#define GDB_ARCH_AARCH64_POE_LINUX_H > + > +/* Feature check for Permission Overlay Extension. */ > +#define AARCH64_HWCAP2_POE (1ULL << 63) > + > +/* Data or instruction abort caused by Protection Key Violation. */ > +#define AARCH64_SEGV_PKUERR 4 > + > +#endif /* GDB_ARCH_AARCH64_POE_LINUX_H. */ check-include-guards.py complains about the comment above: $ gdb/check-include-guards.py gdb/arch/aarch64-poe-linux.h gdb/arch/aarch64-poe-linux.h:29: wrong endif line $ gdb/check-include-guards.py --update gdb/arch/aarch64-poe-linux.h $ git diff diff --git a/gdb/arch/aarch64-poe-linux.h b/gdb/arch/aarch64-poe-linux.h index 8623fa43b549..d6e4a001cbf9 100644 --- a/gdb/arch/aarch64-poe-linux.h +++ b/gdb/arch/aarch64-poe-linux.h @@ -26,4 +26,4 @@ /* Data or instruction abort caused by Protection Key Violation. */ #define AARCH64_SEGV_PKUERR 4 =20 -#endif /* GDB_ARCH_AARCH64_POE_LINUX_H. */ +#endif /* GDB_ARCH_AARCH64_POE_LINUX_H */ Also, nothing in this patch uses this file. It should be moved to patch 2. > diff --git a/gdb/features/aarch64-poe.c b/gdb/features/aarch64-poe.c > new file mode 100644 > index 00000000000..9222d026a6d > --- /dev/null > +++ b/gdb/features/aarch64-poe.c > @@ -0,0 +1,14 @@ > +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: > + Original: aarch64-poe.xml */ > + > +#include "gdbsupport/tdesc.h" > + > +static int > +create_feature_aarch64_poe (struct target_desc *result, long regnum) > +{ > + struct tdesc_feature *feature; You can remove "struct" from the declarations above. > + > + feature =3D tdesc_create_feature (result, "org.gnu.gdb.aarch64.poe"); > + tdesc_create_reg (feature, "por_el0", regnum++, 1, "por", 64, "uint64"= ); > + return regnum; > +} > diff --git a/gdb/features/aarch64-poe.xml b/gdb/features/aarch64-poe.xml > new file mode 100644 > index 00000000000..aa2a2713ac8 > --- /dev/null > +++ b/gdb/features/aarch64-poe.xml > @@ -0,0 +1,11 @@ > + > + > + > + > + > + > + > diff --git a/gdb/nat/aarch64-poe-linux.h b/gdb/nat/aarch64-poe-linux.h > new file mode 100644 > index 00000000000..f3d0256da3f > --- /dev/null > +++ b/gdb/nat/aarch64-poe-linux.h > @@ -0,0 +1,29 @@ > +/* Common native Linux definitions for AArch64 Permission Overlay Extens= ion. > + > + Copyright (C) 2026 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 >From Luis: Shouldn't the above be inside the include guard? > +#ifndef GDB_NAT_AARCH64_POE_LINUX_H > +#define GDB_NAT_AARCH64_POE_LINUX_H > + > +/* Feature check for Permission Overlay Extension. */ > +#ifndef HWCAP2_POE > +#define HWCAP2_POE (1ULL << 63) > +#endif /* HWCAP2_POE. */ > + > +#endif /* GDB_NAT_AARCH64_POE_LINUX_H. */ --=20 Thiago (he/him)