Skip to content

Commit

Permalink
Use registry in gdbarch
Browse files Browse the repository at this point in the history
gdbarch implements its own registry-like approach.  This patch changes
it to instead use registry.h.  It's a rather large patch but largely
uninteresting -- it's mostly a straightforward conversion from the old
approach to the new one.

The main benefit of this change is that it introduces type safety to
the gdbarch registry.  It also removes a bunch of code.

One possible drawback is that, previously, the gdbarch registry
differentiated between pre- and post-initialization setup.  This
doesn't seem very important to me, though.
  • Loading branch information
tromey committed Aug 4, 2022
1 parent 8b15404 commit cb27553
Show file tree
Hide file tree
Showing 41 changed files with 532 additions and 836 deletions.
112 changes: 3 additions & 109 deletions gdb/arch-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1092,10 +1092,6 @@ default_read_core_file_mappings
{
}

/* Static function declarations */

static void alloc_gdbarch_data (struct gdbarch *);

/* Non-zero if we want to trace architecture code. */

#ifndef GDBARCH_DEBUG
Expand Down Expand Up @@ -1204,114 +1200,12 @@ gdbarch_tdep_1 (struct gdbarch *gdbarch)
return gdbarch->tdep;
}

/* Keep a registry of per-architecture data-pointers required by GDB
modules. */

struct gdbarch_data
{
unsigned index;
int init_p;
gdbarch_data_pre_init_ftype *pre_init;
gdbarch_data_post_init_ftype *post_init;
};

struct gdbarch_data_registration
{
struct gdbarch_data *data;
struct gdbarch_data_registration *next;
};

struct gdbarch_data_registry
{
unsigned nr;
struct gdbarch_data_registration *registrations;
};

static struct gdbarch_data_registry gdbarch_data_registry =
{
0, NULL,
};

static struct gdbarch_data *
gdbarch_data_register (gdbarch_data_pre_init_ftype *pre_init,
gdbarch_data_post_init_ftype *post_init)
{
struct gdbarch_data_registration **curr;

/* Append the new registration. */
for (curr = &gdbarch_data_registry.registrations;
(*curr) != NULL;
curr = &(*curr)->next);
(*curr) = XNEW (struct gdbarch_data_registration);
(*curr)->next = NULL;
(*curr)->data = XNEW (struct gdbarch_data);
(*curr)->data->index = gdbarch_data_registry.nr++;
(*curr)->data->pre_init = pre_init;
(*curr)->data->post_init = post_init;
(*curr)->data->init_p = 1;
return (*curr)->data;
}

struct gdbarch_data *
gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init)
{
return gdbarch_data_register (pre_init, NULL);
}

struct gdbarch_data *
gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init)
{
return gdbarch_data_register (NULL, post_init);
}

/* 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 = GDBARCH_OBSTACK_CALLOC (gdbarch, gdbarch->nr_data, void *);
}

/* Return the current value of the specified per-architecture
data-pointer. */

void *
gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data)
registry<gdbarch> *
registry_accessor<gdbarch>::get (gdbarch *arch)
{
gdb_assert (data->index < gdbarch->nr_data);
if (gdbarch->data[data->index] == NULL)
{
/* The data-pointer isn't initialized, call init() to get a
value. */
if (data->pre_init != NULL)
/* Mid architecture creation: pass just the obstack, and not
the entire architecture, as that way it isn't possible for
pre-init code to refer to undefined architecture
fields. */
gdbarch->data[data->index] = data->pre_init (&gdbarch->obstack);
else if (gdbarch->initialized_p
&& data->post_init != NULL)
/* Post architecture creation: pass the entire architecture
(as all fields are valid), but be careful to also detect
recursive references. */
{
gdb_assert (data->init_p);
data->init_p = 0;
gdbarch->data[data->index] = data->post_init (gdbarch);
data->init_p = 1;
}
else
internal_error (__FILE__, __LINE__,
_("gdbarch post-init data field can only be used "
"after gdbarch is fully initialised"));
gdb_assert (gdbarch->data[data->index] != NULL);
}
return gdbarch->data[data->index];
return &arch->registry_fields;
}


/* Keep a registry of the architectures known by GDB. */

struct gdbarch_registration
Expand Down
37 changes: 15 additions & 22 deletions gdb/bsd-uthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,24 @@ static bsd_uthread_target bsd_uthread_ops;

/* Architecture-specific operations. */

/* Per-architecture data key. */
static struct gdbarch_data *bsd_uthread_data;

struct bsd_uthread_ops
{
/* Supply registers for an inactive thread to a register cache. */
void (*supply_uthread)(struct regcache *, int, CORE_ADDR);
void (*supply_uthread)(struct regcache *, int, CORE_ADDR) = nullptr;

/* Collect registers for an inactive thread from a register cache. */
void (*collect_uthread)(const struct regcache *, int, CORE_ADDR);
void (*collect_uthread)(const struct regcache *, int, CORE_ADDR) = nullptr;
};

static void *
bsd_uthread_init (struct obstack *obstack)
{
struct bsd_uthread_ops *ops;
/* Per-architecture data key. */
static const registry<gdbarch>::key<struct bsd_uthread_ops> bsd_uthread_data;

ops = OBSTACK_ZALLOC (obstack, struct bsd_uthread_ops);
static struct bsd_uthread_ops *
get_bsd_uthread (struct gdbarch *gdbarch)
{
struct bsd_uthread_ops *ops = bsd_uthread_data.get (gdbarch);
if (ops == nullptr)
ops = bsd_uthread_data.emplace (gdbarch);
return ops;
}

Expand All @@ -99,8 +99,7 @@ bsd_uthread_set_supply_uthread (struct gdbarch *gdbarch,
void (*supply_uthread) (struct regcache *,
int, CORE_ADDR))
{
struct bsd_uthread_ops *ops
= (struct bsd_uthread_ops *) gdbarch_data (gdbarch, bsd_uthread_data);
struct bsd_uthread_ops *ops = get_bsd_uthread (gdbarch);

ops->supply_uthread = supply_uthread;
}
Expand All @@ -113,8 +112,7 @@ bsd_uthread_set_collect_uthread (struct gdbarch *gdbarch,
void (*collect_uthread) (const struct regcache *,
int, CORE_ADDR))
{
struct bsd_uthread_ops *ops
= (struct bsd_uthread_ops *) gdbarch_data (gdbarch, bsd_uthread_data);
struct bsd_uthread_ops *ops = get_bsd_uthread (gdbarch);

ops->collect_uthread = collect_uthread;
}
Expand Down Expand Up @@ -196,8 +194,7 @@ static int
bsd_uthread_activate (struct objfile *objfile)
{
struct gdbarch *gdbarch = target_gdbarch ();
struct bsd_uthread_ops *ops
= (struct bsd_uthread_ops *) gdbarch_data (gdbarch, bsd_uthread_data);
struct bsd_uthread_ops *ops = get_bsd_uthread (gdbarch);

/* Skip if the thread stratum has already been activated. */
if (bsd_uthread_active)
Expand Down Expand Up @@ -317,8 +314,7 @@ void
bsd_uthread_target::fetch_registers (struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = regcache->arch ();
struct bsd_uthread_ops *uthread_ops
= (struct bsd_uthread_ops *) gdbarch_data (gdbarch, bsd_uthread_data);
struct bsd_uthread_ops *uthread_ops = get_bsd_uthread (gdbarch);
ptid_t ptid = regcache->ptid ();
CORE_ADDR addr = ptid.tid ();
CORE_ADDR active_addr;
Expand Down Expand Up @@ -349,8 +345,7 @@ void
bsd_uthread_target::store_registers (struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = regcache->arch ();
struct bsd_uthread_ops *uthread_ops
= (struct bsd_uthread_ops *) gdbarch_data (gdbarch, bsd_uthread_data);
struct bsd_uthread_ops *uthread_ops = get_bsd_uthread (gdbarch);
ptid_t ptid = regcache->ptid ();
CORE_ADDR addr = ptid.tid ();
CORE_ADDR active_addr;
Expand Down Expand Up @@ -549,8 +544,6 @@ void _initialize_bsd_uthread ();
void
_initialize_bsd_uthread ()
{
bsd_uthread_data = gdbarch_data_register_pre_init (bsd_uthread_init);

gdb::observers::inferior_created.attach (bsd_uthread_inferior_created,
"bsd-uthread");
gdb::observers::solib_loaded.attach (bsd_uthread_solib_loaded,
Expand Down
21 changes: 10 additions & 11 deletions gdb/d-lang.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,10 @@ static d_language d_language_defn;

/* Build all D language types for the specified architecture. */

static void *
static struct builtin_d_type *
build_d_types (struct gdbarch *gdbarch)
{
struct builtin_d_type *builtin_d_type
= GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_d_type);
struct builtin_d_type *builtin_d_type = new struct builtin_d_type;

/* Basic types. */
builtin_d_type->builtin_void
Expand Down Expand Up @@ -265,19 +264,19 @@ build_d_types (struct gdbarch *gdbarch)
return builtin_d_type;
}

static struct gdbarch_data *d_type_data;
static const registry<gdbarch>::key<struct builtin_d_type> d_type_data;

/* Return the D type table for the specified architecture. */

const struct builtin_d_type *
builtin_d_type (struct gdbarch *gdbarch)
{
return (const struct builtin_d_type *) gdbarch_data (gdbarch, d_type_data);
}
struct builtin_d_type *result = d_type_data.get (gdbarch);
if (result == nullptr)
{
result = build_d_types (gdbarch);
d_type_data.set (gdbarch, result);
}

void _initialize_d_language ();
void
_initialize_d_language ()
{
d_type_data = gdbarch_data_register_post_init (build_d_types);
return result;
}
48 changes: 24 additions & 24 deletions gdb/d-lang.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,30 @@

struct builtin_d_type
{
struct type *builtin_void;
struct type *builtin_bool;
struct type *builtin_byte;
struct type *builtin_ubyte;
struct type *builtin_short;
struct type *builtin_ushort;
struct type *builtin_int;
struct type *builtin_uint;
struct type *builtin_long;
struct type *builtin_ulong;
struct type *builtin_cent;
struct type *builtin_ucent;
struct type *builtin_float;
struct type *builtin_double;
struct type *builtin_real;
struct type *builtin_ifloat;
struct type *builtin_idouble;
struct type *builtin_ireal;
struct type *builtin_cfloat;
struct type *builtin_cdouble;
struct type *builtin_creal;
struct type *builtin_char;
struct type *builtin_wchar;
struct type *builtin_dchar;
struct type *builtin_void = nullptr;
struct type *builtin_bool = nullptr;
struct type *builtin_byte = nullptr;
struct type *builtin_ubyte = nullptr;
struct type *builtin_short = nullptr;
struct type *builtin_ushort = nullptr;
struct type *builtin_int = nullptr;
struct type *builtin_uint = nullptr;
struct type *builtin_long = nullptr;
struct type *builtin_ulong = nullptr;
struct type *builtin_cent = nullptr;
struct type *builtin_ucent = nullptr;
struct type *builtin_float = nullptr;
struct type *builtin_double = nullptr;
struct type *builtin_real = nullptr;
struct type *builtin_ifloat = nullptr;
struct type *builtin_idouble = nullptr;
struct type *builtin_ireal = nullptr;
struct type *builtin_cfloat = nullptr;
struct type *builtin_cdouble = nullptr;
struct type *builtin_creal = nullptr;
struct type *builtin_char = nullptr;
struct type *builtin_wchar = nullptr;
struct type *builtin_dchar = nullptr;
};

/* Defined in d-exp.y. */
Expand Down
32 changes: 6 additions & 26 deletions gdb/dwarf2/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,17 @@
#include "gdbarch.h"
#include "objfiles.h"

/* Cookie for gdbarch data. */

static struct gdbarch_data *dwarf_arch_cookie;

/* This holds gdbarch-specific types used by the DWARF expression
evaluator. See comments in execute_stack_op. */

struct dwarf_gdbarch_types
{
struct type *dw_types[3];
struct type *dw_types[3] {};
};

/* Allocate and fill in dwarf_gdbarch_types for an arch. */

static void *
dwarf_gdbarch_types_init (struct gdbarch *gdbarch)
{
struct dwarf_gdbarch_types *types
= GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf_gdbarch_types);

/* The types themselves are lazily initialized. */
/* Cookie for gdbarch data. */

return types;
}
static const registry<gdbarch>::key<dwarf_gdbarch_types> dwarf_arch_cookie;

/* Ensure that a FRAME is defined, throw an exception otherwise. */

Expand Down Expand Up @@ -701,8 +688,9 @@ struct type *
dwarf_expr_context::address_type () const
{
gdbarch *arch = this->m_per_objfile->objfile->arch ();
dwarf_gdbarch_types *types
= (dwarf_gdbarch_types *) gdbarch_data (arch, dwarf_arch_cookie);
dwarf_gdbarch_types *types = dwarf_arch_cookie.get (arch);
if (types == nullptr)
types = dwarf_arch_cookie.emplace (arch);
int ndx;

if (this->m_addr_size == 2)
Expand Down Expand Up @@ -2398,11 +2386,3 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
this->m_recursion_depth--;
gdb_assert (this->m_recursion_depth >= 0);
}

void _initialize_dwarf2expr ();
void
_initialize_dwarf2expr ()
{
dwarf_arch_cookie
= gdbarch_data_register_post_init (dwarf_gdbarch_types_init);
}
Loading

0 comments on commit cb27553

Please sign in to comment.