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]
Other format: [Raw text]

[patch,rfc] Switch user-regs.[hc] to per-gdbarch obstack


Hello,

The attached patch switches the per-architecture user registers to use the per-architecture obstack. That way, if the architecture ever gets deleted, the allocated memory goes with it.

I'll look to commit this to the mainline in a few days.

Andrew
2003-07-28  Andrew Cagney  <cagney@redhat.com>

	* user-regs.c (struct user_reg): Add "next" link.
	(struct user_regs): Replace "user" with "first" and "last" links.
	(append_user_reg): Add pre-allocated "reg" parameter.
	(builtin_user_regs): Provide initial value for "last".
	(user_reg_add_builtin): XMALLOC memory for append_user_reg.
	(user_regs_init): Allocate memory from the gdbarch obstack.
	(user_reg_add): GDBARCH_OBSTACK_ZALLOC memory for append_user_reg.
	(user_reg_map_name_to_regnum): Rewrite to search the user_reg
	linked list.
	(usernum_to_user_reg): New function.
	(user_reg_map_regnum_to_name): Use usernum_to_user_reg.
	(value_of_user_reg): Use usernum_to_user_reg.
	(user_regs_free): Delete function.
	(_initialize_user_regs): Update register_gdbarch_data call.

Index: user-regs.c
===================================================================
RCS file: /cvs/src/src/gdb/user-regs.c,v
retrieving revision 1.1
diff -u -r1.1 user-regs.c
--- user-regs.c	7 Jul 2003 14:36:58 -0000	1.1
+++ user-regs.c	28 Jul 2003 18:05:33 -0000
@@ -42,33 +42,39 @@
 {
   const char *name;
   struct value *(*read) (struct frame_info * frame);
+  struct user_reg *next;
 };
 
 struct user_regs
 {
-  struct user_reg *user;
-  int nr;
+  struct user_reg *first;
+  struct user_reg **last;
 };
 
 static void
-append_user_reg (struct user_regs *regs,
-		    const char *name, user_reg_read_ftype *read)
+append_user_reg (struct user_regs *regs, const char *name,
+		 user_reg_read_ftype *read, struct user_reg *reg)
 {
-  regs->nr++;
-  regs->user = xrealloc (regs->user,
-			    regs->nr * sizeof (struct user_reg));
-  regs->user[regs->nr - 1].name = name;
-  regs->user[regs->nr - 1].read = read;
+  /* The caller is responsible for allocating memory needed to store
+     the register.  By doing this, the function can operate on a
+     register list stored in the common heap or a specific obstack.  */
+  gdb_assert (reg != NULL);
+  reg->name = name;
+  reg->read = read;
+  reg->next = NULL;
+  (*regs->last) = reg;
+  regs->last = &(*regs->last)->next;
 }
 
 /* An array of the builtin user registers.  */
 
-static struct user_regs builtin_user_regs;
+static struct user_regs builtin_user_regs = { NULL, &builtin_user_regs.first };
 
 void
 user_reg_add_builtin (const char *name, user_reg_read_ftype *read)
 {
-  append_user_reg (&builtin_user_regs, name, read);
+  append_user_reg (&builtin_user_regs, name, read,
+		   XMALLOC (struct user_reg));
 }
 
 /* Per-architecture user registers.  Start with the builtin user
@@ -79,23 +85,15 @@
 static void *
 user_regs_init (struct gdbarch *gdbarch)
 {
-  int i;
-  struct user_regs *regs = XMALLOC (struct user_regs);
-  memset (regs, 0, sizeof (struct user_regs));
-  for (i = 0; i < builtin_user_regs.nr; i++)
-    append_user_reg (regs, builtin_user_regs.user[i].name,
-		     builtin_user_regs.user[i].read);
+  struct user_reg *reg;
+  struct user_regs *regs = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_regs);
+  regs->last = &regs->first;
+  for (reg = builtin_user_regs.first; reg != NULL; reg = reg->next)
+    append_user_reg (regs, reg->name, reg->read,
+		     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
   return regs;
 }
 
-static void
-user_regs_free (struct gdbarch *gdbarch, void *data)
-{
-  struct user_regs *regs = data;
-  xfree (regs->user);
-  xfree (regs);
-}
-
 void
 user_reg_add (struct gdbarch *gdbarch, const char *name,
 		 user_reg_read_ftype *read)
@@ -108,7 +106,8 @@
       regs = user_regs_init (gdbarch);
       set_gdbarch_data (gdbarch, user_regs_data, regs);
     }
-  append_user_reg (regs, name, read);
+  append_user_reg (regs, name, read,
+		   GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
 }
 
 int
@@ -139,42 +138,62 @@
   /* Search the user name space.  */
   {
     struct user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
-    int reg;
-    for (reg = 0; reg < regs->nr; reg++)
+    struct user_reg *reg;
+    int nr;
+    for (nr = 0, reg = regs->first; reg != NULL; reg = reg->next, nr++)
       {
-	if ((len < 0 && strcmp (regs->user[reg].name, name))
-	    || (len == strlen (regs->user[reg].name)
-		&& strncmp (regs->user[reg].name, name, len) == 0))
-	  return NUM_REGS + NUM_PSEUDO_REGS + reg;
+	if ((len < 0 && strcmp (reg->name, name))
+	    || (len == strlen (reg->name)
+		&& strncmp (reg->name, name, len) == 0))
+	  return NUM_REGS + NUM_PSEUDO_REGS + nr;
       }
   }
 
   return -1;
 }
 
+static struct user_reg *
+usernum_to_user_reg (struct gdbarch *gdbarch, int usernum)
+{
+  struct user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
+  struct user_reg *reg;
+  for (reg = regs->first; reg != NULL; reg = reg->next)
+    {
+      if (usernum == 0)
+	return reg;
+      usernum--;
+    }
+  return NULL;
+}
+
 const char *
 user_reg_map_regnum_to_name (struct gdbarch *gdbarch, int regnum)
 {
   int maxregs = (gdbarch_num_regs (gdbarch)
 		 + gdbarch_num_pseudo_regs (gdbarch));
-  struct user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
   if (regnum < 0)
     return NULL;
-  if (regnum < maxregs)
+  else if (regnum < maxregs)
     return gdbarch_register_name (gdbarch, regnum);
-  if (regnum < (maxregs + regs->nr))
-    return regs->user[regnum - maxregs].name;
-  return NULL;
+  else
+    {
+      struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs);
+      if (reg == NULL)
+	return NULL;
+      else
+	return reg->name;
+    }
 }
 
 struct value *
 value_of_user_reg (int regnum, struct frame_info *frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  struct user_regs *regs = gdbarch_data (gdbarch, user_regs_data);
-  int reg = regnum - (NUM_REGS + NUM_PSEUDO_REGS);
-  gdb_assert (reg >= 0 && reg < regs->nr);
-  return regs->user[reg].read (frame);
+  int maxregs = (gdbarch_num_regs (gdbarch)
+		 + gdbarch_num_pseudo_regs (gdbarch));
+  struct user_reg *reg = usernum_to_user_reg (gdbarch, regnum - maxregs);
+  gdb_assert (reg != NULL);
+  return reg->read (frame);
 }
 
 extern initialize_file_ftype _initialize_user_regs; /* -Wmissing-prototypes */
@@ -182,5 +201,5 @@
 void
 _initialize_user_regs (void)
 {
-  user_regs_data = register_gdbarch_data (user_regs_init, user_regs_free);
+  user_regs_data = register_gdbarch_data (user_regs_init, NULL);
 }

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