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]

[7/17] add registry.h


We have the "registry" pattern, where modules can add data to some
container using a per-module key, in use in 3 places: objfiles,
inferiors, and program spaces.  The code is mostly cut-and-pasted
between these places.

This patch introduces a registry.h that has all the code for this as big
macros, a la vec.h.  Then it changes the existing instances to use the
macros.  If we can't have real templates, we'll have this.

Tom

>From 39e21a8510e7b5fd456aad7e82941445559b6c51 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@redhat.com>
Date: Mon, 5 Dec 2011 11:56:29 -0700
Subject: [PATCH 07/18] add registry.h, change existing users

	* solib-svr4.c (_initialize_svr4_solib): Update
	* solib-dsbt.c (_initialize_dsbt_solib): Update.
	* registry.h: New file.
	* python/py-progspace.c (gdbpy_initialize_pspace): Update.
	* python/py-inferior.c (gdbpy_initialize_inferior): Update.
	* python/py-auto-load.c (gdbpy_initialize_auto_load): Update.
	* progspace.h: Include registry.h.  Use DECLARE_REGISTRY.
	(register_program_space_data_with_cleanup)
	(register_program_space_data, program_space_alloc_data)
	(clear_program_space_data, set_program_space_data)
	(program_space_data): Don't declare.
	* progspace.c: Use DEFINE_REGISTRY.
	(struct program_space_data, struct
	program_space_data_registration, struct
	program_space_data_registry, program_space_data_registry)
	(register_program_space_data_with_cleanup)
	(register_program_space_data, program_space_alloc_data)
	(program_space_free_data, clear_program_space_data)
	(set_program_space_data, program_space_data): Remove.
	* objfiles.h: Include registry.h.  Use DECLARE_REGISTRY.
	(struct objfile) <data, num_data>: Replace with REGISTRY_FIELDS.
	(register_objfile_data_with_cleanup, register_objfile_data)
	(clear_objfile_data, set_objfile_data, objfile_data): Don't
	declare.
	* objfiles.c: Use DEFINE_REGISTRY.
	(struct objfile_data, struct objfile_data_registration, struct
	objfile_data_registry, objfile_data_registry)
	(register_objfile_data_with_cleanup, register_objfile_data)
	(objfile_alloc_data, objfile_free_data, clear_objfile_data)
	(set_objfile_data, objfile_data): Remove.
	(_initialize_objfiles): Update.
	* jit.c (_initialize_jit): Update.
	* inflow.c (_initialize_inflow): Update.
	* inferior.h: Include registry.h.  Use DECLARE_REGISTRY.
	(struct inferior) <data, num_data>: Replace with REGISTRY_FIELDS.
	(register_inferior_data_with_cleanup, register_inferior_data)
	(clear_inferior_data, set_inferior_data, inferior_data): Don't
	declare.
	* inferior.c: Use DEFINE_REGISTRY.
	(struct inferior_data, struct inferior_data_registration, struct
	inferior_data_registry, inferior_data_registry)
	(register_inferior_data_with_cleanup, register_inferior_data)
	(inferior_alloc_data, inferior_free_data  clear_inferior_data)
	(set_inferior_data, inferior_data): Remove.
	* auxv.c (_initialize_auxv): Update.
	* ada-lang.c (_initialize_ada_language): Update.
---
 gdb/ada-lang.c            |    2 +-
 gdb/auxv.c                |    2 +-
 gdb/inferior.c            |  105 +------------------------
 gdb/inferior.h            |   13 +---
 gdb/inflow.c              |    2 +-
 gdb/jit.c                 |    2 +-
 gdb/objfiles.c            |  118 +---------------------------
 gdb/objfiles.h            |   23 +-----
 gdb/progspace.c           |  111 ++-------------------------
 gdb/progspace.h           |   14 +---
 gdb/python/py-auto-load.c |    3 +-
 gdb/python/py-inferior.c  |    2 +-
 gdb/python/py-progspace.c |    2 +-
 gdb/registry.h            |  187 +++++++++++++++++++++++++++++++++++++++++++++
 gdb/solib-dsbt.c          |    2 +-
 gdb/solib-svr4.c          |    2 +-
 16 files changed, 221 insertions(+), 369 deletions(-)
 create mode 100644 gdb/registry.h

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 3843539..beefb03 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12455,5 +12455,5 @@ With an argument, catch only exceptions with the given name."),
   /* Setup per-inferior data.  */
   observer_attach_inferior_exit (ada_inferior_exit);
   ada_inferior_data
-    = register_inferior_data_with_cleanup (ada_inferior_data_cleanup);
+    = register_inferior_data_with_cleanup (NULL, ada_inferior_data_cleanup);
 }
diff --git a/gdb/auxv.c b/gdb/auxv.c
index 934441b..f68dcfd 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -527,7 +527,7 @@ This is information provided by the operating system at program startup."));
 
   /* Set an auxv cache per-inferior.  */
   auxv_inferior_data
-    = register_inferior_data_with_cleanup (auxv_inferior_data_cleanup);
+    = register_inferior_data_with_cleanup (NULL, auxv_inferior_data_cleanup);
 
   /* Observers used to invalidate the auxv cache when needed.  */
   observer_attach_inferior_exit (invalidate_auxv_cache_inf);
diff --git a/gdb/inferior.c b/gdb/inferior.c
index b4b33de..207cc45 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -35,8 +35,10 @@
 
 void _initialize_inferiors (void);
 
-static void inferior_alloc_data (struct inferior *inf);
-static void inferior_free_data (struct inferior *inf);
+/* Keep a registry of per-inferior data-pointers required by other GDB
+   modules.  */
+
+DEFINE_REGISTRY (inferior, REGISTRY_ACCESS_FIELD)
 
 struct inferior *inferior_list = NULL;
 static int highest_inferior_num;
@@ -963,105 +965,6 @@ show_print_inferior_events (struct ui_file *file, int from_tty,
 
 
 
-/* Keep a registry of per-inferior data-pointers required by other GDB
-   modules.  */
-
-struct inferior_data
-{
-  unsigned index;
-  void (*cleanup) (struct inferior *, void *);
-};
-
-struct inferior_data_registration
-{
-  struct inferior_data *data;
-  struct inferior_data_registration *next;
-};
-
-struct inferior_data_registry
-{
-  struct inferior_data_registration *registrations;
-  unsigned num_registrations;
-};
-
-static struct inferior_data_registry inferior_data_registry
-  = { NULL, 0 };
-
-const struct inferior_data *
-register_inferior_data_with_cleanup
-  (void (*cleanup) (struct inferior *, void *))
-{
-  struct inferior_data_registration **curr;
-
-  /* Append new registration.  */
-  for (curr = &inferior_data_registry.registrations;
-       *curr != NULL; curr = &(*curr)->next);
-
-  *curr = XMALLOC (struct inferior_data_registration);
-  (*curr)->next = NULL;
-  (*curr)->data = XMALLOC (struct inferior_data);
-  (*curr)->data->index = inferior_data_registry.num_registrations++;
-  (*curr)->data->cleanup = cleanup;
-
-  return (*curr)->data;
-}
-
-const struct inferior_data *
-register_inferior_data (void)
-{
-  return register_inferior_data_with_cleanup (NULL);
-}
-
-static void
-inferior_alloc_data (struct inferior *inf)
-{
-  gdb_assert (inf->data == NULL);
-  inf->num_data = inferior_data_registry.num_registrations;
-  inf->data = XCALLOC (inf->num_data, void *);
-}
-
-static void
-inferior_free_data (struct inferior *inf)
-{
-  gdb_assert (inf->data != NULL);
-  clear_inferior_data (inf);
-  xfree (inf->data);
-  inf->data = NULL;
-}
-
-void
-clear_inferior_data (struct inferior *inf)
-{
-  struct inferior_data_registration *registration;
-  int i;
-
-  gdb_assert (inf->data != NULL);
-
-  for (registration = inferior_data_registry.registrations, i = 0;
-       i < inf->num_data;
-       registration = registration->next, i++)
-    if (inf->data[i] != NULL && registration->data->cleanup)
-      registration->data->cleanup (inf, inf->data[i]);
-
-  memset (inf->data, 0, inf->num_data * sizeof (void *));
-}
-
-void
-set_inferior_data (struct inferior *inf,
-		       const struct inferior_data *data,
-		       void *value)
-{
-  gdb_assert (data->index < inf->num_data);
-  inf->data[data->index] = value;
-}
-
-void *
-inferior_data (struct inferior *inf, const struct inferior_data *data)
-{
-  gdb_assert (data->index < inf->num_data);
-  return inf->data[data->index];
-}
-
 void
 initialize_inferiors (void)
 {
diff --git a/gdb/inferior.h b/gdb/inferior.h
index cfaea7f..5fec211 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -44,6 +44,7 @@ struct terminal_info;
 #include "frame.h"
 
 #include "progspace.h"
+#include "registry.h"
 
 struct infcall_suspend_state;
 struct infcall_control_state;
@@ -515,21 +516,13 @@ struct inferior
   int total_syscalls_count;
 
   /* Per inferior data-pointers required by other GDB modules.  */
-  void **data;
-  unsigned num_data;
+  REGISTRY_FIELDS;
 };
 
 /* Keep a registry of per-inferior data-pointers required by other GDB
    modules.  */
 
-extern const struct inferior_data *register_inferior_data (void);
-extern const struct inferior_data *register_inferior_data_with_cleanup
-  (void (*cleanup) (struct inferior *, void *));
-extern void clear_inferior_data (struct inferior *inf);
-extern void set_inferior_data (struct inferior *inf,
-			       const struct inferior_data *data, void *value);
-extern void *inferior_data (struct inferior *inf,
-			    const struct inferior_data *data);
+DECLARE_REGISTRY (inferior);
 
 /* Create an empty inferior list, or empty the existing one.  */
 extern void init_inferior_list (void);
diff --git a/gdb/inflow.c b/gdb/inflow.c
index 7876347..00c6c4d 100644
--- a/gdb/inflow.c
+++ b/gdb/inflow.c
@@ -927,5 +927,5 @@ input settings."),
   observer_attach_inferior_exit (inflow_inferior_exit);
 
   inflow_inferior_data
-    = register_inferior_data_with_cleanup (inflow_inferior_data_cleanup);
+    = register_inferior_data_with_cleanup (NULL, inflow_inferior_data_cleanup);
 }
diff --git a/gdb/jit.c b/gdb/jit.c
index 24ab237..62ccc91 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -1382,7 +1382,7 @@ _initialize_jit (void)
   jit_objfile_data =
     register_objfile_data_with_cleanup (NULL, free_objfile_data);
   jit_inferior_data =
-    register_inferior_data_with_cleanup (jit_inferior_data_cleanup);
+    register_inferior_data_with_cleanup (NULL, jit_inferior_data_cleanup);
   jit_gdbarch_data = gdbarch_data_register_pre_init (jit_gdbarch_data_init);
   if (is_dl_available ())
     {
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 8f73600..148a9ed 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -57,10 +57,10 @@
 #include "solist.h"
 #include "gdb_bfd.h"
 
-/* Prototypes for local functions */
+/* Keep a registry of per-objfile data-pointers required by other GDB
+   modules.  */
 
-static void objfile_alloc_data (struct objfile *objfile);
-static void objfile_free_data (struct objfile *objfile);
+DEFINE_REGISTRY (objfile, REGISTRY_ACCESS_FIELD)
 
 /* Externally visible variables that are owned by this module.
    See declarations in objfile.h for more info.  */
@@ -1355,115 +1355,6 @@ in_plt_section (CORE_ADDR pc, char *name)
 }
 
 
-/* Keep a registry of per-objfile data-pointers required by other GDB
-   modules.  */
-
-struct objfile_data
-{
-  unsigned index;
-  void (*save) (struct objfile *, void *);
-  void (*free) (struct objfile *, void *);
-};
-
-struct objfile_data_registration
-{
-  struct objfile_data *data;
-  struct objfile_data_registration *next;
-};
-  
-struct objfile_data_registry
-{
-  struct objfile_data_registration *registrations;
-  unsigned num_registrations;
-};
-
-static struct objfile_data_registry objfile_data_registry = { NULL, 0 };
-
-const struct objfile_data *
-register_objfile_data_with_cleanup (void (*save) (struct objfile *, void *),
-				    void (*free) (struct objfile *, void *))
-{
-  struct objfile_data_registration **curr;
-
-  /* Append new registration.  */
-  for (curr = &objfile_data_registry.registrations;
-       *curr != NULL; curr = &(*curr)->next);
-
-  *curr = XMALLOC (struct objfile_data_registration);
-  (*curr)->next = NULL;
-  (*curr)->data = XMALLOC (struct objfile_data);
-  (*curr)->data->index = objfile_data_registry.num_registrations++;
-  (*curr)->data->save = save;
-  (*curr)->data->free = free;
-
-  return (*curr)->data;
-}
-
-const struct objfile_data *
-register_objfile_data (void)
-{
-  return register_objfile_data_with_cleanup (NULL, NULL);
-}
-
-static void
-objfile_alloc_data (struct objfile *objfile)
-{
-  gdb_assert (objfile->data == NULL);
-  objfile->num_data = objfile_data_registry.num_registrations;
-  objfile->data = XCALLOC (objfile->num_data, void *);
-}
-
-static void
-objfile_free_data (struct objfile *objfile)
-{
-  gdb_assert (objfile->data != NULL);
-  clear_objfile_data (objfile);
-  xfree (objfile->data);
-  objfile->data = NULL;
-}
-
-void
-clear_objfile_data (struct objfile *objfile)
-{
-  struct objfile_data_registration *registration;
-  int i;
-
-  gdb_assert (objfile->data != NULL);
-
-  /* Process all the save handlers.  */
-
-  for (registration = objfile_data_registry.registrations, i = 0;
-       i < objfile->num_data;
-       registration = registration->next, i++)
-    if (objfile->data[i] != NULL && registration->data->save != NULL)
-      registration->data->save (objfile, objfile->data[i]);
-
-  /* Now process all the free handlers.  */
-
-  for (registration = objfile_data_registry.registrations, i = 0;
-       i < objfile->num_data;
-       registration = registration->next, i++)
-    if (objfile->data[i] != NULL && registration->data->free != NULL)
-      registration->data->free (objfile, objfile->data[i]);
-
-  memset (objfile->data, 0, objfile->num_data * sizeof (void *));
-}
-
-void
-set_objfile_data (struct objfile *objfile, const struct objfile_data *data,
-		  void *value)
-{
-  gdb_assert (data->index < objfile->num_data);
-  objfile->data[data->index] = value;
-}
-
-void *
-objfile_data (struct objfile *objfile, const struct objfile_data *data)
-{
-  gdb_assert (data->index < objfile->num_data);
-  return objfile->data[data->index];
-}
-
 /* Set objfiles_changed_p so section map will be rebuilt next time it
    is used.  Called by reread_symbols.  */
 
@@ -1481,5 +1372,6 @@ void
 _initialize_objfiles (void)
 {
   objfiles_pspace_data
-    = register_program_space_data_with_cleanup (objfiles_pspace_data_cleanup);
+    = register_program_space_data_with_cleanup (NULL,
+						objfiles_pspace_data_cleanup);
 }
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index e502541..1514f34 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -25,6 +25,7 @@
 #include "gdb_obstack.h"	/* For obstack internals.  */
 #include "symfile.h"		/* For struct psymbol_allocation_list.  */
 #include "progspace.h"
+#include "registry.h"
 
 struct bcache;
 struct htab;
@@ -335,8 +336,7 @@ struct objfile
        deprecated_sym_stab_info and deprecated_sym_private
        entirely.  */
 
-    void **data;
-    unsigned num_data;
+    REGISTRY_FIELDS;
 
     /* Set of relocation offsets to apply to each section.
        Currently on the objfile_obstack (which makes no sense, but I'm
@@ -516,24 +516,7 @@ extern int in_plt_section (CORE_ADDR, char *);
 
 /* Keep a registry of per-objfile data-pointers required by other GDB
    modules.  */
-
-/* Allocate an entry in the per-objfile registry.  */
-extern const struct objfile_data *register_objfile_data (void);
-
-/* Allocate an entry in the per-objfile registry.
-   SAVE and FREE are called when clearing objfile data.
-   First all registered SAVE functions are called.
-   Then all registered FREE functions are called.
-   Either or both of SAVE, FREE may be NULL.  */
-extern const struct objfile_data *register_objfile_data_with_cleanup
-  (void (*save) (struct objfile *, void *),
-   void (*free) (struct objfile *, void *));
-
-extern void clear_objfile_data (struct objfile *objfile);
-extern void set_objfile_data (struct objfile *objfile,
-			      const struct objfile_data *data, void *value);
-extern void *objfile_data (struct objfile *objfile,
-			   const struct objfile_data *data);
+DECLARE_REGISTRY(objfile);
 
 
 
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 2d0dce7..6692f93 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -37,10 +37,13 @@ struct program_space *current_program_space;
 /* The last address space number assigned.  */
 static int highest_address_space_num;
 
-/* Prototypes for local functions */
+
+
+/* Keep a registry of per-program_space data-pointers required by other GDB
+   modules.  */
+
+DEFINE_REGISTRY (program_space, REGISTRY_ACCESS_FIELD)
 
-static void program_space_alloc_data (struct program_space *);
-static void program_space_free_data (struct program_space *);
 
 
 /* An address space.  Currently this is not used for much other than
@@ -503,108 +506,6 @@ switch_to_program_space_and_thread (struct program_space *pspace)
 
 
 
-/* Keep a registry of per-program_space data-pointers required by other GDB
-   modules.  */
-
-struct program_space_data
-{
-  unsigned index;
-  void (*cleanup) (struct program_space *, void *);
-};
-
-struct program_space_data_registration
-{
-  struct program_space_data *data;
-  struct program_space_data_registration *next;
-};
-
-struct program_space_data_registry
-{
-  struct program_space_data_registration *registrations;
-  unsigned num_registrations;
-};
-
-static struct program_space_data_registry program_space_data_registry
-  = { NULL, 0 };
-
-const struct program_space_data *
-register_program_space_data_with_cleanup
-  (void (*cleanup) (struct program_space *, void *))
-{
-  struct program_space_data_registration **curr;
-
-  /* Append new registration.  */
-  for (curr = &program_space_data_registry.registrations;
-       *curr != NULL; curr = &(*curr)->next);
-
-  *curr = XMALLOC (struct program_space_data_registration);
-  (*curr)->next = NULL;
-  (*curr)->data = XMALLOC (struct program_space_data);
-  (*curr)->data->index = program_space_data_registry.num_registrations++;
-  (*curr)->data->cleanup = cleanup;
-
-  return (*curr)->data;
-}
-
-const struct program_space_data *
-register_program_space_data (void)
-{
-  return register_program_space_data_with_cleanup (NULL);
-}
-
-static void
-program_space_alloc_data (struct program_space *pspace)
-{
-  gdb_assert (pspace->data == NULL);
-  pspace->num_data = program_space_data_registry.num_registrations;
-  pspace->data = XCALLOC (pspace->num_data, void *);
-}
-
-static void
-program_space_free_data (struct program_space *pspace)
-{
-  gdb_assert (pspace->data != NULL);
-  clear_program_space_data (pspace);
-  xfree (pspace->data);
-  pspace->data = NULL;
-}
-
-void
-clear_program_space_data (struct program_space *pspace)
-{
-  struct program_space_data_registration *registration;
-  int i;
-
-  gdb_assert (pspace->data != NULL);
-
-  for (registration = program_space_data_registry.registrations, i = 0;
-       i < pspace->num_data;
-       registration = registration->next, i++)
-    if (pspace->data[i] != NULL && registration->data->cleanup)
-      registration->data->cleanup (pspace, pspace->data[i]);
-
-  memset (pspace->data, 0, pspace->num_data * sizeof (void *));
-}
-
-void
-set_program_space_data (struct program_space *pspace,
-		       const struct program_space_data *data,
-		       void *value)
-{
-  gdb_assert (data->index < pspace->num_data);
-  pspace->data[data->index] = value;
-}
-
-void *
-program_space_data (struct program_space *pspace,
-		    const struct program_space_data *data)
-{
-  gdb_assert (data->index < pspace->num_data);
-  return pspace->data[data->index];
-}
-
-
-
 void
 initialize_progspace (void)
 {
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 76e8080..9f08a4d 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -23,6 +23,7 @@
 
 #include "target.h"
 #include "vec.h"
+#include "registry.h"
 
 struct target_ops;
 struct bfd;
@@ -189,8 +190,7 @@ struct program_space
     unsigned solib_add_generation;
 
     /* Per pspace data-pointers required by other GDB modules.  */
-    void **data;
-    unsigned num_data;
+    REGISTRY_FIELDS;
   };
 
 /* The object file that the main symbol table was loaded from (e.g. the
@@ -281,14 +281,6 @@ extern void prune_program_spaces (void);
 /* Keep a registry of per-pspace data-pointers required by other GDB
    modules.  */
 
-extern const struct program_space_data *register_program_space_data (void);
-extern const struct program_space_data *register_program_space_data_with_cleanup
-  (void (*cleanup) (struct program_space *, void *));
-extern void clear_program_space_data (struct program_space *pspace);
-extern void set_program_space_data (struct program_space *pspace,
-				    const struct program_space_data *data,
-				    void *value);
-extern void *program_space_data (struct program_space *pspace,
-			   const struct program_space_data *data);
+DECLARE_REGISTRY (program_space);
 
 #endif
diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c
index 2a17ed0..5f9512e 100644
--- a/gdb/python/py-auto-load.c
+++ b/gdb/python/py-auto-load.c
@@ -604,7 +604,8 @@ void
 gdbpy_initialize_auto_load (void)
 {
   auto_load_pspace_data
-    = register_program_space_data_with_cleanup (auto_load_pspace_data_cleanup);
+    = register_program_space_data_with_cleanup (NULL,
+						auto_load_pspace_data_cleanup);
 
   observer_attach_new_objfile (auto_load_new_objfile);
 
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 7b2981e..76c2bee 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -726,7 +726,7 @@ gdbpy_initialize_inferior (void)
 		      (PyObject *) &inferior_object_type);
 
   infpy_inf_data_key =
-    register_inferior_data_with_cleanup (py_free_inferior);
+    register_inferior_data_with_cleanup (NULL, py_free_inferior);
 
   observer_attach_new_thread (add_thread_object);
   observer_attach_thread_exit (delete_thread_object);
diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c
index c30b37d..4e1c9c5 100644
--- a/gdb/python/py-progspace.c
+++ b/gdb/python/py-progspace.c
@@ -179,7 +179,7 @@ void
 gdbpy_initialize_pspace (void)
 {
   pspy_pspace_data_key
-    = register_program_space_data_with_cleanup (py_free_pspace);
+    = register_program_space_data_with_cleanup (NULL, py_free_pspace);
 
   if (PyType_Ready (&pspace_object_type) < 0)
     return;
diff --git a/gdb/registry.h b/gdb/registry.h
new file mode 100644
index 0000000..c2a102b
--- /dev/null
+++ b/gdb/registry.h
@@ -0,0 +1,187 @@
+/* Macros for general registry objects.
+
+   Copyright (C) 2011
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef REGISTRY_H
+#define REGISTRY_H
+
+/* The macros here implement a template type and functions for
+   associating some user data with a container object.
+
+   The API user requests a key from a registry during gdb
+   initialization.  Later this key can be used to associate some
+   module-specific data with a specific container object.
+
+   A registry is associated with a struct tag name.
+
+   The exported API is best used via the wrapper macros:
+   
+   - register_TAG_data(TAG)
+   Get a new key for the container type TAG.
+   
+   - register_TAG_data_with_cleanup(TAG, SAVE, FREE)
+   Get a new key for the container type TAG.
+   SAVE and FREE are defined as void (*) (struct TAG *, void *)
+   When the container is destroyed, first all registered SAVE
+   functions are called.
+   Then all FREE functions are called.
+   Either or both may be NULL.
+   
+   - clear_TAG_data(TAG, OBJECT)
+   Clear all the data associated with OBJECT.  Should be called by the
+   container implementation when a container object is destroyed.
+   
+   - set_TAG_data(TAG, OBJECT, KEY, DATA)
+   Set the data on an object.
+   
+   - TAG_data(TAG, OBJECT, KEY)
+   Fetch the data for an object; returns NULL if it has not been set.
+*/
+
+/* This macro is used in a container struct definition to define the
+   fields used by the registry code.  */
+
+#define REGISTRY_FIELDS				\
+  void **data;					\
+  unsigned num_data
+
+/* Define a new registry implementation.  */
+
+#define DEFINE_REGISTRY(TAG)						\
+struct TAG ## _data							\
+{									\
+  unsigned index;							\
+  void (*save) (struct TAG *, void *);					\
+  void (*free) (struct TAG *, void *);					\
+};									\
+									\
+struct TAG ## _data_registration					\
+{									\
+  struct TAG ## _data *data;						\
+  struct TAG ## _data_registration *next;				\
+};									\
+									\
+struct TAG ## _data_registry						\
+{									\
+  struct TAG ## _data_registration *registrations;			\
+  unsigned num_registrations;						\
+};									\
+									\
+struct TAG ## _data_registry TAG ## _data_registry = { NULL, 0 };	\
+									\
+const struct TAG ## _data *						\
+register_ ## TAG ## _data_with_cleanup (void (*save) (struct TAG *, void *), \
+				    void (*free) (struct TAG *, void *)) \
+{									\
+  struct TAG ## _data_registration **curr;				\
+									\
+  /* Append new registration.  */					\
+  for (curr = &TAG ## _data_registry.registrations;			\
+       *curr != NULL; curr = &(*curr)->next);				\
+									\
+  *curr = XMALLOC (struct TAG ## _data_registration);			\
+  (*curr)->next = NULL;							\
+  (*curr)->data = XMALLOC (struct TAG ## _data);			\
+  (*curr)->data->index = TAG ## _data_registry.num_registrations++;	\
+  (*curr)->data->save = save;						\
+  (*curr)->data->free = free;						\
+									\
+  return (*curr)->data;							\
+}									\
+									\
+const struct TAG ## _data *						\
+register_ ## TAG ## _data (void)					\
+{									\
+  return register_ ## TAG ## _data_with_cleanup (NULL, NULL);		\
+}									\
+									\
+void									\
+TAG ## _alloc_data (struct TAG *container)				\
+{									\
+  gdb_assert (container->data == NULL);					\
+  container->num_data = TAG ## _data_registry.num_registrations;	\
+  container->data = XCALLOC (container->num_data, void *);		\
+}									\
+									\
+void									\
+clear_ ## TAG ## _data (struct TAG *container)				\
+{									\
+  struct TAG ## _data_registration *registration;			\
+  int i;								\
+									\
+  gdb_assert (container->data != NULL);					\
+									\
+  /* Process all the save handlers.  */					\
+									\
+  for (registration = TAG ## _data_registry.registrations, i = 0;	\
+       i < container->num_data;						\
+       registration = registration->next, i++)				\
+    if (container->data[i] != NULL && registration->data->save != NULL)	\
+      registration->data->save (container, container->data[i]);		\
+									\
+  /* Now process all the free handlers.  */				\
+									\
+  for (registration = TAG ## _data_registry.registrations, i = 0;	\
+       i < container->num_data;						\
+       registration = registration->next, i++)				\
+    if (container->data[i] != NULL && registration->data->free != NULL)	\
+      registration->data->free (container, container->data[i]);		\
+									\
+  memset (container->data, 0, container->num_data * sizeof (void *));	\
+}									\
+									\
+void									\
+TAG ## _free_data (struct TAG *container)				\
+{									\
+  struct registry_fields *rdata = &ACCESS (container)->registry_data;	\
+  gdb_assert (rdata->data != NULL);					\
+  clear_ ## TAG ## _data (container);					\
+  xfree (rdata->data);							\
+  rdata->data = NULL;							\
+}									\
+									\
+void									\
+set_ ## TAG ## _data (struct TAG *container, const struct TAG ## _data *data, \
+		  void *value)						\
+{									\
+  gdb_assert (data->index < container->num_data);			\
+  container->data[data->index] = value;					\
+}									\
+									\
+void *									\
+TAG ## _data (struct TAG *container, const struct TAG ## _data *data)	\
+{									\
+  gdb_assert (data->index < container->num_data);			\
+  return container->data[data->index];					\
+}
+
+
+/* External declarations for the registry functions.  */
+
+#define DECLARE_REGISTRY(TAG)						\
+extern const struct TAG ## _data *register_ ## TAG ## _data (void);	\
+extern const struct TAG ## _data *register_ ## TAG ## _data_with_cleanup \
+ (void (*save) (struct TAG *, void *), void (*free) (struct TAG *, void *)); \
+extern void clear_ ## TAG ## _data (struct TAG *);		\
+extern void set_ ## TAG ## _data (struct TAG *,			\
+			       const struct TAG ## _data *data, void *value); \
+extern void *TAG ## _data (struct TAG *,			\
+			   const struct TAG ## _data *data);
+
+#endif /* REGISTRY_H */
diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index 40dc3f6..6eaaaf7 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -1174,7 +1174,7 @@ void
 _initialize_dsbt_solib (void)
 {
   solib_dsbt_pspace_data
-    = register_program_space_data_with_cleanup (dsbt_pspace_data_cleanup);
+    = register_program_space_data_with_cleanup (NULL, dsbt_pspace_data_cleanup);
 
   dsbt_so_ops.relocate_section_addresses = dsbt_relocate_section_addresses;
   dsbt_so_ops.free_so = dsbt_free_so;
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 83d7904..16c9c5e 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -2473,7 +2473,7 @@ _initialize_svr4_solib (void)
 {
   solib_svr4_data = gdbarch_data_register_pre_init (solib_svr4_init);
   solib_svr4_pspace_data
-    = register_program_space_data_with_cleanup (svr4_pspace_data_cleanup);
+    = register_program_space_data_with_cleanup (NULL, svr4_pspace_data_cleanup);
 
   svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
   svr4_so_ops.free_so = svr4_free_so;
-- 
1.7.6.4


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