From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14723 invoked by alias); 15 May 2002 04:52:41 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 14715 invoked from network); 15 May 2002 04:52:39 -0000 Received: from unknown (HELO localhost.redhat.com) (24.112.240.27) by sources.redhat.com with SMTP; 15 May 2002 04:52:39 -0000 Received: from cygnus.com (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id A0EC63E60 for ; Wed, 15 May 2002 00:52:47 -0400 (EDT) Message-ID: <3CE1E99F.6070005@cygnus.com> Date: Tue, 14 May 2002 21:52:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-US; rv:1.0rc1) Gecko/20020429 X-Accept-Language: en-us, en MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: [rfa:doco] Coding: Per-architecture data-pointers Content-Type: multipart/mixed; boundary="------------060502010609020500030603" X-SW-Source: 2002-05/txt/msg00580.txt.bz2 This is a multi-part message in MIME format. --------------060502010609020500030603 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 226 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 --------------060502010609020500030603 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 4608 2002-05-15 Andrew Cagney * 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 --------------060502010609020500030603--