aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog52
-rw-r--r--gdb/ada-lang.c2
-rw-r--r--gdb/auto-load.c3
-rw-r--r--gdb/auxv.c2
-rw-r--r--gdb/breakpoint.c3
-rw-r--r--gdb/i386-nat.c2
-rw-r--r--gdb/inferior.c105
-rw-r--r--gdb/inferior.h13
-rw-r--r--gdb/inflow.c2
-rw-r--r--gdb/jit.c2
-rw-r--r--gdb/objfiles.c118
-rw-r--r--gdb/objfiles.h23
-rw-r--r--gdb/progspace.c111
-rw-r--r--gdb/progspace.h14
-rw-r--r--gdb/python/py-inferior.c2
-rw-r--r--gdb/python/py-progspace.c2
-rw-r--r--gdb/registry.h187
-rw-r--r--gdb/solib-darwin.c3
-rw-r--r--gdb/solib-dsbt.c2
-rw-r--r--gdb/solib-svr4.c2
20 files changed, 278 insertions, 372 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 964b6fd..385e312 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,57 @@
2012-08-22 Tom Tromey <tromey@redhat.com>
+ * auto-load.c (_initialize_auto_load): Update.
+ * solib-svr4.c (_initialize_svr4_solib): Update
+ * solib-dsbt.c (_initialize_dsbt_solib): Update.
+ * solib-darwin.c (_initialize_darwin_solib): Update.
+ * registry.h: New file.
+ * python/py-progspace.c (gdbpy_initialize_pspace): Update.
+ * python/py-inferior.c (gdbpy_initialize_inferior): 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.
+ * breakpoint.c (_initialize_breakpoint): Update.
+ * i386-nat.c (i386_use_watchpoints): Update.
+
+2012-08-22 Tom Tromey <tromey@redhat.com>
+
* exec.c (exec_close, exec_file_attach): Update.
(add_to_section_table): Initialize 'key' field.
(add_target_sections, remove_target_sections): Add 'key' argument.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 38bc637..bba045b 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12657,5 +12657,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/auto-load.c b/gdb/auto-load.c
index 03a7539..2971183 100644
--- a/gdb/auto-load.c
+++ b/gdb/auto-load.c
@@ -1130,7 +1130,8 @@ _initialize_auto_load (void)
struct cmd_list_element *cmd;
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/auxv.c b/gdb/auxv.c
index 12dcb89..62628c6 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -530,7 +530,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/breakpoint.c b/gdb/breakpoint.c
index c693d42..b2a00be 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -15876,7 +15876,8 @@ _initialize_breakpoint (void)
= register_objfile_data_with_cleanup (NULL, free_breakpoint_probes);
catch_syscall_inferior_data
- = register_inferior_data_with_cleanup (catch_syscall_inferior_data_cleanup);
+ = register_inferior_data_with_cleanup (NULL,
+ catch_syscall_inferior_data_cleanup);
breakpoint_chain = 0;
/* Don't bother to call set_breakpoint_count. $bpnum isn't useful
diff --git a/gdb/i386-nat.c b/gdb/i386-nat.c
index 753de67..e7d9b4d 100644
--- a/gdb/i386-nat.c
+++ b/gdb/i386-nat.c
@@ -873,7 +873,7 @@ i386_use_watchpoints (struct target_ops *t)
if (i386_inferior_data == NULL)
i386_inferior_data
- = register_inferior_data_with_cleanup (i386_inferior_data_cleanup);
+ = register_inferior_data_with_cleanup (NULL, i386_inferior_data_cleanup);
}
void
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 805acb4..c812d39 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -36,8 +36,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)
struct inferior *inferior_list = NULL;
static int highest_inferior_num;
@@ -955,105 +957,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 86402f1..b2607c3 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -43,6 +43,7 @@ struct terminal_info;
#include "frame.h"
#include "progspace.h"
+#include "registry.h"
struct infcall_suspend_state;
struct infcall_control_state;
@@ -513,21 +514,13 @@ struct inferior
int symfile_flags;
/* 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 711b2aa..de6ee56 100644
--- a/gdb/inflow.c
+++ b/gdb/inflow.c
@@ -925,5 +925,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 2ba6d7e..26de189 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -1414,7 +1414,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 411618f..b33a0cf 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -55,10 +55,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)
/* Externally visible variables that are owned by this module.
See declarations in objfile.h for more info. */
@@ -1339,115 +1339,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. */
@@ -1490,5 +1381,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 0df5798..097f4db 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -23,6 +23,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;
@@ -323,8 +324,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.
The table is indexed by the_bfd_section->index, thus it is generally
@@ -503,24 +503,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);
extern void default_iterate_over_objfiles_in_search_order
(struct gdbarch *gdbarch,
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 1065c27..6498738 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)
-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
@@ -517,108 +520,6 @@ clear_program_space_solib_cache (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 3db3938..9348c3f 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -24,6 +24,7 @@
#include "target.h"
#include "vec.h"
#include "gdb_vecs.h"
+#include "registry.h"
struct target_ops;
struct bfd;
@@ -201,8 +202,7 @@ struct program_space
VEC (char_ptr) *deleted_solibs;
/* 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
@@ -298,14 +298,6 @@ extern void clear_program_space_solib_cache (struct program_space *);
/* 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-inferior.c b/gdb/python/py-inferior.c
index 907b73e..211a643 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -725,7 +725,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 1cb8240..e4b029b 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..d696781
--- /dev/null
+++ b/gdb/registry.h
@@ -0,0 +1,187 @@
+/* Macros for general registry objects.
+
+ Copyright (C) 2011, 2012
+ 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); \
+} \
+ \
+static 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 *)); \
+} \
+ \
+static void \
+TAG ## _free_data (struct TAG *container) \
+{ \
+ void ***rdata = &container->data; \
+ gdb_assert (*rdata != NULL); \
+ clear_ ## TAG ## _data (container); \
+ xfree (*rdata); \
+ *rdata = 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-darwin.c b/gdb/solib-darwin.c
index db8f187..d08bd38 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -534,7 +534,8 @@ void
_initialize_darwin_solib (void)
{
solib_darwin_pspace_data
- = register_program_space_data_with_cleanup (darwin_pspace_data_cleanup);
+ = register_program_space_data_with_cleanup (NULL,
+ darwin_pspace_data_cleanup);
darwin_so_ops.relocate_section_addresses = darwin_relocate_section_addresses;
darwin_so_ops.free_so = darwin_free_so;
diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index 3005326..8276db2 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -1171,7 +1171,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 2f4a345..3d60aa1 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -2484,7 +2484,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;