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>
* 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
{
ABI_NONE,
ABI_LINUX_S390,
ABI_LINUX_ZSERIES
};
@ -111,9 +112,11 @@ struct gdbarch_tdep
int cc_regnum;
int v0_full_regnum;
bool have_upper;
int have_linux_v1;
int have_linux_v2;
int have_tdb;
bool have_vx;
bool have_gs;
};
@ -7804,6 +7807,32 @@ 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. */
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. */
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;
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;
static const char *const stap_register_prefixes[] = { "%", NULL };
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[] = { ")",
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;
tdep->abi = ABI_LINUX_S390;
break;
case bfd_mach_s390_64:
tdep_abi = ABI_LINUX_ZSERIES;
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)
if (tdep->abi == ABI_LINUX_S390)
tdesc = tdesc_s390_linux32;
else
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");
if (feature == NULL)
return NULL;
{
xfree (tdep);
gdbarch_free (gdbarch);
return NULL;
}
tdesc_data = tdesc_data_alloc ();
@ -7916,7 +7944,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
}
else
{
have_upper = 1;
tdep->have_upper = true;
for (i = 0; i < 16; i++)
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)
{
tdesc_data_cleanup (tdesc_data);
xfree (tdep);
gdbarch_free (gdbarch);
return NULL;
}
@ -7945,6 +7975,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
if (feature == NULL)
{
tdesc_data_cleanup (tdesc_data);
xfree (tdep);
gdbarch_free (gdbarch);
return NULL;
}
@ -7961,13 +7993,13 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
if (tdesc_numbered_register (feature, tdesc_data,
S390_LAST_BREAK_REGNUM, "last_break"))
have_linux_v1 = 1;
tdep->have_linux_v1 = 1;
if (tdesc_numbered_register (feature, tdesc_data,
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;
}
@ -7979,7 +8011,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
valid_p &= tdesc_numbered_register (feature, tdesc_data,
S390_TDB_DWORD0_REGNUM + i,
tdb_regs[i]);
have_tdb = 1;
tdep->have_tdb = 1;
}
/* 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,
S390_V16_REGNUM + i,
vxrs_high[i]);
have_vx = 1;
tdep->have_vx = true;
}
/* 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,
S390_GSD_REGNUM + i,
gs_cb[i]);
have_gs = 1;
tdep->have_gs = true;
}
/* Guarded-storage broadcast control. */
feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.gsbc");
if (feature)
{
valid_p &= have_gs;
valid_p &= tdep->have_gs;
for (i = 0; i < 3; i++)
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)
{
tdesc_data_cleanup (tdesc_data);
xfree (tdep);
gdbarch_free (gdbarch);
return NULL;
}
}
/* Determine vector ABI. */
vector_abi = S390_VECTOR_ABI_NONE;
#ifdef HAVE_ELF
if (have_vx
if (tdep->have_vx
&& info.abfd != NULL
&& info.abfd->format == bfd_object
&& bfd_get_flavour (info.abfd) == bfd_target_elf_flavour
&& bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
Tag_GNU_S390_ABI_Vector) == 2)
vector_abi = S390_VECTOR_ABI_128;
tdep->vector_abi = S390_VECTOR_ABI_128;
#endif
/* Find a candidate among extant architectures. */
@ -8044,29 +8077,21 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
arches != NULL;
arches = gdbarch_list_lookup_by_info (arches->next, &info))
{
tdep = gdbarch_tdep (arches->gdbarch);
if (!tdep)
struct gdbarch_tdep *tmp = gdbarch_tdep (arches->gdbarch);
if (!tmp)
continue;
/* A program can 'choose' not to use the vector registers when they
are present. Leading to the same tdesc but different tdep and
thereby a different gdbarch. */
if (tdep->vector_abi != vector_abi)
if (tmp->vector_abi != tdep->vector_abi)
continue;
if (tdesc_data != NULL)
tdesc_data_cleanup (tdesc_data);
xfree (tdep);
gdbarch_free (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_char_signed (gdbarch, 0);
@ -8118,14 +8143,12 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Assign pseudo register numbers. */
first_pseudo_reg = gdbarch_num_regs (gdbarch);
last_pseudo_reg = first_pseudo_reg;
tdep->gpr_full_regnum = -1;
if (have_upper)
if (tdep->have_upper)
{
tdep->gpr_full_regnum = last_pseudo_reg;
last_pseudo_reg += 16;
}
tdep->v0_full_regnum = -1;
if (have_vx)
if (tdep->have_vx)
{
tdep->v0_full_regnum = last_pseudo_reg;
last_pseudo_reg += 16;