diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 964b6fdc73..385e3125df 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,55 @@ +2012-08-22 Tom Tromey + + * 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) : 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) : 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 * exec.c (exec_close, exec_file_attach): Update. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 38bc6372fc..bba045b4ba 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 03a7539458..29711832b6 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 12dcb8929d..62628c60f8 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 c693d420d5..b2a00be020 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 753de67d04..e7d9b4d69b 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 805acb4e92..c812d3980f 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 86402f155e..b2607c39f5 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 711b2aa626..de6ee56918 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 2ba6d7ef60..26de189601 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 411618f908..b33a0cf449 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 0df5798864..097f4dbbd5 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 1065c277b9..6498738909 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 3db3938aac..9348c3f231 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 907b73e8da..211a643dda 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 1cb82408ce..e4b029b207 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 0000000000..d69678116a --- /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 . */ + +#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 db8f187ad0..d08bd38769 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 300532627c..8276db2951 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 2f4a345d24..3d60aa1ae4 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;