gdb
* dwarf2loc.c (read_pieced_value): Exit loop when result is full. <DWARF_VALUE_OPTIMIZED_OUT>: New case. * dwarf2expr.h (enum dwarf_value_location) <DWARF_VALUE_OPTIMIZED_OUT>: New constant. * dwarf2expr.c (dwarf_expr_stack_empty_p): New function. (add_piece): Handle empty piece. (execute_stack_op) <DW_OP_piece>: Handle DWARF_VALUE_OPTIMIZED_OUT. gdb/testsuite * gdb.dwarf2/pieces.exp (pieces_test_f6): New proc. Call it. * gdb.dwarf2/pieces.c (struct C): New. (f6): New function. * gdb.dwarf2/pieces.S: Replace.
This commit is contained in:
parent
74de6778b1
commit
cb82636715
8 changed files with 539 additions and 207 deletions
|
@ -1,3 +1,14 @@
|
||||||
|
2010-05-21 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* dwarf2loc.c (read_pieced_value): Exit loop when result is full.
|
||||||
|
<DWARF_VALUE_OPTIMIZED_OUT>: New case.
|
||||||
|
* dwarf2expr.h (enum dwarf_value_location)
|
||||||
|
<DWARF_VALUE_OPTIMIZED_OUT>: New constant.
|
||||||
|
* dwarf2expr.c (dwarf_expr_stack_empty_p): New function.
|
||||||
|
(add_piece): Handle empty piece.
|
||||||
|
(execute_stack_op) <DW_OP_piece>: Handle
|
||||||
|
DWARF_VALUE_OPTIMIZED_OUT.
|
||||||
|
|
||||||
2010-05-21 Tom Tromey <tromey@redhat.com>
|
2010-05-21 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* eval.c (evaluate_subexp_standard) <BINOP_SUBSCRIPT>: Call
|
* eval.c (evaluate_subexp_standard) <BINOP_SUBSCRIPT>: Call
|
||||||
|
|
|
@ -143,6 +143,14 @@ dwarf_expr_fetch_in_stack_memory (struct dwarf_expr_context *ctx, int n)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if the expression stack is empty. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
dwarf_expr_stack_empty_p (struct dwarf_expr_context *ctx)
|
||||||
|
{
|
||||||
|
return ctx->stack_len == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add a new piece to CTX's piece list. */
|
/* Add a new piece to CTX's piece list. */
|
||||||
static void
|
static void
|
||||||
add_piece (struct dwarf_expr_context *ctx, ULONGEST size)
|
add_piece (struct dwarf_expr_context *ctx, ULONGEST size)
|
||||||
|
@ -167,6 +175,15 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size)
|
||||||
p->v.literal.data = ctx->data;
|
p->v.literal.data = ctx->data;
|
||||||
p->v.literal.length = ctx->len;
|
p->v.literal.length = ctx->len;
|
||||||
}
|
}
|
||||||
|
else if (dwarf_expr_stack_empty_p (ctx))
|
||||||
|
{
|
||||||
|
p->location = DWARF_VALUE_OPTIMIZED_OUT;
|
||||||
|
/* Also reset the context's location, for our callers. This is
|
||||||
|
a somewhat strange approach, but this lets us avoid setting
|
||||||
|
the location to DWARF_VALUE_MEMORY in all the individual
|
||||||
|
cases in the evaluator. */
|
||||||
|
ctx->location = DWARF_VALUE_OPTIMIZED_OUT;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p->v.expr.value = dwarf_expr_fetch (ctx, 0);
|
p->v.expr.value = dwarf_expr_fetch (ctx, 0);
|
||||||
|
@ -859,7 +876,8 @@ execute_stack_op (struct dwarf_expr_context *ctx,
|
||||||
|
|
||||||
/* Pop off the address/regnum, and reset the location
|
/* Pop off the address/regnum, and reset the location
|
||||||
type. */
|
type. */
|
||||||
if (ctx->location != DWARF_VALUE_LITERAL)
|
if (ctx->location != DWARF_VALUE_LITERAL
|
||||||
|
&& ctx->location != DWARF_VALUE_OPTIMIZED_OUT)
|
||||||
dwarf_expr_pop (ctx);
|
dwarf_expr_pop (ctx);
|
||||||
ctx->location = DWARF_VALUE_MEMORY;
|
ctx->location = DWARF_VALUE_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,10 @@ enum dwarf_value_location
|
||||||
DWARF_VALUE_STACK,
|
DWARF_VALUE_STACK,
|
||||||
|
|
||||||
/* The piece is a literal. */
|
/* The piece is a literal. */
|
||||||
DWARF_VALUE_LITERAL
|
DWARF_VALUE_LITERAL,
|
||||||
|
|
||||||
|
/* The piece was optimized out. */
|
||||||
|
DWARF_VALUE_OPTIMIZED_OUT
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The dwarf expression stack. */
|
/* The dwarf expression stack. */
|
||||||
|
|
|
@ -384,6 +384,16 @@ read_pieced_value (struct value *v)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DWARF_VALUE_OPTIMIZED_OUT:
|
||||||
|
/* We just leave the bits empty for now. This is not ideal
|
||||||
|
but gdb currently does not have a nice way to represent
|
||||||
|
optimized-out pieces. */
|
||||||
|
warning (_("bytes %ld-%ld in computed object were optimized out; "
|
||||||
|
"replacing with zeroes"),
|
||||||
|
offset,
|
||||||
|
offset + (long) this_size);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
internal_error (__FILE__, __LINE__, _("invalid location type"));
|
internal_error (__FILE__, __LINE__, _("invalid location type"));
|
||||||
}
|
}
|
||||||
|
@ -609,6 +619,9 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* DWARF_VALUE_OPTIMIZED_OUT can't occur in this context --
|
||||||
|
it can only be encountered when making a piece. */
|
||||||
|
case DWARF_VALUE_OPTIMIZED_OUT:
|
||||||
default:
|
default:
|
||||||
internal_error (__FILE__, __LINE__, _("invalid location type"));
|
internal_error (__FILE__, __LINE__, _("invalid location type"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
2010-05-21 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* gdb.dwarf2/pieces.exp (pieces_test_f6): New proc.
|
||||||
|
Call it.
|
||||||
|
* gdb.dwarf2/pieces.c (struct C): New.
|
||||||
|
(f6): New function.
|
||||||
|
* gdb.dwarf2/pieces.S: Replace.
|
||||||
|
|
||||||
2010-05-21 Tom Tromey <tromey@redhat.com>
|
2010-05-21 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* gdb.dwarf2/pieces.exp (pieces_test_f2): New proc.
|
* gdb.dwarf2/pieces.exp (pieces_test_f2): New proc.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
struct A { int i; int j; };
|
struct A { int i; int j; };
|
||||||
struct B { int : 4; int i : 12; int j : 12; int : 4; };
|
struct B { int : 4; int i : 12; int j : 12; int : 4; };
|
||||||
|
struct C { int i; int j; int q; };
|
||||||
|
|
||||||
__attribute__((noinline)) void
|
__attribute__((noinline)) void
|
||||||
bar (int x)
|
bar (int x)
|
||||||
|
@ -84,6 +85,18 @@ f5 (int k)
|
||||||
return a.i + a.j; /* f5 breakpoint */
|
return a.i + a.j; /* f5 breakpoint */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((noinline)) int
|
||||||
|
f6 (int k)
|
||||||
|
{
|
||||||
|
int z = 23;
|
||||||
|
struct C a = { k, k, z};
|
||||||
|
asm ("" : "+r" (a.i));
|
||||||
|
a.j++;
|
||||||
|
bar (a.i);
|
||||||
|
bar (a.j);
|
||||||
|
return a.i + a.j; /* f6 breakpoint */
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
|
@ -94,5 +107,6 @@ main (void)
|
||||||
f3 (k);
|
f3 (k);
|
||||||
f4 (k);
|
f4 (k);
|
||||||
f5 (k);
|
f5 (k);
|
||||||
|
f6 (k);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,5 +67,28 @@ proc pieces_test_f2 {} {
|
||||||
gdb_test "print a\[1\]" " = 14" "print a\[1\] in pieces:f2"
|
gdb_test "print a\[1\]" " = 14" "print a\[1\] in pieces:f2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Function f6 tests for an empty DW_OP_piece.
|
||||||
|
proc pieces_test_f6 {} {
|
||||||
|
global csrcfile
|
||||||
|
set line [gdb_get_line_number "f6 breakpoint" $csrcfile]
|
||||||
|
gdb_test "break pieces.c:$line" "Breakpoint 4.*" \
|
||||||
|
"set f6 breakpoint for pieces"
|
||||||
|
gdb_continue_to_breakpoint "continue to f6 breakpoint for pieces"
|
||||||
|
gdb_test "print a" \
|
||||||
|
"warning: bytes .* in computed object were.* = {i = 7, j = 8, q = 0}" \
|
||||||
|
"print a with optimized out piece"
|
||||||
|
# Note: no warning for this case.
|
||||||
|
gdb_test_multiple "print a.i" \
|
||||||
|
"print a.i with optimized out piece" {
|
||||||
|
-re "warning: some bits in computed object" {
|
||||||
|
fail "print a.i with optimized out piece"
|
||||||
|
}
|
||||||
|
-re " = 7" {
|
||||||
|
pass "print a.i with optimized out piece"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pieces_test_f1
|
pieces_test_f1
|
||||||
pieces_test_f2
|
pieces_test_f2
|
||||||
|
pieces_test_f6
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue