[aarch64] tpidr2: Fix erroneous detection logic for TPIDR2

The detection logic for TPIDR2 was implemented incorrectly.  Originally
the detection was supposed to be through a ptrace error code, but in reality,
for backwards compatibility, the detection should be based on the size of
the returned iovec.

For instance, if a target supports both TPIDR and TPIDR2, ptrace will return a
iovec size of 16.  If a target only supports TPIDR and not TPIDR2, it will
return a iovec size of 8, even if we asked for 16 bytes.

This patch fixes this issue in code that is shared between gdb and gdbserver,
therefore both gdb and gdbserver are fixed.

Tested on AArch64/Linux Ubuntu 20.04.
This commit is contained in:
Luis Machado 2023-03-13 13:14:41 +00:00
parent 4978296176
commit d747348d02

View File

@ -261,13 +261,13 @@ aarch64_tls_register_count (int tid)
iovec.iov_base = tls_regs; iovec.iov_base = tls_regs;
iovec.iov_len = sizeof (tls_regs); iovec.iov_len = sizeof (tls_regs);
/* Attempt to read both TPIDR and TPIDR2. If the request fails, it means /* Attempt to read both TPIDR and TPIDR2. If ptrace returns less data than
the Linux Kernel does not support TPIDR2. we are expecting, that means it doesn't support all the registers. From
the iovec length, figure out how many TPIDR registers the target actually
Otherwise the Linux Kernel supports both TPIDR and TPIDR2. */ supports. */
if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_TLS, &iovec) != 0) if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_TLS, &iovec) != 0)
return 1; return 0;
/* TPIDR2 is available as well. */ /* Calculate how many TPIDR registers we have. */
return 2; return iovec.iov_len / sizeof (uint64_t);
} }