mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-01 13:26:47 +08:00
S390: Fix TDB regset recognition
When checking for the presence of the TDB regset, the current code interprets ENODATA from PTRACE_GETREGSET as an indication that the TDB regset *could* occur on this system, but the inferior stopped outside a transaction. However, the Linux kernel actually reports ENODATA even on systems without the transactional execution facility. Thus the logic is now changed to check the TE field in the HWCAP as well. This version also checks the existence of the TDB regset -- just to be on the safe side when running on TE-enabled hardware with a kernel that does not offer the TDB regset for some reason. gdb/ * s390-linux-nat.c (s390_read_description): Consider the TE field in the HWCAP for determining 'have_regset_tdb'. gdbserver/ * linux-s390-low.c (HWCAP_S390_TE): New define. (s390_arch_setup): Consider the TE field in the HWCAP for determining 'have_regset_tdb'.
This commit is contained in:
parent
1d946cb356
commit
6682d9595e
@ -1,3 +1,8 @@
|
||||
2013-11-06 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||||
|
||||
* s390-linux-nat.c (s390_read_description): Consider the TE field
|
||||
in the HWCAP for determining 'have_regset_tdb'.
|
||||
|
||||
2013-11-06 Will Newton <will.newton@linaro.org>
|
||||
|
||||
PR gdb/12866
|
||||
|
@ -1,3 +1,9 @@
|
||||
2013-11-06 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||||
|
||||
* linux-s390-low.c (HWCAP_S390_TE): New define.
|
||||
(s390_arch_setup): Consider the TE field in the HWCAP for
|
||||
determining 'have_regset_tdb'.
|
||||
|
||||
2013-10-16 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
|
||||
PR gdb/16014
|
||||
|
@ -32,6 +32,10 @@
|
||||
#define HWCAP_S390_HIGH_GPRS 512
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_S390_TE
|
||||
#define HWCAP_S390_TE 1024
|
||||
#endif
|
||||
|
||||
#ifndef PTRACE_GETREGSET
|
||||
#define PTRACE_GETREGSET 0x4204
|
||||
#endif
|
||||
@ -425,6 +429,61 @@ s390_arch_setup (void)
|
||||
= s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
|
||||
int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
|
||||
|
||||
/* Assume 31-bit inferior process. */
|
||||
if (have_regset_system_call)
|
||||
tdesc = tdesc_s390_linux32v2;
|
||||
else if (have_regset_last_break)
|
||||
tdesc = tdesc_s390_linux32v1;
|
||||
else
|
||||
tdesc = tdesc_s390_linux32;
|
||||
|
||||
/* On a 64-bit host, check the low bit of the (31-bit) PSWM
|
||||
-- if this is one, we actually have a 64-bit inferior. */
|
||||
#ifdef __s390x__
|
||||
{
|
||||
unsigned int pswm;
|
||||
struct regcache *regcache = new_register_cache (tdesc);
|
||||
|
||||
fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
|
||||
collect_register_by_name (regcache, "pswm", &pswm);
|
||||
free_register_cache (regcache);
|
||||
|
||||
if (pswm & 1)
|
||||
{
|
||||
if (have_regset_tdb)
|
||||
have_regset_tdb =
|
||||
(s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_TE) != 0;
|
||||
|
||||
if (have_regset_tdb)
|
||||
tdesc = tdesc_s390x_te_linux64;
|
||||
else if (have_regset_system_call)
|
||||
tdesc = tdesc_s390x_linux64v2;
|
||||
else if (have_regset_last_break)
|
||||
tdesc = tdesc_s390x_linux64v1;
|
||||
else
|
||||
tdesc = tdesc_s390x_linux64;
|
||||
}
|
||||
|
||||
/* For a 31-bit inferior, check whether the kernel supports
|
||||
using the full 64-bit GPRs. */
|
||||
else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
|
||||
{
|
||||
have_hwcap_s390_high_gprs = 1;
|
||||
if (have_regset_tdb)
|
||||
have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0;
|
||||
|
||||
if (have_regset_tdb)
|
||||
tdesc = tdesc_s390_te_linux64;
|
||||
else if (have_regset_system_call)
|
||||
tdesc = tdesc_s390_linux64v2;
|
||||
else if (have_regset_last_break)
|
||||
tdesc = tdesc_s390_linux64v1;
|
||||
else
|
||||
tdesc = tdesc_s390_linux64;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update target_regsets according to available register sets. */
|
||||
for (regset = s390_regsets; regset->fill_function != NULL; regset++)
|
||||
if (regset->get_request == PTRACE_GETREGSET)
|
||||
@ -442,53 +501,6 @@ s390_arch_setup (void)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Assume 31-bit inferior process. */
|
||||
if (have_regset_system_call)
|
||||
tdesc = tdesc_s390_linux32v2;
|
||||
else if (have_regset_last_break)
|
||||
tdesc = tdesc_s390_linux32v1;
|
||||
else
|
||||
tdesc = tdesc_s390_linux32;
|
||||
|
||||
/* On a 64-bit host, check the low bit of the (31-bit) PSWM
|
||||
-- if this is one, we actually have a 64-bit inferior. */
|
||||
#ifdef __s390x__
|
||||
{
|
||||
unsigned int pswm;
|
||||
struct regcache *regcache = new_register_cache (tdesc);
|
||||
fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
|
||||
collect_register_by_name (regcache, "pswm", &pswm);
|
||||
free_register_cache (regcache);
|
||||
|
||||
if (pswm & 1)
|
||||
{
|
||||
if (have_regset_tdb)
|
||||
tdesc = tdesc_s390x_te_linux64;
|
||||
if (have_regset_system_call)
|
||||
tdesc = tdesc_s390x_linux64v2;
|
||||
else if (have_regset_last_break)
|
||||
tdesc = tdesc_s390x_linux64v1;
|
||||
else
|
||||
tdesc = tdesc_s390x_linux64;
|
||||
}
|
||||
|
||||
/* For a 31-bit inferior, check whether the kernel supports
|
||||
using the full 64-bit GPRs. */
|
||||
else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
|
||||
{
|
||||
have_hwcap_s390_high_gprs = 1;
|
||||
|
||||
if (have_regset_tdb)
|
||||
tdesc = tdesc_s390_te_linux64;
|
||||
else if (have_regset_system_call)
|
||||
tdesc = tdesc_s390_linux64v2;
|
||||
else if (have_regset_last_break)
|
||||
tdesc = tdesc_s390_linux64v1;
|
||||
else
|
||||
tdesc = tdesc_s390_linux64;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
current_process ()->tdesc = tdesc;
|
||||
}
|
||||
|
||||
|
@ -632,8 +632,6 @@ s390_read_description (struct target_ops *ops)
|
||||
= check_regset (tid, NT_S390_LAST_BREAK, 8);
|
||||
have_regset_system_call
|
||||
= check_regset (tid, NT_S390_SYSTEM_CALL, 4);
|
||||
have_regset_tdb
|
||||
= check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
|
||||
|
||||
#ifdef __s390x__
|
||||
/* If GDB itself is compiled as 64-bit, we are running on a machine in
|
||||
@ -642,6 +640,9 @@ s390_read_description (struct target_ops *ops)
|
||||
addressing mode, but the kernel supports using 64-bit registers in
|
||||
that mode, report s390 architecture with 64-bit GPRs. */
|
||||
|
||||
have_regset_tdb = (s390_get_hwcap () & HWCAP_S390_TE) ?
|
||||
check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset) : 0;
|
||||
|
||||
if (s390_target_wordsize () == 8)
|
||||
return (have_regset_tdb ? tdesc_s390x_te_linux64 :
|
||||
have_regset_system_call? tdesc_s390x_linux64v2 :
|
||||
|
Loading…
Reference in New Issue
Block a user