[7/17] add registry.h
Tom Tromey
tromey@redhat.com
Wed Dec 14 21:18:00 GMT 2011
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
More information about the Gdb-patches
mailing list