386 lines
14 KiB
Diff
386 lines
14 KiB
Diff
|
commit 1b63490c9173f8c9770b7885def720516aa9b9f8
|
||
|
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||
|
Date: Mon Sep 25 16:02:23 2017 +0200
|
||
|
|
||
|
S390: Add guarded-storage register support to GDB
|
||
|
|
||
|
Recognize targets with the new guarded-storage feature and then present
|
||
|
the guarded-storage registers and the Linux-specific guarded-storage
|
||
|
broadcast control block appropriately.
|
||
|
|
||
|
gdb/ChangeLog:
|
||
|
|
||
|
* s390-linux-nat.c (have_regset_gs): New static variable.
|
||
|
(s390_linux_fetch_inferior_registers): Handle guarded-storage
|
||
|
control block and guarded-storage broadcast control regsets.
|
||
|
(s390_read_description): Detect whether the target has
|
||
|
guarded-storage support, return appropriate tdesc.
|
||
|
* s390-linux-tdep.c (features/s390-gs-linux64.c): New include.
|
||
|
(features/s390x-gs-linux64.c): Likewise.
|
||
|
(struct gdbarch_tdep) <have_gs>: New field.
|
||
|
(s390_regmap_gs, s390_regmap_gsbc, s390_gs_regset)
|
||
|
(s390_gsbc_regset): New variables.
|
||
|
(s390_iterate_over_regset_sections): Iterate over s390_gs_regset
|
||
|
and s390_gsbc_regset, if applicable.
|
||
|
(s390_core_read_description): Check whether core file was from a
|
||
|
target with guarded-storage support; include appropriate regsets.
|
||
|
(s390_gdbarch_init): Add registers for guarded-storage support.
|
||
|
(_initialize_s390_tdep): Initialize new target descriptions that
|
||
|
include registers for guarded-storage support.
|
||
|
* s390-linux-tdep.h (HWCAP_S390_GS, S390_GSD_REGNUM)
|
||
|
(S390_GSSM_REGNUM, S390_GSEPLA_REGNUM)
|
||
|
(S390_BC_GSD_REGNUM, S390_BC_GSSM_REGNUM): New defines.
|
||
|
(S390_NUM_REGS): Adjust macro definition.
|
||
|
(s390_gs_regset, s390_gsbc_regset, tdesc_s390_gs_linux64)
|
||
|
(tdesc_s390x_gs_linux64): New declarations.
|
||
|
|
||
|
### a/gdb/ChangeLog
|
||
|
### b/gdb/ChangeLog
|
||
|
## -1,5 +1,31 @@
|
||
|
2017-09-25 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||
|
|
||
|
+ * s390-linux-nat.c (have_regset_gs): New static variable.
|
||
|
+ (s390_linux_fetch_inferior_registers): Handle guarded-storage
|
||
|
+ control block and guarded-storage broadcast control regsets.
|
||
|
+ (s390_read_description): Detect whether the target has
|
||
|
+ guarded-storage support, return appropriate tdesc.
|
||
|
+ * s390-linux-tdep.c (features/s390-gs-linux64.c): New include.
|
||
|
+ (features/s390x-gs-linux64.c): Likewise.
|
||
|
+ (struct gdbarch_tdep) <have_gs>: New field.
|
||
|
+ (s390_regmap_gs, s390_regmap_gsbc, s390_gs_regset)
|
||
|
+ (s390_gsbc_regset): New variables.
|
||
|
+ (s390_iterate_over_regset_sections): Iterate over s390_gs_regset
|
||
|
+ and s390_gsbc_regset, if applicable.
|
||
|
+ (s390_core_read_description): Check whether core file was from a
|
||
|
+ target with guarded-storage support; include appropriate regsets.
|
||
|
+ (s390_gdbarch_init): Add registers for guarded-storage support.
|
||
|
+ (_initialize_s390_tdep): Initialize new target descriptions that
|
||
|
+ include registers for guarded-storage support.
|
||
|
+ * s390-linux-tdep.h (HWCAP_S390_GS, S390_GSD_REGNUM)
|
||
|
+ (S390_GSSM_REGNUM, S390_GSEPLA_REGNUM)
|
||
|
+ (S390_BC_GSD_REGNUM, S390_BC_GSSM_REGNUM): New defines.
|
||
|
+ (S390_NUM_REGS): Adjust macro definition.
|
||
|
+ (s390_gs_regset, s390_gsbc_regset, tdesc_s390_gs_linux64)
|
||
|
+ (tdesc_s390x_gs_linux64): New declarations.
|
||
|
+
|
||
|
+2017-09-25 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||
|
+
|
||
|
* features/s390-gs-linux64.xml: New file.
|
||
|
* features/s390-gs.xml: New file.
|
||
|
* features/s390-gsbc.xml: New file.
|
||
|
--- a/gdb/s390-linux-nat.c
|
||
|
+++ b/gdb/s390-linux-nat.c
|
||
|
@@ -54,6 +54,7 @@ static int have_regset_last_break = 0;
|
||
|
static int have_regset_system_call = 0;
|
||
|
static int have_regset_tdb = 0;
|
||
|
static int have_regset_vxrs = 0;
|
||
|
+static int have_regset_gs = 0;
|
||
|
|
||
|
/* Register map for 32-bit executables running under a 64-bit
|
||
|
kernel. */
|
||
|
@@ -406,6 +407,18 @@ s390_linux_fetch_inferior_registers (struct target_ops *ops,
|
||
|
fetch_regset (regcache, tid, NT_S390_VXRS_HIGH, 16 * 16,
|
||
|
&s390_vxrs_high_regset);
|
||
|
}
|
||
|
+
|
||
|
+ if (have_regset_gs)
|
||
|
+ {
|
||
|
+ if (regnum == -1 || (regnum >= S390_GSD_REGNUM
|
||
|
+ && regnum <= S390_GSEPLA_REGNUM))
|
||
|
+ fetch_regset (regcache, tid, NT_S390_GS_CB, 4 * 8,
|
||
|
+ &s390_gs_regset);
|
||
|
+ if (regnum == -1 || (regnum >= S390_BC_GSD_REGNUM
|
||
|
+ && regnum <= S390_BC_GSEPLA_REGNUM))
|
||
|
+ fetch_regset (regcache, tid, NT_S390_GS_BC, 4 * 8,
|
||
|
+ &s390_gsbc_regset);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
/* Store register REGNUM back into the child process. If REGNUM is
|
||
|
@@ -974,8 +987,13 @@ s390_read_description (struct target_ops *ops)
|
||
|
&& check_regset (tid, NT_S390_VXRS_LOW, 16 * 8)
|
||
|
&& check_regset (tid, NT_S390_VXRS_HIGH, 16 * 16);
|
||
|
|
||
|
+ have_regset_gs = (hwcap & HWCAP_S390_GS)
|
||
|
+ && check_regset (tid, NT_S390_GS_CB, 4 * 8)
|
||
|
+ && check_regset (tid, NT_S390_GS_BC, 4 * 8);
|
||
|
+
|
||
|
if (s390_target_wordsize () == 8)
|
||
|
- return (have_regset_vxrs ?
|
||
|
+ return (have_regset_gs ? tdesc_s390x_gs_linux64 :
|
||
|
+ have_regset_vxrs ?
|
||
|
(have_regset_tdb ? tdesc_s390x_tevx_linux64 :
|
||
|
tdesc_s390x_vx_linux64) :
|
||
|
have_regset_tdb ? tdesc_s390x_te_linux64 :
|
||
|
@@ -984,7 +1002,8 @@ s390_read_description (struct target_ops *ops)
|
||
|
tdesc_s390x_linux64);
|
||
|
|
||
|
if (hwcap & HWCAP_S390_HIGH_GPRS)
|
||
|
- return (have_regset_vxrs ?
|
||
|
+ return (have_regset_gs ? tdesc_s390_gs_linux64 :
|
||
|
+ have_regset_vxrs ?
|
||
|
(have_regset_tdb ? tdesc_s390_tevx_linux64 :
|
||
|
tdesc_s390_vx_linux64) :
|
||
|
have_regset_tdb ? tdesc_s390_te_linux64 :
|
||
|
--- a/gdb/s390-linux-tdep.c
|
||
|
+++ b/gdb/s390-linux-tdep.c
|
||
|
@@ -69,12 +69,14 @@
|
||
|
#include "features/s390-te-linux64.c"
|
||
|
#include "features/s390-vx-linux64.c"
|
||
|
#include "features/s390-tevx-linux64.c"
|
||
|
+#include "features/s390-gs-linux64.c"
|
||
|
#include "features/s390x-linux64.c"
|
||
|
#include "features/s390x-linux64v1.c"
|
||
|
#include "features/s390x-linux64v2.c"
|
||
|
#include "features/s390x-te-linux64.c"
|
||
|
#include "features/s390x-vx-linux64.c"
|
||
|
#include "features/s390x-tevx-linux64.c"
|
||
|
+#include "features/s390x-gs-linux64.c"
|
||
|
|
||
|
#define XML_SYSCALL_FILENAME_S390 "syscalls/s390-linux.xml"
|
||
|
#define XML_SYSCALL_FILENAME_S390X "syscalls/s390x-linux.xml"
|
||
|
@@ -113,6 +115,7 @@ struct gdbarch_tdep
|
||
|
int have_linux_v1;
|
||
|
int have_linux_v2;
|
||
|
int have_tdb;
|
||
|
+ bool have_gs;
|
||
|
};
|
||
|
|
||
|
|
||
|
@@ -834,6 +837,24 @@ static const struct regcache_map_entry s390_regmap_vxrs_high[] =
|
||
|
{ 0 }
|
||
|
};
|
||
|
|
||
|
+static const struct regcache_map_entry s390_regmap_gs[] =
|
||
|
+ {
|
||
|
+ { 1, REGCACHE_MAP_SKIP, 8 },
|
||
|
+ { 1, S390_GSD_REGNUM, 8 },
|
||
|
+ { 1, S390_GSSM_REGNUM, 8 },
|
||
|
+ { 1, S390_GSEPLA_REGNUM, 8 },
|
||
|
+ { 0 }
|
||
|
+ };
|
||
|
+
|
||
|
+static const struct regcache_map_entry s390_regmap_gsbc[] =
|
||
|
+ {
|
||
|
+ { 1, REGCACHE_MAP_SKIP, 8 },
|
||
|
+ { 1, S390_BC_GSD_REGNUM, 8 },
|
||
|
+ { 1, S390_BC_GSSM_REGNUM, 8 },
|
||
|
+ { 1, S390_BC_GSEPLA_REGNUM, 8 },
|
||
|
+ { 0 }
|
||
|
+ };
|
||
|
+
|
||
|
|
||
|
/* Supply the TDB regset. Like regcache_supply_regset, but invalidate
|
||
|
the TDB registers unless the TDB format field is valid. */
|
||
|
@@ -905,6 +926,18 @@ const struct regset s390_vxrs_high_regset = {
|
||
|
regcache_collect_regset
|
||
|
};
|
||
|
|
||
|
+const struct regset s390_gs_regset = {
|
||
|
+ s390_regmap_gs,
|
||
|
+ regcache_supply_regset,
|
||
|
+ regcache_collect_regset
|
||
|
+};
|
||
|
+
|
||
|
+const struct regset s390_gsbc_regset = {
|
||
|
+ s390_regmap_gsbc,
|
||
|
+ regcache_supply_regset,
|
||
|
+ regcache_collect_regset
|
||
|
+};
|
||
|
+
|
||
|
/* Iterate over supported core file register note sections. */
|
||
|
|
||
|
static void
|
||
|
@@ -951,6 +984,23 @@ s390_iterate_over_regset_sections (struct gdbarch *gdbarch,
|
||
|
cb (".reg-s390-vxrs-high", 16 * 16, &s390_vxrs_high_regset,
|
||
|
"s390 vector registers 16-31", cb_data);
|
||
|
}
|
||
|
+
|
||
|
+ /* Iterate over the guarded-storage regsets if in "read" mode, or if
|
||
|
+ their registers are available. */
|
||
|
+ if (tdep->have_gs)
|
||
|
+ {
|
||
|
+ if (regcache == NULL
|
||
|
+ || REG_VALID == regcache_register_status (regcache,
|
||
|
+ S390_GSD_REGNUM))
|
||
|
+ cb (".reg-s390-gs-cb", 4 * 8, &s390_gs_regset,
|
||
|
+ "s390 guarded-storage registers", cb_data);
|
||
|
+
|
||
|
+ if (regcache == NULL
|
||
|
+ || REG_VALID == regcache_register_status (regcache,
|
||
|
+ S390_BC_GSD_REGNUM))
|
||
|
+ cb (".reg-s390-gs-bc", 4 * 8, &s390_gsbc_regset,
|
||
|
+ "s390 guarded-storage broadcast control", cb_data);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
static const struct target_desc *
|
||
|
@@ -959,7 +1009,7 @@ s390_core_read_description (struct gdbarch *gdbarch,
|
||
|
{
|
||
|
asection *section = bfd_get_section_by_name (abfd, ".reg");
|
||
|
CORE_ADDR hwcap = 0;
|
||
|
- int high_gprs, v1, v2, te, vx;
|
||
|
+ bool high_gprs, v1, v2, te, vx, gs;
|
||
|
|
||
|
target_auxv_search (target, AT_HWCAP, &hwcap);
|
||
|
if (!section)
|
||
|
@@ -971,12 +1021,14 @@ s390_core_read_description (struct gdbarch *gdbarch,
|
||
|
v2 = (bfd_get_section_by_name (abfd, ".reg-s390-system-call") != NULL);
|
||
|
vx = (hwcap & HWCAP_S390_VX);
|
||
|
te = (hwcap & HWCAP_S390_TE);
|
||
|
+ gs = (hwcap & HWCAP_S390_GS);
|
||
|
|
||
|
switch (bfd_section_size (abfd, section))
|
||
|
{
|
||
|
case s390_sizeof_gregset:
|
||
|
if (high_gprs)
|
||
|
- return (te && vx ? tdesc_s390_tevx_linux64 :
|
||
|
+ return (gs ? tdesc_s390_gs_linux64 :
|
||
|
+ te && vx ? tdesc_s390_tevx_linux64 :
|
||
|
vx ? tdesc_s390_vx_linux64 :
|
||
|
te ? tdesc_s390_te_linux64 :
|
||
|
v2 ? tdesc_s390_linux64v2 :
|
||
|
@@ -986,7 +1038,8 @@ s390_core_read_description (struct gdbarch *gdbarch,
|
||
|
v1 ? tdesc_s390_linux32v1 : tdesc_s390_linux32);
|
||
|
|
||
|
case s390x_sizeof_gregset:
|
||
|
- return (te && vx ? tdesc_s390x_tevx_linux64 :
|
||
|
+ return (gs ? tdesc_s390x_gs_linux64 :
|
||
|
+ te && vx ? tdesc_s390x_tevx_linux64 :
|
||
|
vx ? tdesc_s390x_vx_linux64 :
|
||
|
te ? tdesc_s390x_te_linux64 :
|
||
|
v2 ? tdesc_s390x_linux64v2 :
|
||
|
@@ -7767,6 +7820,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||
|
int have_linux_v2 = 0;
|
||
|
int have_tdb = 0;
|
||
|
int have_vx = 0;
|
||
|
+ int have_gs = 0;
|
||
|
int first_pseudo_reg, last_pseudo_reg;
|
||
|
static const char *const stap_register_prefixes[] = { "%", NULL };
|
||
|
static const char *const stap_register_indirection_prefixes[] = { "(",
|
||
|
@@ -7834,6 +7888,12 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||
|
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24",
|
||
|
"v25", "v26", "v27", "v28", "v29", "v30", "v31",
|
||
|
};
|
||
|
+ static const char *const gs_cb[] = {
|
||
|
+ "gsd", "gssm", "gsepla",
|
||
|
+ };
|
||
|
+ static const char *const gs_bc[] = {
|
||
|
+ "bc_gsd", "bc_gssm", "bc_gsepla",
|
||
|
+ };
|
||
|
const struct tdesc_feature *feature;
|
||
|
int i, valid_p = 1;
|
||
|
|
||
|
@@ -7937,6 +7997,29 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||
|
have_vx = 1;
|
||
|
}
|
||
|
|
||
|
+ /* Guarded-storage registers. */
|
||
|
+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.gs");
|
||
|
+ if (feature)
|
||
|
+ {
|
||
|
+ for (i = 0; i < 3; i++)
|
||
|
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||
|
+ S390_GSD_REGNUM + i,
|
||
|
+ gs_cb[i]);
|
||
|
+ have_gs = 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Guarded-storage broadcast control. */
|
||
|
+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.gsbc");
|
||
|
+ if (feature)
|
||
|
+ {
|
||
|
+ valid_p &= have_gs;
|
||
|
+
|
||
|
+ for (i = 0; i < 3; i++)
|
||
|
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||
|
+ S390_BC_GSD_REGNUM + i,
|
||
|
+ gs_bc[i]);
|
||
|
+ }
|
||
|
+
|
||
|
if (!valid_p)
|
||
|
{
|
||
|
tdesc_data_cleanup (tdesc_data);
|
||
|
@@ -7970,6 +8053,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||
|
continue;
|
||
|
if ((tdep->gpr_full_regnum != -1) != have_upper)
|
||
|
continue;
|
||
|
+ if (tdep->have_gs != have_gs)
|
||
|
+ continue;
|
||
|
if (tdesc_data != NULL)
|
||
|
tdesc_data_cleanup (tdesc_data);
|
||
|
return arches->gdbarch;
|
||
|
@@ -7982,6 +8067,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||
|
tdep->have_linux_v1 = have_linux_v1;
|
||
|
tdep->have_linux_v2 = have_linux_v2;
|
||
|
tdep->have_tdb = have_tdb;
|
||
|
+ tdep->have_gs = have_gs;
|
||
|
gdbarch = gdbarch_alloc (&info, tdep);
|
||
|
|
||
|
set_gdbarch_believe_pcc_promotion (gdbarch, 0);
|
||
|
@@ -8157,10 +8243,12 @@ _initialize_s390_tdep (void)
|
||
|
initialize_tdesc_s390_te_linux64 ();
|
||
|
initialize_tdesc_s390_vx_linux64 ();
|
||
|
initialize_tdesc_s390_tevx_linux64 ();
|
||
|
+ initialize_tdesc_s390_gs_linux64 ();
|
||
|
initialize_tdesc_s390x_linux64 ();
|
||
|
initialize_tdesc_s390x_linux64v1 ();
|
||
|
initialize_tdesc_s390x_linux64v2 ();
|
||
|
initialize_tdesc_s390x_te_linux64 ();
|
||
|
initialize_tdesc_s390x_vx_linux64 ();
|
||
|
initialize_tdesc_s390x_tevx_linux64 ();
|
||
|
+ initialize_tdesc_s390x_gs_linux64 ();
|
||
|
}
|
||
|
--- a/gdb/s390-linux-tdep.h
|
||
|
+++ b/gdb/s390-linux-tdep.h
|
||
|
@@ -33,6 +33,10 @@
|
||
|
#define HWCAP_S390_VX 2048
|
||
|
#endif
|
||
|
|
||
|
+#ifndef HWCAP_S390_GS
|
||
|
+#define HWCAP_S390_GS 16384
|
||
|
+#endif
|
||
|
+
|
||
|
/* Register information. */
|
||
|
|
||
|
/* Program Status Word. */
|
||
|
@@ -166,8 +170,14 @@
|
||
|
#define S390_V29_REGNUM 119
|
||
|
#define S390_V30_REGNUM 120
|
||
|
#define S390_V31_REGNUM 121
|
||
|
+#define S390_GSD_REGNUM 122
|
||
|
+#define S390_GSSM_REGNUM 123
|
||
|
+#define S390_GSEPLA_REGNUM 124
|
||
|
+#define S390_BC_GSD_REGNUM 125
|
||
|
+#define S390_BC_GSSM_REGNUM 126
|
||
|
+#define S390_BC_GSEPLA_REGNUM 127
|
||
|
/* Total. */
|
||
|
-#define S390_NUM_REGS 122
|
||
|
+#define S390_NUM_REGS 128
|
||
|
|
||
|
/* Special register usage. */
|
||
|
#define S390_SP_REGNUM S390_R15_REGNUM
|
||
|
@@ -198,6 +208,8 @@ extern const struct regset s390_tdb_regset;
|
||
|
#define s390_sizeof_tdbregset 0x100
|
||
|
extern const struct regset s390_vxrs_low_regset;
|
||
|
extern const struct regset s390_vxrs_high_regset;
|
||
|
+extern const struct regset s390_gs_regset;
|
||
|
+extern const struct regset s390_gsbc_regset;
|
||
|
|
||
|
/* GNU/Linux target descriptions. */
|
||
|
extern struct target_desc *tdesc_s390_linux32;
|
||
|
@@ -209,11 +221,13 @@ extern struct target_desc *tdesc_s390_linux64v2;
|
||
|
extern struct target_desc *tdesc_s390_te_linux64;
|
||
|
extern struct target_desc *tdesc_s390_vx_linux64;
|
||
|
extern struct target_desc *tdesc_s390_tevx_linux64;
|
||
|
+extern struct target_desc *tdesc_s390_gs_linux64;
|
||
|
extern struct target_desc *tdesc_s390x_linux64;
|
||
|
extern struct target_desc *tdesc_s390x_linux64v1;
|
||
|
extern struct target_desc *tdesc_s390x_linux64v2;
|
||
|
extern struct target_desc *tdesc_s390x_te_linux64;
|
||
|
extern struct target_desc *tdesc_s390x_vx_linux64;
|
||
|
extern struct target_desc *tdesc_s390x_tevx_linux64;
|
||
|
+extern struct target_desc *tdesc_s390x_gs_linux64;
|
||
|
|
||
|
#endif
|