diff options
author | Andrew Cagney <cagney@redhat.com> | 2001-10-15 18:18:30 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2001-10-15 18:18:30 +0000 |
commit | 89f60614a741c7cb4c367ef5b77b1d56b9a0f283 (patch) | |
tree | 7349d78c248c475102674588870e31eb67976b34 /gdb/values.c | |
parent | f2943c13d768acd64f9f58de2baa46d94abfed4b (diff) | |
download | gdb-89f60614a741c7cb4c367ef5b77b1d56b9a0f283.tar.gz |
Add INTEGER_TO_ADDRESS to hadle nasty harvard architectures that do
funnies to integer to address conversions.
Diffstat (limited to 'gdb/values.c')
-rw-r--r-- | gdb/values.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/gdb/values.c b/gdb/values.c index ededf9d368f..bf032af358f 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -572,35 +572,49 @@ value_as_pointer (value_ptr val) return ADDR_BITS_REMOVE (value_as_long (val)); #else 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_void_data_ptr))) - { - val = value_cast (builtin_type_void_data_ptr, val); - } + + /* Some architectures (e.g. Harvard), map instruction and data + addresses onto a single large unified address space. For + instance: An architecture may consider a large integer in the + range 0x10000000 .. 0x1000ffff to already represent a data + addresses (hence not need a pointer to address conversion) while + a small integer would still need to be converted integer to + pointer to address. Just assume such architectures handle all + integer conversions in a single function. */ + + /* JimB writes: + + I think INTEGER_TO_ADDRESS is a good idea as proposed --- but we + must admonish GDB hackers to make sure its behavior matches the + compiler's, whenever possible. + + In general, I think GDB should evaluate expressions the same way + the compiler does. When the user copies an expression out of + their source code and hands it to a `print' command, they should + get the same value the compiler would have computed. Any + deviation from this rule can cause major confusion and annoyance, + and needs to be justified carefully. In other words, GDB doesn't + really have the freedom to do these conversions in clever and + useful ways. + + AndrewC pointed out that users aren't complaining about how GDB + casts integers to pointers; they are complaining that they can't + take an address from a disassembly listing and give it to `x/i'. + This is certainly important. + + Adding an architecture method like INTEGER_TO_ADDRESS certainly + makes it possible for GDB to "get it right" in all circumstances + --- the target has complete control over how things get done, so + people can Do The Right Thing for their target without breaking + anyone else. The standard doesn't specify how integers get + converted to pointers; usually, the ABI doesn't either, but + ABI-specific code is a more reasonable place to handle it. */ + + if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_PTR + && TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_REF + && INTEGER_TO_ADDRESS_P ()) + return INTEGER_TO_ADDRESS (VALUE_TYPE (val), VALUE_CONTENTS (val)); + return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val)); #endif } |