This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] S390: Fix TDB regset recognition
- From: Andreas Arnez <arnez at linux dot vnet dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Cc: Ulrich Weigand <uweigand at de dot ibm dot com>, Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- Date: Mon, 04 Nov 2013 15:18:00 +0100
- Subject: [PATCH] S390: Fix TDB regset recognition
- Authentication-results: sourceware.org; auth=none
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 instead.
gdb/
* s390-linux-nat.c (s390_read_description): Deduce
'have_regset_tdb' from the TE field in HWCAP instead of from the
regset presence as reported by the system.
gdbserver/
* linux-s390-low.c (HWCAP_S390_TE): New define.
(s390_arch_setup): Deduce 'have_regset_tdb' from the TE field in
HWCAP instead of from the regset presence as reported by the
system.
---
gdb/gdbserver/linux-s390-low.c | 52 +++++++++++++++++++++++++-----------------
gdb/s390-linux-nat.c | 4 ++--
2 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c
index a2df037..a5937c1 100644
--- a/gdb/gdbserver/linux-s390-low.c
+++ b/gdb/gdbserver/linux-s390-low.c
@@ -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
@@ -423,24 +427,7 @@ s390_arch_setup (void)
= s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
int have_regset_system_call
= s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
- int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
-
- /* Update target_regsets according to available register sets. */
- for (regset = s390_regsets; regset->fill_function != NULL; regset++)
- if (regset->get_request == PTRACE_GETREGSET)
- switch (regset->nt_type)
- {
- case NT_S390_LAST_BREAK:
- regset->size = have_regset_last_break? 8 : 0;
- break;
- case NT_S390_SYSTEM_CALL:
- regset->size = have_regset_system_call? 4 : 0;
- break;
- case NT_S390_TDB:
- regset->size = have_regset_tdb ? 256 : 0;
- default:
- break;
- }
+ int have_regset_tdb = 0;
/* Assume 31-bit inferior process. */
if (have_regset_system_call)
@@ -456,16 +443,20 @@ s390_arch_setup (void)
{
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;
+ {
+ tdesc = tdesc_s390x_linux64v2;
+ have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0;
+ if (have_regset_tdb)
+ tdesc = tdesc_s390x_te_linux64;
+ }
else if (have_regset_last_break)
tdesc = tdesc_s390x_linux64v1;
else
@@ -477,6 +468,7 @@ s390_arch_setup (void)
else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
{
have_hwcap_s390_high_gprs = 1;
+ have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0;
if (have_regset_tdb)
tdesc = tdesc_s390_te_linux64;
@@ -489,6 +481,24 @@ s390_arch_setup (void)
}
}
#endif
+
+ /* Update target_regsets according to available register sets. */
+ for (regset = s390_regsets; regset->fill_function != NULL; regset++)
+ if (regset->get_request == PTRACE_GETREGSET)
+ switch (regset->nt_type)
+ {
+ case NT_S390_LAST_BREAK:
+ regset->size = have_regset_last_break? 8 : 0;
+ break;
+ case NT_S390_SYSTEM_CALL:
+ regset->size = have_regset_system_call? 4 : 0;
+ break;
+ case NT_S390_TDB:
+ regset->size = have_regset_tdb ? 256 : 0;
+ default:
+ break;
+ }
+
current_process ()->tdesc = tdesc;
}
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index 67f97f9..02d5b5f 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -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,8 @@ 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) ? 1 : 0;
+
if (s390_target_wordsize () == 8)
return (have_regset_tdb ? tdesc_s390x_te_linux64 :
have_regset_system_call? tdesc_s390x_linux64v2 :
--
1.7.11.4