* 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:
Tom Tromey 2010-05-21 21:01:46 +00:00
parent 74de6778b1
commit cb82636715
8 changed files with 539 additions and 207 deletions

View file

@ -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>
* eval.c (evaluate_subexp_standard) <BINOP_SUBSCRIPT>: Call

View file

@ -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. */
static void
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.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
{
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
type. */
if (ctx->location != DWARF_VALUE_LITERAL)
if (ctx->location != DWARF_VALUE_LITERAL
&& ctx->location != DWARF_VALUE_OPTIMIZED_OUT)
dwarf_expr_pop (ctx);
ctx->location = DWARF_VALUE_MEMORY;
}

View file

@ -38,7 +38,10 @@ enum dwarf_value_location
DWARF_VALUE_STACK,
/* The piece is a literal. */
DWARF_VALUE_LITERAL
DWARF_VALUE_LITERAL,
/* The piece was optimized out. */
DWARF_VALUE_OPTIMIZED_OUT
};
/* The dwarf expression stack. */

View file

@ -384,6 +384,16 @@ read_pieced_value (struct value *v)
}
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:
internal_error (__FILE__, __LINE__, _("invalid location type"));
}
@ -609,6 +619,9 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
}
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:
internal_error (__FILE__, __LINE__, _("invalid location type"));
}

View file

@ -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>
* gdb.dwarf2/pieces.exp (pieces_test_f2): New proc.

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,7 @@
struct A { int i; int j; };
struct B { int : 4; int i : 12; int j : 12; int : 4; };
struct C { int i; int j; int q; };
__attribute__((noinline)) void
bar (int x)
@ -84,6 +85,18 @@ f5 (int k)
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
main (void)
{
@ -94,5 +107,6 @@ main (void)
f3 (k);
f4 (k);
f5 (k);
f6 (k);
return 0;
}

View file

@ -67,5 +67,28 @@ proc pieces_test_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_f2
pieces_test_f6