From d99093fd0a66da4667938224d1cdb54714f93b25 Mon Sep 17 00:00:00 2001 From: Michael Eager Date: Mon, 2 Mar 2015 09:57:14 -0800 Subject: Support gdbarch_convert_register_p targets in address_from_register 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 --- gdb/ChangeLog | 5 +++++ 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  + + * findvar.c (address_from_register): Handle targets requiring + a special conversion routine even for plain pointer types. + 2015-01-15 Joel Brobecker * 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); -- cgit v1.1