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] Add set_gdbarch_data() and revamp


Hello,

To follow up on previous discussion.  The attatched adds a
set_gdbarch_data() method to the gdbarch framework.

At the same time, it simplifies the existing data-pointer code (using
things like gdb_assert()).

Hand testing is continuing (gdb.wp?).

	Andrew
Wed Jan 31 09:58:18 2001  Andrew Cagney  <cagney@redhat.com>

	* gdbarch.sh: Include "gdb_assert.h".
	(struct gdbarch): Change ``nr_data'' to unsigned.
	(alloc_gdbarch_data, free_gdbarch_data): New functions.
	(gdbarch_free): Free the data-pointer vector.  Use xfree to delete
 	architecture vector.
 	(struct gdbarch_data, struct gdbarch_data_registration): Move init
 	method to gdbarch_data.  Add free method, make index unsigned.
	(struct gdbarch_data_registry): Make nr unsigned.
	(register_gdbarch_data): Add free parameter. Store in
 	gdbarch_data.
	(init_gdbarch_data): Use set_gdbarch_data.
	(set_gdbarch_data): New function.
	
	* gdbarch.h, gdbarch.c: Re-generate.
	
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.51
diff -p -r1.51 gdbarch.sh
*** gdbarch.sh	2001/01/22 23:32:49	1.51
--- gdbarch.sh	2001/02/01 07:50:18
*************** extern int gdbarch_update_p (struct gdba
*** 855,883 ****
  
     Reserve space for a per-architecture data-pointer.  An identifier
     for the reserved data-pointer is returned.  That identifer should
!    be saved in a local static.
  
!    When a new architecture is selected, INIT() is called.  When a
!    previous architecture is re-selected, the per-architecture
!    data-pointer for that previous architecture is restored (INIT() is
!    not called).
  
-    INIT() shall return the initial value for the per-architecture
-    data-pointer for the current architecture.
- 
     Multiple registrarants for any architecture are allowed (and
     strongly encouraged).  */
  
! typedef void *(gdbarch_data_ftype) (void);
! extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_ftype *init);
  
! /* Return the value of the per-architecture data-pointer for the
!    current architecture. */
  
  extern void *gdbarch_data (struct gdbarch_data*);
  
  
- 
  /* Register per-architecture memory region.
  
     Provide a memory-region swap mechanism.  Per-architecture memory
--- 855,894 ----
  
     Reserve space for a per-architecture data-pointer.  An identifier
     for the reserved data-pointer is returned.  That identifer should
!    be saved in a local static variable.
  
!    The per-architecture data-pointer can be initialized in one of two
!    ways: The value can be set explicitly using a call to
!    set_gdbarch_data(); the value can be set implicitly using the value
!    returned by a non-NULL INIT() callback.  INIT(), when non-NULL is
!    called after the basic architecture vector has been created.
! 
!    When a previously created architecture is re-selected, the
!    per-architecture data-pointer for that previous architecture is
!    restored.  INIT() is not called.
! 
!    During initialization, multiple assignments of the data-pointer are
!    allowed, non-NULL values are deleted by calling FREE().  If the
!    architecture is deleted using gdbarch_free() all non-NULL data
!    pointers are also deleted using FREE().
  
     Multiple registrarants for any architecture are allowed (and
     strongly encouraged).  */
  
! struct gdbarch_data;
  
! typedef void *(gdbarch_data_init_ftype) (struct gdbarch *gdbarch);
! typedef void (gdbarch_data_free_ftype) (struct gdbarch *gdbarch,
! 					void *pointer);
! extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init,
! 						   gdbarch_data_free_ftype *free);
! extern void set_gdbarch_data (struct gdbarch *gdbarch,
! 			      struct gdbarch_data *data,
! 			      void *pointer);
  
  extern void *gdbarch_data (struct gdbarch_data*);
  
  
  /* Register per-architecture memory region.
  
     Provide a memory-region swap mechanism.  Per-architecture memory
*************** cat <<EOF
*** 1049,1058 ****
--- 1060,1073 ----
  
  #include "floatformat.h"
  
+ #include "gdb_assert.h"
+ 
  /* Static function declarations */
  
  static void verify_gdbarch (struct gdbarch *gdbarch);
+ static void alloc_gdbarch_data (struct gdbarch *);
  static void init_gdbarch_data (struct gdbarch *);
+ static void free_gdbarch_data (struct gdbarch *);
  static void init_gdbarch_swap (struct gdbarch *);
  static void swapout_gdbarch_swap (struct gdbarch *);
  static void swapin_gdbarch_swap (struct gdbarch *);
*************** printf "  struct gdbarch_tdep *tdep;\n"
*** 1093,1099 ****
  printf "  gdbarch_dump_tdep_ftype *dump_tdep;\n"
  printf "\n"
  printf "  /* per-architecture data-pointers */\n"
! printf "  int nr_data;\n"
  printf "  void **data;\n"
  printf "\n"
  printf "  /* per-architecture swap-regions */\n"
--- 1108,1114 ----
  printf "  gdbarch_dump_tdep_ftype *dump_tdep;\n"
  printf "\n"
  printf "  /* per-architecture data-pointers */\n"
! printf "  unsigned nr_data;\n"
  printf "  void **data;\n"
  printf "\n"
  printf "  /* per-architecture swap-regions */\n"
*************** gdbarch_alloc (const struct gdbarch_info
*** 1196,1201 ****
--- 1211,1218 ----
    struct gdbarch *gdbarch = XMALLOC (struct gdbarch);
    memset (gdbarch, 0, sizeof (*gdbarch));
  
+   alloc_gdbarch_data (gdbarch);
+ 
    gdbarch->tdep = tdep;
  EOF
  printf "\n"
*************** cat <<EOF
*** 1238,1245 ****
  void
  gdbarch_free (struct gdbarch *arch)
  {
!   /* At the moment, this is trivial.  */
!   free (arch);
  }
  EOF
  
--- 1255,1263 ----
  void
  gdbarch_free (struct gdbarch *arch)
  {
!   gdb_assert (arch != NULL);
!   free_gdbarch_data (arch);
!   xfree (arch);
  }
  EOF
  
*************** cat <<EOF
*** 1488,1506 ****
  
  struct gdbarch_data
  {
!   int index;
  };
  
  struct gdbarch_data_registration
  {
-   gdbarch_data_ftype *init;
    struct gdbarch_data *data;
    struct gdbarch_data_registration *next;
  };
  
  struct gdbarch_data_registry
  {
!   int nr;
    struct gdbarch_data_registration *registrations;
  };
  
--- 1506,1525 ----
  
  struct gdbarch_data
  {
!   unsigned index;
!   gdbarch_data_init_ftype *init;
!   gdbarch_data_free_ftype *free;
  };
  
  struct gdbarch_data_registration
  {
    struct gdbarch_data *data;
    struct gdbarch_data_registration *next;
  };
  
  struct gdbarch_data_registry
  {
!   unsigned nr;
    struct gdbarch_data_registration *registrations;
  };
  
*************** struct gdbarch_data_registry gdbarch_dat
*** 1510,1516 ****
  };
  
  struct gdbarch_data *
! register_gdbarch_data (gdbarch_data_ftype *init)
  {
    struct gdbarch_data_registration **curr;
    for (curr = &gdbarch_data_registry.registrations;
--- 1529,1536 ----
  };
  
  struct gdbarch_data *
! register_gdbarch_data (gdbarch_data_init_ftype *init,
!                        gdbarch_data_free_ftype *free)
  {
    struct gdbarch_data_registration **curr;
    for (curr = &gdbarch_data_registry.registrations;
*************** register_gdbarch_data (gdbarch_data_ftyp
*** 1518,1526 ****
         curr = &(*curr)->next);
    (*curr) = XMALLOC (struct gdbarch_data_registration);
    (*curr)->next = NULL;
-   (*curr)->init = init;
    (*curr)->data = XMALLOC (struct gdbarch_data);
    (*curr)->data->index = gdbarch_data_registry.nr++;
    return (*curr)->data;
  }
  
--- 1538,1547 ----
         curr = &(*curr)->next);
    (*curr) = XMALLOC (struct gdbarch_data_registration);
    (*curr)->next = NULL;
    (*curr)->data = XMALLOC (struct gdbarch_data);
    (*curr)->data->index = gdbarch_data_registry.nr++;
+   (*curr)->data->init = init;
+   (*curr)->data->free = free;
    return (*curr)->data;
  }
  
*************** register_gdbarch_data (gdbarch_data_ftyp
*** 1530,1556 ****
  static void
  init_gdbarch_data (struct gdbarch *gdbarch)
  {
    struct gdbarch_data_registration *rego;
!   gdbarch->nr_data = gdbarch_data_registry.nr + 1;
!   gdbarch->data = xmalloc (sizeof (void*) * gdbarch->nr_data);
    for (rego = gdbarch_data_registry.registrations;
         rego != NULL;
         rego = rego->next)
      {
!       if (rego->data->index < gdbarch->nr_data)
! 	gdbarch->data[rego->data->index] = rego->init ();
      }
  }
  
  
  /* Return the current value of the specified per-architecture
     data-pointer. */
  
  void *
  gdbarch_data (struct gdbarch_data *data)
  {
!   if (data->index >= current_gdbarch->nr_data)
!     internal_error ("gdbarch_data: request for non-existant data.");
    return current_gdbarch->data[data->index];
  }
  
--- 1551,1624 ----
  static void
  init_gdbarch_data (struct gdbarch *gdbarch)
  {
+   struct gdbarch_data_registration *rego;
+   for (rego = gdbarch_data_registry.registrations;
+        rego != NULL;
+        rego = rego->next)
+     {
+       struct gdbarch_data *data = rego->data;
+       gdb_assert (data->index < gdbarch->nr_data);
+       if (data->init != NULL)
+         {
+           void *pointer = data->init (gdbarch);
+           set_gdbarch_data (gdbarch, data, pointer);
+         }
+     }
+ }
+ 
+ /* Create/delete the gdbarch data vector. */
+ 
+ static void
+ alloc_gdbarch_data (struct gdbarch *gdbarch)
+ {
+   gdb_assert (gdbarch->data == NULL);
+   gdbarch->nr_data = gdbarch_data_registry.nr;
+   gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
+ }
+ 
+ static void
+ free_gdbarch_data (struct gdbarch *gdbarch)
+ {
    struct gdbarch_data_registration *rego;
!   gdb_assert (gdbarch->data != NULL);
    for (rego = gdbarch_data_registry.registrations;
         rego != NULL;
         rego = rego->next)
      {
!       struct gdbarch_data *data = rego->data;
!       gdb_assert (data->index < gdbarch->nr_data);
!       if (data->free != NULL && gdbarch->data[data->index] != NULL)
!         {
!           data->free (gdbarch, gdbarch->data[data->index]);
!           gdbarch->data[data->index] = NULL;
!         }
      }
+   xfree (gdbarch->data);
+   gdbarch->data = NULL;
  }
  
  
+ /* Initialize the current value of thee specified per-architecture
+    data-pointer. */
+ 
+ void
+ set_gdbarch_data (struct gdbarch *gdbarch,
+                   struct gdbarch_data *data,
+                   void *pointer)
+ {
+   gdb_assert (data->index < gdbarch->nr_data);
+   if (data->free != NULL && gdbarch->data[data->index] != NULL)
+     data->free (gdbarch, gdbarch->data[data->index]);
+   gdbarch->data[data->index] = pointer;
+ }
+ 
  /* Return the current value of the specified per-architecture
     data-pointer. */
  
  void *
  gdbarch_data (struct gdbarch_data *data)
  {
!   gdb_assert (data->index < current_gdbarch->nr_data);
    return current_gdbarch->data[data->index];
  }
  

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