diff options
Diffstat (limited to 'gdb/gdbarch.c')
-rw-r--r-- | gdb/gdbarch.c | 96 |
1 files changed, 44 insertions, 52 deletions
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index adf2f81..2bd957f 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -65,7 +65,8 @@ /* Static function declarations */ static void verify_gdbarch (struct gdbarch *gdbarch); -static void check_gdbarch_data (struct gdbarch *); +static void alloc_gdbarch_data (struct gdbarch *); +static void init_gdbarch_data (struct gdbarch *); static void free_gdbarch_data (struct gdbarch *); static void init_gdbarch_swap (struct gdbarch *); static void swapout_gdbarch_swap (struct gdbarch *); @@ -397,6 +398,8 @@ gdbarch_alloc (const struct gdbarch_info *info, struct gdbarch *gdbarch = XMALLOC (struct gdbarch); memset (gdbarch, 0, sizeof (*gdbarch)); + alloc_gdbarch_data (gdbarch); + gdbarch->tdep = tdep; gdbarch->bfd_arch_info = info->bfd_arch_info; @@ -4334,81 +4337,66 @@ register_gdbarch_data (gdbarch_data_init_ftype *init, } -/* Delete GDBARCH's data vector. */ +/* Walk through all the registered users initializing each in turn. */ static void -free_gdbarch_data (struct gdbarch *gdbarch) +init_gdbarch_data (struct gdbarch *gdbarch) { - if (gdbarch->data != NULL) + struct gdbarch_data_registration *rego; + for (rego = gdbarch_data_registry.registrations; + rego != NULL; + rego = rego->next) { - struct gdbarch_data_registration *rego; - - for (rego = gdbarch_data_registry.registrations; - rego != NULL; - rego = rego->next) + struct gdbarch_data *data = rego->data; + gdb_assert (data->index < gdbarch->nr_data); + if (data->init != NULL) { - struct gdbarch_data *data = rego->data; - - if (data->index < gdbarch->nr_data - && data->free != NULL - && gdbarch->data[data->index] != NULL) - { - data->free (gdbarch, gdbarch->data[data->index]); - gdbarch->data[data->index] = NULL; - } + void *pointer = data->init (gdbarch); + set_gdbarch_data (gdbarch, data, pointer); } - xfree (gdbarch->data); - gdbarch->data = NULL; } } +/* Create/delete the gdbarch data vector. */ -/* Make sure that GDBARCH has space for all registered per- - architecture data. If not, expand the table and initialize the - data values. */ static void -check_gdbarch_data (struct gdbarch *gdbarch) +alloc_gdbarch_data (struct gdbarch *gdbarch) { - int nr_allocated = gdbarch->nr_data; - - /* How many per-architecture data items are registered so far? */ - int nr_registered = gdbarch_data_registry.nr; + gdb_assert (gdbarch->data == NULL); + gdbarch->nr_data = gdbarch_data_registry.nr; + gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*)); +} - if (nr_allocated < nr_registered) +static void +free_gdbarch_data (struct gdbarch *gdbarch) +{ + struct gdbarch_data_registration *rego; + gdb_assert (gdbarch->data != NULL); + for (rego = gdbarch_data_registry.registrations; + rego != NULL; + rego = rego->next) { - /* Get enough room for all registered items, not just DATA. */ - int new_size = sizeof (gdbarch->data[0]) * nr_registered; - struct gdbarch_data_registration *rego; - - /* Expand the array, or perhaps allocate it for the first time. */ - gdbarch->data = (void **) (gdbarch->data - ? xrealloc (gdbarch->data, new_size) - : xmalloc (new_size)); - - /* Record the size now allocated. */ - gdbarch->nr_data = nr_registered; - - /* Initialize the elements we just added. */ - for (rego = gdbarch_data_registry.registrations; - rego != NULL; - rego = rego->next) + struct gdbarch_data *data = rego->data; + gdb_assert (data->index < gdbarch->nr_data); + if (data->free != NULL && gdbarch->data[data->index] != NULL) { - struct gdbarch_data *data = rego->data; - - if (data->index >= nr_allocated) - gdbarch->data[data->index] - = (data->init != NULL ? data->init (gdbarch) : NULL); + data->free (gdbarch, gdbarch->data[data->index]); + gdbarch->data[data->index] = NULL; } } + xfree (gdbarch->data); + gdbarch->data = NULL; } +/* Initialize the current value of thee specified per-architecture + data-pointer. */ + void set_gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data, void *pointer) { - check_gdbarch_data (gdbarch); gdb_assert (data->index < gdbarch->nr_data); if (data->free != NULL && gdbarch->data[data->index] != NULL) data->free (gdbarch, gdbarch->data[data->index]); @@ -4421,7 +4409,6 @@ set_gdbarch_data (struct gdbarch *gdbarch, void * gdbarch_data (struct gdbarch_data *data) { - check_gdbarch_data (current_gdbarch); gdb_assert (data->index < current_gdbarch->nr_data); return current_gdbarch->data[data->index]; } @@ -4790,6 +4777,11 @@ gdbarch_update_p (struct gdbarch_info info) called. */ init_gdbarch_swap (new_gdbarch); + /* Initialize the per-architecture data-pointer of all parties that + registered an interest in this architecture. CURRENT_GDBARCH + must be updated before these modules are called. */ + init_gdbarch_data (new_gdbarch); + if (gdbarch_debug) gdbarch_dump (current_gdbarch, gdb_stdlog); |