From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29549 invoked by alias); 16 Oct 2002 07:24:47 -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 29541 invoked from network); 16 Oct 2002 07:24:44 -0000 Received: from unknown (HELO zenia.red-bean.com) (66.244.67.22) by sources.redhat.com with SMTP; 16 Oct 2002 07:24:44 -0000 Received: (from jimb@localhost) by zenia.red-bean.com (8.11.6/8.11.6) id g9G76go28927; Wed, 16 Oct 2002 02:06:42 -0500 To: Kevin Buettner Cc: gdb-patches@sources.redhat.com Subject: Re: [PATCH RFA/RFC] Address class support References: <1021016004200.ZM22063@localhost.localdomain> From: Jim Blandy Date: Wed, 16 Oct 2002 00:24:00 -0000 In-Reply-To: <1021016004200.ZM22063@localhost.localdomain> Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2.90 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-10/txt/msg00276.txt.bz2 The dwarf2read.c part is approved. Kevin Buettner writes: > The patch below supercedes the "Short pointer support" patch that > I sent to the list last week: > > http://sources.redhat.com/ml/gdb-patches/2002-10/msg00239.html > > Instead, due in part to Jim Blandy's comments on my previous patch, > I've implemented a more general (and robust) solution that will > hopefully prove to have more uses than my immediate need for it (which > is still short pointer support). E.g, it could be used to implement > the near16/far16/huge16/near32/far32 address distinctions for x86. (I > suspect though that other work would be necessary too.) > > As before, I'll need approval on the dwarf2read.c changes from > either Jim or Elena and I'll need Eli's okay on the Docs changes. > > Kevin > > * dwarf2read.c (dwarf2_invalid_pointer_size): New complaint. > (read_tag_pointer_type): Add address class support. > * gdbarch.sh (ADDRESS_CLASS_TYPE_FLAGS) > (ADDRESS_CLASS_TYPE_FLAGS_TO_NAME, ADDRESS_CLASS_NAME_TO_TYPE_FLAGS): > New methods. > * gdbarch.h, gdbarch.c: Regenerate. > * gdbtypes.c (address_space_name_to_int, address_space_int_to_name) > (make_type_with_address_space, recursive_type_dump): Add address > class support. > * gdbtypes.h (TYPE_FLAG_ADDRESS_CLASS_1, TYPE_FLAG_ADDRESS_CLASS_2) > (TYPE_FLAG_ADDRESS_CLASS_ALL, TYPE_ADDRESS_CLASS_1) > (TYPE_ADDRESS_CLASS_2, TYPE_ADDRESS_CLASS_ALL): New defines > > Index: dwarf2read.c > =================================================================== > RCS file: /cvs/src/src/gdb/dwarf2read.c,v > retrieving revision 1.68 > diff -u -p -r1.68 dwarf2read.c > --- dwarf2read.c 9 Oct 2002 04:43:49 -0000 1.68 > +++ dwarf2read.c 16 Oct 2002 00:15:07 -0000 > @@ -683,6 +683,10 @@ static struct complaint dwarf2_invalid_a > { > "invalid attribute class or form for '%s' in '%s'", 0, 0 > }; > +static struct complaint dwarf2_invalid_pointer_size = > +{ > + "invalid pointer size %d", 0, 0 > +}; > > /* local function prototypes */ > > @@ -2925,7 +2929,9 @@ read_tag_pointer_type (struct die_info * > const struct comp_unit_head *cu_header) > { > struct type *type; > - struct attribute *attr; > + struct attribute *attr_byte_size; > + struct attribute *attr_address_class; > + int byte_size, addr_class; > > if (die->type) > { > @@ -2933,15 +2939,42 @@ read_tag_pointer_type (struct die_info * > } > > type = lookup_pointer_type (die_type (die, objfile, cu_header)); > - attr = dwarf_attr (die, DW_AT_byte_size); > - if (attr) > - { > - TYPE_LENGTH (type) = DW_UNSND (attr); > - } > + > + attr_byte_size = dwarf_attr (die, DW_AT_byte_size); > + if (attr_byte_size) > + byte_size = DW_UNSND (attr_byte_size); > else > + byte_size = cu_header->addr_size; > + > + attr_address_class = dwarf_attr (die, DW_AT_address_class); > + if (attr_address_class) > + addr_class = DW_UNSND (attr_address_class); > + else > + addr_class = DW_ADDR_none; > + > + /* If the pointer size or address class is different than the > + default, create a type variant marked as such and set the > + length accordingly. */ > + if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none) > { > - TYPE_LENGTH (type) = cu_header->addr_size; > + if (ADDRESS_CLASS_TYPE_FLAGS_P ()) > + { > + int type_flags; > + > + type_flags = ADDRESS_CLASS_TYPE_FLAGS (byte_size, addr_class); > + gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0); > + type = make_type_with_address_space (type, type_flags); > + } > + else if (TYPE_LENGTH (type) != byte_size) > + { > + complain (&dwarf2_invalid_pointer_size, byte_size); > + } > + else { > + /* Should we also complain about unhandled address classes? */ > + } > } > + > + TYPE_LENGTH (type) = byte_size; > die->type = type; > } > > Index: gdbarch.sh > =================================================================== > RCS file: /cvs/src/src/gdb/gdbarch.sh,v > retrieving revision 1.164 > diff -u -p -r1.164 gdbarch.sh > --- gdbarch.sh 9 Oct 2002 11:59:54 -0000 1.164 > +++ gdbarch.sh 16 Oct 2002 00:15:09 -0000 > @@ -664,6 +664,9 @@ f:2:COFF_MAKE_MSYMBOL_SPECIAL:void:coff_ > v::NAME_OF_MALLOC:const char *:name_of_malloc::::"malloc":"malloc"::0 > v::CANNOT_STEP_BREAKPOINT:int:cannot_step_breakpoint::::0:0::0 > v::HAVE_NONSTEPPABLE_WATCHPOINT:int:have_nonsteppable_watchpoint::::0:0::0 > +F:2:ADDRESS_CLASS_TYPE_FLAGS:int:address_class_type_flags:int byte_size, int dwarf2_addr_class:byte_size, dwarf2_addr_class > +F:2:ADDRESS_CLASS_TYPE_FLAGS_TO_NAME:char *:address_class_type_flags_to_name:int type_flags:type_flags > +F:2:ADDRESS_CLASS_NAME_TO_TYPE_FLAGS:int:address_class_name_to_type_flags:char *name, int *type_flags_ptr:name, type_flags_ptr > EOF > } > > Index: gdbtypes.c > =================================================================== > RCS file: /cvs/src/src/gdb/gdbtypes.c,v > retrieving revision 1.59 > diff -u -p -r1.59 gdbtypes.c > --- gdbtypes.c 2 Oct 2002 22:01:53 -0000 1.59 > +++ gdbtypes.c 16 Oct 2002 00:15:10 -0000 > @@ -397,11 +397,15 @@ lookup_function_type (struct type *type) > extern int > address_space_name_to_int (char *space_identifier) > { > + int type_flags; > /* Check for known address space delimiters. */ > if (!strcmp (space_identifier, "code")) > return TYPE_FLAG_CODE_SPACE; > else if (!strcmp (space_identifier, "data")) > return TYPE_FLAG_DATA_SPACE; > + else if (ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P () > + && ADDRESS_CLASS_NAME_TO_TYPE_FLAGS (space_identifier, &type_flags)) > + return type_flags; > else > error ("Unknown address space specifier: \"%s\"", space_identifier); > } > @@ -416,6 +420,9 @@ address_space_int_to_name (int space_fla > return "code"; > else if (space_flag & TYPE_FLAG_DATA_SPACE) > return "data"; > + else if ((space_flag & TYPE_FLAG_ADDRESS_CLASS_ALL) > + && ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P ()) > + return ADDRESS_CLASS_TYPE_FLAGS_TO_NAME (space_flag); > else > return NULL; > } > @@ -465,14 +472,17 @@ make_qualified_type (struct type *type, > is identical to the one supplied except that it has an address > space attribute attached to it (such as "code" or "data"). > > - This is for Harvard architectures. */ > + The space attributes "code" and "data" are for Harvard architectures. > + The address space attributes are for architectures which have > + alternately sized pointers or pointers with alternate representations. */ > > struct type * > make_type_with_address_space (struct type *type, int space_flag) > { > struct type *ntype; > int new_flags = ((TYPE_INSTANCE_FLAGS (type) > - & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE)) > + & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE > + | TYPE_FLAG_ADDRESS_CLASS_ALL)) > | space_flag); > > return make_qualified_type (type, new_flags, NULL); > @@ -3139,6 +3149,14 @@ recursive_dump_type (struct type *type, > if (TYPE_DATA_SPACE (type)) > { > puts_filtered (" TYPE_FLAG_DATA_SPACE"); > + } > + if (TYPE_ADDRESS_CLASS_1 (type)) > + { > + puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_1"); > + } > + if (TYPE_ADDRESS_CLASS_2 (type)) > + { > + puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_2"); > } > puts_filtered ("\n"); > printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type)); > Index: gdbtypes.h > =================================================================== > RCS file: /cvs/src/src/gdb/gdbtypes.h,v > retrieving revision 1.36 > diff -u -p -r1.36 gdbtypes.h > --- gdbtypes.h 14 Sep 2002 02:09:39 -0000 1.36 > +++ gdbtypes.h 16 Oct 2002 00:15:10 -0000 > @@ -253,6 +253,22 @@ enum type_code > #define TYPE_FLAG_VECTOR (1 << 12) > #define TYPE_VECTOR(t) (TYPE_FLAGS (t) & TYPE_FLAG_VECTOR) > > +/* Address class flags. Some environments provide for pointers whose > + size is different from that of a normal pointer or address types > + where the bits are interpreted differently than normal addresses. The > + TYPE_FLAG_ADDRESS_CLASS_n flags may be used in target specific > + ways to represent these different types of address classes. */ > +#define TYPE_FLAG_ADDRESS_CLASS_1 (1 << 13) > +#define TYPE_ADDRESS_CLASS_1(t) (TYPE_INSTANCE_FLAGS(t) \ > + & TYPE_FLAG_ADDRESS_CLASS_1) > +#define TYPE_FLAG_ADDRESS_CLASS_2 (1 << 14) > +#define TYPE_ADDRESS_CLASS_2(t) (TYPE_INSTANCE_FLAGS(t) \ > + & TYPE_FLAG_ADDRESS_CLASS_2) > +#define TYPE_FLAG_ADDRESS_CLASS_ALL (TYPE_FLAG_ADDRESS_CLASS_1 \ > + | TYPE_FLAG_ADDRESS_CLASS_2) > +#define TYPE_ADDRESS_CLASS_ALL(t) (TYPE_INSTANCE_FLAGS(t) \ > + & TYPE_FLAG_ADDRESS_CLASS_ALL) > + > struct main_type > { > /* Code for kind of type */ > Index: doc/gdbint.texinfo > =================================================================== > RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v > retrieving revision 1.104 > diff -u -p -r1.104 gdbint.texinfo > --- doc/gdbint.texinfo 11 Oct 2002 14:01:04 -0000 1.104 > +++ doc/gdbint.texinfo 16 Oct 2002 00:15:13 -0000 > @@ -2630,6 +2630,89 @@ This function may safely assume that @va > C@t{++} reference type. > @end deftypefn > > +@section Address Classes > +@cindex address classes > +@cindex DW_AT_byte_size > +@cindex DW_AT_address_class > + > +Sometimes information about different kinds of addresses is available > +via the debug information. For example, some programming environments > +define addresses of several different sizes. If the debug information > +distinguishes these kinds of address classes through either the size > +info (e.g, @code{DW_AT_byte_size} in DWARF 2) or through an explicit > +address class attribute (e.g, @code{DW_AT_address_class} in DWARF 2), the > +following macros should be defined in order to disambiguate these > +types within @value{GDBN} as well as provide the added information to > +a @value{GDBN} user when printing type expressions. > + > +@deftypefn {Target Macro} int ADDRESS_CLASS_TYPE_FLAGS (int @var{byte_size}, int @var{dwarf2_addr_class}) > +Returns the type flags needed to construct a pointer type whose size > +is @var{byte_size} and whose address class is @var{dwarf2_addr_class}. > +This function is normally called from within a symbol reader. See > +@file{dwarf2read.c}. > +@end deftypefn > + > +@deftypefn {Target Macro} char *ADDRESS_CLASS_TYPE_FLAGS_TO_NAME (int @var{type_flags}) > +Given the type flags representing an address class qualifier, return > +its name. > +@end deftypefn > +@deftypefn {Target Macro} int ADDRESS_CLASS_NAME_to_TYPE_FLAGS (int @var{name}, int *var{type_flags_ptr}) > +Given an address qualifier name, set the @code{int} refererenced by @var{type_flags_ptr} to the type flags > +for that address class qualifier. > +@end deftypefn > + > +Since the need for address classes is rather rare, none of > +the address class macros defined by default. Predicate > +macros are provided to detect when they are defined. > + > +Consider a hypothetical architecture in which addresses are normally > +32-bits wide, but 16-bit addresses are also supported. Furthermore, > +suppose that the DWARF 2 information for this architecture simply > +uses a @code{DW_AT_byte_size} value of 2 to indicate the use of one > +of these "short" pointers. The following functions could be defined > +to implement the address class macros: > + > +@smallexample > +somearch_address_class_type_flags (int byte_size, int dwarf2_addr_class) > +{ > + if (byte_size == 2) > + return TYPE_FLAG_ADDRESS_CLASS_1; > + else > + return 0; > +} > + > +static char * > +somearch_address_class_type_flags_to_name (int type_flags) > +{ > + if (type_flags & TYPE_FLAG_ADDRESS_CLASS_1) > + return "short"; > + else > + return NULL; > +} > + > +int > +somearch_address_class_name_to_type_flags (char *name, int *type_flags_ptr) > +{ > + if (strcmp (name, "short") == 0) > + { > + *type_flags_ptr = TYPE_FLAG_ADDRESS_CLASS_1; > + return 1; > + } > + else > + return 0; > +} > +@end smallexample > + > +The qualifier @code{@@short} is used in @value{GDBN}'s type expressions > +to indicate the presence of one of these "short" pointers. E.g, if > +the debug information indicates that @code{short_ptr_var} is one of these > +short pointers, @value{GDBN} might show the following behavior: > + > +@smallexample > +(gdb) ptype short_ptr_var > +type = int * @@short > +@end smallexample > + > > @section Raw and Virtual Register Representations > @cindex raw register representation > @@ -2856,6 +2939,49 @@ instruction. Since instructions must al > boundaries, the processor masks out these bits to generate the actual > address of the instruction. ADDR_BITS_REMOVE should filter out these > bits with an expression such as @code{((addr) & ~3)}. > + > +@item ADDRESS_CLASS_NAME_TO_TYPE_FLAGS (@var{name}, @var{type_flags_ptr}) > +@findex ADDRESS_CLASS_NAME_TO_TYPE_FLAGS > +If @var{name} is a valid address class qualifier name, set the @code{int} > +referenced by @var{type_flags_ptr} to the mask representing the qualifier > +and return 1. If @var{name} is not a valid address class qualifier name, > +return 0. > + > +The value for @var{type_flags_ptr} should be one of > +@code{TYPE_FLAG_ADDRESS_CLASS_1}, @code{TYPE_FLAG_ADDRESS_CLASS_2}, or > +possibly some combination of these values or'd together. > +@xref{Target Architecture Definition, , Address Classes}. > + > +@item ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P () > +@findex ADDRESS_CLASS_NAME_TO_TYPE_FLAGS_P > +Predicate which indicates whether @code{ADDRESS_CLASS_NAME_TO_TYPE_FLAGS} > +has been defined. > + > +@item ADDRESS_CLASS_TYPE_FLAGS (@var{byte_size}, @var{dwarf2_addr_class}) > +@findex ADDRESS_CLASS_TYPE_FLAGS (@var{byte_size}, @var{dwarf2_addr_class}) > +Given a pointers byte size (as described by the debug information) and > +the possible @code{DW_AT_address_class} value, return the type flags > +used by @value{GDBN} to represent this address class. The value > +returned should be one of @code{TYPE_FLAG_ADDRESS_CLASS_1}, > +@code{TYPE_FLAG_ADDRESS_CLASS_2}, or possibly some combination of these > +values or'd together. > +@xref{Target Architecture Definition, , Address Classes}. > + > +@item ADDRESS_CLASS_TYPE_FLAGS_P () > +@findex ADDRESS_CLASS_TYPE_FLAGS_P > +Predicate which indicates whether @code{ADDRESS_CLASS_TYPE_FLAGS} has > +been defined. > + > +@item ADDRESS_CLASS_TYPE_FLAGS_TO_NAME (@var{type_flags}) > +@findex ADDRESS_CLASS_TYPE_FLAGS_TO_NAME > +Return the name of the address class qualifier associated with the type > +flags given by @var{type_flags}. > + > +@item ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P () > +@findex ADDRESS_CLASS_TYPE_FLAGS_TO_NAME_P > +Predicate which indicates whether @code{ADDRESS_CLASS_TYPE_FLAGS_TO_NAME} has > +been defined. > +@xref{Target Architecture Definition, , Address Classes}. > > @item ADDRESS_TO_POINTER (@var{type}, @var{buf}, @var{addr}) > @findex ADDRESS_TO_POINTER