* gdbarch.c Include "gdb_obstack.h".
(struct gdbarch): Add an "obstack".
(alloc_gdbarch_data): Allocate the gdbarch data using
GDBARCH_OBSTACK_CALLOC.
(free_gdbarch_data): Delete function.
(gdbarch_obstack_zalloc): New function.
(gdbarch_free): Free the obstack, do not call free_gdbarch_data.
Assert that the architecture is not initialized.
(gdbarch_alloc): Allocate an obstack, allocate the architecture
vector from the obstack.
(alloc_gdbarch_data, init_gdbarch_swap): Allocate memory using the
architecture obstack.
(GDBARCH_OBSTACK_CALLOC, GDBARCH_OBSTACK_ZALLOC): Define.
(set_gdbarch_data): Assert that the data is not initialized.
(struct gdbarch_data): Delete member "free".
(register_gdbarch_data): Do not initialize "free".
* gdbarch.h, gdbarch.c: Re-generate.
+2003-07-22 Andrew Cagney <cagney@redhat.com>
+
+ * gdbarch.c Include "gdb_obstack.h".
+ (struct gdbarch): Add an "obstack".
+ (alloc_gdbarch_data): Allocate the gdbarch data using
+ GDBARCH_OBSTACK_CALLOC.
+ (free_gdbarch_data): Delete function.
+ (gdbarch_obstack_zalloc): New function.
+ (gdbarch_free): Free the obstack, do not call free_gdbarch_data.
+ Assert that the architecture is not initialized.
+ (gdbarch_alloc): Allocate an obstack, allocate the architecture
+ vector from the obstack.
+ (alloc_gdbarch_data, init_gdbarch_swap): Allocate memory using the
+ architecture obstack.
+ (GDBARCH_OBSTACK_CALLOC, GDBARCH_OBSTACK_ZALLOC): Define.
+ (set_gdbarch_data): Assert that the data is not initialized.
+ (struct gdbarch_data): Delete member "free".
+ (register_gdbarch_data): Do not initialize "free".
+ * gdbarch.h, gdbarch.c: Re-generate.
+
2003-07-22 Andrew Cagney <cagney@redhat.com>
* configure.in (build_warnings): Add -Wformat-nonliteral.
#include "reggroups.h"
#include "osabi.h"
#include "symfile.h" /* For entry_point_address. */
+#include "gdb_obstack.h"
/* Static function declarations */
static void verify_gdbarch (struct gdbarch *gdbarch);
static void alloc_gdbarch_data (struct gdbarch *);
-static void free_gdbarch_data (struct gdbarch *);
static void init_gdbarch_swap (struct gdbarch *);
static void clear_gdbarch_swap (struct gdbarch *);
static void swapout_gdbarch_swap (struct gdbarch *);
{
/* Has this architecture been fully initialized? */
int initialized_p;
+
+ /* An obstack bound to the lifetime of the architecture. */
+ struct obstack *obstack;
+
/* basic architectural information */
const struct bfd_arch_info * bfd_arch_info;
int byte_order;
struct gdbarch startup_gdbarch =
{
1, /* Always initialized. */
+ NULL, /* The obstack. */
/* basic architecture information */
&bfd_default_arch_struct, /* bfd_arch_info */
BFD_ENDIAN_BIG, /* byte_order */
architecture. This ensures that the new architectures initial
values are not influenced by the previous architecture. Once
everything is parameterised with gdbarch, this will go away. */
- struct gdbarch *current_gdbarch = XMALLOC (struct gdbarch);
+ struct gdbarch *current_gdbarch;
+
+ /* Create an obstack for allocating all the per-architecture memory,
+ then use that to allocate the architecture vector. */
+ struct obstack *obstack = XMALLOC (struct obstack);
+ obstack_init (obstack);
+ current_gdbarch = obstack_alloc (obstack, sizeof (*current_gdbarch));
memset (current_gdbarch, 0, sizeof (*current_gdbarch));
+ current_gdbarch->obstack = obstack;
alloc_gdbarch_data (current_gdbarch);
}
+/* Allocate extra space using the per-architecture obstack. */
+
+void *
+gdbarch_obstack_zalloc (struct gdbarch *arch, long size)
+{
+ void *data = obstack_alloc (arch->obstack, size);
+ memset (data, 0, size);
+ return data;
+}
+
+
/* Free a gdbarch struct. This should never happen in normal
operation --- once you've created a gdbarch, you keep it around.
However, if an architecture's init function encounters an error
void
gdbarch_free (struct gdbarch *arch)
{
+ struct obstack *obstack;
gdb_assert (arch != NULL);
- free_gdbarch_data (arch);
- xfree (arch);
+ gdb_assert (!arch->initialized_p);
+ obstack = arch->obstack;
+ obstack_free (obstack, 0); /* Includes the ARCH. */
+ xfree (obstack);
}
unsigned index;
int init_p;
gdbarch_data_init_ftype *init;
- gdbarch_data_free_ftype *free;
};
struct gdbarch_data_registration
(*curr)->data->index = gdbarch_data_registry.nr++;
(*curr)->data->init = init;
(*curr)->data->init_p = 1;
- (*curr)->data->free = free;
return (*curr)->data;
}
{
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;
+ gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *);
}
-
/* Initialize the current value of the specified per-architecture
data-pointer. */
void *pointer)
{
gdb_assert (data->index < gdbarch->nr_data);
- if (gdbarch->data[data->index] != NULL)
- {
- gdb_assert (data->free != NULL);
- data->free (gdbarch, gdbarch->data[data->index]);
- }
+ gdb_assert (gdbarch->data[data->index] == NULL);
gdbarch->data[data->index] = pointer;
}
{
if (rego->data != NULL)
{
- (*curr) = XMALLOC (struct gdbarch_swap);
+ (*curr) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct gdbarch_swap);
(*curr)->source = rego;
- (*curr)->swap = xmalloc (rego->sizeof_data);
+ (*curr)->swap = gdbarch_obstack_zalloc (gdbarch, rego->sizeof_data);
(*curr)->next = NULL;
curr = &(*curr)->next;
}
extern void gdbarch_free (struct gdbarch *);
+/* Helper function. Allocate memory from the ``struct gdbarch''
+ obstack. The memory is freed when the corresponding architecture
+ is also freed. */
+
+extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size);
+#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), (NR) * sizeof (TYPE)))
+#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), sizeof (TYPE)))
+
+
/* Helper function. Force an update of the current architecture.
The actual architecture selected is determined by INFO, ``(gdb) set
The per-architecture data-pointer is either initialized explicitly
(set_gdbarch_data()) or implicitly (by INIT() via a call to
- gdbarch_data()). FREE() is called to delete either an existing
- data-pointer overridden by set_gdbarch_data() or when the
- architecture object is being deleted.
+ gdbarch_data()). FREE() is ignored.
When a previously created architecture is re-selected, the
per-architecture data-pointer for that previous architecture is
extern void gdbarch_free (struct gdbarch *);
+/* Helper function. Allocate memory from the \`\`struct gdbarch''
+ obstack. The memory is freed when the corresponding architecture
+ is also freed. */
+
+extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size);
+#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), (NR) * sizeof (TYPE)))
+#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), sizeof (TYPE)))
+
+
/* Helper function. Force an update of the current architecture.
The actual architecture selected is determined by INFO, \`\`(gdb) set
The per-architecture data-pointer is either initialized explicitly
(set_gdbarch_data()) or implicitly (by INIT() via a call to
- gdbarch_data()). FREE() is called to delete either an existing
- data-pointer overridden by set_gdbarch_data() or when the
- architecture object is being deleted.
+ gdbarch_data()). FREE() is ignored.
When a previously created architecture is re-selected, the
per-architecture data-pointer for that previous architecture is
#include "reggroups.h"
#include "osabi.h"
#include "symfile.h" /* For entry_point_address. */
+#include "gdb_obstack.h"
/* Static function declarations */
static void verify_gdbarch (struct gdbarch *gdbarch);
static void alloc_gdbarch_data (struct gdbarch *);
-static void free_gdbarch_data (struct gdbarch *);
static void init_gdbarch_swap (struct gdbarch *);
static void clear_gdbarch_swap (struct gdbarch *);
static void swapout_gdbarch_swap (struct gdbarch *);
printf "{\n"
printf " /* Has this architecture been fully initialized? */\n"
printf " int initialized_p;\n"
+printf "\n"
+printf " /* An obstack bound to the lifetime of the architecture. */\n"
+printf " struct obstack *obstack;\n"
+printf "\n"
printf " /* basic architectural information */\n"
function_list | while do_read
do
printf "struct gdbarch startup_gdbarch =\n"
printf "{\n"
printf " 1, /* Always initialized. */\n"
+printf " NULL, /* The obstack. */\n"
printf " /* basic architecture information */\n"
function_list | while do_read
do
architecture. This ensures that the new architectures initial
values are not influenced by the previous architecture. Once
everything is parameterised with gdbarch, this will go away. */
- struct gdbarch *current_gdbarch = XMALLOC (struct gdbarch);
+ struct gdbarch *current_gdbarch;
+
+ /* Create an obstack for allocating all the per-architecture memory,
+ then use that to allocate the architecture vector. */
+ struct obstack *obstack = XMALLOC (struct obstack);
+ obstack_init (obstack);
+ current_gdbarch = obstack_alloc (obstack, sizeof (*current_gdbarch));
memset (current_gdbarch, 0, sizeof (*current_gdbarch));
+ current_gdbarch->obstack = obstack;
alloc_gdbarch_data (current_gdbarch);
printf "\n"
printf "\n"
cat <<EOF
+/* Allocate extra space using the per-architecture obstack. */
+
+void *
+gdbarch_obstack_zalloc (struct gdbarch *arch, long size)
+{
+ void *data = obstack_alloc (arch->obstack, size);
+ memset (data, 0, size);
+ return data;
+}
+
+
/* Free a gdbarch struct. This should never happen in normal
operation --- once you've created a gdbarch, you keep it around.
However, if an architecture's init function encounters an error
void
gdbarch_free (struct gdbarch *arch)
{
+ struct obstack *obstack;
gdb_assert (arch != NULL);
- free_gdbarch_data (arch);
- xfree (arch);
+ gdb_assert (!arch->initialized_p);
+ obstack = arch->obstack;
+ obstack_free (obstack, 0); /* Includes the ARCH. */
+ xfree (obstack);
}
EOF
unsigned index;
int init_p;
gdbarch_data_init_ftype *init;
- gdbarch_data_free_ftype *free;
};
struct gdbarch_data_registration
(*curr)->data->index = gdbarch_data_registry.nr++;
(*curr)->data->init = init;
(*curr)->data->init_p = 1;
- (*curr)->data->free = free;
return (*curr)->data;
}
{
gdb_assert (gdbarch->data == NULL);
gdbarch->nr_data = gdbarch_data_registry.nr;
- gdbarch->data = xcalloc (gdbarch->nr_data, sizeof (void*));
+ gdbarch->data = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, 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 the specified per-architecture
data-pointer. */
void *pointer)
{
gdb_assert (data->index < gdbarch->nr_data);
- if (gdbarch->data[data->index] != NULL)
- {
- gdb_assert (data->free != NULL);
- data->free (gdbarch, gdbarch->data[data->index]);
- }
+ gdb_assert (gdbarch->data[data->index] == NULL);
gdbarch->data[data->index] = pointer;
}
{
if (rego->data != NULL)
{
- (*curr) = XMALLOC (struct gdbarch_swap);
+ (*curr) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct gdbarch_swap);
(*curr)->source = rego;
- (*curr)->swap = xmalloc (rego->sizeof_data);
+ (*curr)->swap = gdbarch_obstack_zalloc (gdbarch, rego->sizeof_data);
(*curr)->next = NULL;
curr = &(*curr)->next;
}