mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-09 21:50:35 +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>
|
2012-09-12 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
* dwarf2read.c (dwarf2_read_addr_index): Fix handling the case where
|
* 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 \
|
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
|
||||||
gdb_vecs.o jit.o progspace.o skip.o probe.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 \
|
common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
|
||||||
format.o
|
format.o registry.o
|
||||||
|
|
||||||
TSOBS = inflow.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) \
|
#define REGISTRY_ACCESS_FIELD(CONTAINER) \
|
||||||
(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 a new registry implementation. */
|
||||||
|
|
||||||
#define DEFINE_REGISTRY(TAG, ACCESS) \
|
#define DEFINE_REGISTRY(TAG, ACCESS) \
|
||||||
struct TAG ## _data \
|
struct registry_data_registry TAG ## _data_registry = { NULL, 0 }; \
|
||||||
{ \
|
|
||||||
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 * \
|
const struct TAG ## _data * \
|
||||||
register_ ## TAG ## _data_with_cleanup (void (*save) (struct TAG *, void *), \
|
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. */ \
|
return (struct TAG ## _data *) \
|
||||||
for (curr = &TAG ## _data_registry.registrations; \
|
register_data_with_cleanup (&TAG ## _data_registry, \
|
||||||
*curr != NULL; curr = &(*curr)->next); \
|
(registry_data_callback) save, \
|
||||||
\
|
(registry_data_callback) free); \
|
||||||
*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 * \
|
const struct TAG ## _data * \
|
||||||
@ -139,76 +176,81 @@ static void \
|
|||||||
TAG ## _alloc_data (struct TAG *container) \
|
TAG ## _alloc_data (struct TAG *container) \
|
||||||
{ \
|
{ \
|
||||||
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
||||||
gdb_assert (rdata->data == NULL); \
|
\
|
||||||
rdata->num_data = TAG ## _data_registry.num_registrations; \
|
registry_alloc_data (&TAG ## _data_registry, rdata); \
|
||||||
rdata->data = XCALLOC (rdata->num_data, void *); \
|
} \
|
||||||
|
\
|
||||||
|
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 \
|
void \
|
||||||
clear_ ## TAG ## _data (struct TAG *container) \
|
clear_ ## TAG ## _data (struct TAG *container) \
|
||||||
{ \
|
{ \
|
||||||
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
||||||
struct TAG ## _data_registration *registration; \
|
|
||||||
int i; \
|
|
||||||
\
|
\
|
||||||
gdb_assert (rdata->data != NULL); \
|
registry_clear_data (&TAG ## _data_registry, \
|
||||||
\
|
TAG ## registry_callback_adaptor, \
|
||||||
/* Process all the save handlers. */ \
|
(struct registry_container *) container, \
|
||||||
\
|
rdata); \
|
||||||
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 *)); \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void \
|
static void \
|
||||||
TAG ## _free_data (struct TAG *container) \
|
TAG ## _free_data (struct TAG *container) \
|
||||||
{ \
|
{ \
|
||||||
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
||||||
gdb_assert (rdata->data != NULL); \
|
\
|
||||||
clear_ ## TAG ## _data (container); \
|
registry_container_free_data (&TAG ## _data_registry, \
|
||||||
xfree (rdata->data); \
|
TAG ## registry_callback_adaptor, \
|
||||||
rdata->data = NULL; \
|
(struct registry_container *) container, \
|
||||||
|
rdata); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
void \
|
void \
|
||||||
set_ ## TAG ## _data (struct TAG *container, const struct TAG ## _data *data, \
|
set_ ## TAG ## _data (struct TAG *container, \
|
||||||
void *value) \
|
const struct TAG ## _data *data, \
|
||||||
|
void *value) \
|
||||||
{ \
|
{ \
|
||||||
struct registry_fields *rdata = &ACCESS (container)->registry_data; \
|
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 * \
|
void * \
|
||||||
TAG ## _data (struct TAG *container, const struct TAG ## _data *data) \
|
TAG ## _data (struct TAG *container, const struct TAG ## _data *data) \
|
||||||
{ \
|
{ \
|
||||||
struct registry_fields *rdata = &ACCESS (container)->registry_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. */
|
/* External declarations for the registry functions. */
|
||||||
|
|
||||||
#define DECLARE_REGISTRY(TAG) \
|
#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 (void); \
|
||||||
extern const struct TAG ## _data *register_ ## TAG ## _data_with_cleanup \
|
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 clear_ ## TAG ## _data (struct TAG *); \
|
||||||
extern void set_ ## 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 *, \
|
extern void *TAG ## _data (struct TAG *, \
|
||||||
const struct TAG ## _data *data);
|
const struct TAG ## _data *data);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user