diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-11-10 04:39:17 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-11-10 04:39:17 +0000 |
commit | ebdba546a197a3b14163dbc7066bcf6862bfbe58 (patch) | |
tree | 90febdf7ec1f112f8811c19f37da0dbd91a1a146 /gdb/gdbarch.c | |
parent | 012a452b43b77eaf0f0f8a48192561702beea958 (diff) | |
download | binutils-gdb-ebdba546a197a3b14163dbc7066bcf6862bfbe58.tar.gz |
2003-11-09 Andrew Cagney <cagney@redhat.com>
* arch-utils.c (gdbarch_update_p): New function.
* gdbarch.sh (gdbarch_update_p): Delete function.
(find_arch_by_info, gdbarch_find_by_info): New functions.
(deprecated_current_gdbarch_set_hack): New function.
* gdbarch.c: Re-generate.
Diffstat (limited to 'gdb/gdbarch.c')
-rw-r--r-- | gdb/gdbarch.c | 192 |
1 files changed, 99 insertions, 93 deletions
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 1c79c43ad05..2d7683cf1fc 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -5899,19 +5899,24 @@ gdbarch_list_lookup_by_info (struct gdbarch_list *arches, } -/* Update the current architecture. Return ZERO if the update request - failed. */ +/* Find an architecture that matches the specified INFO. Create a new + architecture if needed. Return that new architecture. Assumes + that there is no current architecture. */ -int -gdbarch_update_p (struct gdbarch_info info) +static struct gdbarch * +find_arch_by_info (struct gdbarch *old_gdbarch, struct gdbarch_info info) { struct gdbarch *new_gdbarch; - struct gdbarch *old_gdbarch; struct gdbarch_registration *rego; + /* The existing architecture has been swapped out - all this code + works from a clean slate. */ + gdb_assert (current_gdbarch == NULL); + /* Fill in missing parts of the INFO struct using a number of - sources: ``set ...''; INFOabfd supplied; existing target. */ - gdbarch_info_fill (current_gdbarch, &info); + sources: "set ..."; INFOabfd supplied; and the existing + architecture. */ + gdbarch_info_fill (old_gdbarch, &info); /* Must have found some sort of architecture. */ gdb_assert (info.bfd_arch_info != NULL); @@ -5919,28 +5924,28 @@ gdbarch_update_p (struct gdbarch_info info) if (gdbarch_debug) { fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.bfd_arch_info %s\n", + "find_arch_by_info: info.bfd_arch_info %s\n", (info.bfd_arch_info != NULL ? info.bfd_arch_info->printable_name : "(null)")); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.byte_order %d (%s)\n", + "find_arch_by_info: info.byte_order %d (%s)\n", info.byte_order, (info.byte_order == BFD_ENDIAN_BIG ? "big" : info.byte_order == BFD_ENDIAN_LITTLE ? "little" : "default")); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.osabi %d (%s)\n", + "find_arch_by_info: info.osabi %d (%s)\n", info.osabi, gdbarch_osabi_name (info.osabi)); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.abfd 0x%lx\n", + "find_arch_by_info: info.abfd 0x%lx\n", (long) info.abfd); fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: info.tdep_info 0x%lx\n", + "find_arch_by_info: info.tdep_info 0x%lx\n", (long) info.tdep_info); } - /* Find the target that knows about this architecture. */ + /* Find the tdep code that knows about this architecture. */ for (rego = gdbarch_registry; rego != NULL; rego = rego->next) @@ -5949,82 +5954,61 @@ gdbarch_update_p (struct gdbarch_info info) if (rego == NULL) { if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: No matching architecture\n"); + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "No matching architecture\n"); return 0; } - /* Swap the data belonging to the old target out setting the - installed data to zero. This stops the ->init() function trying - to refer to the previous architecture's global data structures. */ - current_gdbarch_swap_out_hack (); - - /* Save the previously selected architecture, setting the global to - NULL. This stops ->init() trying to use the previous - architecture's configuration. The previous architecture may not - even be of the same architecture family. The most recent - architecture of the same family is found at the head of the - rego->arches list. */ - old_gdbarch = current_gdbarch; - current_gdbarch = NULL; - - /* Ask the target for a replacement architecture. */ + /* Ask the tdep code for an architecture that matches "info". */ new_gdbarch = rego->init (info, rego->arches); - /* Did the target like it? No. Reject the change and revert to the - old architecture. */ + /* Did the tdep code like it? No. Reject the change and revert to + the old architecture. */ if (new_gdbarch == NULL) { if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Target rejected architecture\n"); - current_gdbarch_swap_in_hack (old_gdbarch); - return 0; + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "Target rejected architecture\n"); + return NULL; } - /* Did the architecture change? No. Oops, put the old architecture - back. */ - if (old_gdbarch == new_gdbarch) + /* Is this a pre-existing architecture (as determined by already + being initialized)? Move it to the front of the architecture + list (keeping the list sorted Most Recently Used). */ + if (new_gdbarch->initialized_p) { + struct gdbarch_list **list; + struct gdbarch_list *this; if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Architecture 0x%08lx (%s) unchanged\n", + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "Previous architecture 0x%08lx (%s) selected\n", (long) new_gdbarch, new_gdbarch->bfd_arch_info->printable_name); - current_gdbarch_swap_in_hack (old_gdbarch); - return 1; + /* Find the existing arch in the list. */ + for (list = ®o->arches; + (*list) != NULL && (*list)->gdbarch != new_gdbarch; + list = &(*list)->next); + /* It had better be in the list of architectures. */ + gdb_assert ((*list) != NULL && (*list)->gdbarch == new_gdbarch); + /* Unlink THIS. */ + this = (*list); + (*list) = this->next; + /* Insert THIS at the front. */ + this->next = rego->arches; + rego->arches = this; + /* Return it. */ + return new_gdbarch; } - /* Is this a pre-existing architecture? Yes. Move it to the front - of the list of architectures (keeping the list sorted Most - Recently Used) and then copy it in. */ - { - struct gdbarch_list **list; - for (list = ®o->arches; - (*list) != NULL; - list = &(*list)->next) - { - if ((*list)->gdbarch == new_gdbarch) - { - struct gdbarch_list *this; - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: Previous architecture 0x%08lx (%s) selected\n", - (long) new_gdbarch, - new_gdbarch->bfd_arch_info->printable_name); - /* Unlink this. */ - this = (*list); - (*list) = this->next; - /* Insert in the front. */ - this->next = rego->arches; - rego->arches = this; - /* Copy the new architecture in. */ - current_gdbarch_swap_in_hack (new_gdbarch); - architecture_changed_event (); - return 1; - } - } - } - - /* Prepend this new architecture to the architecture list (keep the - list sorted Most Recently Used). */ + /* It's a new architecture. */ + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, "find_arch_by_info: " + "New architecture 0x%08lx (%s) selected\n", + (long) new_gdbarch, + new_gdbarch->bfd_arch_info->printable_name); + + /* Insert the new architecture into the front of the architecture + list (keep the list sorted Most Recently Used). */ { struct gdbarch_list *this = XMALLOC (struct gdbarch_list); this->next = rego->arches; @@ -6032,37 +6016,59 @@ gdbarch_update_p (struct gdbarch_info info) rego->arches = this; } - /* Switch to this new architecture marking it initialized. */ - current_gdbarch = new_gdbarch; - current_gdbarch->initialized_p = 1; - if (gdbarch_debug) - { - fprintf_unfiltered (gdb_stdlog, - "gdbarch_update: New architecture 0x%08lx (%s) selected\n", - (long) new_gdbarch, - new_gdbarch->bfd_arch_info->printable_name); - } - /* Check that the newly installed architecture is valid. Plug in any post init values. */ new_gdbarch->dump_tdep = rego->dump_tdep; verify_gdbarch (new_gdbarch); + new_gdbarch->initialized_p = 1; - /* Initialize the per-architecture memory (swap) areas. - CURRENT_GDBARCH must be update before these modules are - called. */ + /* Initialize any per-architecture swap areas. This phase requires + a valid global CURRENT_GDBARCH. Set it momentarially, and then + swap the entire architecture out. */ + current_gdbarch = new_gdbarch; current_gdbarch_swap_init_hack (); - - /* Initialize the per-architecture data. CURRENT_GDBARCH - must be updated before these modules are called. */ - architecture_changed_event (); + current_gdbarch_swap_out_hack (); if (gdbarch_debug) - gdbarch_dump (current_gdbarch, gdb_stdlog); + gdbarch_dump (new_gdbarch, gdb_stdlog); - return 1; + return new_gdbarch; } +struct gdbarch * +gdbarch_find_by_info (struct gdbarch_info info) +{ + /* Save the previously selected architecture, setting the global to + NULL. This stops things like gdbarch->init() trying to use the + previous architecture's configuration. The previous architecture + may not even be of the same architecture family. The most recent + architecture of the same family is found at the head of the + rego->arches list. */ + struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack (); + + /* Find the specified architecture. */ + struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info); + + /* Restore the existing architecture. */ + gdb_assert (current_gdbarch == NULL); + current_gdbarch_swap_in_hack (old_gdbarch); + + return new_gdbarch; +} + +/* Make the specified architecture current, swapping the existing one + out. */ + +void +deprecated_current_gdbarch_select_hack (struct gdbarch *new_gdbarch) +{ + gdb_assert (new_gdbarch != NULL); + gdb_assert (current_gdbarch != NULL); + gdb_assert (new_gdbarch->initialized_p); + current_gdbarch_swap_out_hack (); + current_gdbarch_swap_in_hack (new_gdbarch); + architecture_changed_event (); +} extern void _initialize_gdbarch (void); |