From: Andrew Cagney Date: Mon, 17 Jul 2000 03:39:34 +0000 (+0000) Subject: Cast integers into pointers before converting them into canonical X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=67b2adb2c337c0d262b9b22d6d2b94179dfa0bbd;p=binutils-gdb.git Cast integers into pointers before converting them into canonical addresses. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 45e69b0eaa9..db405af539c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +Mon Jul 17 13:08:10 2000 Andrew Cagney + + * 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 * valops.c (typecmp): Seperate loop into two, add support for diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 3ca1b337c51..67e9a7e5adf 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 ff4951dba03..6a345a07518 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 }