mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-09 05:31:41 +00:00
2012-09-13 Pedro Alves <palves@redhat.com>
* Makefile.in (COMMON_OBS): Add registry.o. * registry.c: New file. * registry.h (struct registry_container): Declare. (registry_data_callback): New typedef. (struct registry_data, struct registry_data_registration, struct registry_data_registry): New type. (register_data_with_cleanup, registry_alloc_data) (registry_callback_adaptor, registry_clear_data) (registry_container_free_data, registry_set_data, registry_data): Declare. (DEFINE_REGISTRY): Refactor structures and functions as shims over the new common structures and functions. (DECLARE_REGISTRY): Declare struct TAG ## _data. Use the tagged callback typedefs.
This commit is contained in:
parent
80c4bb52e5
commit
aa0fbdd82c
@ -1,3 +1,20 @@
|
||||
2012-09-13 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* Makefile.in (COMMON_OBS): Add registry.o.
|
||||
* registry.c: New file.
|
||||
* registry.h (struct registry_container): Declare.
|
||||
(registry_data_callback): New typedef.
|
||||
(struct registry_data, struct registry_data_registration, struct
|
||||
registry_data_registry): New type.
|
||||
(register_data_with_cleanup, registry_alloc_data)
|
||||
(registry_callback_adaptor, registry_clear_data)
|
||||
(registry_container_free_data, registry_set_data, registry_data):
|
||||
Declare.
|
||||
(DEFINE_REGISTRY): Refactor structures and functions as shims over
|
||||
the new common structures and functions.
|
||||
(DECLARE_REGISTRY): Declare struct TAG ## _data. Use the tagged
|
||||
callback typedefs.
|
||||
|
||||
2012-09-12 Doug Evans <dje@google.com>
|
||||
|
||||
* dwarf2read.c (dwarf2_read_addr_index): Fix handling the case where
|
||||
|
@ -921,7 +921,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
|
||||
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
|
||||
gdb_vecs.o jit.o progspace.o skip.o probe.o \
|
||||
common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
|
||||
format.o
|
||||
format.o registry.o
|
||||
|
||||
TSOBS = inflow.o
|
||||
|
||||
|
116
gdb/registry.c
Normal file
116
gdb/registry.c
Normal file
@ -0,0 +1,116 @@
|
||||
/* Support functions 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/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "registry.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
const struct registry_data *
|
||||
register_data_with_cleanup (struct registry_data_registry *registry,
|
||||
registry_data_callback save,
|
||||
registry_data_callback free)
|
||||
{
|
||||
struct registry_data_registration **curr;
|
||||
|
||||
/* Append new registration. */
|
||||
for (curr = ®istry->registrations;
|
||||
*curr != NULL;
|
||||
curr = &(*curr)->next)
|
||||
;
|
||||
|
||||
*curr = XMALLOC (struct registry_data_registration);
|
||||
(*curr)->next = NULL;
|
||||
(*curr)->data = XMALLOC (struct registry_data);
|
||||
(*curr)->data->index = registry->num_registrations++;
|
||||
(*curr)->data->save = save;
|
||||
(*curr)->data->free = free;
|
||||
|
||||
return (*curr)->data;
|
||||
}
|
||||
|
||||
void
|
||||
registry_alloc_data (struct registry_data_registry *registry,
|
||||
struct registry_fields *fields)
|
||||
{
|
||||
gdb_assert (fields->data == NULL);
|
||||
fields->num_data = registry->num_registrations;
|
||||
fields->data = XCALLOC (fields->num_data, void *);
|
||||
}
|
||||
|
||||
void
|
||||
registry_clear_data (struct registry_data_registry *data_registry,
|
||||
registry_callback_adaptor adaptor,
|
||||
struct registry_container *container,
|
||||
struct registry_fields *fields)
|
||||
{
|
||||
struct registry_data_registration *registration;
|
||||
int i;
|
||||
|
||||
gdb_assert (fields->data != NULL);
|
||||
|
||||
/* Process all the save handlers. */
|
||||
|
||||
for (registration = data_registry->registrations, i = 0;
|
||||
i < fields->num_data;
|
||||
registration = registration->next, i++)
|
||||
if (fields->data[i] != NULL && registration->data->save != NULL)
|
||||
adaptor (registration->data->save, container, fields->data[i]);
|
||||
|
||||
/* Now process all the free handlers. */
|
||||
|
||||
for (registration = data_registry->registrations, i = 0;
|
||||
i < fields->num_data;
|
||||
registration = registration->next, i++)
|
||||
if (fields->data[i] != NULL && registration->data->free != NULL)
|
||||
adaptor (registration->data->free, container, fields->data[i]);
|
||||
|
||||
memset (fields->data, 0, fields->num_data * sizeof (void *));
|
||||
}
|
||||
|
||||
void
|
||||
registry_container_free_data (struct registry_data_registry *data_registry,
|
||||
registry_callback_adaptor adaptor,
|
||||
struct registry_container *container,
|
||||
struct registry_fields *fields)
|
||||
{
|
||||
void ***rdata = &fields->data;
|
||||
gdb_assert (*rdata != NULL);
|
||||
registry_clear_data (data_registry, adaptor, container, fields);
|
||||
xfree (*rdata);
|
||||
*rdata = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
registry_set_data (struct registry_fields *fields,
|
||||
const struct registry_data *data,
|
||||
void *value)
|
||||
{
|
||||
gdb_assert (data->index < fields->num_data);
|
||||
fields->data[data->index] = value;
|
||||
}
|
||||
|
||||
void *
|
||||
registry_data (struct registry_fields *fields,
|
||||
const struct registry_data *data)
|
||||
{
|
||||
gdb_assert (data->index < fields->num_data);
|
||||
return fields->data[data->index];
|
||||
}
|
182
gdb/registry.h
182
gdb/registry.h
@ -85,48 +85,85 @@ struct registry_fields
|
||||
#define REGISTRY_ACCESS_FIELD(CONTAINER) \
|
||||
(CONTAINER)
|
||||
|
||||
/* Opaque type representing a container type with a registry. This
|
||||
type is never defined. This is used to factor out common
|
||||
functionality of all struct tag names into common code. IOW,
|
||||
"struct tag name" pointers are cast to and from "struct
|
||||
registry_container" pointers when calling the common registry
|
||||
"backend" functions. */
|
||||
struct registry_container;
|
||||
|
||||
/* Registry callbacks have this type. */
|
||||
typedef void (*registry_data_callback) (struct registry_container *, void *);
|
||||
|
||||
struct registry_data
|
||||
{
|
||||
unsigned index;
|
||||
registry_data_callback save;
|
||||
registry_data_callback free;
|
||||
};
|
||||
|
||||
struct registry_data_registration
|
||||
{
|
||||
struct registry_data *data;
|
||||
struct registry_data_registration *next;
|
||||
};
|
||||
|
||||
struct registry_data_registry
|
||||
{
|
||||
struct registry_data_registration *registrations;
|
||||
unsigned num_registrations;
|
||||
};
|
||||
|
||||
/* Registry backend functions. Client code uses the frontend
|
||||
functions defined by DEFINE_REGISTRY below instead. */
|
||||
|
||||
const struct registry_data *register_data_with_cleanup
|
||||
(struct registry_data_registry *registry,
|
||||
registry_data_callback save,
|
||||
registry_data_callback free);
|
||||
|
||||
void registry_alloc_data (struct registry_data_registry *registry,
|
||||
struct registry_fields *registry_fields);
|
||||
|
||||
/* Cast FUNC and CONTAINER to the real types, and call FUNC, also
|
||||
passing DATA. */
|
||||
typedef void (*registry_callback_adaptor) (registry_data_callback func,
|
||||
struct registry_container *container,
|
||||
void *data);
|
||||
|
||||
void registry_clear_data (struct registry_data_registry *data_registry,
|
||||
registry_callback_adaptor adaptor,
|
||||
struct registry_container *container,
|
||||
struct registry_fields *fields);
|
||||
|
||||
void registry_container_free_data (struct registry_data_registry *data_registry,
|
||||
registry_callback_adaptor adaptor,
|
||||
struct registry_container *container,
|
||||
struct registry_fields *fields);
|
||||
|
||||
void registry_set_data (struct registry_fields *fields,
|
||||
const struct registry_data *data,
|
||||
void *value);
|
||||
|
||||
void *registry_data (struct registry_fields *fields,
|
||||
const struct registry_data *data);
|
||||
|
||||
/* Define a new registry implementation. */
|
||||
|
||||
#define DEFINE_REGISTRY(TAG, ACCESS) \
|
||||
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 }; \
|
||||
struct registry_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 *)) \
|
||||
void (*free) (struct TAG *, void *)) \
|
||||
{ \
|
||||
struct TAG ## _data_registration **curr; \
|
||||
struct registry_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; \
|
||||
return (struct TAG ## _data *) \
|
||||
register_data_with_cleanup (&TAG ## _data_registry, \
|
||||
(registry_data_callback) save, \
|
||||
(registry_data_callback) free); \
|
||||
} \
|
||||
\
|
||||
const struct TAG ## _data * \
|
||||
@ -139,76 +176,81 @@ static void \
|
||||
TAG ## _alloc_data (struct TAG *container) \
|
||||
{ \
|
||||
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
||||
gdb_assert (rdata->data == NULL); \
|
||||
rdata->num_data = TAG ## _data_registry.num_registrations; \
|
||||
rdata->data = XCALLOC (rdata->num_data, void *); \
|
||||
\
|
||||
registry_alloc_data (&TAG ## _data_registry, rdata); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
TAG ## registry_callback_adaptor (registry_data_callback func, \
|
||||
struct registry_container *container, \
|
||||
void *data) \
|
||||
{ \
|
||||
struct TAG *tagged_container = (struct TAG *) container; \
|
||||
struct registry_fields *rdata \
|
||||
= &ACCESS (tagged_container)->registry_data; \
|
||||
\
|
||||
registry_ ## TAG ## _callback tagged_func \
|
||||
= (registry_ ## TAG ## _callback) func; \
|
||||
\
|
||||
tagged_func (tagged_container, data); \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
clear_ ## TAG ## _data (struct TAG *container) \
|
||||
{ \
|
||||
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
||||
struct TAG ## _data_registration *registration; \
|
||||
int i; \
|
||||
\
|
||||
gdb_assert (rdata->data != NULL); \
|
||||
\
|
||||
/* Process all the save handlers. */ \
|
||||
\
|
||||
for (registration = TAG ## _data_registry.registrations, i = 0; \
|
||||
i < rdata->num_data; \
|
||||
registration = registration->next, i++) \
|
||||
if (rdata->data[i] != NULL && registration->data->save != NULL) \
|
||||
registration->data->save (container, rdata->data[i]); \
|
||||
\
|
||||
/* Now process all the free handlers. */ \
|
||||
\
|
||||
for (registration = TAG ## _data_registry.registrations, i = 0; \
|
||||
i < rdata->num_data; \
|
||||
registration = registration->next, i++) \
|
||||
if (rdata->data[i] != NULL && registration->data->free != NULL) \
|
||||
registration->data->free (container, rdata->data[i]); \
|
||||
\
|
||||
memset (rdata->data, 0, rdata->num_data * sizeof (void *)); \
|
||||
registry_clear_data (&TAG ## _data_registry, \
|
||||
TAG ## registry_callback_adaptor, \
|
||||
(struct registry_container *) container, \
|
||||
rdata); \
|
||||
} \
|
||||
\
|
||||
static 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; \
|
||||
\
|
||||
registry_container_free_data (&TAG ## _data_registry, \
|
||||
TAG ## registry_callback_adaptor, \
|
||||
(struct registry_container *) container, \
|
||||
rdata); \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
set_ ## TAG ## _data (struct TAG *container, const struct TAG ## _data *data, \
|
||||
void *value) \
|
||||
set_ ## TAG ## _data (struct TAG *container, \
|
||||
const struct TAG ## _data *data, \
|
||||
void *value) \
|
||||
{ \
|
||||
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
||||
gdb_assert (data->index < rdata->num_data); \
|
||||
rdata->data[data->index] = value; \
|
||||
\
|
||||
registry_set_data (rdata, \
|
||||
(struct registry_data *) data, \
|
||||
value); \
|
||||
} \
|
||||
\
|
||||
void * \
|
||||
TAG ## _data (struct TAG *container, const struct TAG ## _data *data) \
|
||||
{ \
|
||||
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
||||
gdb_assert (data->index < rdata->num_data); \
|
||||
return rdata->data[data->index]; \
|
||||
\
|
||||
return registry_data (rdata, \
|
||||
(struct registry_data *) data); \
|
||||
}
|
||||
|
||||
|
||||
/* External declarations for the registry functions. */
|
||||
|
||||
#define DECLARE_REGISTRY(TAG) \
|
||||
struct TAG ## _data; \
|
||||
typedef void (*registry_ ## TAG ## _callback) (struct TAG *, void *); \
|
||||
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 *)); \
|
||||
(registry_ ## TAG ## _callback save, registry_ ## TAG ## _callback free); \
|
||||
extern void clear_ ## TAG ## _data (struct TAG *); \
|
||||
extern void set_ ## TAG ## _data (struct TAG *, \
|
||||
const struct TAG ## _data *data, void *value); \
|
||||
const struct TAG ## _data *data, \
|
||||
void *value); \
|
||||
extern void *TAG ## _data (struct TAG *, \
|
||||
const struct TAG ## _data *data);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user