This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[rfa:doco] Coding: Per-architecture data-pointers
- From: Andrew Cagney <ac131313 at cygnus dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Wed, 15 May 2002 00:52:47 -0400
- Subject: [rfa:doco] Coding: Per-architecture data-pointers
Hello,
The attatched attempts to document the ``correct'' way to create
per-architecture module data-pointers.
While there are other techniques that use global variables, I think the
attached is the best approach.
Andrew
2002-05-15 Andrew Cagney <ac131313@redhat.com>
* gdbint.texinfo (Coding): Add section ``Per-architecture module
data''.
Index: gdbint.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v
retrieving revision 1.84
diff -u -r1.84 gdbint.texinfo
--- gdbint.texinfo 13 May 2002 17:20:59 -0000 1.84
+++ gdbint.texinfo 15 May 2002 04:48:39 -0000
@@ -4325,6 +4325,111 @@
functions, since they might never return to your code (they
@samp{longjmp} instead).
+@section Per-architecture module data
+@cindex per-architecture module data
+@cindex multi-arch data
+@cindex data-pointer, per-architecture
+@cindex data-pointer, per-module
+
+The multi-arch framework, which allows @value{GDBN} to support multiple
+architectures within a single binary, includes a mechanism for adding
+module specific per-architecture data-pointers to the @code{struct
+gdbarch} architecture object.
+
+A module registers one or more per-architecture data-pointers using the
+function @code{register_gdbarch_data}.
+
+@deftypefun struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype *@var{init}, gdbarch_data_free_ftype *@var{free})
+
+The @var{init} function, which takes the @code{struct gdbarch} object
+just created as a parameter, is called each time a new @code{struct
+gdbarch} object is created. The @var{init} function should return an
+initial value for that modules data-pointer. If @var{init} is
+@code{NULL}, the corresponding data-pointer will be set to @code{NULL}.
+Each @code{init} function is called in same order as they were
+registered.
+
+The @var{free} function, which takes the @code{struct gdbarch} object
+and the data-pointer as parameters, is called whenever a data-pointer
+needs to be destroyed. This occures when either the data-pointer value
+is changed (via @code{set_gdbarch_data}) or the corresponding
+@code{struct gdbarch} object is being destroyed.
+
+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.
+
+@end deftypefun
+
+A registration sequence might look like:
+
+@smallexample
+static struct gdbarch_data *nozle_data_handle;
+static void *nozel_data_init (struct gdbarch *gdbarch);
+static void nozel_data_free (struct gdbarch *gdbarch, void *data);
+@dots{}
+void
+_initialize_nozel (void)
+@{
+ nozel_data_handle =
+ register_gdbarch_data (nozel_data_init, nozel_data_free);
+@end smallexample
+
+The per-architecture data-pointer is accessed using @code{gdbarch_data}
+
+@deftypefun void *gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{data_handle})
+Given the architecture @var{arch} and module data handle
+@var{data_handle} (returned by @code{register_gdbarch_data}, this function returns the current value of the per-architecture data-pointer.
+@end deftypefun
+
+Functions using the per-architecture data-pointer should cache its value
+locally:
+
+@smallexample
+struct nozel *
+nozle_create (struct gdbarch *gdbarch)
+@{
+ struct nozel_data *data = gdbarch_data (gdbarch, nozel_data_handle);
+ void *nozel = xmalloc (data->sizeof_nozel);
+ @dots{}
+@end smallexample
+
+The function @code{set_gdbarch_data} is can be used to modify a
+per-architecture data-pointer. Its use is normally limited to the one
+case described below.
+
+@deftypefun void set_gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *handle, void *@var{pointer})
+Update the data-pointer corresponding to @var{handle} with the value of
+@var{pointer}. If the previous data-pointer value is non-NULL, then it
+is freed using data-pointers @var{free} function.
+@end deftypefun
+
+Although the per-architecture data-pointers are initialized in the same
+order as when they were registered, a module can't determine when its
+@var{init} function is going to be called. Consequently, a module may
+be called before it has had a chance to initialize its per-architecture
+data-pointer. As illustrated in the example below, a module can use the
+function @code{set_gdbarch_data} to initialize its data-pointer on
+demand:
+
+@smallexample
+static struct nozel_data *
+nozel_data (struct gdbarch *gdbarch)
+@{
+ void *data = gdbarch_data (gdbarch, nozel_data_handle);
+ if (data != NULL)
+ return data;
+ else
+ return nozel_data_init (gdbarch);
+@}
+@dots{}
+struct nozel *
+nozel_create (struct gdbarch *gdbarch)
+@{
+ struct nozel_data *data = nozel_data (gdbarch)
+ @dots{}
+@end smallexample
+
@section Wrapping Output Lines
@cindex line wrap in output