This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: partially fix empty DW_OP_piece


I would appreciate comments on this patch.

In DWARF it is valid to have an empty DW_OP_piece.  This means that the
piece in question has been optimized out.  gdb currently does not handle
this (it will give an error), but the VTA+SRA patch that Jakub checked
in will cause gcc to start emitting such empty pieces.

This patch "fixes" the problem in a simple way.  Missing pieces are
filled with zeros, and read_pieced_value emits a warning, so that users
know not to fully trust the result.

This is not an excellent fix.  I think it is an improvement, but I can
understand if people would rather not see it go in.


I am interested in fully fixing this problem.  Doing this will mean
tracking validity of value contents on a bitwise basis (due to
DW_OP_bit_piece, coming soon).

I think there are two basic problems to solve.

First, preserving content validity when transforming values.  I suppose
this means modifying most value_* functions to track validity.

Second, fixing printing to do the right thing.  The tricky bit here is
that the val_print hierarchy would need at least an additional argument
to track the invalid bits.

I thought of two ways to implement the val_print part.  One way would be
to make a temporary 'struct type' instance that encodes the validity in
the type somehow.  The other way is to simply remove val_print entirely
and make all of printing work using values.  I think this is the route I
would prefer.

I'd appreciate comments on this plan.


I built and regtested this on x86-64 (compile farm).
I've updated pieces.exp (and pieces.[Sc]) to test this new functionality.

Tom

2010-05-13  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-13  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.

diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 9e5ce61..482c293 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -141,6 +141,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)
@@ -165,6 +173,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);
@@ -853,7 +870,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;
           }
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index 437ca39..f24f193 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -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.  */
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 7cd33c6..aa54551 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -366,6 +366,14 @@ 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 (_("some bits in computed object were optimized out; "
+		     "replacing with zeroes"));
+	  break;
+
 	default:
 	  internal_error (__FILE__, __LINE__, _("invalid location type"));
 	}
@@ -593,6 +601,9 @@ dwarf2_evaluate_loc_desc (struct symbol *var, 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"));
 	}
diff --git a/gdb/testsuite/gdb.dwarf2/pieces.S b/gdb/testsuite/gdb.dwarf2/pieces.S
index ec578a6..6ea55b8 100644
--- a/gdb/testsuite/gdb.dwarf2/pieces.S
+++ b/gdb/testsuite/gdb.dwarf2/pieces.S
@@ -37,19 +37,19 @@
 bar:
 .LFB0:
 	.file 1 "pieces.c"
-	# pieces.c:10
-	.loc 1 10 0
+	# pieces.c:11
+	.loc 1 11 0
 .LVL0:
 	# basic block 2
 	pushl	%ebp
 .LCFI0:
 	movl	%esp, %ebp
 .LCFI1:
-	# pieces.c:11
-	.loc 1 11 0
-	movl	8(%ebp), %eax
 	# pieces.c:12
 	.loc 1 12 0
+	movl	8(%ebp), %eax
+	# pieces.c:13
+	.loc 1 13 0
 	popl	%ebp
 .LCFI2:
 	ret
@@ -60,8 +60,8 @@ bar:
 	.type	f1, @function
 f1:
 .LFB1:
-	# pieces.c:16
-	.loc 1 16 0
+	# pieces.c:17
+	.loc 1 17 0
 .LVL1:
 	# basic block 2
 	pushl	%ebp
@@ -73,36 +73,36 @@ f1:
 .LCFI5:
 	movl	%esi, -4(%ebp)
 .LCFI6:
-	# pieces.c:19
-	.loc 1 19 0
+	# pieces.c:20
+	.loc 1 20 0
 	movl	8(%ebp), %esi
-	# pieces.c:16
-	.loc 1 16 0
+	# pieces.c:17
+	.loc 1 17 0
 	movl	%ebx, -8(%ebp)
 .LCFI7:
-	# pieces.c:18
-	.loc 1 18 0
+	# pieces.c:19
+	.loc 1 19 0
 	movl	$4, %ebx
 .LVL3:
+	# pieces.c:21
+	.loc 1 21 0
+	movl	%ebx, (%esp)
 	# pieces.c:20
 	.loc 1 20 0
-	movl	%ebx, (%esp)
-	# pieces.c:19
-	.loc 1 19 0
 	addl	$7, %esi
 .LVL4:
-	# pieces.c:20
-	.loc 1 20 0
-	call	bar
 	# pieces.c:21
 	.loc 1 21 0
-	movl	%esi, (%esp)
 	call	bar
 	# pieces.c:22
 	.loc 1 22 0
-	leal	(%ebx,%esi), %eax
+	movl	%esi, (%esp)
+	call	bar
 	# pieces.c:23
 	.loc 1 23 0
+	leal	(%ebx,%esi), %eax
+	# pieces.c:24
+	.loc 1 24 0
 	movl	-8(%ebp), %ebx
 .LVL5:
 	movl	-4(%ebp), %esi
@@ -119,8 +119,8 @@ f1:
 	.type	f2, @function
 f2:
 .LFB2:
-	# pieces.c:27
-	.loc 1 27 0
+	# pieces.c:28
+	.loc 1 28 0
 .LVL7:
 	# basic block 2
 	pushl	%ebp
@@ -132,36 +132,36 @@ f2:
 .LCFI12:
 	movl	%esi, -4(%ebp)
 .LCFI13:
-	# pieces.c:30
-	.loc 1 30 0
+	# pieces.c:31
+	.loc 1 31 0
 	movl	8(%ebp), %esi
-	# pieces.c:27
-	.loc 1 27 0
+	# pieces.c:28
+	.loc 1 28 0
 	movl	%ebx, -8(%ebp)
 .LCFI14:
-	# pieces.c:29
-	.loc 1 29 0
+	# pieces.c:30
+	.loc 1 30 0
 	movl	$4, %ebx
 .LVL9:
+	# pieces.c:32
+	.loc 1 32 0
+	movl	%ebx, (%esp)
 	# pieces.c:31
 	.loc 1 31 0
-	movl	%ebx, (%esp)
-	# pieces.c:30
-	.loc 1 30 0
 	addl	$7, %esi
 .LVL10:
-	# pieces.c:31
-	.loc 1 31 0
-	call	bar
 	# pieces.c:32
 	.loc 1 32 0
-	movl	%esi, (%esp)
 	call	bar
 	# pieces.c:33
 	.loc 1 33 0
-	leal	(%ebx,%esi), %eax
+	movl	%esi, (%esp)
+	call	bar
 	# pieces.c:34
 	.loc 1 34 0
+	leal	(%ebx,%esi), %eax
+	# pieces.c:35
+	.loc 1 35 0
 	movl	-8(%ebp), %ebx
 .LVL11:
 	movl	-4(%ebp), %esi
@@ -178,59 +178,59 @@ f2:
 	.type	f3, @function
 f3:
 .LFB3:
-	# pieces.c:38
-	.loc 1 38 0
+	# pieces.c:39
+	.loc 1 39 0
 .LVL13:
 	# basic block 2
 	pushl	%ebp
 .LCFI17:
-	# pieces.c:40
-	.loc 1 40 0
+	# pieces.c:41
+	.loc 1 41 0
 	movl	$4, %edx
-	# pieces.c:38
-	.loc 1 38 0
+	# pieces.c:39
+	.loc 1 39 0
 	movl	%esp, %ebp
 .LCFI18:
 .LVL14:
 	subl	$12, %esp
 .LCFI19:
-	# pieces.c:40
-	.loc 1 40 0
+	# pieces.c:41
+	.loc 1 41 0
 .LVL15:
-	# pieces.c:38
-	.loc 1 38 0
+	# pieces.c:39
+	.loc 1 39 0
 	movl	%esi, -4(%ebp)
 .LCFI20:
-	# pieces.c:42
-	.loc 1 42 0
+	# pieces.c:43
+	.loc 1 43 0
 	movswl	%dx, %esi
-	# pieces.c:38
-	.loc 1 38 0
+	# pieces.c:39
+	.loc 1 39 0
 	movl	%ebx, -8(%ebp)
 .LCFI21:
-	# pieces.c:42
-	.loc 1 42 0
+	# pieces.c:43
+	.loc 1 43 0
 	movl	%esi, (%esp)
 	call	bar
 .LVL16:
-	# pieces.c:39
-	.loc 1 39 0
+	# pieces.c:40
+	.loc 1 40 0
 	movl	8(%ebp), %edx
 	sall	$4, %edx
-	# pieces.c:41
-	.loc 1 41 0
+	# pieces.c:42
+	.loc 1 42 0
 	addl	$112, %edx
 	sarw	$4, %dx
-	# pieces.c:43
-	.loc 1 43 0
+	# pieces.c:44
+	.loc 1 44 0
 	movswl	%dx, %ebx
 	movl	%ebx, (%esp)
 	call	bar
-	# pieces.c:44
-	.loc 1 44 0
-	leal	(%esi,%ebx), %eax
 	# pieces.c:45
 	.loc 1 45 0
+	leal	(%esi,%ebx), %eax
+	# pieces.c:46
+	.loc 1 46 0
 	movl	-8(%ebp), %ebx
 	movl	-4(%ebp), %esi
 .LVL17:
@@ -246,8 +246,8 @@ f3:
 	.type	f4, @function
 f4:
 .LFB4:
-	# pieces.c:49
-	.loc 1 49 0
+	# pieces.c:50
+	.loc 1 50 0
 .LVL18:
 	# basic block 2
 	pushl	%ebp
@@ -262,28 +262,28 @@ f4:
 .LVL19:
 	movl	%ebx, -8(%ebp)
 .LCFI28:
-	# pieces.c:51
-	.loc 1 51 0
-	movl	%esi, %ebx
 	# pieces.c:52
 	.loc 1 52 0
-	addl	$1, %esi
-	# pieces.c:51
-	.loc 1 51 0
-.LVL20:
+	movl	%esi, %ebx
 	# pieces.c:53
 	.loc 1 53 0
-	movl	%ebx, (%esp)
-	call	bar
+	addl	$1, %esi
+	# pieces.c:52
+	.loc 1 52 0
+.LVL20:
 	# pieces.c:54
 	.loc 1 54 0
-	movl	%esi, (%esp)
+	movl	%ebx, (%esp)
 	call	bar
 	# pieces.c:55
 	.loc 1 55 0
-	leal	(%ebx,%esi), %eax
+	movl	%esi, (%esp)
+	call	bar
 	# pieces.c:56
 	.loc 1 56 0
+	leal	(%ebx,%esi), %eax
+	# pieces.c:57
+	.loc 1 57 0
 	movl	-8(%ebp), %ebx
 .LVL21:
 	movl	-4(%ebp), %esi
@@ -300,8 +300,8 @@ f4:
 	.type	f5, @function
 f5:
 .LFB5:
-	# pieces.c:60
-	.loc 1 60 0
+	# pieces.c:61
+	.loc 1 61 0
 .LVL23:
 	# basic block 2
 	pushl	%ebp
@@ -316,28 +316,28 @@ f5:
 .LVL24:
 	movl	%ebx, -8(%ebp)
 .LCFI35:
-	# pieces.c:62
-	.loc 1 62 0
-	movl	%esi, %ebx
 	# pieces.c:63
 	.loc 1 63 0
-	addl	$1, %esi
-	# pieces.c:62
-	.loc 1 62 0
-.LVL25:
+	movl	%esi, %ebx
 	# pieces.c:64
 	.loc 1 64 0
-	movl	%ebx, (%esp)
-	call	bar
+	addl	$1, %esi
+	# pieces.c:63
+	.loc 1 63 0
+.LVL25:
 	# pieces.c:65
 	.loc 1 65 0
-	movl	%esi, (%esp)
+	movl	%ebx, (%esp)
 	call	bar
 	# pieces.c:66
 	.loc 1 66 0
-	leal	(%ebx,%esi), %eax
+	movl	%esi, (%esp)
+	call	bar
 	# pieces.c:67
 	.loc 1 67 0
+	leal	(%ebx,%esi), %eax
+	# pieces.c:68
+	.loc 1 68 0
 	movl	-8(%ebp), %ebx
 .LVL26:
 	movl	-4(%ebp), %esi
@@ -350,60 +350,118 @@ f5:
 .LFE5:
 	.size	f5, .-f5
 	.p2align 4,,15
-.globl _start
-	.type	_start, @function
-_start:
+.globl f6
+	.type	f6, @function
+f6:
 .LFB6:
-	# pieces.c:71
-	.loc 1 71 0
+	# pieces.c:72
+	.loc 1 72 0
+.LVL28:
 	# basic block 2
 	pushl	%ebp
 .LCFI38:
 	movl	%esp, %ebp
 .LCFI39:
-	pushl	%ebx
+	subl	$12, %esp
 .LCFI40:
-	# pieces.c:73
-	.loc 1 73 0
-	movl	$7, %ebx
-	# pieces.c:71
-	.loc 1 71 0
-	subl	$4, %esp
+	movl	%esi, -4(%ebp)
 .LCFI41:
-	# pieces.c:73
-	.loc 1 73 0
-.LVL28:
-	# pieces.c:74
-	.loc 1 74 0
-	movl	%ebx, (%esp)
-	call	f1
+	movl	8(%ebp), %esi
+.LVL29:
+	movl	%ebx, -8(%ebp)
+.LCFI42:
 	# pieces.c:75
 	.loc 1 75 0
-	movl	%ebx, (%esp)
-	call	f2
+	movl	%esi, %ebx
 	# pieces.c:76
 	.loc 1 76 0
-	movl	%ebx, (%esp)
-	call	f3
+	addl	$1, %esi
+	# pieces.c:75
+	.loc 1 75 0
+.LVL30:
 	# pieces.c:77
 	.loc 1 77 0
 	movl	%ebx, (%esp)
-	call	f4
+	call	bar
 	# pieces.c:78
 	.loc 1 78 0
-	movl	%ebx, (%esp)
-	call	f5
+	movl	%esi, (%esp)
+	call	bar
+	# pieces.c:79
+	.loc 1 79 0
+	leal	(%ebx,%esi), %eax
 	# pieces.c:80
 	.loc 1 80 0
+	movl	-8(%ebp), %ebx
+.LVL31:
+	movl	-4(%ebp), %esi
+.LVL32:
+	movl	%ebp, %esp
+.LCFI43:
+	popl	%ebp
+.LCFI44:
+	ret
+.LFE6:
+	.size	f6, .-f6
+	.p2align 4,,15
+.globl _start
+	.type	_start, @function
+_start:
+.LFB7:
+	# pieces.c:84
+	.loc 1 84 0
+	# basic block 2
+	pushl	%ebp
+.LCFI45:
+	movl	%esp, %ebp
+.LCFI46:
+	pushl	%ebx
+.LCFI47:
+	# pieces.c:86
+	.loc 1 86 0
+	movl	$7, %ebx
+	# pieces.c:84
+	.loc 1 84 0
+	subl	$4, %esp
+.LCFI48:
+	# pieces.c:86
+	.loc 1 86 0
+.LVL33:
+	# pieces.c:87
+	.loc 1 87 0
+	movl	%ebx, (%esp)
+	call	f1
+	# pieces.c:88
+	.loc 1 88 0
+	movl	%ebx, (%esp)
+	call	f2
+	# pieces.c:89
+	.loc 1 89 0
+	movl	%ebx, (%esp)
+	call	f3
+	# pieces.c:90
+	.loc 1 90 0
+	movl	%ebx, (%esp)
+	call	f4
+	# pieces.c:91
+	.loc 1 91 0
+	movl	%ebx, (%esp)
+	call	f5
+	# pieces.c:92
+	.loc 1 92 0
+	movl	%ebx, (%esp)
+	call	f6
+	# pieces.c:94
+	.loc 1 94 0
 	addl	$4, %esp
 	xorl	%eax, %eax
 	popl	%ebx
-.LCFI42:
-.LVL29:
+.LCFI49:
+.LVL34:
 	popl	%ebp
-.LCFI43:
+.LCFI50:
 	ret
-.LFE6:
+.LFE7:
 	.size	_start, .-_start
 #APP
 	.section	.debug_frame,"",@progbits
@@ -649,20 +707,57 @@ _start:
 	.byte	0xd	# DW_CFA_def_cfa_register
 	.uleb128 0x5
 	.byte	0x4	# DW_CFA_advance_loc4
-	.long	.LCFI40-.LCFI39
+	.long	.LCFI41-.LCFI39
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI42-.LCFI41
+	.byte	0x83	# DW_CFA_offset, column 0x3
+	.uleb128 0x4
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI43-.LCFI42
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x4
+	.byte	0xc6	# DW_CFA_restore, column 0x6
+	.byte	0xc3	# DW_CFA_restore, column 0x3
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI44-.LCFI43
+	.byte	0xc5	# DW_CFA_restore, column 0x5
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x4
+	.align 4
+.LEFDE12:
+.LSFDE14:
+	.long	.LEFDE14-.LASFDE14	# FDE Length
+.LASFDE14:
+	.long	.Lframe0	# FDE CIE offset
+	.long	.LFB7	# FDE initial location
+	.long	.LFE7-.LFB7	# FDE address range
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI45-.LFB7
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x8
+	.byte	0x85	# DW_CFA_offset, column 0x5
+	.uleb128 0x2
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI46-.LCFI45
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0x5
+	.byte	0x4	# DW_CFA_advance_loc4
+	.long	.LCFI47-.LCFI46
 	.byte	0x83	# DW_CFA_offset, column 0x3
 	.uleb128 0x3
 	.byte	0x4	# DW_CFA_advance_loc4
-	.long	.LCFI42-.LCFI40
+	.long	.LCFI49-.LCFI47
 	.byte	0xc3	# DW_CFA_restore, column 0x3
 	.byte	0x4	# DW_CFA_advance_loc4
-	.long	.LCFI43-.LCFI42
+	.long	.LCFI50-.LCFI49
 	.byte	0xc5	# DW_CFA_restore, column 0x5
 	.byte	0xc	# DW_CFA_def_cfa
 	.uleb128 0x4
 	.uleb128 0x4
 	.align 4
-.LEFDE12:
+.LEFDE14:
 #NO_APP
 	.text
 .Letext0:
@@ -1130,6 +1225,11 @@ _start:
 	.byte	0x75	# DW_OP_breg5
 	.sleb128 8
 	.long	.LCFI43-.Ltext0	# Location list begin address (*.LLST11)
+	.long	.LCFI44-.Ltext0	# Location list end address (*.LLST11)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.long	.LCFI44-.Ltext0	# Location list begin address (*.LLST11)
 	.long	.LFE6-.Ltext0	# Location list end address (*.LLST11)
 	.value	0x2	# Location expression size
 	.byte	0x74	# DW_OP_breg4
@@ -1137,14 +1237,74 @@ _start:
 	.long	0	# Location list terminator begin (*.LLST11)
 	.long	0	# Location list terminator end (*.LLST11)
 .LLST12:
-	.long	.LVL28-.Ltext0	# Location list begin address (*.LLST12)
-	.long	.LVL29-.Ltext0	# Location list end address (*.LLST12)
-	.value	0x1	# Location expression size
+	.long	.LVL29-.Ltext0	# Location list begin address (*.LLST12)
+	.long	.LVL30-.Ltext0	# Location list end address (*.LLST12)
+	.value	0xa	# Location expression size
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
+	.long	.LVL30-.Ltext0	# Location list begin address (*.LLST12)
+	.long	.LVL31-.Ltext0	# Location list end address (*.LLST12)
+	.value	0x8	# Location expression size
 	.byte	0x53	# DW_OP_reg3
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
+	.byte	0x56	# DW_OP_reg6
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
+	.long	.LVL31-.Ltext0	# Location list begin address (*.LLST12)
+	.long	.LVL32-.Ltext0	# Location list end address (*.LLST12)
+	.value	0x7	# Location expression size
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
+	.byte	0x56	# DW_OP_reg6
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
+	.byte	0x93	# DW_OP_piece
+	.uleb128 0x4
 	.long	0	# Location list terminator begin (*.LLST12)
 	.long	0	# Location list terminator end (*.LLST12)
+.LLST13:
+	.long	.LFB7-.Ltext0	# Location list begin address (*.LLST13)
+	.long	.LCFI45-.Ltext0	# Location list end address (*.LLST13)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	.LCFI45-.Ltext0	# Location list begin address (*.LLST13)
+	.long	.LCFI46-.Ltext0	# Location list end address (*.LLST13)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 8
+	.long	.LCFI46-.Ltext0	# Location list begin address (*.LLST13)
+	.long	.LCFI50-.Ltext0	# Location list end address (*.LLST13)
+	.value	0x2	# Location expression size
+	.byte	0x75	# DW_OP_breg5
+	.sleb128 8
+	.long	.LCFI50-.Ltext0	# Location list begin address (*.LLST13)
+	.long	.LFE7-.Ltext0	# Location list end address (*.LLST13)
+	.value	0x2	# Location expression size
+	.byte	0x74	# DW_OP_breg4
+	.sleb128 4
+	.long	0	# Location list terminator begin (*.LLST13)
+	.long	0	# Location list terminator end (*.LLST13)
+.LLST14:
+	.long	.LVL33-.Ltext0	# Location list begin address (*.LLST14)
+	.long	.LVL34-.Ltext0	# Location list end address (*.LLST14)
+	.value	0x1	# Location expression size
+	.byte	0x53	# DW_OP_reg3
+	.long	0	# Location list terminator begin (*.LLST14)
+	.long	0	# Location list terminator end (*.LLST14)
 	.section	.debug_info
-	.long	0x1e3	# Length of Compilation Unit Info
+	.long	0x252	# Length of Compilation Unit Info
 	.value	0x2	# DWARF version number
 	.long	.Ldebug_abbrev0	# Offset Into Abbrev. Section
 	.byte	0x4	# Pointer Size (in bytes)
@@ -1152,7 +1312,7 @@ _start:
 	.long	.LASF1	# DW_AT_producer: "GNU C 4.6.0 20100506 (experimental) [trunk revision 159117]"
 	.byte	0x1	# DW_AT_language
 	.long	.LASF2	# DW_AT_name: "pieces.c"
-	.long	.LASF3	# DW_AT_comp_dir: "/home/tromey/gnu/PRS/rh589467"
+	.long	.LASF3	# DW_AT_comp_dir: "/home/tromey/gnu/archer/archer/gdb/testsuite/gdb.dwarf2"
 	.long	.Ltext0	# DW_AT_low_pc
 	.long	.Letext0	# DW_AT_high_pc
 	.long	.Ldebug_line0	# DW_AT_stmt_list
@@ -1212,182 +1372,245 @@ _start:
 	.byte	0x23	# DW_OP_plus_uconst
 	.uleb128 0
 	.byte	0	# end of children of DIE 0x4f
-	.uleb128 0x6	# (DIE (0x78) DW_TAG_subprogram)
+	.uleb128 0x2	# (DIE (0x78) DW_TAG_structure_type)
+	.ascii "C\0"	# DW_AT_name
+	.byte	0xc	# DW_AT_byte_size
+	.byte	0x1	# DW_AT_decl_file (pieces.c)
+	.byte	0x7	# DW_AT_decl_line
+	.long	0xa7	# DW_AT_sibling
+	.uleb128 0x3	# (DIE (0x82) DW_TAG_member)
+	.ascii "i\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (pieces.c)
+	.byte	0x7	# DW_AT_decl_line
+	.long	0x48	# DW_AT_type
+	.byte	0x2	# DW_AT_data_member_location
+	.byte	0x23	# DW_OP_plus_uconst
+	.uleb128 0
+	.uleb128 0x3	# (DIE (0x8e) DW_TAG_member)
+	.ascii "j\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (pieces.c)
+	.byte	0x7	# DW_AT_decl_line
+	.long	0x48	# DW_AT_type
+	.byte	0x2	# DW_AT_data_member_location
+	.byte	0x23	# DW_OP_plus_uconst
+	.uleb128 0x4
+	.uleb128 0x3	# (DIE (0x9a) DW_TAG_member)
+	.ascii "q\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (pieces.c)
+	.byte	0x7	# DW_AT_decl_line
+	.long	0x48	# DW_AT_type
+	.byte	0x2	# DW_AT_data_member_location
+	.byte	0x23	# DW_OP_plus_uconst
+	.uleb128 0x8
+	.byte	0	# end of children of DIE 0x78
+	.uleb128 0x6	# (DIE (0xa7) DW_TAG_subprogram)
 	.byte	0x1	# DW_AT_external
 	.ascii "bar\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x9	# DW_AT_decl_line
+	.byte	0xa	# DW_AT_decl_line
 	.byte	0x1	# DW_AT_prototyped
 	.long	.LFB0	# DW_AT_low_pc
 	.long	.LFE0	# DW_AT_high_pc
 	.long	.LLST0	# DW_AT_frame_base
-	.long	0x9e	# DW_AT_sibling
-	.uleb128 0x7	# (DIE (0x91) DW_TAG_formal_parameter)
+	.long	0xcd	# DW_AT_sibling
+	.uleb128 0x7	# (DIE (0xc0) DW_TAG_formal_parameter)
 	.ascii "x\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x9	# DW_AT_decl_line
+	.byte	0xa	# DW_AT_decl_line
 	.long	0x48	# DW_AT_type
 	.byte	0x2	# DW_AT_location
 	.byte	0x91	# DW_OP_fbreg
 	.sleb128 0
-	.byte	0	# end of children of DIE 0x78
-	.uleb128 0x8	# (DIE (0x9e) DW_TAG_subprogram)
+	.byte	0	# end of children of DIE 0xa7
+	.uleb128 0x8	# (DIE (0xcd) DW_TAG_subprogram)
 	.byte	0x1	# DW_AT_external
 	.ascii "f1\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0xf	# DW_AT_decl_line
+	.byte	0x10	# DW_AT_decl_line
 	.byte	0x1	# DW_AT_prototyped
 	.long	0x48	# DW_AT_type
 	.long	.LFB1	# DW_AT_low_pc
 	.long	.LFE1	# DW_AT_high_pc
 	.long	.LLST1	# DW_AT_frame_base
-	.long	0xd4	# DW_AT_sibling
-	.uleb128 0x7	# (DIE (0xba) DW_TAG_formal_parameter)
+	.long	0x103	# DW_AT_sibling
+	.uleb128 0x7	# (DIE (0xe9) DW_TAG_formal_parameter)
 	.ascii "k\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0xf	# DW_AT_decl_line
+	.byte	0x10	# DW_AT_decl_line
 	.long	0x48	# DW_AT_type
 	.byte	0x2	# DW_AT_location
 	.byte	0x91	# DW_OP_fbreg
 	.sleb128 0
-	.uleb128 0x9	# (DIE (0xc6) DW_TAG_variable)
+	.uleb128 0x9	# (DIE (0xf5) DW_TAG_variable)
 	.ascii "a\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x11	# DW_AT_decl_line
+	.byte	0x12	# DW_AT_decl_line
 	.long	0x25	# DW_AT_type
 	.long	.LLST2	# DW_AT_location
-	.byte	0	# end of children of DIE 0x9e
-	.uleb128 0x8	# (DIE (0xd4) DW_TAG_subprogram)
+	.byte	0	# end of children of DIE 0xcd
+	.uleb128 0x8	# (DIE (0x103) DW_TAG_subprogram)
 	.byte	0x1	# DW_AT_external
 	.ascii "f2\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x1a	# DW_AT_decl_line
+	.byte	0x1b	# DW_AT_decl_line
 	.byte	0x1	# DW_AT_prototyped
 	.long	0x48	# DW_AT_type
 	.long	.LFB2	# DW_AT_low_pc
 	.long	.LFE2	# DW_AT_high_pc
 	.long	.LLST3	# DW_AT_frame_base
-	.long	0x10a	# DW_AT_sibling
-	.uleb128 0x7	# (DIE (0xf0) DW_TAG_formal_parameter)
+	.long	0x139	# DW_AT_sibling
+	.uleb128 0x7	# (DIE (0x11f) DW_TAG_formal_parameter)
 	.ascii "k\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x1a	# DW_AT_decl_line
+	.byte	0x1b	# DW_AT_decl_line
 	.long	0x48	# DW_AT_type
 	.byte	0x2	# DW_AT_location
 	.byte	0x91	# DW_OP_fbreg
 	.sleb128 0
-	.uleb128 0x9	# (DIE (0xfc) DW_TAG_variable)
+	.uleb128 0x9	# (DIE (0x12b) DW_TAG_variable)
 	.ascii "a\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x1c	# DW_AT_decl_line
-	.long	0x10a	# DW_AT_type
+	.byte	0x1d	# DW_AT_decl_line
+	.long	0x139	# DW_AT_type
 	.long	.LLST4	# DW_AT_location
-	.byte	0	# end of children of DIE 0xd4
-	.uleb128 0xa	# (DIE (0x10a) DW_TAG_array_type)
+	.byte	0	# end of children of DIE 0x103
+	.uleb128 0xa	# (DIE (0x139) DW_TAG_array_type)
 	.long	0x48	# DW_AT_type
-	.long	0x11a	# DW_AT_sibling
-	.uleb128 0xb	# (DIE (0x113) DW_TAG_subrange_type)
-	.long	0x11a	# DW_AT_type
+	.long	0x149	# DW_AT_sibling
+	.uleb128 0xb	# (DIE (0x142) DW_TAG_subrange_type)
+	.long	0x149	# DW_AT_type
 	.byte	0x1	# DW_AT_upper_bound
-	.byte	0	# end of children of DIE 0x10a
-	.uleb128 0xc	# (DIE (0x11a) DW_TAG_base_type)
+	.byte	0	# end of children of DIE 0x139
+	.uleb128 0xc	# (DIE (0x149) DW_TAG_base_type)
 	.byte	0x4	# DW_AT_byte_size
 	.byte	0x7	# DW_AT_encoding
-	.uleb128 0x8	# (DIE (0x11d) DW_TAG_subprogram)
+	.uleb128 0x8	# (DIE (0x14c) DW_TAG_subprogram)
 	.byte	0x1	# DW_AT_external
 	.ascii "f3\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x25	# DW_AT_decl_line
+	.byte	0x26	# DW_AT_decl_line
 	.byte	0x1	# DW_AT_prototyped
 	.long	0x48	# DW_AT_type
 	.long	.LFB3	# DW_AT_low_pc
 	.long	.LFE3	# DW_AT_high_pc
 	.long	.LLST5	# DW_AT_frame_base
-	.long	0x153	# DW_AT_sibling
-	.uleb128 0x7	# (DIE (0x139) DW_TAG_formal_parameter)
+	.long	0x182	# DW_AT_sibling
+	.uleb128 0x7	# (DIE (0x168) DW_TAG_formal_parameter)
 	.ascii "k\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x25	# DW_AT_decl_line
+	.byte	0x26	# DW_AT_decl_line
 	.long	0x48	# DW_AT_type
 	.byte	0x2	# DW_AT_location
 	.byte	0x91	# DW_OP_fbreg
 	.sleb128 0
-	.uleb128 0x9	# (DIE (0x145) DW_TAG_variable)
+	.uleb128 0x9	# (DIE (0x174) DW_TAG_variable)
 	.ascii "a\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x27	# DW_AT_decl_line
+	.byte	0x28	# DW_AT_decl_line
 	.long	0x4f	# DW_AT_type
 	.long	.LLST6	# DW_AT_location
-	.byte	0	# end of children of DIE 0x11d
-	.uleb128 0x8	# (DIE (0x153) DW_TAG_subprogram)
+	.byte	0	# end of children of DIE 0x14c
+	.uleb128 0x8	# (DIE (0x182) DW_TAG_subprogram)
 	.byte	0x1	# DW_AT_external
 	.ascii "f4\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x30	# DW_AT_decl_line
+	.byte	0x31	# DW_AT_decl_line
 	.byte	0x1	# DW_AT_prototyped
 	.long	0x48	# DW_AT_type
 	.long	.LFB4	# DW_AT_low_pc
 	.long	.LFE4	# DW_AT_high_pc
 	.long	.LLST7	# DW_AT_frame_base
-	.long	0x189	# DW_AT_sibling
-	.uleb128 0x7	# (DIE (0x16f) DW_TAG_formal_parameter)
+	.long	0x1b8	# DW_AT_sibling
+	.uleb128 0x7	# (DIE (0x19e) DW_TAG_formal_parameter)
 	.ascii "k\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x30	# DW_AT_decl_line
+	.byte	0x31	# DW_AT_decl_line
 	.long	0x48	# DW_AT_type
 	.byte	0x2	# DW_AT_location
 	.byte	0x91	# DW_OP_fbreg
 	.sleb128 0
-	.uleb128 0x9	# (DIE (0x17b) DW_TAG_variable)
+	.uleb128 0x9	# (DIE (0x1aa) DW_TAG_variable)
 	.ascii "a\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x32	# DW_AT_decl_line
-	.long	0x10a	# DW_AT_type
+	.byte	0x33	# DW_AT_decl_line
+	.long	0x139	# DW_AT_type
 	.long	.LLST8	# DW_AT_location
-	.byte	0	# end of children of DIE 0x153
-	.uleb128 0x8	# (DIE (0x189) DW_TAG_subprogram)
+	.byte	0	# end of children of DIE 0x182
+	.uleb128 0x8	# (DIE (0x1b8) DW_TAG_subprogram)
 	.byte	0x1	# DW_AT_external
 	.ascii "f5\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x3b	# DW_AT_decl_line
+	.byte	0x3c	# DW_AT_decl_line
 	.byte	0x1	# DW_AT_prototyped
 	.long	0x48	# DW_AT_type
 	.long	.LFB5	# DW_AT_low_pc
 	.long	.LFE5	# DW_AT_high_pc
 	.long	.LLST9	# DW_AT_frame_base
-	.long	0x1bf	# DW_AT_sibling
-	.uleb128 0x7	# (DIE (0x1a5) DW_TAG_formal_parameter)
+	.long	0x1ee	# DW_AT_sibling
+	.uleb128 0x7	# (DIE (0x1d4) DW_TAG_formal_parameter)
 	.ascii "k\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x3b	# DW_AT_decl_line
+	.byte	0x3c	# DW_AT_decl_line
 	.long	0x48	# DW_AT_type
 	.byte	0x2	# DW_AT_location
 	.byte	0x91	# DW_OP_fbreg
 	.sleb128 0
-	.uleb128 0x9	# (DIE (0x1b1) DW_TAG_variable)
+	.uleb128 0x9	# (DIE (0x1e0) DW_TAG_variable)
 	.ascii "a\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x3d	# DW_AT_decl_line
+	.byte	0x3e	# DW_AT_decl_line
 	.long	0x25	# DW_AT_type
 	.long	.LLST10	# DW_AT_location
-	.byte	0	# end of children of DIE 0x189
-	.uleb128 0xd	# (DIE (0x1bf) DW_TAG_subprogram)
+	.byte	0	# end of children of DIE 0x1b8
+	.uleb128 0x8	# (DIE (0x1ee) DW_TAG_subprogram)
 	.byte	0x1	# DW_AT_external
-	.long	.LASF0	# DW_AT_name: "main"
+	.ascii "f6\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x46	# DW_AT_decl_line
+	.byte	0x47	# DW_AT_decl_line
 	.byte	0x1	# DW_AT_prototyped
 	.long	0x48	# DW_AT_type
 	.long	.LFB6	# DW_AT_low_pc
 	.long	.LFE6	# DW_AT_high_pc
 	.long	.LLST11	# DW_AT_frame_base
-	.uleb128 0x9	# (DIE (0x1d8) DW_TAG_variable)
+	.long	0x22e	# DW_AT_sibling
+	.uleb128 0x7	# (DIE (0x20a) DW_TAG_formal_parameter)
 	.ascii "k\0"	# DW_AT_name
 	.byte	0x1	# DW_AT_decl_file (pieces.c)
-	.byte	0x48	# DW_AT_decl_line
+	.byte	0x47	# DW_AT_decl_line
 	.long	0x48	# DW_AT_type
+	.byte	0x2	# DW_AT_location
+	.byte	0x91	# DW_OP_fbreg
+	.sleb128 0
+	.uleb128 0xd	# (DIE (0x216) DW_TAG_variable)
+	.ascii "z\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (pieces.c)
+	.byte	0x49	# DW_AT_decl_line
+	.long	0x48	# DW_AT_type
+	.byte	0x17	# DW_AT_const_value
+	.uleb128 0x9	# (DIE (0x220) DW_TAG_variable)
+	.ascii "a\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (pieces.c)
+	.byte	0x4a	# DW_AT_decl_line
+	.long	0x78	# DW_AT_type
 	.long	.LLST12	# DW_AT_location
-	.byte	0	# end of children of DIE 0x1bf
+	.byte	0	# end of children of DIE 0x1ee
+	.uleb128 0xe	# (DIE (0x22e) DW_TAG_subprogram)
+	.byte	0x1	# DW_AT_external
+	.long	.LASF0	# DW_AT_name: "main"
+	.byte	0x1	# DW_AT_decl_file (pieces.c)
+	.byte	0x53	# DW_AT_decl_line
+	.byte	0x1	# DW_AT_prototyped
+	.long	0x48	# DW_AT_type
+	.long	.LFB7	# DW_AT_low_pc
+	.long	.LFE7	# DW_AT_high_pc
+	.long	.LLST13	# DW_AT_frame_base
+	.uleb128 0x9	# (DIE (0x247) DW_TAG_variable)
+	.ascii "k\0"	# DW_AT_name
+	.byte	0x1	# DW_AT_decl_file (pieces.c)
+	.byte	0x55	# DW_AT_decl_line
+	.long	0x48	# DW_AT_type
+	.long	.LLST14	# DW_AT_location
+	.byte	0	# end of children of DIE 0x22e
 	.byte	0	# end of children of DIE 0xb
 	.section	.debug_abbrev
 	.uleb128 0x1	# (abbrev code)
@@ -1577,6 +1800,21 @@ _start:
 	.byte	0
 	.byte	0
 	.uleb128 0xd	# (abbrev code)
+	.uleb128 0x34	# (TAG: DW_TAG_variable)
+	.byte	0	# DW_children_no
+	.uleb128 0x3	# (DW_AT_name)
+	.uleb128 0x8	# (DW_FORM_string)
+	.uleb128 0x3a	# (DW_AT_decl_file)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x3b	# (DW_AT_decl_line)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.uleb128 0x49	# (DW_AT_type)
+	.uleb128 0x13	# (DW_FORM_ref4)
+	.uleb128 0x1c	# (DW_AT_const_value)
+	.uleb128 0xb	# (DW_FORM_data1)
+	.byte	0
+	.byte	0
+	.uleb128 0xe	# (abbrev code)
 	.uleb128 0x2e	# (TAG: DW_TAG_subprogram)
 	.byte	0x1	# DW_children_yes
 	.uleb128 0x3f	# (DW_AT_external)
@@ -1601,34 +1839,38 @@ _start:
 	.byte	0
 	.byte	0
 	.section	.debug_pubnames,"",@progbits
-	.long	0x42	# Length of Public Names Info
+	.long	0x49	# Length of Public Names Info
 	.value	0x2	# DWARF Version
 	.long	.Ldebug_info0	# Offset of Compilation Unit Info
-	.long	0x1e7	# Compilation Unit Length
-	.long	0x78	# DIE offset
+	.long	0x256	# Compilation Unit Length
+	.long	0xa7	# DIE offset
 	.ascii "bar\0"	# external name
-	.long	0x9e	# DIE offset
+	.long	0xcd	# DIE offset
 	.ascii "f1\0"	# external name
-	.long	0xd4	# DIE offset
+	.long	0x103	# DIE offset
 	.ascii "f2\0"	# external name
-	.long	0x11d	# DIE offset
+	.long	0x14c	# DIE offset
 	.ascii "f3\0"	# external name
-	.long	0x153	# DIE offset
+	.long	0x182	# DIE offset
 	.ascii "f4\0"	# external name
-	.long	0x189	# DIE offset
+	.long	0x1b8	# DIE offset
 	.ascii "f5\0"	# external name
-	.long	0x1bf	# DIE offset
+	.long	0x1ee	# DIE offset
+	.ascii "f6\0"	# external name
+	.long	0x22e	# DIE offset
 	.ascii "main\0"	# external name
 	.long	0
 	.section	.debug_pubtypes,"",@progbits
-	.long	0x1a	# Length of Public Type Names Info
+	.long	0x20	# Length of Public Type Names Info
 	.value	0x2	# DWARF Version
 	.long	.Ldebug_info0	# Offset of Compilation Unit Info
-	.long	0x1e7	# Compilation Unit Length
+	.long	0x256	# Compilation Unit Length
 	.long	0x25	# DIE offset
 	.ascii "A\0"	# external name
 	.long	0x4f	# DIE offset
 	.ascii "B\0"	# external name
+	.long	0x78	# DIE offset
+	.ascii "C\0"	# external name
 	.long	0
 	.section	.debug_aranges,"",@progbits
 	.long	0x1c	# Length of Address Ranges Info
@@ -1645,10 +1887,10 @@ _start:
 	.section	.debug_str,"MS",@progbits,1
 .LASF2:
 	.string	"pieces.c"
+.LASF3:
+	.string	"/home/tromey/gnu/archer/archer/gdb/testsuite/gdb.dwarf2"
 .LASF1:
 	.string	"GNU C 4.6.0 20100506 (experimental) [trunk revision 159117]"
-.LASF3:
-	.string	"/home/tromey/gnu/PRS/rh589467"
 .LASF0:
 	.string	"main"
 	.ident	"GCC: (GNU) 4.6.0 20100506 (experimental) [trunk revision 159117]"
diff --git a/gdb/testsuite/gdb.dwarf2/pieces.c b/gdb/testsuite/gdb.dwarf2/pieces.c
index 07fae64..2736f9f 100644
--- a/gdb/testsuite/gdb.dwarf2/pieces.c
+++ b/gdb/testsuite/gdb.dwarf2/pieces.c
@@ -4,6 +4,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)
@@ -66,6 +67,18 @@ f5 (int k)
   return a.i + a.j;
 }
 
+__attribute__((noinline)) int
+f6 (int k)
+{
+  int z = 23;
+  struct C a = { k, k, z};
+  asm ("" : "+r" (a.i));
+  a.j++;
+  bar (a.i);		/* { dg-final { gdb-test 20 "a.i" "4" } } */
+  bar (a.j);		/* { dg-final { gdb-test 20 "a.j" "14" } } */
+  return a.i + a.j;
+}
+
 int
 main (void)
 {
@@ -76,5 +89,6 @@ main (void)
   f3 (k);
   f4 (k);
   f5 (k);
+  f6 (k);
   return 0;
 }
diff --git a/gdb/testsuite/gdb.dwarf2/pieces.exp b/gdb/testsuite/gdb.dwarf2/pieces.exp
index e6c1431..3ec67d4 100644
--- a/gdb/testsuite/gdb.dwarf2/pieces.exp
+++ b/gdb/testsuite/gdb.dwarf2/pieces.exp
@@ -68,5 +68,26 @@ 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 {} {
+    gdb_test "break pieces.c:79" "Breakpoint 4.*" \
+       "set third breakpoint for pieces"
+    gdb_continue_to_breakpoint "third continue to breakpoint for pieces"
+    gdb_test "print a" \
+	"warning: some bits 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]