From 8dccd430c9de0e6cf747ae4bb1bf9d944fe3397c Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 18 Mar 2011 18:42:41 +0000 Subject: [PATCH] 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 | 27 +++++++++++++++++++-------- 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/testsuite/ChangeLog | 34 ++++++++++++++++++++++++++++++++++ gdb/valops.c | 12 ++++++++++-- 18 files changed, 240 insertions(+), 71 deletions(-) diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index cc49a07..2f309a7 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -239,21 +239,28 @@ alpha_convert_register_p (struct gdbarch *gdbarch, int regno, && 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 diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index f90ee71..285081e 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -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, struct value *from) { 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, diff --git a/gdb/findvar.c b/gdb/findvar.c index 809a99e..2b361efe 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -628,6 +628,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) 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, int regnum, struct frame_info *frame) 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, int regnum, struct frame_info *frame) 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; } diff --git a/gdb/frame.c b/gdb/frame.c index 42380eb..5bd1b03 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1001,7 +1001,8 @@ frame_register_read (struct frame_info *frame, int regnum, 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_info *frame, int regnum, 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_info *frame, int regnum, 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]; + enum lval_type lval; + CORE_ADDR addr; + int realnum; - if (!frame_register_read (frame, regnum, buf)) + 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_info *frame, int regnum, regnum++; } + *optimizedp = 0; + *unavailablep = 0; return 1; } diff --git a/gdb/frame.h b/gdb/frame.h index 605528c..e7053a8 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -520,10 +520,13 @@ extern void put_frame_register (struct frame_info *frame, int regnum, 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. */ diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 8b97f20..7f98306 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -2262,14 +2262,14 @@ set_gdbarch_convert_register_p (struct gdbarch *gdbarch, 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 diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 7284f76..50221d7 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -384,8 +384,8 @@ typedef int (gdbarch_convert_register_p_ftype) (struct gdbarch *gdbarch, int reg 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); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 2f987ae..3112f44 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -484,7 +484,7 @@ F:int:get_longjmp_target:struct frame_info *frame, CORE_ADDR *pc:frame, pc 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 diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 6330ceb..62df614 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -2746,21 +2746,17 @@ i386_convert_register_p (struct gdbarch *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. */ @@ -2771,11 +2767,18 @@ i386_register_to_value (struct frame_info *frame, int regnum, 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 diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index 122bd83..9eece41 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -307,9 +307,10 @@ i387_convert_register_p (struct gdbarch *gdbarch, int regnum, /* 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_info *frame, int regnum, { 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 diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h index bd592ba..b876549 100644 --- a/gdb/i387-tdep.h +++ b/gdb/i387-tdep.h @@ -66,8 +66,9 @@ extern int i387_convert_register_p (struct gdbarch *gdbarch, int regnum, /* 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. */ diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index cbd8514..363800d 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -1223,14 +1223,23 @@ ia64_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type) && 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 diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index 082cb84..2706969 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -203,9 +203,10 @@ m68k_convert_register_p (struct gdbarch *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_info *frame, int regnum, { 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 diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 04ce30a..e5aed94 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -737,9 +737,10 @@ mips_convert_register_p (struct gdbarch *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_info *frame, int regnum, { 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 { diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index b8c87fb..23fe9e3 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -2504,20 +2504,27 @@ rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum, != 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 diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index 7f0cd7d..da7024a 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -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_info *frame) 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_info *frame, CORE_ADDR *pc) 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; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 77bad9f..5984d2d 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,39 @@ 2011-03-18 Pedro Alves + * 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. + +2011-03-18 Pedro Alves + * gdb.trace/unavailable.exp (fpreg, spreg, pcreg): Define. (test_register, test_register_unavailable): New procedures. (gdb_unavailable_registers_test): New procedure. diff --git a/gdb/valops.c b/gdb/valops.c index 0c07e5c..b9f5508 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1343,8 +1343,16 @@ value_assign (struct value *toval, struct value *fromval) "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)); -- 2.7.4