diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3b1460ece52..b45624e021d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2003-10-27 Mark Kettenis + + * arch-utils.c (deprecated_select_gdbarch_hack): New function. + (gdbarch_from_bfd): New function. + (set_gdbarch_from_file): Re-implement using gdbarch_from_bfd and + deprecated_select_gdbarch_hack. + * arch-utils.h (gdbarch_from_bfd): New prototype. + 2003-10-27 Andrew Cagney * osabi.c (gdbarch_init_osabi): Use info.bfd_arch_info instead of diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index ca0f514a549..38ad4862dd1 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -496,17 +496,68 @@ set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c) show_architecture (NULL, from_tty); } +/* FIXME: kettenis/20031124: Of the functions that follow, only + gdbarch_from_bfd is supposed to survive. The others will + dissappear since in the future GDB will (hopefully) be truly + multi-arch. However, for now we're still stuck with the concept of + a single active architecture. */ + +/* Make GDBARCH the currently selected architecture. */ + +static void +deprecated_select_gdbarch_hack (struct gdbarch *gdbarch) +{ + struct gdbarch_info info; + + /* FIXME: kettenis/20031024: The only way to select a specific + architecture is to clone its `struct gdbarch_info', and update + according to that copy. This is gross, but significant work will + need to be done before we can take a more sane approach. */ + gdbarch_info_init (&info); + info.bfd_arch_info = gdbarch_bfd_arch_info (gdbarch); + info.byte_order = gdbarch_byte_order (gdbarch); + info.osabi = gdbarch_osabi (gdbarch); + gdbarch_update_p (info); + gdb_assert (gdbarch == current_gdbarch); +} + +/* Return the architecture for ABFD. If no suitable architecture + could be find, return NULL. */ + +struct gdbarch * +gdbarch_from_bfd (bfd *abfd) +{ + struct gdbarch *old_gdbarch = current_gdbarch; + struct gdbarch *new_gdbarch; + struct gdbarch_info info; + + /* FIXME: kettenis/20031024: The only way to find the architecture + for a certain BFD is by doing an architecture update. This + activates the architecture, so we need to reactivate the old + architecture. This is gross, but significant work will need to + be done before we can take a more sane approach. */ + gdbarch_info_init (&info); + info.abfd = abfd; + if (! gdbarch_update_p (info)) + return NULL; + + new_gdbarch = current_gdbarch; + deprecated_select_gdbarch_hack (old_gdbarch); + return new_gdbarch; +} + /* Set the dynamic target-system-dependent parameters (architecture, byte-order) using information found in the BFD */ void set_gdbarch_from_file (bfd *abfd) { - struct gdbarch_info info; - gdbarch_info_init (&info); - info.abfd = abfd; - if (! gdbarch_update_p (info)) + struct gdbarch *gdbarch; + + gdbarch = gdbarch_from_bfd (abfd); + if (gdbarch == NULL) error ("Architecture of file not recognized.\n"); + deprecated_select_gdbarch_hack (gdbarch); } /* Initialize the current architecture. Update the ``set diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 9d6718040b0..27df54dd1f7 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -151,4 +151,9 @@ extern int legacy_register_sim_regno (int regnum); default values are not zero. */ extern void gdbarch_info_init (struct gdbarch_info *info); +/* Return the architecture for ABFD. If no suitable architecture + could be find, return NULL. */ + +extern struct gdbarch *gdbarch_from_bfd (bfd *abfd); + #endif