From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1936) id F25213858427; Tue, 3 May 2022 23:11:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F25213858427 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: John Baldwin To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Read the tpidr register from NT_ARM_TLS on Linux. X-Act-Checkin: binutils-gdb X-Git-Author: John Baldwin X-Git-Refname: refs/heads/master X-Git-Oldrev: 9c27bc99e4e1c4fbf51dc8f6186f0fdd5994a38b X-Git-Newrev: 3b4b3e438d2cbf685133df5425931a2355192045 Message-Id: <20220503231119.F25213858427@sourceware.org> Date: Tue, 3 May 2022 23:11:19 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 May 2022 23:11:20 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D3b4b3e438d2c= bf685133df5425931a2355192045 commit 3b4b3e438d2cbf685133df5425931a2355192045 Author: John Baldwin Date: Tue May 3 16:05:11 2022 -0700 Read the tpidr register from NT_ARM_TLS on Linux. Diff: --- gdb/aarch64-linux-nat.c | 68 +++++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index 4da274c285a..10b0ca10984 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -431,6 +431,60 @@ store_mteregs_to_thread (struct regcache *regcache) perror_with_name (_("unable to store MTE registers.")); } =20 +/* Fill GDB's register array with the TLS register values from + the current thread. */ + +static void +fetch_tlsregs_from_thread (struct regcache *regcache) +{ + aarch64_gdbarch_tdep *tdep + =3D (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ()); + int regno =3D tdep->tls_regnum; + + gdb_assert (regno !=3D -1); + + uint64_t tpidr =3D 0; + struct iovec iovec; + + iovec.iov_base =3D &tpidr; + iovec.iov_len =3D sizeof (tpidr); + + int tid =3D get_ptrace_pid (regcache->ptid ()); + if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_TLS, &iovec) !=3D 0) + perror_with_name (_("unable to fetch TLS register.")); + + regcache->raw_supply (regno, &tpidr); +} + +/* Store to the current thread the valid TLS register set in GDB's + register array. */ + +static void +store_tlsregs_to_thread (struct regcache *regcache) +{ + aarch64_gdbarch_tdep *tdep + =3D (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ()); + int regno =3D tdep->tls_regnum; + + gdb_assert (regno !=3D -1); + + uint64_t tpidr =3D 0; + + if (REG_VALID !=3D regcache->get_register_status (regno)) + return; + + regcache->raw_collect (regno, (char *) &tpidr); + + struct iovec iovec; + + iovec.iov_base =3D &tpidr; + iovec.iov_len =3D sizeof (tpidr); + + int tid =3D get_ptrace_pid (regcache->ptid ()); + if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_TLS, &iovec) !=3D 0) + perror_with_name (_("unable to store TLS register.")); +} + /* Implement the "fetch_registers" target_ops method. */ =20 void @@ -453,6 +507,9 @@ aarch64_linux_nat_target::fetch_registers (struct regca= che *regcache, =20 if (tdep->has_mte ()) fetch_mteregs_from_thread (regcache); + + if (tdep->has_tls ()) + fetch_tlsregs_from_thread (regcache); } else if (regno < AARCH64_V0_REGNUM) fetch_gregs_from_thread (regcache); @@ -472,6 +529,9 @@ aarch64_linux_nat_target::fetch_registers (struct regca= che *regcache, if (tdep->has_mte () && (regno =3D=3D tdep->mte_reg_base)) fetch_mteregs_from_thread (regcache); + + if (tdep->has_tls () && regno =3D=3D tdep->tls_regnum) + fetch_tlsregs_from_thread (regcache); } =20 /* Implement the "store_registers" target_ops method. */ @@ -493,6 +553,9 @@ aarch64_linux_nat_target::store_registers (struct regca= che *regcache, =20 if (tdep->has_mte ()) store_mteregs_to_thread (regcache); + + if (tdep->has_tls ()) + store_tlsregs_to_thread (regcache); } else if (regno < AARCH64_V0_REGNUM) store_gregs_to_thread (regcache); @@ -505,6 +568,9 @@ aarch64_linux_nat_target::store_registers (struct regca= che *regcache, if (tdep->has_mte () && (regno =3D=3D tdep->mte_reg_base)) store_mteregs_to_thread (regcache); + + if (tdep->has_tls () && regno =3D=3D tdep->tls_regnum) + store_tlsregs_to_thread (regcache); } =20 /* Fill register REGNO (if it is a general-purpose register) in @@ -647,7 +713,7 @@ aarch64_linux_nat_target::read_description () bool mte_p =3D hwcap2 & HWCAP2_MTE; =20 return aarch64_read_description (aarch64_sve_get_vq (tid), pauth_p, mte_= p, - false); + true); } =20 /* Convert a native/host siginfo object, into/from the siginfo in the