aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authorAndreas Arnez <arnez at linux dot vnet dot ibm dot com>2013-11-05 18:43:50 +0100
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2013-11-06 21:44:31 +0100
commit6682d9595ed8d9b9bba5470bfd7fd1ccd378f19a (patch)
tree21f06984e24e3cd8d274d1be59ff1f3e33176305 /gdb/gdbserver
parent1d946cb356d22867128b40b9560857f930b2b0b0 (diff)
downloadgdb-6682d9595ed8d9b9bba5470bfd7fd1ccd378f19a.zip
gdb-6682d9595ed8d9b9bba5470bfd7fd1ccd378f19a.tar.gz
gdb-6682d9595ed8d9b9bba5470bfd7fd1ccd378f19a.tar.bz2
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'.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog6
-rw-r--r--gdb/gdbserver/linux-s390-low.c48
2 files changed, 36 insertions, 18 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 4f15cfb..9d514e5 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -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
diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c
index a2df037..ae8204b 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
@@ -425,23 +429,6 @@ 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);
- /* 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;
- }
-
/* Assume 31-bit inferior process. */
if (have_regset_system_call)
tdesc = tdesc_s390_linux32v2;
@@ -456,6 +443,7 @@ 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);
@@ -463,8 +451,12 @@ s390_arch_setup (void)
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;
- if (have_regset_system_call)
+ else if (have_regset_system_call)
tdesc = tdesc_s390x_linux64v2;
else if (have_regset_last_break)
tdesc = tdesc_s390x_linux64v1;
@@ -477,6 +469,8 @@ s390_arch_setup (void)
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;
@@ -489,6 +483,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;
}