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/rfc] multi-arch gdbtypes #1 of N


Hello,

The attached patch adds the function:
    const struct builtin_type *builtin_type (gdbarch)
which returns an architecture specific table of types.  It then modifies the d10v to use that method.

To avoid the very long:
    builtin_type (gdbarch)->builtin_type_char
and the uncompileable:
    builtin_type (gdbarch)->char
I've added fprefixes to the type names.  See gdbtypes.h for the list.

Part #2..N consist of converting everthing to this. The language code could be fun.

In preparing the next patch (to language) I found I could significantly trim this one back (removing all the language specific builtin types).


The attached is what I committed,
Andrew

2004-07-27  Andrew Cagney  <cagney@gnu.org>

	* gdbtypes.h (struct builtin_type): Declare.
	(builtin_type): Declare.
	* d10v-tdep.c (d10v_register_type): Use builtin_type.
	* gdbtypes.c (_initialize_gdbtypes): Register gdbtypes_post_init.
	(gdbtypes_post_init): New function.
	(builtin_type): New function.

Index: d10v-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/d10v-tdep.c,v
retrieving revision 1.144
diff -p -u -r1.144 d10v-tdep.c
--- d10v-tdep.c	7 Jun 2004 02:02:46 -0000	1.144
+++ d10v-tdep.c	28 Jul 2004 00:59:48 -0000
@@ -282,14 +282,14 @@ static struct type *
 d10v_register_type (struct gdbarch *gdbarch, int reg_nr)
 {
   if (reg_nr == D10V_PC_REGNUM)
-    return builtin_type_void_func_ptr;
+    return builtin_type (gdbarch)->builtin_func_ptr;
   if (reg_nr == D10V_SP_REGNUM || reg_nr == D10V_FP_REGNUM)
-    return builtin_type_void_data_ptr;
+    return builtin_type (gdbarch)->builtin_data_ptr;
   else if (reg_nr >= a0_regnum (gdbarch)
 	   && reg_nr < (a0_regnum (gdbarch) + NR_A_REGS))
-    return builtin_type_int64;
+    return builtin_type (gdbarch)->builtin_int64;
   else
-    return builtin_type_int16;
+    return builtin_type (gdbarch)->builtin_int16;
 }
 
 static int
Index: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.83
diff -p -u -r1.83 gdbtypes.c
--- gdbtypes.c	26 Jul 2004 14:53:01 -0000	1.83
+++ gdbtypes.c	28 Jul 2004 00:59:48 -0000
@@ -3360,6 +3360,191 @@ build_gdbtypes (void)
 	       "__bfd_vma", (struct objfile *) NULL);
 }
 
+static struct gdbarch_data *gdbtypes_data;
+
+const struct builtin_type *
+builtin_type (struct gdbarch *gdbarch)
+{
+  return gdbarch_data (gdbarch, gdbtypes_data);
+}
+
+static void *
+gdbtypes_post_init (struct gdbarch *gdbarch)
+{
+  struct builtin_type *builtin_type
+    = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_type);
+
+  builtin_type->builtin_void =
+    init_type (TYPE_CODE_VOID, 1,
+	       0,
+	       "void", (struct objfile *) NULL);
+  builtin_type->builtin_char =
+    init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+	       (TYPE_FLAG_NOSIGN
+                | (TARGET_CHAR_SIGNED ? 0 : TYPE_FLAG_UNSIGNED)),
+	       "char", (struct objfile *) NULL);
+  builtin_type->true_char =
+    init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "true character", (struct objfile *) NULL);
+  builtin_type->builtin_signed_char =
+    init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "signed char", (struct objfile *) NULL);
+  builtin_type->builtin_unsigned_char =
+    init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+	       TYPE_FLAG_UNSIGNED,
+	       "unsigned char", (struct objfile *) NULL);
+  builtin_type->builtin_short =
+    init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "short", (struct objfile *) NULL);
+  builtin_type->builtin_unsigned_short =
+    init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+	       TYPE_FLAG_UNSIGNED,
+	       "unsigned short", (struct objfile *) NULL);
+  builtin_type->builtin_int =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "int", (struct objfile *) NULL);
+  builtin_type->builtin_unsigned_int =
+    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+	       TYPE_FLAG_UNSIGNED,
+	       "unsigned int", (struct objfile *) NULL);
+  builtin_type->builtin_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "long", (struct objfile *) NULL);
+  builtin_type->builtin_unsigned_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
+	       TYPE_FLAG_UNSIGNED,
+	       "unsigned long", (struct objfile *) NULL);
+  builtin_type->builtin_long_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "long long", (struct objfile *) NULL);
+  builtin_type->builtin_unsigned_long_long =
+    init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+	       TYPE_FLAG_UNSIGNED,
+	       "unsigned long long", (struct objfile *) NULL);
+  builtin_type->builtin_float =
+    init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "float", (struct objfile *) NULL);
+  TYPE_FLOATFORMAT (builtin_type->builtin_float) = TARGET_FLOAT_FORMAT;
+  builtin_type->builtin_double =
+    init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "double", (struct objfile *) NULL);
+  TYPE_FLOATFORMAT (builtin_type->builtin_double) = TARGET_DOUBLE_FORMAT;
+  builtin_type->builtin_long_double =
+    init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "long double", (struct objfile *) NULL);
+  TYPE_FLOATFORMAT (builtin_type->builtin_long_double) = TARGET_LONG_DOUBLE_FORMAT;
+  builtin_type->builtin_complex =
+    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "complex", (struct objfile *) NULL);
+  TYPE_TARGET_TYPE (builtin_type->builtin_complex) = builtin_type->builtin_float;
+  builtin_type->builtin_double_complex =
+    init_type (TYPE_CODE_COMPLEX, 2 * TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "double complex", (struct objfile *) NULL);
+  TYPE_TARGET_TYPE (builtin_type->builtin_double_complex) = builtin_type->builtin_double;
+  builtin_type->builtin_string =
+    init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "string", (struct objfile *) NULL);
+  builtin_type->builtin_int0 =
+    init_type (TYPE_CODE_INT, 0 / 8,
+	       0,
+	       "int0_t", (struct objfile *) NULL);
+  builtin_type->builtin_int8 =
+    init_type (TYPE_CODE_INT, 8 / 8,
+	       0,
+	       "int8_t", (struct objfile *) NULL);
+  builtin_type->builtin_uint8 =
+    init_type (TYPE_CODE_INT, 8 / 8,
+	       TYPE_FLAG_UNSIGNED,
+	       "uint8_t", (struct objfile *) NULL);
+  builtin_type->builtin_int16 =
+    init_type (TYPE_CODE_INT, 16 / 8,
+	       0,
+	       "int16_t", (struct objfile *) NULL);
+  builtin_type->builtin_uint16 =
+    init_type (TYPE_CODE_INT, 16 / 8,
+	       TYPE_FLAG_UNSIGNED,
+	       "uint16_t", (struct objfile *) NULL);
+  builtin_type->builtin_int32 =
+    init_type (TYPE_CODE_INT, 32 / 8,
+	       0,
+	       "int32_t", (struct objfile *) NULL);
+  builtin_type->builtin_uint32 =
+    init_type (TYPE_CODE_INT, 32 / 8,
+	       TYPE_FLAG_UNSIGNED,
+	       "uint32_t", (struct objfile *) NULL);
+  builtin_type->builtin_int64 =
+    init_type (TYPE_CODE_INT, 64 / 8,
+	       0,
+	       "int64_t", (struct objfile *) NULL);
+  builtin_type->builtin_uint64 =
+    init_type (TYPE_CODE_INT, 64 / 8,
+	       TYPE_FLAG_UNSIGNED,
+	       "uint64_t", (struct objfile *) NULL);
+  builtin_type->builtin_int128 =
+    init_type (TYPE_CODE_INT, 128 / 8,
+	       0,
+	       "int128_t", (struct objfile *) NULL);
+  builtin_type->builtin_uint128 =
+    init_type (TYPE_CODE_INT, 128 / 8,
+	       TYPE_FLAG_UNSIGNED,
+	       "uint128_t", (struct objfile *) NULL);
+  builtin_type->builtin_bool =
+    init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+	       0,
+	       "bool", (struct objfile *) NULL);
+
+  /* Pointer/Address types. */
+
+  /* NOTE: on some targets, addresses and pointers are not necessarily
+     the same --- for example, on the D10V, pointers are 16 bits long,
+     but addresses are 32 bits long.  See doc/gdbint.texinfo,
+     ``Pointers Are Not Always Addresses''.
+
+     The upshot is:
+     - gdb's `struct type' always describes the target's
+       representation.
+     - gdb's `struct value' objects should always hold values in
+       target form.
+     - gdb's CORE_ADDR values are addresses in the unified virtual
+       address space that the assembler and linker work with.  Thus,
+       since target_read_memory takes a CORE_ADDR as an argument, it
+       can access any memory on the target, even if the processor has
+       separate code and data address spaces.
+
+     So, for example:
+     - If v is a value holding a D10V code pointer, its contents are
+       in target form: a big-endian address left-shifted two bits.
+     - If p is a D10V pointer type, TYPE_LENGTH (p) == 2, just as
+       sizeof (void *) == 2 on the target.
+
+     In this context, builtin_type->CORE_ADDR is a bit odd: it's a
+     target type for a value the target will never see.  It's only
+     used to hold the values of (typeless) linker symbols, which are
+     indeed in the unified virtual address space.  */
+  builtin_type->builtin_data_ptr
+    = make_pointer_type (builtin_type->builtin_void, NULL);
+  builtin_type->builtin_func_ptr
+    = lookup_pointer_type (lookup_function_type (builtin_type->builtin_void));
+  builtin_type->builtin_core_addr =
+    init_type (TYPE_CODE_INT, TARGET_ADDR_BIT / 8,
+	       TYPE_FLAG_UNSIGNED,
+	       "__CORE_ADDR", (struct objfile *) NULL);
+
+  return builtin_type;
+}
+
 extern void _initialize_gdbtypes (void);
 void
 _initialize_gdbtypes (void)
@@ -3367,6 +3552,8 @@ _initialize_gdbtypes (void)
   struct cmd_list_element *c;
   build_gdbtypes ();
 
+  gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init);
+
   /* FIXME - For the moment, handle types by swapping them in and out.
      Should be using the per-architecture data-pointer and a large
      struct. */
Index: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.53
diff -p -u -r1.53 gdbtypes.h
--- gdbtypes.h	2 Jun 2004 21:01:55 -0000	1.53
+++ gdbtypes.h	28 Jul 2004 00:59:49 -0000
@@ -923,7 +923,77 @@ extern void allocate_cplus_struct_type (
                                   (TYPE_NFIELDS (thistype) == 0)                     && \
                                   (TYPE_CPLUS_SPECIFIC (thistype) && (TYPE_NFN_FIELDS (thistype) == 0)))
 
+struct builtin_type
+{
+  /* Address/pointer types.  */
+
+  /* `pointer to data' type.  Some target platforms use an implicitly
+     {sign,zero} -extended 32-bit ABI pointer on a 64-bit ISA.  */
+  struct type *builtin_data_ptr;
+
+  /* `pointer to function (returning void)' type.  Harvard
+     architectures mean that ABI function and code pointers are not
+     interconvertible.  Similarly, since ANSI, C standards have
+     explicitly said that pointers to functions and pointers to data
+     are not interconvertible --- that is, you can't cast a function
+     pointer to void * and back, and expect to get the same value.
+     However, all function pointer types are interconvertible, so void
+     (*) () can server as a generic function pointer.  */
+  struct type *builtin_func_ptr;
+
+  /* The target CPU's address type.  This is the ISA address size.  */
+  struct type *builtin_core_addr;
+
+  /* Integral types.  */
+
+  /* Explicit sizes.  These are assumed to be 2's complement and in
+     the architecture's byte order.  The "int0" is for when an ISA
+     needs to describe a register that has no size.  The naming schema
+     is based on C9X <intypes.h>.  */
+  /* FIXME: cagney/2004-07-26: As with floating-point, there should be
+     explicit big, little and little-byte-big-word endian types that
+     exist outside of the architecture vector.  */
+  struct type *builtin_int0;
+  struct type *builtin_int8;
+  struct type *builtin_uint8;
+  struct type *builtin_int16;
+  struct type *builtin_uint16;
+  struct type *builtin_int32;
+  struct type *builtin_uint32;
+  struct type *builtin_int64;
+  struct type *builtin_uint64;
+  struct type *builtin_int128;
+  struct type *builtin_uint128;
+
+  /* We use this for the '/c' print format, because c_char is just a
+     one-byte integral type, which languages less laid back than C
+     will print as ... well, a one-byte integral type.  */
+  struct type *true_char;
+
+  /* Implicit size/sign (based on the the architecture's ABI).  */
+  struct type *builtin_void;
+  struct type *builtin_char;
+  struct type *builtin_short;
+  struct type *builtin_int;
+  struct type *builtin_long;
+  struct type *builtin_signed_char;
+  struct type *builtin_unsigned_char;
+  struct type *builtin_unsigned_short;
+  struct type *builtin_unsigned_int;
+  struct type *builtin_unsigned_long;
+  struct type *builtin_float;
+  struct type *builtin_double;
+  struct type *builtin_long_double;
+  struct type *builtin_complex;
+  struct type *builtin_double_complex;
+  struct type *builtin_string;
+  struct type *builtin_bool;
+  struct type *builtin_long_long;
+  struct type *builtin_unsigned_long_long;
+};
 
+/* Return the type table for the specified architecture.  */
+extern const struct builtin_type *builtin_type (struct gdbarch *gdbarch);
 
 /* Implicit sizes */
 extern struct type *builtin_type_void;
@@ -1157,8 +1227,6 @@ extern struct type *lookup_primitive_typ
 
 extern char *gdb_mangle_name (struct type *, int, int);
 
-extern struct type *builtin_type (char **);
-
 extern struct type *lookup_typename (char *, struct block *, int);
 
 extern struct type *lookup_template_type (char *, struct type *,

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