summaryrefslogtreecommitdiff
path: root/gdb/gdbarch.c
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2003-11-10 04:39:17 +0000
committerAndrew Cagney <cagney@redhat.com>2003-11-10 04:39:17 +0000
commitebdba546a197a3b14163dbc7066bcf6862bfbe58 (patch)
tree90febdf7ec1f112f8811c19f37da0dbd91a1a146 /gdb/gdbarch.c
parent012a452b43b77eaf0f0f8a48192561702beea958 (diff)
downloadbinutils-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.c192
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 = &rego->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 = &rego->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);