This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] 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 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]