aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/gdbtypes.c9
-rw-r--r--gdb/values.c31
3 files changed, 41 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 45e69b0..db405af 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 3ca1b33..67e9a7e 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -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,
diff --git a/gdb/values.c b/gdb/values.c
index ff4951d..6a345a0 100644
--- a/gdb/values.c
+++ b/gdb/values.c
@@ -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
}