From: Ulrich Weigand Date: Wed, 10 Sep 2014 17:01:26 +0000 (+0200) Subject: Support gdbarch_convert_register_p targets in address_from_register X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eeef931a6a0596c2121e66dd70e1a36ef0fc576f;p=binutils-gdb.git 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2388096e639..8faf764d73c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2014-09-10 Ulrich Weigand  + + * findvar.c (address_from_register): Handle targets requiring + a special conversion routine even for plain pointer types. + 2014-09-10 Ulrich Weigand  * rs6000-nat.c (exec_one_dummy_insn): Remove. diff --git a/gdb/findvar.c b/gdb/findvar.c index f69a8e0daea..cb98b869c47 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -758,11 +758,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);