This is the mail archive of the gdb-patches@sources.redhat.com 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]

[rfc] Swap out current when creating a new architecture


Hello,

The attached changes the run-time environment within which a new 
architectures are created.  Briefly the simplified sequence:

- call XXX_gdbarch_init()
- swap out old architecture
- install new architecture

is changed to:

- swap out old architecture
- call XX_gdbarch_init()
- install new architecture

This has the effect of making current_gdbarch invalid for the lifetime 
of the XXX_gdbarch_init() call.

The motivation behind this change is to stop XXXX_gdbarch_init() 
functions refering (unintentionally I suspect) to the previous 
architecture.  I think it is proving effective since it has so far 
flushed out two bugs.

I can think of one additional tweek: add a ``gdb_assert (gdbarch != 
NULL)'' to each architecture method.  Without it a XXX_gdbarch_init() 
function that tries to use current_gdbarch will dump core :-/

thoughts?
Andrew
2001-09-25  Andrew Cagney  <ac131313@redhat.com>

	* gdbarch.sh (gdbarch_update_p): Swap out the old architecture
	before probing for a new one.  Detect errorenous gdbarch_init
	functions.
	* gdbarch.c: Regenerate.

Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.77
diff -p -r1.77 gdbarch.sh
*** gdbarch.sh	2001/09/05 23:44:43	1.77
--- gdbarch.sh	2001/09/26 04:25:06
*************** int
*** 1963,1968 ****
--- 1963,1969 ----
  gdbarch_update_p (struct gdbarch_info info)
  {
    struct gdbarch *new_gdbarch;
+   struct gdbarch *old_gdbarch;
    struct gdbarch_list **list;
    struct gdbarch_registration *rego;
  
*************** gdbarch_update_p (struct gdbarch_info in
*** 2032,2061 ****
        return 0;
      }
  
    /* Ask the target for a replacement architecture. */
    new_gdbarch = rego->init (info, rego->arches);
  
!   /* Did the target like it?  No. Reject the change. */
    if (new_gdbarch == NULL)
      {
        if (gdbarch_debug)
  	fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Target rejected architecture\\n");
        return 0;
      }
  
!   /* Did the architecture change?  No. Do nothing. */
!   if (current_gdbarch == new_gdbarch)
      {
        if (gdbarch_debug)
  	fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Architecture 0x%08lx (%s) unchanged\\n",
  			    (long) new_gdbarch,
  			    new_gdbarch->bfd_arch_info->printable_name);
        return 1;
      }
  
-   /* Swap all data belonging to the old target out */
-   swapout_gdbarch_swap (current_gdbarch);
- 
    /* Is this a pre-existing architecture?  Yes. Swap it in.  */
    for (list = &rego->arches;
         (*list) != NULL;
--- 2033,2072 ----
        return 0;
      }
  
+   /* Swap the data belonging to the old target out.  This stops the
+      ->init() function trying to refer to the previous architecture.  */
+   swapout_gdbarch_swap (current_gdbarch);
+   init_gdbarch_swap (current_gdbarch);
+   old_gdbarch = current_gdbarch;
+   current_gdbarch = NULL;
+ 
    /* Ask the target for a replacement architecture. */
    new_gdbarch = rego->init (info, rego->arches);
  
!   /* Did the target 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");
+       swapin_gdbarch_swap (old_gdbarch);
+       current_gdbarch = old_gdbarch;
        return 0;
      }
  
!   /* Did the architecture change?  No.  Oops, put the old architecture
!      back.  */
!   if (old_gdbarch == new_gdbarch)
      {
        if (gdbarch_debug)
  	fprintf_unfiltered (gdb_stdlog, "gdbarch_update: Architecture 0x%08lx (%s) unchanged\\n",
  			    (long) new_gdbarch,
  			    new_gdbarch->bfd_arch_info->printable_name);
+       swapin_gdbarch_swap (old_gdbarch);
+       current_gdbarch = old_gdbarch;
        return 1;
      }
  
    /* Is this a pre-existing architecture?  Yes. Swap it in.  */
    for (list = &rego->arches;
         (*list) != NULL;
*************** gdbarch_update_p (struct gdbarch_info in
*** 2095,2108 ****
    new_gdbarch->dump_tdep = rego->dump_tdep;
    verify_gdbarch (new_gdbarch);
  
!   /* Initialize the per-architecture memory (swap) areas.
!      CURRENT_GDBARCH must be update before these modules are
!      called. */
!   init_gdbarch_swap (new_gdbarch);
!   
!   /* Initialize the per-architecture data-pointer of all parties that
!      registered an interest in this architecture.  CURRENT_GDBARCH
!      must be updated before these modules are called. */
    init_gdbarch_data (new_gdbarch);
    architecture_changed_event ();
  
--- 2106,2115 ----
    new_gdbarch->dump_tdep = rego->dump_tdep;
    verify_gdbarch (new_gdbarch);
  
!   /* Initialize the per-architecture data-pointers and swap areas for
!      all parties that registered an interest in this architecture.
!      CURRENT_GDBARCH must be updated before these modules are called.
!      The swap area's will have already been initialized to zero.  */
    init_gdbarch_data (new_gdbarch);
    architecture_changed_event ();
  

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