This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[unavailable regs/locals, 04/11] more glue between registers and values (get_frame_register_bytes)
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 22 Feb 2011 13:29:32 +0000
- Subject: [unavailable regs/locals, 04/11] more glue between registers and values (get_frame_register_bytes)
Starting from get_frame_register_bytes (which has always
returned an int to indicate error, but nothing is presently
checking that), add it output parameters to be able to
tell _why_ it failed. We can then use that info to mark
a register value as unavailable, if that's the case.
We then trip on gdbarch_register_to_value, which requires a
similar interface change, and then, this requires
all implementation of this callback to be updated.
--
Pedro Alves
2011-02-22 Pedro Alves <pedro@codesourcery.com>
gdb/
* dwarf2loc.c (read_pieced_value): Handle get_frame_register_bytes
returning that the register piece is unavailable/optimized out.
(write_pieced_value): Handle get_frame_register_bytes returning
that the register piece is unavailable/optimized out when doing a
read-modify write of a bitfield.
* findvar.c (value_from_register): Handle get_frame_register_bytes
returning that the register piece is unavailable/optimized out.
* frame.c (get_frame_register_bytes): New parameters `optimizedp'
and `unavailablep'. Throw error on bad debug info. Use
frame_register instead of frame_register_read, to fill in the new
arguments.
* frame.h (get_frame_register_bytes): New parameters `optimizedp'
and `unavailablep'.
* valops.c: (value_assign): Adjust, and handle
get_frame_register_bytes failing.
* spu-tdep.c: Include exceptions.h.
(spu_software_single_step): Adjust, and handle
get_frame_register_bytes failing.
(spu_get_longjmp_target): Ditto.
* gdbarch.sh (register_to_value): Change to return int. New
parameters `optimizedp' and `unavailablep'.
* gdbarch.h, gdbarch.c: Regenerate.
* i386-tdep.c (i386_register_to_value): Adjust to new
gdbarch_register_to_value interface.
* i387-tdep.c (i387_register_to_value): Ditto.
* i387-tdep.h (i387_register_to_value): Ditto.
* alpha-tdep.c (alpha_register_to_value): Ditto.
* ia64-tdep.c (ia64_register_to_value): Ditto.
* m68k-tdep.c (m68k_register_to_value): Ditto.
* mips-tdep.c (mips_register_to_value): Ditto.
* rs6000-tdep.c (rs6000_register_to_value): Ditto.
---
gdb/alpha-tdep.c | 25 ++++++++++++++++---------
gdb/dwarf2loc.c | 34 ++++++++++++++++++++++++++++++----
gdb/findvar.c | 19 +++++++++++++++----
gdb/frame.c | 29 ++++++++++++++++++++---------
gdb/frame.h | 7 +++++--
gdb/gdbarch.c | 6 +++---
gdb/gdbarch.h | 4 ++--
gdb/gdbarch.sh | 2 +-
gdb/i386-tdep.c | 23 +++++++++++++----------
gdb/i387-tdep.c | 15 +++++++++++----
gdb/i387-tdep.h | 5 +++--
gdb/ia64-tdep.c | 15 ++++++++++++---
gdb/m68k-tdep.c | 17 +++++++++++++----
gdb/mips-tdep.c | 28 ++++++++++++++++++++++------
gdb/rs6000-tdep.c | 13 ++++++++++---
gdb/spu-tdep.c | 25 +++++++++++++++++++++----
gdb/valops.c | 12 ++++++++++--
17 files changed, 207 insertions(+), 72 deletions(-)
Index: src/gdb/dwarf2loc.c
===================================================================
--- src.orig/gdb/dwarf2loc.c 2011-02-21 20:30:31.919344007 +0000
+++ src/gdb/dwarf2loc.c 2011-02-22 11:45:37.714708002 +0000
@@ -591,8 +591,20 @@ read_pieced_value (struct value *v)
if (gdb_regnum != -1)
{
- get_frame_register_bytes (frame, gdb_regnum, reg_offset,
- this_size, buffer);
+ int optim, unavail;
+
+ if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
+ this_size, buffer,
+ &optim, &unavail))
+ {
+ /* Just so garbage doesn't ever shine through. */
+ memset (buffer, 0, this_size);
+
+ if (optim)
+ set_value_optimized_out (v, 1);
+ if (unavail)
+ mark_value_bytes_unavailable (v, offset, this_size);
+ }
}
else
{
@@ -776,8 +788,22 @@ write_pieced_value (struct value *to, st
{
if (need_bitwise)
{
- get_frame_register_bytes (frame, gdb_regnum, reg_offset,
- this_size, buffer);
+ int optim, unavail;
+
+ if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
+ this_size, buffer,
+ &optim, &unavail))
+ {
+ if (optim)
+ error (_("Can't do read-modify-write to "
+ "update bitfield; containing word has been "
+ "optimized out"));
+ if (unavail)
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("Can't do read-modify-write to update "
+ "bitfield; containing word "
+ "is unavailable"));
+ }
copy_bitwise (buffer, dest_offset_bits,
contents, source_offset_bits,
this_size_bits,
Index: src/gdb/findvar.c
===================================================================
--- src.orig/gdb/findvar.c 2011-02-22 11:39:35.994707993 +0000
+++ src/gdb/findvar.c 2011-02-22 11:45:37.714708002 +0000
@@ -628,6 +628,7 @@ value_from_register (struct type *type,
struct gdbarch *gdbarch = get_frame_arch (frame);
struct type *type1 = check_typedef (type);
struct value *v;
+ int optim, unavail, ok;
if (gdbarch_convert_register_p (gdbarch, regnum, type1))
{
@@ -642,8 +643,9 @@ value_from_register (struct type *type,
VALUE_LVAL (v) = lval_register;
VALUE_FRAME_ID (v) = get_frame_id (frame);
VALUE_REGNUM (v) = regnum;
- gdbarch_register_to_value (gdbarch,
- frame, regnum, type1, value_contents_raw (v));
+ ok = gdbarch_register_to_value (gdbarch, frame, regnum, type1,
+ value_contents_raw (v), &optim,
+ &unavail);
}
else
{
@@ -653,10 +655,19 @@ value_from_register (struct type *type,
v = gdbarch_value_from_register (gdbarch, type, regnum, frame);
/* Get the data. */
- if (!get_frame_register_bytes (frame, regnum, value_offset (v), len,
- value_contents_raw (v)))
+ ok = get_frame_register_bytes (frame, regnum, value_offset (v), len,
+ value_contents_raw (v),
+ &optim, &unavail);
+ }
+
+ if (!ok)
+ {
+ if (optim)
set_value_optimized_out (v, 1);
+ if (unavail)
+ mark_value_bytes_unavailable (v, 0, TYPE_LENGTH (type));
}
+
return v;
}
Index: src/gdb/frame.c
===================================================================
--- src.orig/gdb/frame.c 2011-02-22 11:39:36.004707990 +0000
+++ src/gdb/frame.c 2011-02-22 11:45:37.744708000 +0000
@@ -1001,7 +1001,8 @@ frame_register_read (struct frame_info *
int
get_frame_register_bytes (struct frame_info *frame, int regnum,
- CORE_ADDR offset, int len, gdb_byte *myaddr)
+ CORE_ADDR offset, int len, gdb_byte *myaddr,
+ int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
int i;
@@ -1028,11 +1029,8 @@ get_frame_register_bytes (struct frame_i
maxsize += thissize;
}
if (len > maxsize)
- {
- warning (_("Bad debug information detected: "
- "Attempt to read %d bytes from registers."), len);
- return 0;
- }
+ error (_("Bad debug information detected: "
+ "Attempt to read %d bytes from registers."), len);
/* Copy the data. */
while (len > 0)
@@ -1044,14 +1042,25 @@ get_frame_register_bytes (struct frame_i
if (curr_len == register_size (gdbarch, regnum))
{
- if (!frame_register_read (frame, regnum, myaddr))
+ enum lval_type lval;
+ CORE_ADDR addr;
+ int realnum;
+
+ frame_register (frame, regnum, optimizedp, unavailablep,
+ &lval, &addr, &realnum, myaddr);
+ if (*optimizedp || *unavailablep)
return 0;
}
else
{
gdb_byte buf[MAX_REGISTER_SIZE];
-
- if (!frame_register_read (frame, regnum, buf))
+ enum lval_type lval;
+ CORE_ADDR addr;
+ int realnum;
+
+ frame_register (frame, regnum, optimizedp, unavailablep,
+ &lval, &addr, &realnum, buf);
+ if (*optimizedp || *unavailablep)
return 0;
memcpy (myaddr, buf + offset, curr_len);
}
@@ -1062,6 +1071,8 @@ get_frame_register_bytes (struct frame_i
regnum++;
}
+ *optimizedp = 0;
+ *unavailablep = 0;
return 1;
}
Index: src/gdb/frame.h
===================================================================
--- src.orig/gdb/frame.h 2011-02-22 11:43:39.464708012 +0000
+++ src/gdb/frame.h 2011-02-22 11:47:23.084708008 +0000
@@ -517,10 +517,13 @@ extern void put_frame_register (struct f
const gdb_byte *buf);
/* Read LEN bytes from one or multiple registers starting with REGNUM
- in frame FRAME, starting at OFFSET, into BUF. */
+ in frame FRAME, starting at OFFSET, into BUF. If the register
+ contents are optimized out or unavailable, set *OPTIMIZEDP,
+ *UNAVAILABLEP accordingly. */
extern int get_frame_register_bytes (struct frame_info *frame, int regnum,
CORE_ADDR offset, int len,
- gdb_byte *myaddr);
+ gdb_byte *myaddr,
+ int *optimizedp, int *unavailablep);
/* Write LEN bytes to one or multiple registers starting with REGNUM
in frame FRAME, starting at OFFSET, into BUF. */
Index: src/gdb/spu-tdep.c
===================================================================
--- src.orig/gdb/spu-tdep.c 2011-02-21 21:09:45.499344005 +0000
+++ src/gdb/spu-tdep.c 2011-02-22 11:45:37.744708000 +0000
@@ -45,7 +45,7 @@
#include "observer.h"
#include "infcall.h"
#include "dwarf2.h"
-
+#include "exceptions.h"
#include "spu-tdep.h"
@@ -1594,8 +1594,21 @@ spu_software_single_step (struct frame_i
target += SPUADDR_ADDR (pc);
else if (reg != -1)
{
- get_frame_register_bytes (frame, reg, 0, 4, buf);
- target += extract_unsigned_integer (buf, 4, byte_order) & -4;
+ int optim, unavail;
+
+ if (get_frame_register_bytes (frame, reg, 0, 4, buf,
+ &optim, &unavail))
+ target += extract_unsigned_integer (buf, 4, byte_order) & -4;
+ else
+ {
+ if (optim)
+ error (_("Could not determine address of "
+ "single-step breakpoint."));
+ if (unavail)
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("Could not determine address of "
+ "single-step breakpoint."));
+ }
}
target = target & lslr;
@@ -1618,9 +1631,13 @@ spu_get_longjmp_target (struct frame_inf
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[4];
CORE_ADDR jb_addr;
+ int optim, unavail;
/* Jump buffer is pointed to by the argument register $r3. */
- get_frame_register_bytes (frame, SPU_ARG1_REGNUM, 0, 4, buf);
+ if (!get_frame_register_bytes (frame, SPU_ARG1_REGNUM, 0, 4, buf,
+ &optim, &unavail))
+ return 0;
+
jb_addr = extract_unsigned_integer (buf, 4, byte_order);
if (target_read_memory (SPUADDR (tdep->id, jb_addr), buf, 4))
return 0;
Index: src/gdb/gdbarch.c
===================================================================
--- src.orig/gdb/gdbarch.c 2011-02-21 21:09:45.459344006 +0000
+++ src/gdb/gdbarch.c 2011-02-22 11:45:37.744708000 +0000
@@ -2262,14 +2262,14 @@ set_gdbarch_convert_register_p (struct g
gdbarch->convert_register_p = convert_register_p;
}
-void
-gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf)
+int
+gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->register_to_value != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_register_to_value called\n");
- gdbarch->register_to_value (frame, regnum, type, buf);
+ return gdbarch->register_to_value (frame, regnum, type, buf, optimizedp, unavailablep);
}
void
Index: src/gdb/gdbarch.h
===================================================================
--- src.orig/gdb/gdbarch.h 2011-02-21 21:09:45.449344005 +0000
+++ src/gdb/gdbarch.h 2011-02-22 11:45:37.754708001 +0000
@@ -384,8 +384,8 @@ typedef int (gdbarch_convert_register_p_
extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type);
extern void set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch_convert_register_p_ftype *convert_register_p);
-typedef void (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf);
-extern void gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf);
+typedef int (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep);
+extern int gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep);
extern void set_gdbarch_register_to_value (struct gdbarch *gdbarch, gdbarch_register_to_value_ftype *register_to_value);
typedef void (gdbarch_value_to_register_ftype) (struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf);
Index: src/gdb/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh 2011-02-21 21:09:45.449344005 +0000
+++ src/gdb/gdbarch.sh 2011-02-22 11:45:37.754708001 +0000
@@ -484,7 +484,7 @@ F:int:get_longjmp_target:struct frame_in
v:int:believe_pcc_promotion:::::::
#
m:int:convert_register_p:int regnum, struct type *type:regnum, type:0:generic_convert_register_p::0
-f:void:register_to_value:struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf:frame, regnum, type, buf:0
+f:int:register_to_value:struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep:frame, regnum, type, buf, optimizedp, unavailablep:0
f:void:value_to_register:struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf:frame, regnum, type, buf:0
# Construct a value representing the contents of register REGNUM in
# frame FRAME, interpreted as type TYPE. The routine needs to
Index: src/gdb/i386-tdep.c
===================================================================
--- src.orig/gdb/i386-tdep.c 2011-02-21 21:09:45.459344006 +0000
+++ src/gdb/i386-tdep.c 2011-02-22 11:45:37.754708001 +0000
@@ -2715,21 +2715,17 @@ i386_convert_register_p (struct gdbarch
/* Read a value of type TYPE from register REGNUM in frame FRAME, and
return its contents in TO. */
-static void
+static int
i386_register_to_value (struct frame_info *frame, int regnum,
- struct type *type, gdb_byte *to)
+ struct type *type, gdb_byte *to,
+ int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
int len = TYPE_LENGTH (type);
- /* FIXME: kettenis/20030609: What should we do if REGNUM isn't
- available in FRAME (i.e. if it wasn't saved)? */
-
if (i386_fp_regnum_p (gdbarch, regnum))
- {
- i387_register_to_value (frame, regnum, type, to);
- return;
- }
+ return i387_register_to_value (frame, regnum, type, to,
+ optimizedp, unavailablep);
/* Read a value spread across multiple registers. */
@@ -2740,11 +2736,18 @@ i386_register_to_value (struct frame_inf
gdb_assert (regnum != -1);
gdb_assert (register_size (gdbarch, regnum) == 4);
- get_frame_register (frame, regnum, to);
+ if (!get_frame_register_bytes (frame, regnum, 0,
+ register_size (gdbarch, regnum),
+ to, optimizedp, unavailablep))
+ return 0;
+
regnum = i386_next_regnum (regnum);
len -= 4;
to += 4;
}
+
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
/* Write the contents FROM of a value of type TYPE into register
Index: src/gdb/i387-tdep.c
===================================================================
--- src.orig/gdb/i387-tdep.c 2011-02-21 20:30:31.919344007 +0000
+++ src/gdb/i387-tdep.c 2011-02-22 11:45:37.754708002 +0000
@@ -307,9 +307,10 @@ i387_convert_register_p (struct gdbarch
/* Read a value of type TYPE from register REGNUM in frame FRAME, and
return its contents in TO. */
-void
+int
i387_register_to_value (struct frame_info *frame, int regnum,
- struct type *type, gdb_byte *to)
+ struct type *type, gdb_byte *to,
+ int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte from[I386_MAX_REGISTER_SIZE];
@@ -321,12 +322,18 @@ i387_register_to_value (struct frame_inf
{
warning (_("Cannot convert floating-point register value "
"to non-floating-point type."));
- return;
+ *optimizedp = *unavailablep = 0;
+ return 0;
}
/* Convert to TYPE. */
- get_frame_register (frame, regnum, from);
+ if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type),
+ from, optimizedp, unavailablep))
+ return 0;
+
convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
/* Write the contents FROM of a value of type TYPE into register
Index: src/gdb/i387-tdep.h
===================================================================
--- src.orig/gdb/i387-tdep.h 2011-02-21 20:30:31.919344007 +0000
+++ src/gdb/i387-tdep.h 2011-02-22 11:45:37.754708002 +0000
@@ -66,8 +66,9 @@ extern int i387_convert_register_p (stru
/* Read a value of type TYPE from register REGNUM in frame FRAME, and
return its contents in TO. */
-extern void i387_register_to_value (struct frame_info *frame, int regnum,
- struct type *type, gdb_byte *to);
+extern int i387_register_to_value (struct frame_info *frame, int regnum,
+ struct type *type, gdb_byte *to,
+ int *optimizedp, int *unavailablep);
/* Write the contents FROM of a value of type TYPE into register
REGNUM in frame FRAME. */
Index: src/gdb/alpha-tdep.c
===================================================================
--- src.orig/gdb/alpha-tdep.c 2011-02-21 20:30:31.919344007 +0000
+++ src/gdb/alpha-tdep.c 2011-02-22 11:45:37.754708002 +0000
@@ -239,21 +239,28 @@ alpha_convert_register_p (struct gdbarch
&& TYPE_LENGTH (type) != 8);
}
-static void
+static int
alpha_register_to_value (struct frame_info *frame, int regnum,
- struct type *valtype, gdb_byte *out)
+ struct type *valtype, gdb_byte *out,
+ int *optimizedp, int *unavailablep)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte in[MAX_REGISTER_SIZE];
- frame_register_read (frame, regnum, in);
- switch (TYPE_LENGTH (valtype))
+ /* Convert to TYPE. */
+ if (!get_frame_register_bytes (frame, regnum, 0,
+ register_size (gdbarch, regnum),
+ in, optimizedp, unavailablep))
+ return 0;
+
+ if (TYPE_LENGTH (valtype) == 4)
{
- case 4:
- alpha_sts (get_frame_arch (frame), out, in);
- break;
- default:
- error (_("Cannot retrieve value from floating point register"));
+ alpha_sts (gdbarch, out, in);
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
+
+ error (_("Cannot retrieve value from floating point register"));
}
static void
Index: src/gdb/ia64-tdep.c
===================================================================
--- src.orig/gdb/ia64-tdep.c 2011-02-21 21:09:45.489344004 +0000
+++ src/gdb/ia64-tdep.c 2011-02-22 11:45:37.754708002 +0000
@@ -1223,14 +1223,23 @@ ia64_convert_register_p (struct gdbarch
&& type != ia64_ext_type (gdbarch));
}
-static void
+static int
ia64_register_to_value (struct frame_info *frame, int regnum,
- struct type *valtype, gdb_byte *out)
+ struct type *valtype, gdb_byte *out,
+ int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
char in[MAX_REGISTER_SIZE];
- frame_register_read (frame, regnum, in);
+
+ /* Convert to TYPE. */
+ if (!get_frame_register_bytes (frame, regnum, 0,
+ register_size (gdbarch, regnum),
+ in, optimizedp, unavailablep))
+ return 0;
+
convert_typed_floating (in, ia64_ext_type (gdbarch), out, valtype);
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
static void
Index: src/gdb/m68k-tdep.c
===================================================================
--- src.orig/gdb/m68k-tdep.c 2011-02-21 20:30:31.919344007 +0000
+++ src/gdb/m68k-tdep.c 2011-02-22 11:45:37.754708002 +0000
@@ -203,9 +203,10 @@ m68k_convert_register_p (struct gdbarch
/* Read a value of type TYPE from register REGNUM in frame FRAME, and
return its contents in TO. */
-static void
+static int
m68k_register_to_value (struct frame_info *frame, int regnum,
- struct type *type, gdb_byte *to)
+ struct type *type, gdb_byte *to,
+ int *optimizedp, int *unavailablep)
{
gdb_byte from[M68K_MAX_REGISTER_SIZE];
struct type *fpreg_type = register_type (get_frame_arch (frame),
@@ -216,12 +217,20 @@ m68k_register_to_value (struct frame_inf
{
warning (_("Cannot convert floating-point register value "
"to non-floating-point type."));
- return;
+ *optimizedp = *unavailablep = 0;
+ return 0;
}
/* Convert to TYPE. */
- get_frame_register (frame, regnum, from);
+
+ /* Convert to TYPE. */
+ if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type),
+ from, optimizedp, unavailablep))
+ return 0;
+
convert_typed_floating (from, fpreg_type, to, type);
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
/* Write the contents FROM of a value of type TYPE into register
Index: src/gdb/mips-tdep.c
===================================================================
--- src.orig/gdb/mips-tdep.c 2011-02-21 21:09:45.479344010 +0000
+++ src/gdb/mips-tdep.c 2011-02-22 11:45:37.764708003 +0000
@@ -737,9 +737,10 @@ mips_convert_register_p (struct gdbarch
|| mips_convert_register_gpreg_case_p (gdbarch, regnum, type);
}
-static void
+static int
mips_register_to_value (struct frame_info *frame, int regnum,
- struct type *type, gdb_byte *to)
+ struct type *type, gdb_byte *to,
+ int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -747,14 +748,29 @@ mips_register_to_value (struct frame_inf
{
get_frame_register (frame, regnum + 0, to + 4);
get_frame_register (frame, regnum + 1, to + 0);
+
+ if (!get_frame_register_bytes (frame, regnum + 0, 0, 4, to + 4,
+ optimizedp, unavailablep))
+ return 0;
+
+ if (!get_frame_register_bytes (frame, regnum + 1, 0, 4, to + 0,
+ optimizedp, unavailablep))
+ return 0;
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type))
{
int len = TYPE_LENGTH (type);
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- get_frame_register_bytes (frame, regnum, 8 - len, len, to);
- else
- get_frame_register_bytes (frame, regnum, 0, len, to);
+ CORE_ADDR offset;
+
+ offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 8 - len : 0;
+ if (!get_frame_register_bytes (frame, regnum, offset, len, to,
+ optimizedp, unavailablep))
+ return 0;
+
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
else
{
Index: src/gdb/rs6000-tdep.c
===================================================================
--- src.orig/gdb/rs6000-tdep.c 2011-02-21 21:09:45.489344004 +0000
+++ src/gdb/rs6000-tdep.c 2011-02-22 11:45:37.764708003 +0000
@@ -2504,20 +2504,27 @@ rs6000_convert_register_p (struct gdbarc
!= TYPE_LENGTH (builtin_type (gdbarch)->builtin_double));
}
-static void
+static int
rs6000_register_to_value (struct frame_info *frame,
int regnum,
struct type *type,
- gdb_byte *to)
+ gdb_byte *to,
+ int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
gdb_byte from[MAX_REGISTER_SIZE];
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
- get_frame_register (frame, regnum, from);
+ if (!get_frame_register_bytes (frame, regnum, 0,
+ register_size (gdbarch, regnum),
+ from, optimizedp, unavailablep))
+ return 0;
+
convert_typed_floating (from, builtin_type (gdbarch)->builtin_double,
to, type);
+ *optimizedp = *unavailablep = 0;
+ return 1;
}
static void
Index: src/gdb/valops.c
===================================================================
--- src.orig/gdb/valops.c 2011-02-21 20:30:31.919344007 +0000
+++ src/gdb/valops.c 2011-02-22 11:45:37.764708003 +0000
@@ -1343,8 +1343,16 @@ value_assign (struct value *toval, struc
"don't fit in a %d bit word."),
(int) sizeof (LONGEST) * HOST_CHAR_BIT);
- get_frame_register_bytes (frame, value_reg, offset,
- changed_len, buffer);
+ if (!get_frame_register_bytes (frame, value_reg, offset,
+ changed_len, buffer,
+ &optim, &unavail))
+ {
+ if (optim)
+ error (_("value has been optimized out"));
+ if (unavail)
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("value is not available"));
+ }
modify_field (type, buffer, value_as_long (fromval),
value_bitpos (toval), value_bitsize (toval));