This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]