From b56d6f31a9b4b25da4f3b853ee97a290c8bc4727 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Thu, 27 Oct 2011 17:05:40 +0000 Subject: [PATCH] handle variables stored in muliple consecutive registers gdb/ChangeLog: * value.h (read_frame_register_value): Add declaration. * findvar.c (read_frame_register_value): New function. (value_from_register): Use read_frame_register_value instead of get_frame_register_value + value_contents_copy to get value contents. --- gdb/ChangeLog | 8 ++++++++ gdb/findvar.c | 37 +++++++++++++++++++++++++++++++------ gdb/value.h | 3 +++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 60be381..04503c1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2011-10-27 Joel Brobecker + + * value.h (read_frame_register_value): Add declaration. + * findvar.c (read_frame_register_value): New function. + (value_from_register): Use read_frame_register_value + instead of get_frame_register_value + value_contents_copy + to get value contents. + 2011-10-27 Doug Evans * cli/cli-cmds.c (source_script_with_search): Pass full path to diff --git a/gdb/findvar.c b/gdb/findvar.c index 8e986f1..54e7b4a 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -623,6 +623,35 @@ default_value_from_register (struct type *type, int regnum, return value; } +/* VALUE must be an lval_register value. If regnum is the value's + associated register number, and len the length of the values type, + read one or more registers in FRAME, starting with register REGNUM, + until we've read LEN bytes. */ + +void +read_frame_register_value (struct value *value, struct frame_info *frame) +{ + int offset = 0; + int regnum = VALUE_REGNUM (value); + const int len = TYPE_LENGTH (check_typedef (value_type (value))); + + gdb_assert (VALUE_LVAL (value) == lval_register); + + while (offset < len) + { + struct value *regval = get_frame_register_value (frame, regnum); + int reg_len = TYPE_LENGTH (value_type (regval)); + + if (offset + reg_len > len) + reg_len = len - offset; + value_contents_copy (value, offset, regval, value_offset (regval), + reg_len); + + offset += reg_len; + regnum++; + } +} + /* Return a value of type TYPE, stored in register REGNUM, in frame FRAME. */ struct value * @@ -661,16 +690,11 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) } else { - int len = TYPE_LENGTH (type); - struct value *v2; - /* Construct the value. */ v = gdbarch_value_from_register (gdbarch, type, regnum, frame); /* Get the data. */ - v2 = get_frame_register_value (frame, regnum); - - value_contents_copy (v, 0, v2, value_offset (v), len); + read_frame_register_value (v, frame); } return v; @@ -695,3 +719,4 @@ address_from_register (struct type *type, int regnum, struct frame_info *frame) return result; } + diff --git a/gdb/value.h b/gdb/value.h index f18390e..d2c58ec 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -502,6 +502,9 @@ extern struct value *default_value_from_register (struct type *type, int regnum, struct frame_info *frame); +extern void read_frame_register_value (struct value *value, + struct frame_info *frame); + extern struct value *value_from_register (struct type *type, int regnum, struct frame_info *frame); -- 2.7.4