+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.
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. */
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
&& 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 :
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 :
#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"
int have_linux_v1;
int have_linux_v2;
int have_tdb;
+ bool have_gs;
};
{ 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. */
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
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 *
{
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)
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 :
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 :
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[] = { "(",
"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;
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);
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;
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);
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 ();
}
#define HWCAP_S390_VX 2048
#endif
+#ifndef HWCAP_S390_GS
+#define HWCAP_S390_GS 16384
+#endif
+
/* Register information. */
/* Program Status Word. */
#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
#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;
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