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.
This commit is contained in:
Andreas Arnez 2017-09-25 16:02:23 +02:00
parent 96235dc1ac
commit 1b63490c91
4 changed files with 153 additions and 6 deletions

View File

@ -1,3 +1,29 @@
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.

View File

@ -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 :

View File

@ -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 ();
}

View File

@ -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