This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: 0xa.... and signed addresses
- To: Andrew Cagney <ac131313 at cygnus dot com>
- Subject: Re: 0xa.... and signed addresses
- From: Michael Snyder <msnyder at cygnus dot com>
- Date: Fri, 14 Jul 2000 13:38:51 -0700
- CC: GDB Patches <gdb-patches at sourceware dot cygnus dot com>
- Organization: Cygnus Solutions
- References: <396EC9F9.34DD3BDC@cygnus.com>
Andrew, you can fight it, but you're eventually going to
end up having to consider TARGET_SIGN_EXTENDS_ADDR.
;-)
Michael
Andrew Cagney wrote:
>
> 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