- To: GDB Patches <gdb-patches at sourceware dot cygnus dot com>
- Subject: 0xa.... and signed addresses
- From: Andrew Cagney <ac131313 at cygnus dot com>
- Date: Fri, 14 Jul 2000 18:06:17 +1000
Hello,
Given a system (MIPS) with
sizeof (int) == 4
sizeof (long) == 4
and sizeof (void*) == 4
then, according to ISO-C a value like:
0xa0000000
is an ``unsigned int''. Consequently, in GDB, a command like:
(gdb) list *0xa0000000
is evaluated as:
0xa0000000
-> (unsigned int) 0xa0000000
-> (LONGEST) 0x00000000a0000000
(LONGEST is a builtin type). Unfortunatly, for MIPS, the it was ment to
evaluate it as:
0xa0000000
-> (unsigned int) 0xa0000000
-> (void*) 0xa0000000
-> (LONGEST) 0xffffffffa0000000
(just a little bit different :-).
My question is, how to fix this? As a guess, the below changes
values.c:value_as_pointer() so that it casts any ints/longs onto
pointers before doing the extract. The rationale behind not casting
long-longs is so that the user can specify:
0x12345678a0000000LL
if they really really want to.
Index: values.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/values.c,v
retrieving revision 1.121
diff -p -r1.121 values.c
*** values.c 2000/06/12 12:46:53 1.121
--- values.c 2000/07/14 07:51:10
*************** value_as_pointer (val)
*** 594,600 ****
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);
#endif
}
--- 594,611 ----
for pointers to char, in which the low bits *are* significant.
*/
return ADDR_BITS_REMOVE (value_as_long (val));
#else
! COERCE_ARRAY (val);
! /* If the integer type is smaller than a generic void-pointer, cast
! it. This is so that unpack_long will use the target
! architectures address-to-long mechanism to correctly convert the
! address into a LONGEST. If the type is larger than a standard
! pointer, don't do the cast - assume it was intentional. */
! if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
! && TYPE_LENGTH (VALUE_TYPE (val)) <= (TARGET_PTR_BIT /
HOST_CHAR_BIT))
! {
! val = value_cast (builtin_type_ptr, val);
! }
! return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
#endif
}
and that with the additional fix to make ``builtin_type_ptr'' a true
pointer:
Index: gdbtypes.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbtypes.c,v
retrieving revision 2.110
diff -p -r2.110 gdbtypes.c
*** gdbtypes.c 2000/07/09 05:17:03 2.110
--- gdbtypes.c 2000/07/14 07:54:21
*************** build_gdbtypes ()
*** 3048,3057 ****
/* 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_CORE_ADDR =
init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8,
TYPE_FLAG_UNSIGNED,
--- 3048,3054 ----
/* 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 = make_pointer_type (builtin_type_void, NULL);
builtin_type_CORE_ADDR =
init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8,
TYPE_FLAG_UNSIGNED,
appears to solve the problem. Ok?
Andrew