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]

Re: [PATCH RFA/RFC] Address class support


The dwarf2read.c part is approved.

Kevin Buettner <kevinb@redhat.com> 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


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