s390: Allocate gdbarch & tdep at start of gdbarch_init

Moving the allocation of gdbarch_tdep to the start of s390_gdbarch_init
allows us to use its fields for tracking the different features instead of
using separate variables.  To make the code a little nicer move the actual
allocation and initialization to a separate function.  Also move the
allocation of gdbarch to keep the two together.

gdb/ChangeLog:

	* s390-linux-tdep (s390_abi_kind) <ABI_NONE>: New default field.
	(gdbarch_tdep) <have_upper, have_vx>: New fields.
	(s390_gdbarch_tdep_alloc): New function.
	(s390_gdbarch_init): Allocate tdep at start and use its fields
	instead of separate variables.
This commit is contained in:
Philipp Rudo 2018-01-23 13:37:41 +01:00 committed by Andreas Arnez
parent 0eb97953ad
commit 21f6f5ffc6
2 changed files with 73 additions and 42 deletions

View File

@ -1,3 +1,11 @@
2018-01-23 Philipp Rudo <prudo@linux.vnet.ibm.com>
* s390-linux-tdep (s390_abi_kind) <ABI_NONE>: New default field.
(gdbarch_tdep) <have_upper, have_vx>: New fields.
(s390_gdbarch_tdep_alloc): New function.
(s390_gdbarch_init): Allocate tdep at start and use its fields
instead of separate variables.
2018-01-23 Philipp Rudo <prudo@linux.vnet.ibm.com> 2018-01-23 Philipp Rudo <prudo@linux.vnet.ibm.com>
* s390-linux-tdep.c (s390_gdbarch_init): Remove duplicate checks * s390-linux-tdep.c (s390_gdbarch_init): Remove duplicate checks

View File

@ -85,6 +85,7 @@ static char *s390_disassembler_options;
enum s390_abi_kind enum s390_abi_kind
{ {
ABI_NONE,
ABI_LINUX_S390, ABI_LINUX_S390,
ABI_LINUX_ZSERIES ABI_LINUX_ZSERIES
}; };
@ -111,9 +112,11 @@ struct gdbarch_tdep
int cc_regnum; int cc_regnum;
int v0_full_regnum; int v0_full_regnum;
bool have_upper;
int have_linux_v1; int have_linux_v1;
int have_linux_v2; int have_linux_v2;
int have_tdb; int have_tdb;
bool have_vx;
bool have_gs; bool have_gs;
}; };
@ -7804,6 +7807,32 @@ s390_init_linux_record_tdep (struct linux_record_tdep *record_tdep,
record_tdep->ioctl_FIOQSIZE = 0x545e; record_tdep->ioctl_FIOQSIZE = 0x545e;
} }
/* 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->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 = 0;
tdep->have_linux_v2 = 0;
tdep->have_tdb = 0;
tdep->have_vx = false;
tdep->have_gs = false;
return tdep;
}
/* Set up gdbarch struct. */ /* Set up gdbarch struct. */
static struct gdbarch * static struct gdbarch *
@ -7811,16 +7840,6 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{ {
const struct target_desc *tdesc = info.target_desc; const struct target_desc *tdesc = info.target_desc;
struct tdesc_arch_data *tdesc_data = NULL; struct tdesc_arch_data *tdesc_data = NULL;
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
enum s390_abi_kind tdep_abi;
enum s390_vector_abi_kind vector_abi;
int have_upper = 0;
int have_linux_v1 = 0;
int have_linux_v2 = 0;
int have_tdb = 0;
int have_vx = 0;
int have_gs = 0;
int first_pseudo_reg, last_pseudo_reg; int first_pseudo_reg, last_pseudo_reg;
static const char *const stap_register_prefixes[] = { "%", NULL }; static const char *const stap_register_prefixes[] = { "%", NULL };
static const char *const stap_register_indirection_prefixes[] = { "(", static const char *const stap_register_indirection_prefixes[] = { "(",
@ -7828,25 +7847,30 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
static const char *const stap_register_indirection_suffixes[] = { ")", static const char *const stap_register_indirection_suffixes[] = { ")",
NULL }; NULL };
struct gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();
struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
/* Default ABI and register size. */ /* Default ABI and register size. */
switch (info.bfd_arch_info->mach) switch (info.bfd_arch_info->mach)
{ {
case bfd_mach_s390_31: case bfd_mach_s390_31:
tdep_abi = ABI_LINUX_S390; tdep->abi = ABI_LINUX_S390;
break; break;
case bfd_mach_s390_64: case bfd_mach_s390_64:
tdep_abi = ABI_LINUX_ZSERIES; tdep->abi = ABI_LINUX_ZSERIES;
break; break;
default: default:
xfree (tdep);
gdbarch_free (gdbarch);
return NULL; return NULL;
} }
/* Use default target description if none provided by the target. */ /* Use default target description if none provided by the target. */
if (!tdesc_has_registers (tdesc)) if (!tdesc_has_registers (tdesc))
{ {
if (tdep_abi == ABI_LINUX_S390) if (tdep->abi == ABI_LINUX_S390)
tdesc = tdesc_s390_linux32; tdesc = tdesc_s390_linux32;
else else
tdesc = tdesc_s390x_linux64; tdesc = tdesc_s390x_linux64;
@ -7899,7 +7923,11 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.core"); feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.core");
if (feature == NULL) if (feature == NULL)
{
xfree (tdep);
gdbarch_free (gdbarch);
return NULL; return NULL;
}
tdesc_data = tdesc_data_alloc (); tdesc_data = tdesc_data_alloc ();
@ -7916,7 +7944,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
} }
else else
{ {
have_upper = 1; tdep->have_upper = true;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
valid_p &= tdesc_numbered_register (feature, tdesc_data, valid_p &= tdesc_numbered_register (feature, tdesc_data,
@ -7932,6 +7960,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
if (feature == NULL) if (feature == NULL)
{ {
tdesc_data_cleanup (tdesc_data); tdesc_data_cleanup (tdesc_data);
xfree (tdep);
gdbarch_free (gdbarch);
return NULL; return NULL;
} }
@ -7945,6 +7975,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
if (feature == NULL) if (feature == NULL)
{ {
tdesc_data_cleanup (tdesc_data); tdesc_data_cleanup (tdesc_data);
xfree (tdep);
gdbarch_free (gdbarch);
return NULL; return NULL;
} }
@ -7961,13 +7993,13 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
if (tdesc_numbered_register (feature, tdesc_data, if (tdesc_numbered_register (feature, tdesc_data,
S390_LAST_BREAK_REGNUM, "last_break")) S390_LAST_BREAK_REGNUM, "last_break"))
have_linux_v1 = 1; tdep->have_linux_v1 = 1;
if (tdesc_numbered_register (feature, tdesc_data, if (tdesc_numbered_register (feature, tdesc_data,
S390_SYSTEM_CALL_REGNUM, "system_call")) S390_SYSTEM_CALL_REGNUM, "system_call"))
have_linux_v2 = 1; tdep->have_linux_v2 = 1;
if (have_linux_v2 > have_linux_v1) if (tdep->have_linux_v2 > tdep->have_linux_v1)
valid_p = 0; valid_p = 0;
} }
@ -7979,7 +8011,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
valid_p &= tdesc_numbered_register (feature, tdesc_data, valid_p &= tdesc_numbered_register (feature, tdesc_data,
S390_TDB_DWORD0_REGNUM + i, S390_TDB_DWORD0_REGNUM + i,
tdb_regs[i]); tdb_regs[i]);
have_tdb = 1; tdep->have_tdb = 1;
} }
/* Vector registers. */ /* Vector registers. */
@ -7994,7 +8026,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
valid_p &= tdesc_numbered_register (feature, tdesc_data, valid_p &= tdesc_numbered_register (feature, tdesc_data,
S390_V16_REGNUM + i, S390_V16_REGNUM + i,
vxrs_high[i]); vxrs_high[i]);
have_vx = 1; tdep->have_vx = true;
} }
/* Guarded-storage registers. */ /* Guarded-storage registers. */
@ -8005,14 +8037,14 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
valid_p &= tdesc_numbered_register (feature, tdesc_data, valid_p &= tdesc_numbered_register (feature, tdesc_data,
S390_GSD_REGNUM + i, S390_GSD_REGNUM + i,
gs_cb[i]); gs_cb[i]);
have_gs = 1; tdep->have_gs = true;
} }
/* Guarded-storage broadcast control. */ /* Guarded-storage broadcast control. */
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.gsbc"); feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.gsbc");
if (feature) if (feature)
{ {
valid_p &= have_gs; valid_p &= tdep->have_gs;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
valid_p &= tdesc_numbered_register (feature, tdesc_data, valid_p &= tdesc_numbered_register (feature, tdesc_data,
@ -8023,20 +8055,21 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
if (!valid_p) if (!valid_p)
{ {
tdesc_data_cleanup (tdesc_data); tdesc_data_cleanup (tdesc_data);
xfree (tdep);
gdbarch_free (gdbarch);
return NULL; return NULL;
} }
} }
/* Determine vector ABI. */ /* Determine vector ABI. */
vector_abi = S390_VECTOR_ABI_NONE;
#ifdef HAVE_ELF #ifdef HAVE_ELF
if (have_vx if (tdep->have_vx
&& info.abfd != NULL && info.abfd != NULL
&& info.abfd->format == bfd_object && info.abfd->format == bfd_object
&& bfd_get_flavour (info.abfd) == bfd_target_elf_flavour && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour
&& bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU, && bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
Tag_GNU_S390_ABI_Vector) == 2) Tag_GNU_S390_ABI_Vector) == 2)
vector_abi = S390_VECTOR_ABI_128; tdep->vector_abi = S390_VECTOR_ABI_128;
#endif #endif
/* Find a candidate among extant architectures. */ /* Find a candidate among extant architectures. */
@ -8044,29 +8077,21 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
arches != NULL; arches != NULL;
arches = gdbarch_list_lookup_by_info (arches->next, &info)) arches = gdbarch_list_lookup_by_info (arches->next, &info))
{ {
tdep = gdbarch_tdep (arches->gdbarch); struct gdbarch_tdep *tmp = gdbarch_tdep (arches->gdbarch);
if (!tdep) if (!tmp)
continue; continue;
/* A program can 'choose' not to use the vector registers when they /* A program can 'choose' not to use the vector registers when they
are present. Leading to the same tdesc but different tdep and are present. Leading to the same tdesc but different tdep and
thereby a different gdbarch. */ thereby a different gdbarch. */
if (tdep->vector_abi != vector_abi) if (tmp->vector_abi != tdep->vector_abi)
continue; continue;
if (tdesc_data != NULL) if (tdesc_data != NULL)
tdesc_data_cleanup (tdesc_data); tdesc_data_cleanup (tdesc_data);
xfree (tdep);
gdbarch_free (gdbarch);
return arches->gdbarch; return arches->gdbarch;
} }
/* Otherwise create a new gdbarch for the specified machine type. */
tdep = XCNEW (struct gdbarch_tdep);
tdep->abi = tdep_abi;
tdep->vector_abi = vector_abi;
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); set_gdbarch_believe_pcc_promotion (gdbarch, 0);
set_gdbarch_char_signed (gdbarch, 0); set_gdbarch_char_signed (gdbarch, 0);
@ -8118,14 +8143,12 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Assign pseudo register numbers. */ /* Assign pseudo register numbers. */
first_pseudo_reg = gdbarch_num_regs (gdbarch); first_pseudo_reg = gdbarch_num_regs (gdbarch);
last_pseudo_reg = first_pseudo_reg; last_pseudo_reg = first_pseudo_reg;
tdep->gpr_full_regnum = -1; if (tdep->have_upper)
if (have_upper)
{ {
tdep->gpr_full_regnum = last_pseudo_reg; tdep->gpr_full_regnum = last_pseudo_reg;
last_pseudo_reg += 16; last_pseudo_reg += 16;
} }
tdep->v0_full_regnum = -1; if (tdep->have_vx)
if (have_vx)
{ {
tdep->v0_full_regnum = last_pseudo_reg; tdep->v0_full_regnum = last_pseudo_reg;
last_pseudo_reg += 16; last_pseudo_reg += 16;