s390: Move tdesc validation to separate function
Simplify s390_gdbarch_init by moving the target description validation to a separate function. gdb/ChangeLog: * s390-linux-tdep.c (s390_tdesc_valid): New function. (s390_validate_reg_range): New macro. (s390_gdbarch_init): Adjust.
This commit is contained in:
parent
095085d847
commit
47c9317e71
|
@ -1,3 +1,9 @@
|
|||
2018-01-23 Philipp Rudo <prudo@linux.vnet.ibm.com>
|
||||
|
||||
* s390-linux-tdep.c (s390_tdesc_valid): New function.
|
||||
(s390_validate_reg_range): New macro.
|
||||
(s390_gdbarch_init): Adjust.
|
||||
|
||||
2018-01-23 Philipp Rudo <prudo@linux.vnet.ibm.com>
|
||||
|
||||
* s390-linux-tdep.c (gdbarch_tdep) <tdesc>: New field.
|
||||
|
|
|
@ -7810,81 +7810,27 @@ s390_init_linux_record_tdep (struct linux_record_tdep *record_tdep,
|
|||
record_tdep->ioctl_FIOQSIZE = 0x545e;
|
||||
}
|
||||
|
||||
/* Allocate and initialize new gdbarch_tdep. Caller is responsible to free
|
||||
memory after use. */
|
||||
/* Validate the range of registers. NAMES must be known at compile time. */
|
||||
|
||||
static struct gdbarch_tdep *
|
||||
s390_gdbarch_tdep_alloc ()
|
||||
{
|
||||
struct gdbarch_tdep *tdep = XCNEW (struct gdbarch_tdep);
|
||||
|
||||
tdep->tdesc = NULL;
|
||||
|
||||
tdep->abi = ABI_NONE;
|
||||
tdep->vector_abi = S390_VECTOR_ABI_NONE;
|
||||
|
||||
tdep->gpr_full_regnum = -1;
|
||||
tdep->v0_full_regnum = -1;
|
||||
tdep->pc_regnum = -1;
|
||||
tdep->cc_regnum = -1;
|
||||
|
||||
tdep->have_upper = false;
|
||||
tdep->have_linux_v1 = false;
|
||||
tdep->have_linux_v2 = false;
|
||||
tdep->have_tdb = false;
|
||||
tdep->have_vx = false;
|
||||
tdep->have_gs = false;
|
||||
|
||||
return tdep;
|
||||
}
|
||||
|
||||
/* Set up gdbarch struct. */
|
||||
|
||||
static struct gdbarch *
|
||||
s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
{
|
||||
const struct target_desc *tdesc = info.target_desc;
|
||||
struct tdesc_arch_data *tdesc_data = NULL;
|
||||
int first_pseudo_reg, last_pseudo_reg;
|
||||
static const char *const stap_register_prefixes[] = { "%", NULL };
|
||||
static const char *const stap_register_indirection_prefixes[] = { "(",
|
||||
NULL };
|
||||
static const char *const stap_register_indirection_suffixes[] = { ")",
|
||||
NULL };
|
||||
|
||||
struct gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();
|
||||
struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
|
||||
|
||||
/* Default ABI and register size. */
|
||||
switch (info.bfd_arch_info->mach)
|
||||
{
|
||||
case bfd_mach_s390_31:
|
||||
tdep->abi = ABI_LINUX_S390;
|
||||
break;
|
||||
|
||||
case bfd_mach_s390_64:
|
||||
tdep->abi = ABI_LINUX_ZSERIES;
|
||||
break;
|
||||
|
||||
default:
|
||||
xfree (tdep);
|
||||
gdbarch_free (gdbarch);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Use default target description if none provided by the target. */
|
||||
if (!tdesc_has_registers (tdesc))
|
||||
{
|
||||
if (tdep->abi == ABI_LINUX_S390)
|
||||
tdesc = tdesc_s390_linux32;
|
||||
else
|
||||
tdesc = tdesc_s390x_linux64;
|
||||
}
|
||||
tdep->tdesc = tdesc;
|
||||
|
||||
/* Check any target description for validity. */
|
||||
if (tdesc_has_registers (tdesc))
|
||||
#define s390_validate_reg_range(feature, tdesc_data, start, names) \
|
||||
do \
|
||||
{ \
|
||||
for (int i = 0; i < ARRAY_SIZE (names); i++) \
|
||||
if (!tdesc_numbered_register (feature, tdesc_data, start + i, names[i])) \
|
||||
return false; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Validate the target description. Also numbers registers contained in
|
||||
tdesc. */
|
||||
|
||||
static bool
|
||||
s390_tdesc_valid (struct gdbarch_tdep *tdep,
|
||||
struct tdesc_arch_data *tdesc_data)
|
||||
{
|
||||
static const char *const psw[] = {
|
||||
"pswm", "pswa"
|
||||
};
|
||||
static const char *const gprs[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
|
||||
|
@ -7924,71 +7870,46 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
static const char *const gs_bc[] = {
|
||||
"bc_gsd", "bc_gssm", "bc_gsepla",
|
||||
};
|
||||
const struct tdesc_feature *feature;
|
||||
int i, valid_p = 1;
|
||||
|
||||
const struct target_desc *tdesc = tdep->tdesc;
|
||||
const struct tdesc_feature *feature;
|
||||
|
||||
/* Core registers, i.e. general purpose and PSW. */
|
||||
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.core");
|
||||
if (feature == NULL)
|
||||
{
|
||||
xfree (tdep);
|
||||
gdbarch_free (gdbarch);
|
||||
return NULL;
|
||||
}
|
||||
return false;
|
||||
|
||||
tdesc_data = tdesc_data_alloc ();
|
||||
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_PSWM_REGNUM, "pswm");
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_PSWA_REGNUM, "pswa");
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_PSWM_REGNUM, psw);
|
||||
|
||||
if (tdesc_unnumbered_register (feature, "r0"))
|
||||
{
|
||||
for (i = 0; i < 16; i++)
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_R0_REGNUM + i, gprs[i]);
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_R0_REGNUM, gprs);
|
||||
}
|
||||
else
|
||||
{
|
||||
tdep->have_upper = true;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_R0_REGNUM + i,
|
||||
gprs_lower[i]);
|
||||
for (i = 0; i < 16; i++)
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_R0_UPPER_REGNUM + i,
|
||||
gprs_upper[i]);
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_R0_REGNUM,
|
||||
gprs_lower);
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_R0_UPPER_REGNUM,
|
||||
gprs_upper);
|
||||
}
|
||||
|
||||
/* Floating point registers. */
|
||||
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.fpr");
|
||||
if (feature == NULL)
|
||||
{
|
||||
tdesc_data_cleanup (tdesc_data);
|
||||
xfree (tdep);
|
||||
gdbarch_free (gdbarch);
|
||||
return NULL;
|
||||
}
|
||||
return false;
|
||||
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_FPC_REGNUM, "fpc");
|
||||
for (i = 0; i < 16; i++)
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_F0_REGNUM + i, fprs[i]);
|
||||
if (!tdesc_numbered_register (feature, tdesc_data, S390_FPC_REGNUM, "fpc"))
|
||||
return false;
|
||||
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_F0_REGNUM, fprs);
|
||||
|
||||
/* Access control registers. */
|
||||
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.acr");
|
||||
if (feature == NULL)
|
||||
{
|
||||
tdesc_data_cleanup (tdesc_data);
|
||||
xfree (tdep);
|
||||
gdbarch_free (gdbarch);
|
||||
return NULL;
|
||||
}
|
||||
return false;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_A0_REGNUM + i, acrs[i]);
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_A0_REGNUM, acrs);
|
||||
|
||||
/* Optional GNU/Linux-specific "registers". */
|
||||
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.linux");
|
||||
|
@ -8006,17 +7927,15 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
tdep->have_linux_v2 = true;
|
||||
|
||||
if (tdep->have_linux_v2 && !tdep->have_linux_v1)
|
||||
valid_p = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Transaction diagnostic block. */
|
||||
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.tdb");
|
||||
if (feature)
|
||||
{
|
||||
for (i = 0; i < ARRAY_SIZE (tdb_regs); i++)
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_TDB_DWORD0_REGNUM + i,
|
||||
tdb_regs[i]);
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_TDB_DWORD0_REGNUM,
|
||||
tdb_regs);
|
||||
tdep->have_tdb = true;
|
||||
}
|
||||
|
||||
|
@ -8024,14 +7943,10 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.vx");
|
||||
if (feature)
|
||||
{
|
||||
for (i = 0; i < 16; i++)
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_V0_LOWER_REGNUM + i,
|
||||
vxrs_low[i]);
|
||||
for (i = 0; i < 16; i++)
|
||||
valid_p &= tdesc_numbered_register (feature, tdesc_data,
|
||||
S390_V16_REGNUM + i,
|
||||
vxrs_high[i]);
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_V0_LOWER_REGNUM,
|
||||
vxrs_low);
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_V16_REGNUM,
|
||||
vxrs_high);
|
||||
tdep->have_vx = true;
|
||||
}
|
||||
|
||||
|
@ -8039,10 +7954,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
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]);
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_GSD_REGNUM, gs_cb);
|
||||
tdep->have_gs = true;
|
||||
}
|
||||
|
||||
|
@ -8050,15 +7962,92 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.gsbc");
|
||||
if (feature)
|
||||
{
|
||||
valid_p &= tdep->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 (!tdep->have_gs)
|
||||
return false;
|
||||
s390_validate_reg_range (feature, tdesc_data, S390_BC_GSD_REGNUM,
|
||||
gs_bc);
|
||||
}
|
||||
|
||||
if (!valid_p)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Allocate and initialize new gdbarch_tdep. Caller is responsible to free
|
||||
memory after use. */
|
||||
|
||||
static struct gdbarch_tdep *
|
||||
s390_gdbarch_tdep_alloc ()
|
||||
{
|
||||
struct gdbarch_tdep *tdep = XCNEW (struct gdbarch_tdep);
|
||||
|
||||
tdep->tdesc = NULL;
|
||||
|
||||
tdep->abi = ABI_NONE;
|
||||
tdep->vector_abi = S390_VECTOR_ABI_NONE;
|
||||
|
||||
tdep->gpr_full_regnum = -1;
|
||||
tdep->v0_full_regnum = -1;
|
||||
tdep->pc_regnum = -1;
|
||||
tdep->cc_regnum = -1;
|
||||
|
||||
tdep->have_upper = false;
|
||||
tdep->have_linux_v1 = false;
|
||||
tdep->have_linux_v2 = false;
|
||||
tdep->have_tdb = false;
|
||||
tdep->have_vx = false;
|
||||
tdep->have_gs = false;
|
||||
|
||||
return tdep;
|
||||
}
|
||||
|
||||
/* Set up gdbarch struct. */
|
||||
|
||||
static struct gdbarch *
|
||||
s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
{
|
||||
const struct target_desc *tdesc = info.target_desc;
|
||||
int first_pseudo_reg, last_pseudo_reg;
|
||||
static const char *const stap_register_prefixes[] = { "%", NULL };
|
||||
static const char *const stap_register_indirection_prefixes[] = { "(",
|
||||
NULL };
|
||||
static const char *const stap_register_indirection_suffixes[] = { ")",
|
||||
NULL };
|
||||
|
||||
struct gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();
|
||||
struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
|
||||
struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();
|
||||
info.tdesc_data = tdesc_data;
|
||||
|
||||
/* Default ABI and register size. */
|
||||
switch (info.bfd_arch_info->mach)
|
||||
{
|
||||
case bfd_mach_s390_31:
|
||||
tdep->abi = ABI_LINUX_S390;
|
||||
break;
|
||||
|
||||
case bfd_mach_s390_64:
|
||||
tdep->abi = ABI_LINUX_ZSERIES;
|
||||
break;
|
||||
|
||||
default:
|
||||
xfree (tdep);
|
||||
gdbarch_free (gdbarch);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Use default target description if none provided by the target. */
|
||||
if (!tdesc_has_registers (tdesc))
|
||||
{
|
||||
if (tdep->abi == ABI_LINUX_S390)
|
||||
tdesc = tdesc_s390_linux32;
|
||||
else
|
||||
tdesc = tdesc_s390x_linux64;
|
||||
}
|
||||
tdep->tdesc = tdesc;
|
||||
|
||||
/* Check any target description for validity. */
|
||||
if (tdesc_has_registers (tdesc))
|
||||
{
|
||||
if (!s390_tdesc_valid (tdep, tdesc_data))
|
||||
{
|
||||
tdesc_data_cleanup (tdesc_data);
|
||||
xfree (tdep);
|
||||
|
@ -8091,7 +8080,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
thereby a different gdbarch. */
|
||||
if (tmp->vector_abi != tdep->vector_abi)
|
||||
continue;
|
||||
if (tdesc_data != NULL)
|
||||
|
||||
tdesc_data_cleanup (tdesc_data);
|
||||
xfree (tdep);
|
||||
gdbarch_free (gdbarch);
|
||||
|
|
Loading…
Reference in New Issue