This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[rfc] Add set_gdbarch_data() and revamp
- To: GDB Patches <gdb-patches at sourceware dot cygnus dot com>
- Subject: [rfc] Add set_gdbarch_data() and revamp
- From: Andrew Cagney <ac131313 at cygnus dot com>
- Date: Wed, 31 Jan 2001 23:51:06 -0800
Hello,
To follow up on previous discussion. The attatched adds a
set_gdbarch_data() method to the gdbarch framework.
At the same time, it simplifies the existing data-pointer code (using
things like gdb_assert()).
Hand testing is continuing (gdb.wp?).
Andrew
Wed Jan 31 09:58:18 2001 Andrew Cagney <cagney@redhat.com>
* gdbarch.sh: Include "gdb_assert.h".
(struct gdbarch): Change ``nr_data'' to unsigned.
(alloc_gdbarch_data, free_gdbarch_data): New functions.
(gdbarch_free): Free the data-pointer vector. Use xfree to delete
architecture vector.
(struct gdbarch_data, struct gdbarch_data_registration): Move init
method to gdbarch_data. Add free method, make index unsigned.
(struct gdbarch_data_registry): Make nr unsigned.
(register_gdbarch_data): Add free parameter. Store in
gdbarch_data.
(init_gdbarch_data): Use set_gdbarch_data.
(set_gdbarch_data): New function.
* gdbarch.h, gdbarch.c: Re-generate.
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.51
diff -p -r1.51 gdbarch.sh
*** gdbarch.sh 2001/01/22 23:32:49 1.51
--- gdbarch.sh 2001/02/01 07:50:18
*************** extern int gdbarch_update_p (struct gdba
*** 855,883 ****
Reserve space for a per-architecture data-pointer. An identifier
for the reserved data-pointer is returned. That identifer should
! be saved in a local static.
! When a new architecture is selected, INIT() is called. When a
! previous architecture is re-selected, the per-architecture
! data-pointer for that previous architecture is restored (INIT() is
! not called).
- INIT() shall return the initial value for the per-architecture
- data-pointer for the current architecture.
-
Multiple registrarants for any architecture are allowed (and
strongly encouraged). */
! typedef void *(gdbarch_data_ftype) (void);
! extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_ftype *init);
! /* Return the value of the per-architecture data-pointer for the
! current architecture. */
extern void *gdbarch_data (struct gdbarch_data*);
-
/* Register per-architecture memory region.
Provide a memory-region swap mechanism. Per-architecture memory
--- 855,894 ----
Reserve space for a per-architecture data-pointer. An identifier
for the reserved data-pointer is returned. That identifer should
! be saved in a local static variable.
! The per-architecture data-pointer can be initialized in one of two
! ways: The value can be set explicitly using a call to
! set_gdbarch_data(); the value can be set implicitly using the value
! returned by a non-NULL INIT() callback. INIT(), when non-NULL is
! called after the basic architecture vector has been created.
!
! When a previously created architecture is re-selected, the
! per-architecture data-pointer for that previous architecture is
! restored. INIT() is not called.
!
! During initialization, multiple assignments of the data-pointer are
! allowed, non-NULL values are deleted by calling FREE(). If the
! architecture is deleted using gdbarch_free() all non-NULL data
! pointers are also deleted using FREE().
Multiple registrarants for any architecture are allowed (and
strongly encouraged). */
! struct gdbarch_data;
! typedef void *(gdbarch_data_init_ftype) (struct gdbarch *gdbarch);
! typedef void (gdbarch_data_free_ftype) (struct gdbarch *gdbarch,
! void *pointer);
! extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *init,
! gdbarch_data_free_ftype *free);
! extern void set_gdbarch_data (struct gdbarch *gdbarch,
! struct gdbarch_data *data,
! void *pointer);
extern void *gdbarch_data (struct gdbarch_data*);
/* Register per-architecture memory region.
Provide a memory-region swap mechanism. Per-architecture memory
*************** cat <<EOF
*** 1049,1058 ****
--- 1060,1073 ----
#include "floatformat.h"
+ #include "gdb_assert.h"
+
/* Static function declarations */
static void verify_gdbarch (struct gdbarch *gdbarch);
+ static void alloc_gdbarch_data (struct gdbarch *);
static void init_gdbarch_data (struct gdbarch *);
+ static void free_gdbarch_data (struct gdbarch *);
static void init_gdbarch_swap (struct gdbarch *);
static void swapout_gdbarch_swap (struct gdbarch *);
static void swapin_gdbarch_swap (struct gdbarch *);
*************** printf " struct gdbarch_tdep *tdep;\n"
*** 1093,1099 ****
printf " gdbarch_dump_tdep_ftype *dump_tdep;\n"
printf "\n"
printf " /* per-architecture data-pointers */\n"
! printf " int nr_data;\n"
printf " void **data;\n"
printf "\n"
printf " /* per-architecture swap-regions */\n"
--- 1108,1114 ----
printf " gdbarch_dump_tdep_ftype *dump_tdep;\n"
printf "\n"
printf " /* per-architecture data-pointers */\n"
! printf " unsigned nr_data;\n"
printf " void **data;\n"
printf "\n"
printf " /* per-architecture swap-regions */\n"
*************** gdbarch_alloc (const struct gdbarch_info
*** 1196,1201 ****
--- 1211,1218 ----
struct gdbarch *gdbarch = XMALLOC (struct gdbarch);
memset (gdbarch, 0, sizeof (*gdbarch));
+ alloc_gdbarch_data (gdbarch);
+
gdbarch->tdep = tdep;
EOF
printf "\n"
*************** cat <<EOF
*** 1238,1245 ****
void
gdbarch_free (struct gdbarch *arch)
{
! /* At the moment, this is trivial. */
! free (arch);
}
EOF
--- 1255,1263 ----
void
gdbarch_free (struct gdbarch *arch)
{
! gdb_assert (arch != NULL);
! free_gdbarch_data (arch);
! xfree (arch);
}
EOF
*************** cat <<EOF
*** 1488,1506 ****
struct gdbarch_data
{
! int index;
};
struct gdbarch_data_registration
{
- gdbarch_data_ftype *init;
struct gdbarch_data *data;
struct gdbarch_data_registration *next;
};
struct gdbarch_data_registry
{
! int nr;
struct gdbarch_data_registration *registrations;
};
--- 1506,1525 ----
struct gdbarch_data
{
! unsigned index;
! gdbarch_data_init_ftype *init;
! gdbarch_data_free_ftype *free;
};
struct gdbarch_data_registration
{
struct gdbarch_data *data;
struct gdbarch_data_registration *next;
};
struct gdbarch_data_registry
{
! unsigned nr;
struct gdbarch_data_registration *registrations;
};
*************** struct gdbarch_data_registry gdbarch_dat
*** 1510,1516 ****
};
struct gdbarch_data *
! register_gdbarch_data (gdbarch_data_ftype *init)
{
struct gdbarch_data_registration **curr;
for (curr = &gdbarch_data_registry.registrations;
--- 1529,1536 ----
};
struct gdbarch_data *
! register_gdbarch_data (gdbarch_data_init_ftype *init,
! gdbarch_data_free_ftype *free)
{
struct gdbarch_data_registration **curr;
for (curr = &gdbarch_data_registry.registrations;
*************** register_gdbarch_data (gdbarch_data_ftyp
*** 1518,1526 ****
curr = &(*curr)->next);
(*curr) = XMALLOC (struct gdbarch_data_registration);
(*curr)->next = NULL;
- (*curr)->init = init;
(*curr)->data = XMALLOC (struct gdbarch_data);
(*curr)->data->index = gdbarch_data_registry.nr++;
return (*curr)->data;
}
--- 1538,1547 ----
curr = &(*curr)->next);
(*curr) = XMALLOC (struct gdbarch_data_registration);
(*curr)->next = NULL;
(*curr)->data = XMALLOC (struct gdbarch_data);
(*curr)->data->index = gdbarch_data_registry.nr++;
+ (*curr)->data->init = init;
+ (*curr)->data->free = free;
return (*curr)->data;
}
*************** register_gdbarch_data (gdbarch_data_ftyp
*** 1530,1556 ****
static void
init_gdbarch_data (struct gdbarch *gdbarch)
{
struct gdbarch_data_registration *rego;
! gdbarch->nr_data = gdbarch_data_registry.nr + 1;
! gdbarch->data = xmalloc (sizeof (void*) * gdbarch->nr_data);
for (rego = gdbarch_data_registry.registrations;
rego != NULL;
rego = rego->next)
{
! if (rego->data->index < gdbarch->nr_data)
! gdbarch->data[rego->data->index] = rego->init ();
}
}
/* Return the current value of the specified per-architecture
data-pointer. */
void *
gdbarch_data (struct gdbarch_data *data)
{
! if (data->index >= current_gdbarch->nr_data)
! internal_error ("gdbarch_data: request for non-existant data.");
return current_gdbarch->data[data->index];
}
--- 1551,1624 ----
static void
init_gdbarch_data (struct gdbarch *gdbarch)
{
+ struct gdbarch_data_registration *rego;
+ for (rego = gdbarch_data_registry.registrations;
+ rego != NULL;
+ rego = rego->next)
+ {
+ struct gdbarch_data *data = rego->data;
+ gdb_assert (data->index < gdbarch->nr_data);
+ if (data->init != NULL)
+ {
+ void *pointer = data->init (gdbarch);
+ set_gdbarch_data (gdbarch, data, pointer);
+ }
+ }
+ }
+
+ /* Create/delete the gdbarch data vector. */
+
+ static void
+ alloc_gdbarch_data (struct gdbarch *gdbarch)
+ {
+ gdb_assert (gdbarch->data == NULL);
+ gdbarch->nr_data = gdbarch_data_registry.nr;
+ gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
+ }
+
+ static void
+ free_gdbarch_data (struct gdbarch *gdbarch)
+ {
struct gdbarch_data_registration *rego;
! gdb_assert (gdbarch->data != NULL);
for (rego = gdbarch_data_registry.registrations;
rego != NULL;
rego = rego->next)
{
! struct gdbarch_data *data = rego->data;
! gdb_assert (data->index < gdbarch->nr_data);
! if (data->free != NULL && gdbarch->data[data->index] != NULL)
! {
! data->free (gdbarch, gdbarch->data[data->index]);
! gdbarch->data[data->index] = NULL;
! }
}
+ xfree (gdbarch->data);
+ gdbarch->data = NULL;
}
+ /* Initialize the current value of thee specified per-architecture
+ data-pointer. */
+
+ void
+ set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer)
+ {
+ gdb_assert (data->index < gdbarch->nr_data);
+ if (data->free != NULL && gdbarch->data[data->index] != NULL)
+ data->free (gdbarch, gdbarch->data[data->index]);
+ gdbarch->data[data->index] = pointer;
+ }
+
/* Return the current value of the specified per-architecture
data-pointer. */
void *
gdbarch_data (struct gdbarch_data *data)
{
! gdb_assert (data->index < current_gdbarch->nr_data);
return current_gdbarch->data[data->index];
}