This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rfc] [03/18] Cell multi-arch: Save/restore current_gdbarch


Hello,

this patch would be unnecessary if we were already rid of current_gdbarch.

However, right now it is necessary in a multi-arch debugger to occasionally
temporarily set current_gdbarch to the architecture a subsystem is supposed
to be dealing with.  Those locations include:

- during target routines called from regcache_raw_read/write
- while calling frame sniffer callbacks or gdbarch data post_init callbacks
- while handling one frame during backtrace output

To do that, this patch introduced a new save_current_gdbarch routine 
(that works like save_inferior_ptid) and adds calls at the appropriate places.

Bye,
Ulrich


ChangeLog:

	* arch-utils.h (save_current_gdbarch): New.
	* arch-utils.c (restore_current_gdbarch): New function.
	(save_current_gdbarch): Likewise.

	* frame.c: Include "arch-utils.h".
	(get_frame_id): Reset current_gdbarch while calling frame
	sniffer callbacks.
	(frame_unwind_register_value): Likewise.
	(get_frame_type): Likewise.
	(frame_arch_unwind): Likewise.

	* stack.c: Include "arch-utils.h".
	(print_stack_frame): Reset current_gdbarch to frame arch
	while handling one frame.
	(print_frame_args): Likewise.
	(print_frame_info): Likewise.
	(print_frame_local_vars): Likewise.

	* regcache.c (regcache_raw_read): Reset current_gdbarch
	while calling target routines.
	(regcache_raw_write): Likewise.

	* gdbarch.sh (gdbarch_data): Reset current_gdbarch while
	calling data post_init callback.
	* gdbarch.c: Regenerate.


Index: src/gdb/arch-utils.c
===================================================================
--- src.orig/gdb/arch-utils.c
+++ src/gdb/arch-utils.c
@@ -720,6 +720,27 @@ gdbarch_info_fill (struct gdbarch_info *
   gdb_assert (info->bfd_arch_info != NULL);
 }
 
+
+/* restore_current_gdbarch() will be used by the cleanup machinery
+   to restore the current_gdbarch value saved in a call to
+   save_current_gdbarch().  */
+
+static void
+restore_current_gdbarch (void *arg)
+{
+  current_gdbarch = arg;
+}
+
+/* Save the value of current so that it may be restored by a
+   later call to do_cleanups().  Returns the struct cleanup pointer
+   needed for later doing the cleanup.  */
+
+struct cleanup *
+save_current_gdbarch (void)
+{
+  return make_cleanup (restore_current_gdbarch, current_gdbarch);
+}
+
 /* */
 
 extern initialize_file_ftype _initialize_gdbarch_utils; /* -Wmissing-prototypes */
Index: src/gdb/arch-utils.h
===================================================================
--- src.orig/gdb/arch-utils.h
+++ src/gdb/arch-utils.h
@@ -139,4 +139,9 @@ extern void gdbarch_info_fill (struct gd
 
 extern struct gdbarch *gdbarch_from_bfd (bfd *abfd);
 
+/* Save value of current_gdbarch so that it may be restored by
+   a later call to do_cleanups().  Returns the struct cleanup
+   pointer needed for later doing the cleanup.  */
+struct cleanup *save_current_gdbarch (void);
+
 #endif
Index: src/gdb/frame.c
===================================================================
--- src.orig/gdb/frame.c
+++ src/gdb/frame.c
@@ -41,6 +41,7 @@
 #include "objfiles.h"
 #include "exceptions.h"
 #include "gdbthread.h"
+#include "arch-utils.h"
 
 static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
 
@@ -261,6 +262,9 @@ get_frame_id (struct frame_info *fi)
     }
   if (!fi->this_id.p)
     {
+      struct cleanup *old_chain = save_current_gdbarch ();
+      current_gdbarch = get_frame_arch (fi);
+
       if (frame_debug)
 	fprintf_unfiltered (gdb_stdlog, "{ get_frame_id (fi=%d) ",
 			    fi->level);
@@ -276,6 +280,8 @@ get_frame_id (struct frame_info *fi)
 	  fprint_frame_id (gdb_stdlog, fi->this_id.value);
 	  fprintf_unfiltered (gdb_stdlog, " }\n");
 	}
+
+      do_cleanups (old_chain);
     }
   return fi->this_id.value;
 }
@@ -659,6 +665,7 @@ frame_unwind_register_value (struct fram
 {
   struct gdbarch *gdbarch;
   struct value *value;
+  struct cleanup *old_chain;
 
   gdb_assert (frame != NULL);
   gdbarch = frame_arch_unwind (frame);
@@ -671,6 +678,9 @@ frame_unwind_register_value (struct fram
 			  user_reg_map_regnum_to_name (gdbarch, regnum));
     }
 
+  old_chain = save_current_gdbarch ();
+  current_gdbarch = gdbarch;
+
   /* Find the unwinder.  */
   if (frame->unwind == NULL)
     frame->unwind = frame_unwind_find_by_frame (frame, &frame->prologue_cache);
@@ -712,6 +722,7 @@ frame_unwind_register_value (struct fram
       fprintf_unfiltered (gdb_stdlog, " }\n");
     }
 
+  do_cleanups (old_chain);
   return value;
 }
 
@@ -1715,9 +1726,17 @@ enum frame_type
 get_frame_type (struct frame_info *frame)
 {
   if (frame->unwind == NULL)
-    /* Initialize the frame's unwinder because that's what
-       provides the frame's type.  */
-    frame->unwind = frame_unwind_find_by_frame (frame, &frame->prologue_cache);
+    {
+      struct cleanup *old_chain = save_current_gdbarch ();
+      current_gdbarch = get_frame_arch (frame);
+
+      /* Initialize the frame's unwinder because that's what
+	 provides the frame's type.  */
+      frame->unwind = frame_unwind_find_by_frame (frame,
+						  &frame->prologue_cache);
+      do_cleanups (old_chain);
+    }
+
   return frame->unwind->type;
 }
 
@@ -1798,6 +1817,10 @@ frame_arch_unwind (struct frame_info *ne
   if (!next_frame->prev_arch.p)
     {
       struct gdbarch *arch;
+      struct cleanup *old_chain = save_current_gdbarch ();
+
+      if (next_frame->level >= 0)
+	current_gdbarch = get_frame_arch (next_frame);
 
       if (next_frame->unwind == NULL)
 	next_frame->unwind
@@ -1817,6 +1840,8 @@ frame_arch_unwind (struct frame_info *ne
 			    "{ frame_arch_unwind (next_frame=%d) -> %s }\n",
 			    next_frame->level,
 			    gdbarch_bfd_arch_info (arch)->printable_name);
+
+      do_cleanups (old_chain);
     }
 
   return next_frame->prev_arch.arch;
Index: src/gdb/gdbarch.c
===================================================================
--- src.orig/gdb/gdbarch.c
+++ src/gdb/gdbarch.c
@@ -3368,10 +3368,15 @@ gdbarch_data (struct gdbarch *gdbarch, s
 	   (as all fields are valid), but be careful to also detect
 	   recursive references.  */
 	{
+	  struct cleanup *old_chain = save_current_gdbarch ();
+	  current_gdbarch = gdbarch;
+
 	  gdb_assert (data->init_p);
 	  data->init_p = 0;
 	  gdbarch->data[data->index] = data->post_init (gdbarch);
 	  data->init_p = 1;
+
+	  do_cleanups (old_chain);
 	}
       else
 	/* The architecture initialization hasn't completed - punt -
Index: src/gdb/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh
+++ src/gdb/gdbarch.sh
@@ -1725,10 +1725,15 @@ gdbarch_data (struct gdbarch *gdbarch, s
 	   (as all fields are valid), but be careful to also detect
 	   recursive references.  */
 	{
+	  struct cleanup *old_chain = save_current_gdbarch ();
+	  current_gdbarch = gdbarch;
+
 	  gdb_assert (data->init_p);
 	  data->init_p = 0;
 	  gdbarch->data[data->index] = data->post_init (gdbarch);
 	  data->init_p = 1;
+
+	  do_cleanups (old_chain);
 	}
       else
 	/* The architecture initialization hasn't completed - punt -
Index: src/gdb/regcache.c
===================================================================
--- src.orig/gdb/regcache.c
+++ src/gdb/regcache.c
@@ -29,6 +29,7 @@
 #include "gdb_string.h"
 #include "gdbcmd.h"		/* For maintenanceprintlist.  */
 #include "observer.h"
+#include "arch-utils.h"
 
 /*
  * DATA STRUCTURE
@@ -544,6 +545,8 @@ regcache_raw_read (struct regcache *regc
 	{
 	  struct cleanup *old_chain = save_inferior_ptid ();
 	  inferior_ptid = regcache->ptid;
+	  save_current_gdbarch ();
+	  current_gdbarch = get_regcache_arch (regcache);
 	  target_fetch_registers (regcache, regnum);
 	  do_cleanups (old_chain);
 	}
@@ -702,6 +705,8 @@ regcache_raw_write (struct regcache *reg
 
   old_chain = save_inferior_ptid ();
   inferior_ptid = regcache->ptid;
+  save_current_gdbarch ();
+  current_gdbarch = get_regcache_arch (regcache);
 
   target_prepare_to_store (regcache);
   memcpy (register_buffer (regcache, regnum), buf,
Index: src/gdb/stack.c
===================================================================
--- src.orig/gdb/stack.c
+++ src/gdb/stack.c
@@ -45,6 +45,7 @@
 #include "valprint.h"
 #include "gdbthread.h"
 #include "cp-support.h"
+#include "arch-utils.h"
 
 #include "gdb_assert.h"
 #include <ctype.h>
@@ -109,6 +110,8 @@ print_stack_frame (struct frame_info *fr
 		   enum print_what print_what)
 {
   struct print_stack_frame_args args;
+  struct cleanup *old_chain = save_current_gdbarch ();
+  current_gdbarch = get_frame_arch (frame);
 
   args.frame = frame;
   args.print_level = print_level;
@@ -118,6 +121,7 @@ print_stack_frame (struct frame_info *fr
   args.print_args = 1;
 
   catch_errors (print_stack_frame_stub, &args, "", RETURN_MASK_ERROR);
+  do_cleanups (old_chain);
 }  
 
 struct print_args_args
@@ -223,6 +227,9 @@ print_frame_args (struct symbol *func, s
   stb = ui_out_stream_new (uiout);
   old_chain = make_cleanup_ui_out_stream_delete (stb);
 
+  save_current_gdbarch ();
+  current_gdbarch = get_frame_arch (frame);
+
   if (func)
     {
       struct block *b = SYMBOL_BLOCK_VALUE (func);
@@ -471,6 +478,7 @@ print_frame_info (struct frame_info *fra
   struct symtab_and_line sal;
   int source_print;
   int location_print;
+  struct cleanup *old_chain;
 
   if (get_frame_type (frame) == DUMMY_FRAME
       || get_frame_type (frame) == SIGTRAMP_FRAME
@@ -524,6 +532,10 @@ print_frame_info (struct frame_info *fra
      the next frame is a SIGTRAMP_FRAME or a DUMMY_FRAME, then the
      next frame was not entered as the result of a call, and we want
      to get the line containing FRAME->pc.  */
+
+  old_chain = save_current_gdbarch ();
+  current_gdbarch = get_frame_arch (frame);
+
   find_frame_sal (frame, &sal);
 
   location_print = (print_what == LOCATION 
@@ -577,6 +589,7 @@ print_frame_info (struct frame_info *fra
   annotate_frame_end ();
 
   gdb_flush (gdb_stdout);
+  do_cleanups (old_chain);
 }
 
 static void
@@ -1436,6 +1449,7 @@ static void
 print_frame_local_vars (struct frame_info *frame, int num_tabs,
 			struct ui_file *stream)
 {
+  struct cleanup *old_chain;
   struct block *block = get_frame_block (frame, 0);
   int values_printed = 0;
 
@@ -1445,6 +1459,9 @@ print_frame_local_vars (struct frame_inf
       return;
     }
 
+  old_chain = save_current_gdbarch ();
+  current_gdbarch = get_frame_arch (frame);
+
   while (block)
     {
       if (print_block_frame_locals (block, frame, num_tabs, stream))
@@ -1458,6 +1475,8 @@ print_frame_local_vars (struct frame_inf
 
   if (!values_printed)
     fprintf_filtered (stream, _("No locals.\n"));
+
+  do_cleanups (old_chain);
 }
 
 /* Same, but print labels.  */
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]