Cast integers into pointers before converting them into canonical
authorAndrew Cagney <cagney@redhat.com>
Mon, 17 Jul 2000 03:39:34 +0000 (03:39 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 17 Jul 2000 03:39:34 +0000 (03:39 +0000)
addresses.

gdb/ChangeLog
gdb/gdbtypes.c
gdb/values.c

index 45e69b0..db405af 100644 (file)
@@ -1,3 +1,10 @@
+Mon Jul 17 13:08:10 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * values.c (value_as_pointer): When VAL is an integer, explictly
+       cast to a pointer before converting to a CORE_ADDR.
+       * gdbtypes.c (build_gdbtypes): For builtin_type_ptr, construct a
+       real void pointer instead of an integer.
+
 2000-07-15  Daniel Berlin  <dberlin@redhat.com>
 
        * valops.c (typecmp):  Seperate loop into two, add support for
index 3ca1b33..67e9a7e 100644 (file)
@@ -179,7 +179,9 @@ make_pointer_type (type, typeptr)
   TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT;
   TYPE_CODE (ntype) = TYPE_CODE_PTR;
 
-  /* pointers are unsigned */
+  /* Mark pointers as unsigned.  The target converts between pointers
+     and addresses (CORE_ADDRs) using POINTER_TO_ADDRESS() and
+     ADDRESS_TO_POINTER(). */
   TYPE_FLAGS (ntype) |= TYPE_FLAG_UNSIGNED;
 
   if (!TYPE_POINTER_TYPE (type))       /* Remember it, if don't have one.  */
@@ -3034,10 +3036,7 @@ build_gdbtypes ()
   /* NOTE: At present there is no way of differentiating between at
      target address and the target C language pointer type type even
      though the two can be different (cf d10v) */
-  builtin_type_ptr =
-    init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8,
-              TYPE_FLAG_UNSIGNED,
-              "__ptr", (struct objfile *) NULL);
+  builtin_type_ptr = make_pointer_type (builtin_type_void, NULL);
   builtin_type_CORE_ADDR =
     init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8,
               TYPE_FLAG_UNSIGNED,
index ff4951d..6a345a0 100644 (file)
@@ -594,7 +594,36 @@ value_as_pointer (val)
      for pointers to char, in which the low bits *are* significant.  */
   return ADDR_BITS_REMOVE (value_as_long (val));
 #else
-  return value_as_long (val);
+  COERCE_ARRAY (val);
+  /* In converting VAL to an address (CORE_ADDR), any small integers
+     are first cast to a generic pointer.  The function unpack_long
+     will then correctly convert that pointer into a canonical address
+     (using POINTER_TO_ADDRESS).
+
+     Without the cast, the MIPS gets: 0xa0000000 -> (unsigned int)
+     0xa0000000 -> (LONGEST) 0x00000000a0000000
+
+     With the cast, the MIPS gets: 0xa0000000 -> (unsigned int)
+     0xa0000000 -> (void*) 0xa0000000 -> (LONGEST) 0xffffffffa0000000.
+
+     If the user specifies an integer that is larger than the target
+     pointer type, it is assumed that it was intentional and the value
+     is converted directly into an ADDRESS.  This ensures that no
+     information is discarded.
+
+     NOTE: The cast operation may eventualy be converted into a TARGET
+     method (see POINTER_TO_ADDRESS() and ADDRESS_TO_POINTER()) so
+     that the TARGET ISA/ABI can apply an arbitrary conversion.
+
+     NOTE: In pure harvard architectures function and data pointers
+     can be different and may require different integer to pointer
+     conversions. */
+  if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
+      && TYPE_LENGTH (VALUE_TYPE (val)) <= TYPE_LENGTH (builtin_type_ptr))
+    {
+      val = value_cast (builtin_type_ptr, val);
+    }
+  return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
 #endif
 }
 \f