Andrew Cagney | 9 Jun 2002 19:18
Picon

Re: [patch/rfa:doc] Make gdbarch_data() on-demand

....  and the attached is the final committed doco.  Its been expanded, 
again, to provide a better example involving set_gdbarch_data() along 
with a typo fix.

If it still contains errors, please let me know,

Andrew
2002-06-09  Andrew Cagney  <ac131313 <at> 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.90
diff -u -r1.90 gdbint.texinfo
--- gdbint.texinfo	9 Jun 2002 15:11:47 -0000	1.90
+++ gdbint.texinfo	9 Jun 2002 17:13:49 -0000
 <at>  <at>  -4616,6 +4616,143  <at>  <at> 
 functions, since they might never return to your code (they
  <at> samp{longjmp} instead).

+ <at> section Per-architecture module data
+ <at> cindex per-architecture module data
+ <at> cindex multi-arch data
+ <at> cindex data-pointer, per-architecture/per-module
+
+The multi-arch framework includes a mechanism for adding module specific
+per-architecture data-pointers to the  <at> code{struct gdbarch} architecture
+object.
+
+A module registers one or more per-architecture data-pointers using the
+function  <at> code{register_gdbarch_data}:
+
+ <at> deftypefun struct gdbarch_data *register_gdbarch_data (gdbarch_data_init_ftype * <at> var{init},
gdbarch_data_free_ftype * <at> var{free})
+
+The  <at> 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 ( <at> code{NULL}) and its value has been requested via a call
+to  <at> code{gdbarch_data}.  A data-pointer can also be initialize
+explicitly using  <at> code{set_gdbarch_data}.
+
+The  <at> var{free} function is called when a data-pointer needs to be
+destroyed.  This occurs when either the corresponding  <at> code{struct
+gdbarch} object is being destroyed or when  <at> code{set_gdbarch_data} is
+overriding a non- <at> code{NULL} data-pointer value.
+
+The function  <at> code{register_gdbarch_data} returns a  <at> code{struct
+gdbarch_data} that is used to identify the data-pointer that was added
+to the module.
+
+ <at> end deftypefun
+
+A typical module has  <at> code{init} and  <at> code{free} functions of the form:
+
+ <at> smallexample
+static struct gdbarch_data *nozel_handle;
+static void *
+nozel_init (struct gdbarch *gdbarch)
+ <at> {
+  struct nozel *data = XMALLOC (struct nozel);
+   <at> dots{}
+  return data;
+ <at> }
+ <at> dots{}
+static void
+nozel_free (struct gdbarch *gdbarch, void *data)
+ <at> {
+  xfree (data);
+ <at> }
+ <at> end smallexample
+
+Since uninitialized ( <at> code{NULL}) data-pointers are initialized
+on-demand, an  <at> 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  <at> code{init} call graph
+does not contain cycles.
+
+The data-pointer is registered with the call:
+
+ <at> smallexample
+void
+_initialize_nozel (void)
+ <at> {
+  nozel_handle = register_gdbarch_data (nozel_init, nozel_free);
+ <at> dots{}
+ <at> end smallexample
+
+The per-architecture data-pointer is accessed using the function:
+
+ <at> deftypefun void *gdbarch_data (struct gdbarch * <at> var{gdbarch}, struct gdbarch_data * <at> var{data_handle})
+Given the architecture  <at> var{arch} and module data handle
+ <at> var{data_handle} (returned by  <at> code{register_gdbarch_data}, this
+function returns the current value of the per-architecture data-pointer.
+ <at> end deftypefun
+
+The non- <at> code{NULL} data-pointer returned by  <at> code{gdbarch_data} should
+be saved in a local variable and then used directly:
+
+ <at> smallexample
+int
+nozel_total (struct gdbarch *gdbarch)
+ <at> {
+  int total;
+  struct nozel *data = gdbarch_data (gdbarch, nozel_handle);
+   <at> dots{}
+  return total;
+ <at> }
+ <at> end smallexample
+
+It is also possible to directly initialize the data-pointer using:
+
+ <at> deftypefun void set_gdbarch_data (struct gdbarch * <at> var{gdbarch}, struct gdbarch_data *handle,
void * <at> var{pointer})
+Update the data-pointer corresponding to  <at> var{handle} with the value of
+ <at> var{pointer}.  If the previous data-pointer value is non-NULL, then it
+is freed using data-pointers  <at> var{free} function.
+ <at> end deftypefun
+
+This function is used by modules that require a mechanism for explicitly
+setting the per-architecture data-pointer during architecture creation:
+
+ <at> smallexample
+/* Called during architecture creation.  */
+extern void
+set_gdbarch_nozel (struct gdbarch *gdbarch,
+                   int total)
+ <at> {
+  struct nozel *data = XMALLOC (struct nozel);
+   <at> dots{}
+  set_gdbarch_data (gdbarch, nozel_handle, nozel);
+ <at> }
+ <at> end smallexample
+
+ <at> smallexample
+/* Default, called when nozel not set by set_gdbarch_nozel().  */
+static void *
+nozel_init (struct gdbarch *gdbarch)
+ <at> {
+  struct nozel *default_nozel = XMALLOC (struc nozel);
+   <at> dots{}
+  return default_nozel;
+ <at> }
+ <at> end smallexample
+
+ <at> smallexample
+void
+_initialize_nozel (void)
+ <at> {
+  nozel_handle = register_gdbarch_data (nozel_init, NULL);
+   <at> dots{}
+ <at> end smallexample
+
+ <at> noindent
+Note that an  <at> 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.
+
+
  <at> section Wrapping Output Lines
  <at> cindex line wrap in output


Gmane