aboutsummaryrefslogtreecommitdiff
path: root/gdb/values.c
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2000-07-17 03:39:34 +0000
committerAndrew Cagney <cagney@redhat.com>2000-07-17 03:39:34 +0000
commit67b2adb2c337c0d262b9b22d6d2b94179dfa0bbd (patch)
tree99d36a529a094d571130fd2ec681b728d80a81b6 /gdb/values.c
parent4f823a66fa0c764d76967a10c222804cb97f29c5 (diff)
downloadgdb-67b2adb2c337c0d262b9b22d6d2b94179dfa0bbd.zip
gdb-67b2adb2c337c0d262b9b22d6d2b94179dfa0bbd.tar.gz
gdb-67b2adb2c337c0d262b9b22d6d2b94179dfa0bbd.tar.bz2
Cast integers into pointers before converting them into canonical
addresses.
Diffstat (limited to 'gdb/values.c')
-rw-r--r--gdb/values.c31
1 files changed, 30 insertions, 1 deletions
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
}