aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbarch.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbarch.c')
-rw-r--r--gdb/gdbarch.c66
1 files changed, 48 insertions, 18 deletions
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 1ee401f..7927925 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -5382,7 +5382,8 @@ struct gdbarch_data
{
unsigned index;
int init_p;
- gdbarch_data_init_ftype *init;
+ gdbarch_data_pre_init_ftype *pre_init;
+ gdbarch_data_post_init_ftype *post_init;
};
struct gdbarch_data_registration
@@ -5402,8 +5403,9 @@ struct gdbarch_data_registry gdbarch_data_registry =
0, NULL,
};
-struct gdbarch_data *
-register_gdbarch_data (gdbarch_data_init_ftype *init)
+static struct gdbarch_data *
+gdbarch_data_register (gdbarch_data_pre_init_ftype *pre_init,
+ gdbarch_data_post_init_ftype *post_init)
{
struct gdbarch_data_registration **curr;
/* Append the new registraration. */
@@ -5414,11 +5416,23 @@ register_gdbarch_data (gdbarch_data_init_ftype *init)
(*curr)->next = NULL;
(*curr)->data = XMALLOC (struct gdbarch_data);
(*curr)->data->index = gdbarch_data_registry.nr++;
- (*curr)->data->init = init;
+ (*curr)->data->pre_init = pre_init;
+ (*curr)->data->post_init = post_init;
(*curr)->data->init_p = 1;
return (*curr)->data;
}
+struct gdbarch_data *
+gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init)
+{
+ return gdbarch_data_register (pre_init, NULL);
+}
+
+struct gdbarch_data *
+gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init)
+{
+ return gdbarch_data_register (NULL, post_init);
+}
/* Create/delete the gdbarch data vector. */
@@ -5434,12 +5448,13 @@ alloc_gdbarch_data (struct gdbarch *gdbarch)
data-pointer. */
void
-set_gdbarch_data (struct gdbarch *gdbarch,
- struct gdbarch_data *data,
- void *pointer)
+deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer)
{
gdb_assert (data->index < gdbarch->nr_data);
gdb_assert (gdbarch->data[data->index] == NULL);
+ gdb_assert (data->pre_init == NULL);
gdbarch->data[data->index] = pointer;
}
@@ -5450,18 +5465,33 @@ void *
gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data)
{
gdb_assert (data->index < gdbarch->nr_data);
- /* The data-pointer isn't initialized, call init() to get a value but
- only if the architecture initializaiton has completed. Otherwise
- punt - hope that the caller knows what they are doing. */
- if (gdbarch->data[data->index] == NULL
- && gdbarch->initialized_p)
+ if (gdbarch->data[data->index] == NULL)
{
- /* Be careful to detect an initialization cycle. */
- gdb_assert (data->init_p);
- data->init_p = 0;
- gdb_assert (data->init != NULL);
- gdbarch->data[data->index] = data->init (gdbarch);
- data->init_p = 1;
+ /* The data-pointer isn't initialized, call init() to get a
+ value. */
+ if (data->pre_init != NULL)
+ /* Mid architecture creation: pass just the obstack, and not
+ the entire architecture, as that way it isn't possible for
+ pre-init code to refer to undefined architecture
+ fields. */
+ gdbarch->data[data->index] = data->pre_init (gdbarch->obstack);
+ else if (gdbarch->initialized_p
+ && data->post_init != NULL)
+ /* Post architecture creation: pass the entire architecture
+ (as all fields are valid), but be careful to also detect
+ recursive references. */
+ {
+ gdb_assert (data->init_p);
+ data->init_p = 0;
+ gdbarch->data[data->index] = data->post_init (gdbarch);
+ data->init_p = 1;
+ }
+ else
+ /* The architecture initialization hasn't completed - punt -
+ hope that the caller knows what they are doing. Once
+ deprecated_set_gdbarch_data has been initialized, this can be
+ changed to an internal error. */
+ return NULL;
gdb_assert (gdbarch->data[data->index] != NULL);
}
return gdbarch->data[data->index];