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]

[PATCH RFA/RFC] Address class support


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]