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]

[RFA][PATCH v4 4/5] S/390: Exploit dynamic core regset sections


Exploit dynamic core regset sections on S/390, such that the presence of
the TDB regset in a gcore-written core file depends on the validity of
the TDB registers.

2013-07-03  Andreas Arnez  <arnez@linux.vnet.ibm.com>

	* s390-tdep.c (gdbarch_tdep): New fields "have_linux_v1" and
	"have_linux_v2".
	(s390_linux32_regset_sections): Remove array.
	(s390_linux32v1_regset_sections): Likewise.
	(s390_linux32v2_regset_sections): Likewise.
	(s390_linux64_regset_sections): Likewise.
	(s390_linux64v1_regset_sections): Likewise.
	(s390_linux64v2_regset_sections): Likewise.
	(s390x_linux64_regset_sections): Likewise.
	(s390x_linux64v1_regset_sections): Likewise.
	(s390x_linux64v2_regset_sections): Likewise.
	(s390_iterate_over_regset_sections ): New function.
	(s390_gdbarch_init): Initialize new tdep fields "have_linux_v1"
	and "have_linux_v2".  Remove all invocations of
	set_gdbarch_core_regset_sections; instead, call
	set_gdbarch_iterate_over_regset_sections.

Index: gdb/gdb/s390-tdep.c
===================================================================
--- gdb.orig/gdb/s390-tdep.c
+++ gdb/gdb/s390-tdep.c
@@ -84,6 +84,9 @@ struct gdbarch_tdep
 
   const struct regset *fpregset;
   int sizeof_fpregset;
+
+  int have_linux_v1;
+  int have_linux_v2;
 };
 
 
@@ -673,83 +676,38 @@ static const struct regset s390_tdb_regs
   s390_collect_regset
 };
 
-static struct core_regset_section s390_linux32_regset_sections[] =
-{
-  { ".reg", s390_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { NULL, 0}
-};
-
-static struct core_regset_section s390_linux32v1_regset_sections[] =
-{
-  { ".reg", s390_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { ".reg-s390-last-break", 8, "s390 last-break address" },
-  { NULL, 0}
-};
-
-static struct core_regset_section s390_linux32v2_regset_sections[] =
-{
-  { ".reg", s390_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { ".reg-s390-last-break", 8, "s390 last-break address" },
-  { ".reg-s390-system-call", 4, "s390 system-call" },
-  { NULL, 0}
-};
-
-static struct core_regset_section s390_linux64_regset_sections[] =
-{
-  { ".reg", s390_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" },
-  { NULL, 0}
-};
-
-static struct core_regset_section s390_linux64v1_regset_sections[] =
-{
-  { ".reg", s390_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" },
-  { ".reg-s390-last-break", 8, "s930 last-break address" },
-  { NULL, 0}
-};
-
-static struct core_regset_section s390_linux64v2_regset_sections[] =
-{
-  { ".reg", s390_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" },
-  { ".reg-s390-last-break", 8, "s930 last-break address" },
-  { ".reg-s390-system-call", 4, "s390 system-call" },
-  { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" },
-  { NULL, 0}
-};
-
-static struct core_regset_section s390x_linux64_regset_sections[] =
-{
-  { ".reg", s390x_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { NULL, 0}
-};
-
-static struct core_regset_section s390x_linux64v1_regset_sections[] =
-{
-  { ".reg", s390x_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { ".reg-s390-last-break", 8, "s930 last-break address" },
-  { NULL, 0}
-};
+/* Iterate over supported core file register note sections. */
 
-static struct core_regset_section s390x_linux64v2_regset_sections[] =
+static void
+s390_iterate_over_regset_sections (struct gdbarch *gdbarch,
+				   iterate_over_regset_sections_cb *cb,
+				   void *cb_data,
+				   const struct regcache *regcache)
 {
-  { ".reg", s390x_sizeof_gregset, "general-purpose" },
-  { ".reg2", s390_sizeof_fpregset, "floating-point" },
-  { ".reg-s390-last-break", 8, "s930 last-break address" },
-  { ".reg-s390-system-call", 4, "s390 system-call" },
-  { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" },
-  { NULL, 0}
-};
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int is_32_bit = tdep->abi == ABI_LINUX_S390 && tdep->gpr_full_regnum == -1;
 
+  if (cb (".reg", is_32_bit ? s390_sizeof_gregset : s390x_sizeof_gregset,
+	  "general-purpose", cb_data))
+    return;
+  if (cb (".reg2", s390_sizeof_fpregset, "floating-point", cb_data))
+    return;
+  if (tdep->abi == ABI_LINUX_S390 && tdep->gpr_full_regnum != -1)
+    if (cb (".reg-s390-high-gprs", 16*4, "s390 GPR upper halves", cb_data))
+      return;
+  if (tdep->have_linux_v1)
+    if (cb (".reg-s390-last-break", 8, "s930 last-break address", cb_data))
+      return;
+  if (tdep->have_linux_v2)
+    {
+      if (cb (".reg-s390-system-call", 4, "s390 system-call", cb_data))
+	return;
+      if (regcache == NULL
+	  || REG_VALID == regcache_register_status (regcache,
+						    S390_TDB_DWORD0_REGNUM))
+	cb (".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB", cb_data);
+    }
+}
 
 /* Return the appropriate register set for the core section identified
    by SECT_NAME and SECT_SIZE.  */
@@ -3160,20 +3118,23 @@ s390_gdbarch_init (struct gdbarch_info i
        arches = gdbarch_list_lookup_by_info (arches->next, &info))
     {
       tdep = gdbarch_tdep (arches->gdbarch);
-      if (!tdep)
-	continue;
-      if (tdep->abi != tdep_abi)
-	continue;
-      if ((tdep->gpr_full_regnum != -1) != have_upper)
-	continue;
-      if (tdesc_data != NULL)
-	tdesc_data_cleanup (tdesc_data);
-      return arches->gdbarch;
+      if (tdep
+	  && tdep->abi == tdep_abi
+	  && (tdep->gpr_full_regnum != -1) == have_upper
+	  && tdep->have_linux_v1 == have_linux_v1
+	  && tdep->have_linux_v2 == have_linux_v2)
+	{
+	  if (tdesc_data != NULL)
+	    tdesc_data_cleanup (tdesc_data);
+	  return arches->gdbarch;
+	}
     }
 
   /* Otherwise create a new gdbarch for the specified machine type.  */
   tdep = XCALLOC (1, struct gdbarch_tdep);
   tdep->abi = tdep_abi;
+  tdep->have_linux_v1 = have_linux_v1;
+  tdep->have_linux_v2 = have_linux_v2;
   gdbarch = gdbarch_alloc (&info, tdep);
 
   set_gdbarch_believe_pcc_promotion (gdbarch, 0);
@@ -3204,6 +3165,8 @@ s390_gdbarch_init (struct gdbarch_info i
   set_gdbarch_regset_from_core_section (gdbarch,
                                         s390_regset_from_core_section);
   set_gdbarch_core_read_description (gdbarch, s390_core_read_description);
+  set_gdbarch_iterate_over_regset_sections (gdbarch,
+					    s390_iterate_over_regset_sections);
   set_gdbarch_cannot_store_register (gdbarch, s390_cannot_store_register);
   set_gdbarch_write_pc (gdbarch, s390_write_pc);
   set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read);
@@ -3271,31 +3234,6 @@ s390_gdbarch_init (struct gdbarch_info i
       set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove);
       set_solib_svr4_fetch_link_map_offsets
 	(gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
-      if (have_upper)
-	{
-	  if (have_linux_v2)
-	    set_gdbarch_core_regset_sections (gdbarch,
-					      s390_linux64v2_regset_sections);
-	  else if (have_linux_v1)
-	    set_gdbarch_core_regset_sections (gdbarch,
-					      s390_linux64v1_regset_sections);
-	  else
-	    set_gdbarch_core_regset_sections (gdbarch,
-					      s390_linux64_regset_sections);
-	}
-      else
-	{
-	  if (have_linux_v2)
-	    set_gdbarch_core_regset_sections (gdbarch,
-					      s390_linux32v2_regset_sections);
-	  else if (have_linux_v1)
-	    set_gdbarch_core_regset_sections (gdbarch,
-					      s390_linux32v1_regset_sections);
-	  else
-	    set_gdbarch_core_regset_sections (gdbarch,
-					      s390_linux32_regset_sections);
-	}
       break;
 
     case ABI_LINUX_ZSERIES:
@@ -3315,16 +3253,6 @@ s390_gdbarch_init (struct gdbarch_info i
                                                     s390_address_class_type_flags_to_name);
       set_gdbarch_address_class_name_to_type_flags (gdbarch,
                                                     s390_address_class_name_to_type_flags);
-
-      if (have_linux_v2)
-	set_gdbarch_core_regset_sections (gdbarch,
-					  s390x_linux64v2_regset_sections);
-      else if (have_linux_v1)
-	set_gdbarch_core_regset_sections (gdbarch,
-					  s390x_linux64v1_regset_sections);
-      else
-	set_gdbarch_core_regset_sections (gdbarch,
-					  s390x_linux64_regset_sections);
       break;
     }
 


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