2004-03-18 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Thu, 18 Mar 2004 20:13:34 +0000 (20:13 +0000)
committerAndrew Cagney <cagney@redhat.com>
Thu, 18 Mar 2004 20:13:34 +0000 (20:13 +0000)
* gdbint.texinfo (Coding): Update section on gdbarch_data,
describe pre_init and post_init.

gdb/doc/ChangeLog
gdb/doc/gdbint.texinfo

index a92080e..8a3f7f9 100644 (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>
 
        * gdb.texinfo (Debugging Output): Document values for "set debug
index 1071099..394870a 100644 (file)
@@ -4872,134 +4872,104 @@ functions, since they might never return to your code (they
 @cindex multi-arch data
 @cindex data-pointer, per-architecture/per-module
 
-The multi-arch framework 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})
+The multi-arch framework 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:
+
+@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
 
-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}.
+@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
 
-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.
+These functions return a @code{struct gdbarch_data} that is used to
+identify the per-architecture data-pointer added for that module.
 
-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.
+The per-architecture data-pointer is accessed using the function:
 
+@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{gdbarch_data_register_pre_init}
+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
 
-A typical module has an @code{init} function of the form:
+The examples below assume the following definitions:
 
 @smallexample
 struct nozel @{ int total; @};
 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.
+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.
 
-The data-pointer is registered with the call:
+In the below, the module's per-architecture @emph{nozel} is added.  An
+architecture can specify its nozel by calling @code{set_gdbarch_nozel}
+from @code{gdbarch_init}.
 
 @smallexample
-void
-_initialize_nozel (void)
+static void *
+nozel_pre_init (struct obstack *obstack)
 @{
-  nozel_handle = register_gdbarch_data (nozel_init);
-@dots{}
+  struct nozel *data = OBSTACK_ZALLOC (obstack, struct nozel);
+  return data;
+@}
 @end smallexample
 
-The per-architecture data-pointer is accessed using the function:
-
-@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
-
-The non-@code{NULL} data-pointer returned by @code{gdbarch_data} should
-be saved in a local variable and then used directly:
-
 @smallexample
-int
-nozel_total (struct gdbarch *gdbarch)
+extern void
+set_gdbarch_nozel (struct gdbarch *gdbarch, int total)
 @{
-  int total;
   struct nozel *data = gdbarch_data (gdbarch, nozel_handle);
-  @dots{}
-  return total;
+  data->total = nozel;
 @}
 @end smallexample
 
-It is also possible to directly initialize the data-pointer using:
-
-@deftypefun void set_gdbarch_data (struct gdbarch *@var{gdbarch}, struct gdbarch_data *@var{handle}, void *@var{pointer})
-Set the still @code{NULL} data-pointer corresponding to @var{handle}
-to the non-@code{NULL} @var{pointer} value.
-@end deftypefun
+A module can on-demand create architecture dependant data structures
+using @code{post_init}.
 
-This function is used by modules that require a mechanism for explicitly
-setting the per-architecture data-pointer during architecture creation:
+In the below, the nozel's total is computed on-demand by
+@code{nozel_post_init} using information obtained from the
+architecture.
 
 @smallexample
-/* Always return a non-NULL nozel.  */
-static struct nozel *
-gdbarch_nozel (struct gdbarch *gdbarch)
+static void *
+nozel_post_init (struct gdbarch *gdbarch)
 @{
-  struct nozel *nozel = gdbarch_data (gdbarch, nozel_handle);
-  if (nozel == NULL)
-    @{
-      nozel = nozel_init (gdbarch);
-      set_gdbarch_data (gdbarch, nozel_handle, nozel);
-    @}
-  return nozel;
+  struct nozel *data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct nozel);
+  nozel->total = gdbarch@dots{} (gdbarch);
+  return data;
 @}
 @end smallexample
 
 @smallexample
-/* Called during architecture creation.  */
-extern void
-set_gdbarch_nozel (struct gdbarch *gdbarch, int total)
+extern int
+nozel_total (struct gdbarch *gdbarch)
 @{
-  struct nozel *data = gdbarch_nozel (gdbarch);
-  @dots{}
-  data->total = total;
+  struct nozel *data = gdbarch_data (gdbarch, nozel_handle);
+  return data->total;
 @}
 @end smallexample
 
-@smallexample
-void
-_initialize_nozel (void)
-@{
-  nozel_handle = register_gdbarch_data (nozel_init);
-  @dots{}
-@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
 @cindex line wrap in output