diff options
author | Jim Blandy <jimb@codesourcery.com> | 2001-11-09 16:41:50 +0000 |
---|---|---|
committer | Jim Blandy <jimb@codesourcery.com> | 2001-11-09 16:41:50 +0000 |
commit | f312f057407f275b27753c401ede0938c45d299c (patch) | |
tree | dca01a0418007b80920aa0e1e13f34e4fa0bb4dc /gdb | |
parent | e333d2c4011881ec0a6b72d6a8093c9dbeb6a448 (diff) | |
download | gdb-f312f057407f275b27753c401ede0938c45d299c.zip gdb-f312f057407f275b27753c401ede0938c45d299c.tar.gz gdb-f312f057407f275b27753c401ede0938c45d299c.tar.bz2 |
* values.c (value_as_address): If VAL is a function or method,
just return its address; don't let COERCE_ARRAY convert its
address to a pointer, and then have unpack_long convert it back to
an address.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/values.c | 42 |
2 files changed, 49 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 940c06b..04d1f19 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2001-11-09 Jim Blandy <jimb@redhat.com> + + * values.c (value_as_address): If VAL is a function or method, + just return its address; don't let COERCE_ARRAY convert its + address to a pointer, and then have unpack_long convert it back to + an address. + 2001-11-06 Pierre Muller <muller@ics.u-strasbg.fr> * p-lang.c (is_pascal_string_type): New function to determine if a diff --git a/gdb/values.c b/gdb/values.c index 639f7bf..e75941f 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -571,6 +571,48 @@ value_as_address (value_ptr val) for pointers to char, in which the low bits *are* significant. */ return ADDR_BITS_REMOVE (value_as_long (val)); #else + + /* There are several targets (IA-64, PowerPC, and others) which + don't represent pointers to functions as simply the address of + the function's entry point. For example, on the IA-64, a + function pointer points to a two-word descriptor, generated by + the linker, which contains the function's entry point, and the + value the IA-64 "global pointer" register should have --- to + support position-independent code. The linker generates + descriptors only for those functions whose addresses are taken. + + On such targets, it's difficult for GDB to convert an arbitrary + function address into a function pointer; it has to either find + an existing descriptor for that function, or call malloc and + build its own. On some targets, it is impossible for GDB to + build a descriptor at all: the descriptor must contain a jump + instruction; data memory cannot be executed; and code memory + cannot be modified. + + Upon entry to this function, if VAL is a value of type `function' + (that is, TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC), then + VALUE_ADDRESS (val) is the address of the function. This is what + you'll get if you evaluate an expression like `main'. The call + to COERCE_ARRAY below actually does all the usual unary + conversions, which includes converting values of type `function' + to `pointer to function'. This is the challenging conversion + discussed above. Then, `unpack_long' will convert that pointer + back into an address. + + So, suppose the user types `disassemble foo' on an architecture + with a strange function pointer representation, on which GDB + cannot build its own descriptors, and suppose further that `foo' + has no linker-built descriptor. The address->pointer conversion + will signal an error and prevent the command from running, even + though the next step would have been to convert the pointer + directly back into the same address. + + The following shortcut avoids this whole mess. If VAL is a + function, just return its address directly. */ + if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC + || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_METHOD) + return VALUE_ADDRESS (val); + COERCE_ARRAY (val); /* Some architectures (e.g. Harvard), map instruction and data |