* 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.
This commit is contained in:
Pedro Alves 2011-03-18 18:42:41 +00:00
parent 0fdb4f184b
commit 8dccd430c9
18 changed files with 241 additions and 72 deletions

View File

@ -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

View File

@ -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,

View File

@ -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)))
set_value_optimized_out (v, 1);
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;
}

View File

@ -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;
}

View File

@ -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. */

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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

View File

@ -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;

View File

@ -1,3 +1,37 @@
2011-03-18 Pedro Alves <pedro@codesourcery.com>
* 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 <pedro@codesourcery.com>
* gdb.trace/unavailable.exp (fpreg, spreg, pcreg): Define.

View File

@ -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));