2004-03-18 Andrew Cagney <cagney@redhat.com>

* gdbint.texinfo (Coding): Update section on gdbarch_data,
	describe pre_init and post_init.
This commit is contained in:
Andrew Cagney 2004-03-18 20:13:34 +00:00
parent dbfe462616
commit fc989b7a7c
2 changed files with 69 additions and 94 deletions

View File

@ -1,3 +1,8 @@
2004-03-18 Andrew Cagney <cagney@redhat.com>
* gdbint.texinfo (Coding): Update section on gdbarch_data,
describe pre_init and post_init.
2004-03-09 Daniel Jacobowitz <drow@mvista.com> 2004-03-09 Daniel Jacobowitz <drow@mvista.com>
* gdb.texinfo (Debugging Output): Document values for "set debug * gdb.texinfo (Debugging Output): Document values for "set debug

View File

@ -4872,134 +4872,104 @@ functions, since they might never return to your code (they
@cindex multi-arch data @cindex multi-arch data
@cindex data-pointer, per-architecture/per-module @cindex data-pointer, per-architecture/per-module
The multi-arch framework includes a mechanism for adding module specific The multi-arch framework includes a mechanism for adding module
per-architecture data-pointers to the @code{struct gdbarch} architecture specific per-architecture data-pointers to the @code{struct gdbarch}
object. architecture object.
A module registers one or more per-architecture data-pointers using the A module registers one or more per-architecture data-pointers using:
function @code{register_gdbarch_data}:
@deftypefun struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *@var{init})
The @var{init} function is used to obtain an initial value for a
per-architecture data-pointer. The function is called, after the
architecture has been created, when the data-pointer is still
uninitialized (@code{NULL}) and its value has been requested via a call
to @code{gdbarch_data}. A data-pointer can also be initialize
explicitly using @code{set_gdbarch_data}.
Any memory required by the @var{init} function should be allocated
using @code{GDBARCH_OBSTACK_ZALLOC}. That memory is automatically
released when the corresponding architecture is deleted.
The function @code{register_gdbarch_data} returns a @code{struct
gdbarch_data} that is used to identify the data-pointer that was added
to the module.
@deftypefun struct gdbarch_data *gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *@var{pre_init})
@var{pre_init} is used to, on-demand, allocate an initial value for a
per-architecture data-pointer using the architecture's obstack (passed
in as a parameter). Since @var{pre_init} can be called during
architecture creation, it is not parameterized with the architecture.
and must not call modules that use per-architecture data.
@end deftypefun @end deftypefun
A typical module has an @code{init} function of the form: @deftypefun struct gdbarch_data *gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *@var{post_init})
@var{post_init} is used to obtain an initial value for a
per-architecture data-pointer @emph{after}. Since @var{post_init} is
always called after architecture creation, it both receives the fully
initialized architecture and is free to call modules that use
per-architecture data (care needs to be taken to ensure that those
other modules do not try to call back to this module as that will
create in cycles in the initialization call graph).
@end deftypefun
@smallexample These functions return a @code{struct gdbarch_data} that is used to
struct nozel @{ int total; @}; identify the per-architecture data-pointer added for that module.
static struct gdbarch_data *nozel_handle;
static void *
nozel_init (struct gdbarch *gdbarch)
@{
struct nozel *data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nozel);
@dots{}
return data;
@}
@end smallexample
Since uninitialized (@code{NULL}) data-pointers are initialized
on-demand, an @code{init} function is free to call other modules that
use data-pointers. Those modules data-pointers will be initialized as
needed. Care should be taken to ensure that the @code{init} call graph
does not contain cycles.
The data-pointer is registered with the call:
@smallexample
void
_initialize_nozel (void)
@{
nozel_handle = register_gdbarch_data (nozel_init);
@dots{}
@end smallexample
The per-architecture data-pointer is accessed using the function: The per-architecture data-pointer is accessed using the function:
@deftypefun void *gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{data_handle}) @deftypefun void *gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{data_handle})
Given the architecture @var{arch} and module data handle Given the architecture @var{arch} and module data handle
@var{data_handle} (returned by @code{register_gdbarch_data}, this @var{data_handle} (returned by @code{gdbarch_data_register_pre_init}
function returns the current value of the per-architecture data-pointer. or @code{gdbarch_data_register_post_init}), this function returns the
current value of the per-architecture data-pointer. If the data
pointer is @code{NULL}, it is first initialized by calling the
corresponding @var{pre_init} or @var{post_init} method.
@end deftypefun @end deftypefun
The non-@code{NULL} data-pointer returned by @code{gdbarch_data} should The examples below assume the following definitions:
be saved in a local variable and then used directly:
@smallexample @smallexample
int struct nozel @{ int total; @};
nozel_total (struct gdbarch *gdbarch) static struct gdbarch_data *nozel_handle;
@{
int total;
struct nozel *data = gdbarch_data (gdbarch, nozel_handle);
@dots{}
return total;
@}
@end smallexample @end smallexample
It is also possible to directly initialize the data-pointer using: A module can extend the architecture vector, adding additional
per-architecture data, using the @var{pre_init} method. The module's
per-architecture data is then initialized during architecture
creation.
@deftypefun void set_gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{handle}, void *@var{pointer}) In the below, the module's per-architecture @emph{nozel} is added. An
Set the still @code{NULL} data-pointer corresponding to @var{handle} architecture can specify its nozel by calling @code{set_gdbarch_nozel}
to the non-@code{NULL} @var{pointer} value. from @code{gdbarch_init}.
@end deftypefun
This function is used by modules that require a mechanism for explicitly
setting the per-architecture data-pointer during architecture creation:
@smallexample @smallexample
/* Always return a non-NULL nozel. */ static void *
static struct nozel * nozel_pre_init (struct obstack *obstack)
gdbarch_nozel (struct gdbarch *gdbarch)
@{ @{
struct nozel *nozel = gdbarch_data (gdbarch, nozel_handle); struct nozel *data = OBSTACK_ZALLOC (obstack, struct nozel);
if (nozel == NULL) return data;
@{
nozel = nozel_init (gdbarch);
set_gdbarch_data (gdbarch, nozel_handle, nozel);
@}
return nozel;
@} @}
@end smallexample @end smallexample
@smallexample @smallexample
/* Called during architecture creation. */
extern void extern void
set_gdbarch_nozel (struct gdbarch *gdbarch, int total) set_gdbarch_nozel (struct gdbarch *gdbarch, int total)
@{ @{
struct nozel *data = gdbarch_nozel (gdbarch); struct nozel *data = gdbarch_data (gdbarch, nozel_handle);
@dots{} data->total = nozel;
data->total = total; @}
@end smallexample
A module can on-demand create architecture dependant data structures
using @code{post_init}.
In the below, the nozel's total is computed on-demand by
@code{nozel_post_init} using information obtained from the
architecture.
@smallexample
static void *
nozel_post_init (struct gdbarch *gdbarch)
@{
struct nozel *data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nozel);
nozel->total = gdbarch@dots{} (gdbarch);
return data;
@} @}
@end smallexample @end smallexample
@smallexample @smallexample
void extern int
_initialize_nozel (void) nozel_total (struct gdbarch *gdbarch)
@{ @{
nozel_handle = register_gdbarch_data (nozel_init); struct nozel *data = gdbarch_data (gdbarch, nozel_handle);
@dots{} return data->total;
@}
@end smallexample @end smallexample
@noindent
Note that an @code{init} function still needs to be registered. It is
used to initialize the data-pointer when the architecture creation phase
fail to set an initial value.
@section Wrapping Output Lines @section Wrapping Output Lines
@cindex line wrap in output @cindex line wrap in output