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:
parent
dbfe462616
commit
fc989b7a7c
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue