[PATCH v2 02/11] s390: Allocate gdbarch & tdep at start of gdbarch init

Philipp Rudo
2017-12-05T12:29:29Z

Moving the allocation of gdbarch_tdep to the start of s390_gdbarch_init
allows to use its fields to track the different features instead of using
separate variables. To make the code a little nicer move actual allocation
and initialization in 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.
---
gdb/s390-linux-tdep.c | 100 ++++++++++++++++++++++++++++++--------------------
1 file changed, 61 insertions(+), 39 deletions(-)

diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index e3e036a70d..89e5ec55ba 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -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;
};

@@ -7805,6 +7808,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 *
@@ -7812,16 +7841,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[] = { "(",
@@ -7834,25 +7853,31 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
if (arches != NULL)
return arches->gdbarch;

+ /* Otherwise create a new gdbarch for the specified machine type. */
+ 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;
@@ -7905,7 +7930,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 ();

@@ -7922,7 +7951,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,
@@ -7938,6 +7967,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;
}

@@ -7951,6 +7982,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;
}

@@ -7967,13 +8000,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;
}

@@ -7985,7 +8018,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. */
@@ -8000,7 +8033,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. */
@@ -8011,14 +8044,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,
@@ -8029,32 +8062,23 @@ 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

- /* 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);

@@ -8106,14 +8130,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;
--
2.13.5