summaryrefslogtreecommitdiff
path: root/gdb/frame.c
diff options
context:
space:
mode:
authorPedro Alves <pedro@codesourcery.com>2011-03-18 18:41:35 +0000
committerPedro Alves <pedro@codesourcery.com>2011-03-18 18:41:35 +0000
commitef749a8958424d7fde1db60719cdc6425831f9de (patch)
tree277542963fd88950a203537d81efbbfd0c9c7027 /gdb/frame.c
parentb9dea663f5c79d3d7a9554da1554bb00a52e4b5e (diff)
downloadgdb-ef749a8958424d7fde1db60719cdc6425831f9de.tar.gz
gdb/
* findvar.c (value_of_register): Mark the value as unavailable, if the register is unavailable. * frame.h (frame_register_unwind): New `unavailablep' parameter. (frame_register): New `unavailablep' parameter. (frame_register_read): Update comment. * frame.c (frame_register_unwind): New `unavailablep' parameter. Set it if the register is unavailable. If the register is unavailable, clear the output buffer. (frame_register): New `unavailablep' parameter. Pass it down. (frame_unwind_register): Adjust. (put_frame_register): Adjust. (frame_register_read): Adjust. Also return false if the register is not available. (frame_register_unwind_location): Adjust. * sentinel-frame.c (sentinel_frame_prev_register): If the register is unavailable, mark the value accordingly. * stack.c (frame_info): Handle unavailable registers. gdb/testsuite/ * gdb.trace/unavailable.exp (fpreg, spreg, pcreg): Define. (test_register, test_register_unavailable): New procedures. (gdb_unavailable_registers_test): New procedure. (gdb_trace_collection_test): Call it.
Diffstat (limited to 'gdb/frame.c')
-rw-r--r--gdb/frame.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/gdb/frame.c b/gdb/frame.c
index 3bc211ebbb9..42380eb550e 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -757,8 +757,9 @@ frame_pop (struct frame_info *this_frame)
void
frame_register_unwind (struct frame_info *frame, int regnum,
- int *optimizedp, enum lval_type *lvalp,
- CORE_ADDR *addrp, int *realnump, gdb_byte *bufferp)
+ int *optimizedp, int *unavailablep,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, gdb_byte *bufferp)
{
struct value *value;
@@ -775,13 +776,19 @@ frame_register_unwind (struct frame_info *frame, int regnum,
gdb_assert (value != NULL);
*optimizedp = value_optimized_out (value);
+ *unavailablep = !value_entirely_available (value);
*lvalp = VALUE_LVAL (value);
*addrp = value_address (value);
*realnump = VALUE_REGNUM (value);
- if (bufferp && !*optimizedp)
- memcpy (bufferp, value_contents_all (value),
- TYPE_LENGTH (value_type (value)));
+ if (bufferp)
+ {
+ if (!*optimizedp && !*unavailablep)
+ memcpy (bufferp, value_contents_all (value),
+ TYPE_LENGTH (value_type (value)));
+ else
+ memset (bufferp, 0, TYPE_LENGTH (value_type (value)));
+ }
/* Dispose of the new value. This prevents watchpoints from
trying to watch the saved frame pointer. */
@@ -791,7 +798,7 @@ frame_register_unwind (struct frame_info *frame, int regnum,
void
frame_register (struct frame_info *frame, int regnum,
- int *optimizedp, enum lval_type *lvalp,
+ int *optimizedp, int *unavailablep, enum lval_type *lvalp,
CORE_ADDR *addrp, int *realnump, gdb_byte *bufferp)
{
/* Require all but BUFFERP to be valid. A NULL BUFFERP indicates
@@ -805,20 +812,21 @@ frame_register (struct frame_info *frame, int regnum,
/* Obtain the register value by unwinding the register from the next
(more inner frame). */
gdb_assert (frame != NULL && frame->next != NULL);
- frame_register_unwind (frame->next, regnum, optimizedp, lvalp, addrp,
- realnump, bufferp);
+ frame_register_unwind (frame->next, regnum, optimizedp, unavailablep,
+ lvalp, addrp, realnump, bufferp);
}
void
frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf)
{
int optimized;
+ int unavailable;
CORE_ADDR addr;
int realnum;
enum lval_type lval;
- frame_register_unwind (frame, regnum, &optimized, &lval, &addr,
- &realnum, buf);
+ frame_register_unwind (frame, regnum, &optimized, &unavailable,
+ &lval, &addr, &realnum, buf);
}
void
@@ -940,10 +948,12 @@ put_frame_register (struct frame_info *frame, int regnum,
struct gdbarch *gdbarch = get_frame_arch (frame);
int realnum;
int optim;
+ int unavail;
enum lval_type lval;
CORE_ADDR addr;
- frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL);
+ frame_register (frame, regnum, &optim, &unavail,
+ &lval, &addr, &realnum, NULL);
if (optim)
error (_("Attempt to assign to a value that was optimized out."));
switch (lval)
@@ -978,13 +988,15 @@ frame_register_read (struct frame_info *frame, int regnum,
gdb_byte *myaddr)
{
int optimized;
+ int unavailable;
enum lval_type lval;
CORE_ADDR addr;
int realnum;
- frame_register (frame, regnum, &optimized, &lval, &addr, &realnum, myaddr);
+ frame_register (frame, regnum, &optimized, &unavailable,
+ &lval, &addr, &realnum, myaddr);
- return !optimized;
+ return !optimized && !unavailable;
}
int
@@ -1425,8 +1437,10 @@ frame_register_unwind_location (struct frame_info *this_frame, int regnum,
while (this_frame != NULL)
{
- frame_register_unwind (this_frame, regnum, optimizedp, lvalp,
- addrp, realnump, NULL);
+ int unavailable;
+
+ frame_register_unwind (this_frame, regnum, optimizedp, &unavailable,
+ lvalp, addrp, realnump, NULL);
if (*optimizedp)
break;