diff options
author | Michael Eager <eager@eagercon.com> | 2015-03-02 09:57:14 -0800 |
---|---|---|
committer | Michael Eager <eager@eagercon.com> | 2015-03-02 09:57:14 -0800 |
commit | d99093fd0a66da4667938224d1cdb54714f93b25 (patch) | |
tree | 7d3320c0a3f228cf0ef2d2caa04af379358436e0 | |
parent | 129ee12d013f4a2f09fe40a33072e6e47e949890 (diff) | |
download | binutils-gdb-7.8-branch.zip binutils-gdb-7.8-branch.tar.gz binutils-gdb-7.8-branch.tar.bz2 |
Support gdbarch_convert_register_p targets in address_from_registergdb-7.8-branch
Since the last change to address_from_register, it no longer supports
targets that require a special conversion (gdbarch_convert_register_p)
for plain pointer type; I had assumed no target does so.
This turned out to be incorrect: MIPS64 n32 big-endian needs such a
conversion in order to properly sign-extend pointer values.
This patch fixes this regression by handling targets that need a
special conversion in address_from_register as well.
gdb/ChangeLog:
* findvar.c (address_from_register): Handle targets requiring
a special conversion routine even for plain pointer types
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/findvar.c | 25 |
2 files changed, 26 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7527a53..2ad0da9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2015-03-02 Ulrich Weigand <uweigand@de.ibm.com> + + * findvar.c (address_from_register): Handle targets requiring + a special conversion routine even for plain pointer types. + 2015-01-15 Joel Brobecker <brobecker@adacore.com> * version.in: Set GDB version number to 7.8.2.DATE-cvs. diff --git a/gdb/findvar.c b/gdb/findvar.c index 9390c8a..1a542d8 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -766,11 +766,28 @@ address_from_register (int regnum, struct frame_info *frame) would therefore abort in get_frame_id. However, since we only need a temporary value that is never used as lvalue, we actually do not really need to set its VALUE_FRAME_ID. Therefore, we re-implement - the core of value_from_register, but use the null_frame_id. + the core of value_from_register, but use the null_frame_id. */ - This works only if we do not require a special conversion routine, - which is true for plain pointer types for all current targets. */ - gdb_assert (!gdbarch_convert_register_p (gdbarch, regnum, type)); + /* Some targets require a special conversion routine even for plain + pointer types. Avoid constructing a value object in those cases. */ + if (gdbarch_convert_register_p (gdbarch, regnum, type)) + { + gdb_byte *buf = alloca (TYPE_LENGTH (type)); + int optim, unavail, ok; + + ok = gdbarch_register_to_value (gdbarch, frame, regnum, type, + buf, &optim, &unavail); + if (!ok) + { + /* This function is used while computing a location expression. + Complain about the value being optimized out, rather than + letting value_as_address complain about some random register + the expression depends on not being saved. */ + error_value_optimized_out (); + } + + return unpack_long (type, buf); + } value = gdbarch_value_from_register (gdbarch, type, regnum, null_frame_id); read_frame_register_value (value, frame); |