gdb
authorTom Tromey <tromey@redhat.com>
Fri, 21 May 2010 20:39:50 +0000 (20:39 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 21 May 2010 20:39:50 +0000 (20:39 +0000)
* dwarf2loc.c (read_pieced_value): Work properly when 'v' has an
offset.
(write_pieced_value): Likewise.
gdb/testsuite
* gdb.dwarf2.pieces.exp: New file.
* gdb.dwarf2.pieces.S: New file.
* gdb.dwarf2.pieces.c: New file.

gdb/ChangeLog
gdb/dwarf2loc.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.dwarf2/pieces.S [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/pieces.c [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/pieces.exp [new file with mode: 0644]

index 0751599..b701354 100644 (file)
@@ -1,3 +1,9 @@
+2010-05-21  Tom Tromey  <tromey@redhat.com>
+
+       * dwarf2loc.c (read_pieced_value): Work properly when 'v' has an
+       offset.
+       (write_pieced_value): Likewise.
+
 2010-05-21  Pierre Muller  <muller@ics.u-strasbg.fr>
 
        * dwarf2read.c (process_die): Also allow DW_TAG_const_type
index c137b97..f40be6c 100644 (file)
@@ -264,14 +264,46 @@ read_pieced_value (struct value *v)
 {
   int i;
   long offset = 0;
+  ULONGEST bytes_to_skip;
   gdb_byte *contents;
   struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
   struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (v));
+  size_t type_len;
+
+  if (value_type (v) != value_enclosing_type (v))
+    internal_error (__FILE__, __LINE__,
+                   _("Should not be able to create a lazy value with "
+                     "an enclosing type"));
 
   contents = value_contents_raw (v);
-  for (i = 0; i < c->n_pieces; i++)
+  bytes_to_skip = value_offset (v);
+  type_len = TYPE_LENGTH (value_type (v));
+  for (i = 0; i < c->n_pieces && offset < type_len; i++)
     {
       struct dwarf_expr_piece *p = &c->pieces[i];
+      size_t this_size;
+      long dest_offset, source_offset;
+
+      if (bytes_to_skip > 0 && bytes_to_skip >= p->size)
+       {
+         bytes_to_skip -= p->size;
+         continue;
+       }
+      this_size = p->size;
+      if (this_size > type_len - offset)
+       this_size = type_len - offset;
+      if (bytes_to_skip > 0)
+       {
+         dest_offset = 0;
+         source_offset = bytes_to_skip;
+         this_size -= bytes_to_skip;
+         bytes_to_skip = 0;
+       }
+      else
+       {
+         dest_offset = offset;
+         source_offset = 0;
+       }
 
       switch (p->location)
        {
@@ -280,17 +312,17 @@ read_pieced_value (struct value *v)
            struct gdbarch *arch = get_frame_arch (frame);
            int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch,
                                                           p->v.expr.value);
-           int reg_offset = 0;
+           int reg_offset = source_offset;
 
            if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
-               && p->size < register_size (arch, gdb_regnum))
+               && this_size < register_size (arch, gdb_regnum))
              /* Big-endian, and we want less than full size.  */
-             reg_offset = register_size (arch, gdb_regnum) - p->size;
+             reg_offset = register_size (arch, gdb_regnum) - this_size;
 
            if (gdb_regnum != -1)
              {
                get_frame_register_bytes (frame, gdb_regnum, reg_offset, 
-                                         p->size, contents + offset);
+                                         this_size, contents + dest_offset);
              }
            else
              {
@@ -302,38 +334,60 @@ read_pieced_value (struct value *v)
 
        case DWARF_VALUE_MEMORY:
          if (p->v.expr.in_stack_memory)
-           read_stack (p->v.expr.value, contents + offset, p->size);
+           read_stack (p->v.expr.value + source_offset,
+                       contents + dest_offset, this_size);
          else
-           read_memory (p->v.expr.value, contents + offset, p->size);
+           read_memory (p->v.expr.value + source_offset,
+                        contents + dest_offset, this_size);
          break;
 
        case DWARF_VALUE_STACK:
          {
            struct gdbarch *gdbarch = get_type_arch (value_type (v));
-           size_t n = p->size;
+           size_t n = this_size;
 
-           if (n > c->addr_size)
-             n = c->addr_size;
-           store_unsigned_integer (contents + offset, n,
-                                   gdbarch_byte_order (gdbarch),
-                                   p->v.expr.value);
+           if (n > c->addr_size - source_offset)
+             n = (c->addr_size >= source_offset
+                  ? c->addr_size - source_offset
+                  : 0);
+           if (n == 0)
+             {
+               /* Nothing.  */
+             }
+           else if (source_offset == 0)
+             store_unsigned_integer (contents + dest_offset, n,
+                                     gdbarch_byte_order (gdbarch),
+                                     p->v.expr.value);
+           else
+             {
+               gdb_byte bytes[sizeof (ULONGEST)];
+
+               store_unsigned_integer (bytes, n + source_offset,
+                                       gdbarch_byte_order (gdbarch),
+                                       p->v.expr.value);
+               memcpy (contents + dest_offset, bytes + source_offset, n);
+             }
          }
          break;
 
        case DWARF_VALUE_LITERAL:
          {
-           size_t n = p->size;
-
-           if (n > p->v.literal.length)
-             n = p->v.literal.length;
-           memcpy (contents + offset, p->v.literal.data, n);
+           size_t n = this_size;
+
+           if (n > p->v.literal.length - source_offset)
+             n = (p->v.literal.length >= source_offset
+                  ? p->v.literal.length - source_offset
+                  : 0);
+           if (n != 0)
+             memcpy (contents + dest_offset,
+                     p->v.literal.data + source_offset, n);
          }
          break;
 
        default:
          internal_error (__FILE__, __LINE__, _("invalid location type"));
        }
-      offset += p->size;
+      offset += this_size;
     }
 }
 
@@ -342,9 +396,11 @@ write_pieced_value (struct value *to, struct value *from)
 {
   int i;
   long offset = 0;
-  gdb_byte *contents;
+  ULONGEST bytes_to_skip;
+  const gdb_byte *contents;
   struct piece_closure *c = (struct piece_closure *) value_computed_closure (to);
   struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (to));
+  size_t type_len;
 
   if (frame == NULL)
     {
@@ -352,10 +408,35 @@ write_pieced_value (struct value *to, struct value *from)
       return;
     }
 
-  contents = value_contents_raw (from);
-  for (i = 0; i < c->n_pieces; i++)
+  contents = value_contents (from);
+  bytes_to_skip = value_offset (to);
+  type_len = TYPE_LENGTH (value_type (to));
+  for (i = 0; i < c->n_pieces && offset < type_len; i++)
     {
       struct dwarf_expr_piece *p = &c->pieces[i];
+      size_t this_size;
+      long dest_offset, source_offset;
+
+      if (bytes_to_skip > 0 && bytes_to_skip >= p->size)
+       {
+         bytes_to_skip -= p->size;
+         continue;
+       }
+      this_size = p->size;
+      if (this_size > type_len - offset)
+       this_size = type_len - offset;
+      if (bytes_to_skip > 0)
+       {
+         dest_offset = bytes_to_skip;
+         source_offset = 0;
+         this_size -= bytes_to_skip;
+         bytes_to_skip = 0;
+       }
+      else
+       {
+         dest_offset = 0;
+         source_offset = offset;
+       }
 
       switch (p->location)
        {
@@ -363,17 +444,17 @@ write_pieced_value (struct value *to, struct value *from)
          {
            struct gdbarch *arch = get_frame_arch (frame);
            int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.expr.value);
-           int reg_offset = 0;
+           int reg_offset = dest_offset;
 
            if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
-               && p->size < register_size (arch, gdb_regnum))
+               && this_size <= register_size (arch, gdb_regnum))
              /* Big-endian, and we want less than full size.  */
-             reg_offset = register_size (arch, gdb_regnum) - p->size;
+             reg_offset = register_size (arch, gdb_regnum) - this_size;
 
            if (gdb_regnum != -1)
              {
                put_frame_register_bytes (frame, gdb_regnum, reg_offset, 
-                                         p->size, contents + offset);
+                                         this_size, contents + source_offset);
              }
            else
              {
@@ -383,13 +464,14 @@ write_pieced_value (struct value *to, struct value *from)
          }
          break;
        case DWARF_VALUE_MEMORY:
-         write_memory (p->v.expr.value, contents + offset, p->size);
+         write_memory (p->v.expr.value + dest_offset,
+                       contents + source_offset, this_size);
          break;
        default:
          set_value_optimized_out (to, 1);
          return;
        }
-      offset += p->size;
+      offset += this_size;
     }
 }
 
index 93df121..304334d 100644 (file)
@@ -1,3 +1,9 @@
+2010-05-21  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.dwarf2.pieces.exp: New file.
+       * gdb.dwarf2.pieces.S: New file.
+       * gdb.dwarf2.pieces.c: New file.
+
 2010-05-20  Pedro Alves  <pedro@codesourcery.com>
             Joel Brobecker  <brobecker@adacore.com>
 
diff --git a/gdb/testsuite/gdb.dwarf2/pieces.S b/gdb/testsuite/gdb.dwarf2/pieces.S
new file mode 100644 (file)
index 0000000..d6791c1
--- /dev/null
@@ -0,0 +1,1655 @@
+/*
+   Copyright 2010 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This was compiled with a version of gcc modified to emit better
+   debuginfo for SRA'd structures.  See:
+       http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43983
+       
+    The original program is "pieces.c", in this directory.
+*/
+
+       .file   "pieces.c"
+       .section        .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+       .section        .debug_info,"",@progbits
+.Ldebug_info0:
+       .section        .debug_line,"",@progbits
+.Ldebug_line0:
+       .text
+.Ltext0:
+       .p2align 4,,15
+.globl bar
+       .type   bar, @function
+bar:
+.LFB0:
+       .file 1 "pieces.c"
+       # pieces.c:28
+       .loc 1 28 0
+.LVL0:
+       # basic block 2
+       pushl   %ebp
+.LCFI0:
+       movl    %esp, %ebp
+.LCFI1:
+       # pieces.c:29
+       .loc 1 29 0
+       movl    8(%ebp), %eax
+       # pieces.c:30
+       .loc 1 30 0
+       popl    %ebp
+.LCFI2:
+       ret
+.LFE0:
+       .size   bar, .-bar
+       .p2align 4,,15
+.globl f1
+       .type   f1, @function
+f1:
+.LFB1:
+       # pieces.c:34
+       .loc 1 34 0
+.LVL1:
+       # basic block 2
+       pushl   %ebp
+.LCFI3:
+       movl    %esp, %ebp
+.LCFI4:
+.LVL2:
+       subl    $12, %esp
+.LCFI5:
+       movl    %esi, -4(%ebp)
+.LCFI6:
+       # pieces.c:37
+       .loc 1 37 0
+       movl    8(%ebp), %esi
+       # pieces.c:34
+       .loc 1 34 0
+       movl    %ebx, -8(%ebp)
+.LCFI7:
+       # pieces.c:36
+       .loc 1 36 0
+       movl    $4, %ebx
+.LVL3:
+       # pieces.c:38
+       .loc 1 38 0
+       movl    %ebx, (%esp)
+       # pieces.c:37
+       .loc 1 37 0
+       addl    $7, %esi
+.LVL4:
+       # pieces.c:38
+       .loc 1 38 0
+       call    bar
+       # pieces.c:39
+       .loc 1 39 0
+       movl    %esi, (%esp)
+       call    bar
+       # pieces.c:40
+       .loc 1 40 0
+       leal    (%ebx,%esi), %eax
+       # pieces.c:41
+       .loc 1 41 0
+       movl    -8(%ebp), %ebx
+.LVL5:
+       movl    -4(%ebp), %esi
+.LVL6:
+       movl    %ebp, %esp
+.LCFI8:
+       popl    %ebp
+.LCFI9:
+       ret
+.LFE1:
+       .size   f1, .-f1
+       .p2align 4,,15
+.globl f2
+       .type   f2, @function
+f2:
+.LFB2:
+       # pieces.c:45
+       .loc 1 45 0
+.LVL7:
+       # basic block 2
+       pushl   %ebp
+.LCFI10:
+       movl    %esp, %ebp
+.LCFI11:
+.LVL8:
+       subl    $12, %esp
+.LCFI12:
+       movl    %esi, -4(%ebp)
+.LCFI13:
+       # pieces.c:48
+       .loc 1 48 0
+       movl    8(%ebp), %esi
+       # pieces.c:45
+       .loc 1 45 0
+       movl    %ebx, -8(%ebp)
+.LCFI14:
+       # pieces.c:47
+       .loc 1 47 0
+       movl    $4, %ebx
+.LVL9:
+       # pieces.c:49
+       .loc 1 49 0
+       movl    %ebx, (%esp)
+       # pieces.c:48
+       .loc 1 48 0
+       addl    $7, %esi
+.LVL10:
+       # pieces.c:49
+       .loc 1 49 0
+       call    bar
+       # pieces.c:50
+       .loc 1 50 0
+       movl    %esi, (%esp)
+       call    bar
+       # pieces.c:51
+       .loc 1 51 0
+       leal    (%ebx,%esi), %eax
+       # pieces.c:52
+       .loc 1 52 0
+       movl    -8(%ebp), %ebx
+.LVL11:
+       movl    -4(%ebp), %esi
+.LVL12:
+       movl    %ebp, %esp
+.LCFI15:
+       popl    %ebp
+.LCFI16:
+       ret
+.LFE2:
+       .size   f2, .-f2
+       .p2align 4,,15
+.globl f3
+       .type   f3, @function
+f3:
+.LFB3:
+       # pieces.c:56
+       .loc 1 56 0
+.LVL13:
+       # basic block 2
+       pushl   %ebp
+.LCFI17:
+       # pieces.c:58
+       .loc 1 58 0
+       movl    $4, %edx
+       # pieces.c:56
+       .loc 1 56 0
+       movl    %esp, %ebp
+.LCFI18:
+.LVL14:
+       subl    $12, %esp
+.LCFI19:
+       # pieces.c:58
+       .loc 1 58 0
+.LVL15:
+       # pieces.c:56
+       .loc 1 56 0
+       movl    %esi, -4(%ebp)
+.LCFI20:
+       # pieces.c:60
+       .loc 1 60 0
+       movswl  %dx, %esi
+       # pieces.c:56
+       .loc 1 56 0
+       movl    %ebx, -8(%ebp)
+.LCFI21:
+       # pieces.c:60
+       .loc 1 60 0
+       movl    %esi, (%esp)
+       call    bar
+.LVL16:
+       # pieces.c:57
+       .loc 1 57 0
+       movl    8(%ebp), %edx
+       sall    $4, %edx
+       # pieces.c:59
+       .loc 1 59 0
+       addl    $112, %edx
+       sarw    $4, %dx
+       # pieces.c:61
+       .loc 1 61 0
+       movswl  %dx, %ebx
+       movl    %ebx, (%esp)
+       call    bar
+       # pieces.c:62
+       .loc 1 62 0
+       leal    (%esi,%ebx), %eax
+       # pieces.c:63
+       .loc 1 63 0
+       movl    -8(%ebp), %ebx
+       movl    -4(%ebp), %esi
+.LVL17:
+       movl    %ebp, %esp
+.LCFI22:
+       popl    %ebp
+.LCFI23:
+       ret
+.LFE3:
+       .size   f3, .-f3
+       .p2align 4,,15
+.globl f4
+       .type   f4, @function
+f4:
+.LFB4:
+       # pieces.c:67
+       .loc 1 67 0
+.LVL18:
+       # basic block 2
+       pushl   %ebp
+.LCFI24:
+       movl    %esp, %ebp
+.LCFI25:
+       subl    $12, %esp
+.LCFI26:
+       movl    %esi, -4(%ebp)
+.LCFI27:
+       movl    8(%ebp), %esi
+.LVL19:
+       movl    %ebx, -8(%ebp)
+.LCFI28:
+       # pieces.c:69
+       .loc 1 69 0
+       movl    %esi, %ebx
+       # pieces.c:70
+       .loc 1 70 0
+       addl    $1, %esi
+       # pieces.c:69
+       .loc 1 69 0
+.LVL20:
+       # pieces.c:71
+       .loc 1 71 0
+       movl    %ebx, (%esp)
+       call    bar
+       # pieces.c:72
+       .loc 1 72 0
+       movl    %esi, (%esp)
+       call    bar
+       # pieces.c:73
+       .loc 1 73 0
+       leal    (%ebx,%esi), %eax
+       # pieces.c:74
+       .loc 1 74 0
+       movl    -8(%ebp), %ebx
+.LVL21:
+       movl    -4(%ebp), %esi
+.LVL22:
+       movl    %ebp, %esp
+.LCFI29:
+       popl    %ebp
+.LCFI30:
+       ret
+.LFE4:
+       .size   f4, .-f4
+       .p2align 4,,15
+.globl f5
+       .type   f5, @function
+f5:
+.LFB5:
+       # pieces.c:78
+       .loc 1 78 0
+.LVL23:
+       # basic block 2
+       pushl   %ebp
+.LCFI31:
+       movl    %esp, %ebp
+.LCFI32:
+       subl    $12, %esp
+.LCFI33:
+       movl    %esi, -4(%ebp)
+.LCFI34:
+       movl    8(%ebp), %esi
+.LVL24:
+       movl    %ebx, -8(%ebp)
+.LCFI35:
+       # pieces.c:80
+       .loc 1 80 0
+       movl    %esi, %ebx
+       # pieces.c:81
+       .loc 1 81 0
+       addl    $1, %esi
+       # pieces.c:80
+       .loc 1 80 0
+.LVL25:
+       # pieces.c:82
+       .loc 1 82 0
+       movl    %ebx, (%esp)
+       call    bar
+       # pieces.c:83
+       .loc 1 83 0
+       movl    %esi, (%esp)
+       call    bar
+       # pieces.c:84
+       .loc 1 84 0
+       leal    (%ebx,%esi), %eax
+       # pieces.c:85
+       .loc 1 85 0
+       movl    -8(%ebp), %ebx
+.LVL26:
+       movl    -4(%ebp), %esi
+.LVL27:
+       movl    %ebp, %esp
+.LCFI36:
+       popl    %ebp
+.LCFI37:
+       ret
+.LFE5:
+       .size   f5, .-f5
+       .p2align 4,,15
+.globl main
+       .type   main, @function
+main:
+.LFB6:
+       # pieces.c:89
+       .loc 1 89 0
+       # basic block 2
+       pushl   %ebp
+.LCFI38:
+       movl    %esp, %ebp
+.LCFI39:
+       pushl   %ebx
+.LCFI40:
+       # pieces.c:91
+       .loc 1 91 0
+       movl    $7, %ebx
+       # pieces.c:89
+       .loc 1 89 0
+       subl    $4, %esp
+.LCFI41:
+       # pieces.c:91
+       .loc 1 91 0
+.LVL28:
+       # pieces.c:92
+       .loc 1 92 0
+       movl    %ebx, (%esp)
+       call    f1
+       # pieces.c:93
+       .loc 1 93 0
+       movl    %ebx, (%esp)
+       call    f2
+       # pieces.c:94
+       .loc 1 94 0
+       movl    %ebx, (%esp)
+       call    f3
+       # pieces.c:95
+       .loc 1 95 0
+       movl    %ebx, (%esp)
+       call    f4
+       # pieces.c:96
+       .loc 1 96 0
+       movl    %ebx, (%esp)
+       call    f5
+       # pieces.c:98
+       .loc 1 98 0
+       addl    $4, %esp
+       xorl    %eax, %eax
+       popl    %ebx
+.LCFI42:
+.LVL29:
+       popl    %ebp
+.LCFI43:
+       ret
+.LFE6:
+       .size   main, .-main
+#APP
+       .section        .debug_frame,"",@progbits
+.Lframe0:
+       .long   .LECIE0-.LSCIE0 # Length of Common Information Entry
+.LSCIE0:
+       .long   0xffffffff      # CIE Identifier Tag
+       .byte   0x1     # CIE Version
+       .ascii "\0"     # CIE Augmentation
+       .uleb128 0x1    # CIE Code Alignment Factor
+       .sleb128 -4     # CIE Data Alignment Factor
+       .byte   0x8     # CIE RA Column
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x4
+       .uleb128 0x4
+       .byte   0x88    # DW_CFA_offset, column 0x8
+       .uleb128 0x1
+       .align 4
+.LECIE0:
+.LSFDE0:
+       .long   .LEFDE0-.LASFDE0        # FDE Length
+.LASFDE0:
+       .long   .Lframe0        # FDE CIE offset
+       .long   .LFB0   # FDE initial location
+       .long   .LFE0-.LFB0     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI0-.LFB0
+       .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   .LCFI1-.LCFI0
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x5
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI2-.LCFI1
+       .byte   0xc5    # DW_CFA_restore, column 0x5
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x4
+       .uleb128 0x4
+       .align 4
+.LEFDE0:
+.LSFDE2:
+       .long   .LEFDE2-.LASFDE2        # FDE Length
+.LASFDE2:
+       .long   .Lframe0        # FDE CIE offset
+       .long   .LFB1   # FDE initial location
+       .long   .LFE1-.LFB1     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI3-.LFB1
+       .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   .LCFI4-.LCFI3
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x5
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI6-.LCFI4
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x3
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI7-.LCFI6
+       .byte   0x83    # DW_CFA_offset, column 0x3
+       .uleb128 0x4
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI8-.LCFI7
+       .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   .LCFI9-.LCFI8
+       .byte   0xc5    # DW_CFA_restore, column 0x5
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x4
+       .align 4
+.LEFDE2:
+.LSFDE4:
+       .long   .LEFDE4-.LASFDE4        # FDE Length
+.LASFDE4:
+       .long   .Lframe0        # FDE CIE offset
+       .long   .LFB2   # FDE initial location
+       .long   .LFE2-.LFB2     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI10-.LFB2
+       .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   .LCFI11-.LCFI10
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x5
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI13-.LCFI11
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x3
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI14-.LCFI13
+       .byte   0x83    # DW_CFA_offset, column 0x3
+       .uleb128 0x4
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI15-.LCFI14
+       .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   .LCFI16-.LCFI15
+       .byte   0xc5    # DW_CFA_restore, column 0x5
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x4
+       .align 4
+.LEFDE4:
+.LSFDE6:
+       .long   .LEFDE6-.LASFDE6        # FDE Length
+.LASFDE6:
+       .long   .Lframe0        # FDE CIE offset
+       .long   .LFB3   # FDE initial location
+       .long   .LFE3-.LFB3     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI17-.LFB3
+       .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   .LCFI18-.LCFI17
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x5
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI20-.LCFI18
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x3
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI21-.LCFI20
+       .byte   0x83    # DW_CFA_offset, column 0x3
+       .uleb128 0x4
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI22-.LCFI21
+       .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   .LCFI23-.LCFI22
+       .byte   0xc5    # DW_CFA_restore, column 0x5
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x4
+       .align 4
+.LEFDE6:
+.LSFDE8:
+       .long   .LEFDE8-.LASFDE8        # FDE Length
+.LASFDE8:
+       .long   .Lframe0        # FDE CIE offset
+       .long   .LFB4   # FDE initial location
+       .long   .LFE4-.LFB4     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI24-.LFB4
+       .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   .LCFI25-.LCFI24
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x5
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI27-.LCFI25
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x3
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI28-.LCFI27
+       .byte   0x83    # DW_CFA_offset, column 0x3
+       .uleb128 0x4
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI29-.LCFI28
+       .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   .LCFI30-.LCFI29
+       .byte   0xc5    # DW_CFA_restore, column 0x5
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x4
+       .align 4
+.LEFDE8:
+.LSFDE10:
+       .long   .LEFDE10-.LASFDE10      # FDE Length
+.LASFDE10:
+       .long   .Lframe0        # FDE CIE offset
+       .long   .LFB5   # FDE initial location
+       .long   .LFE5-.LFB5     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI31-.LFB5
+       .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   .LCFI32-.LCFI31
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x5
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI34-.LCFI32
+       .byte   0x86    # DW_CFA_offset, column 0x6
+       .uleb128 0x3
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI35-.LCFI34
+       .byte   0x83    # DW_CFA_offset, column 0x3
+       .uleb128 0x4
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI36-.LCFI35
+       .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   .LCFI37-.LCFI36
+       .byte   0xc5    # DW_CFA_restore, column 0x5
+       .byte   0xe     # DW_CFA_def_cfa_offset
+       .uleb128 0x4
+       .align 4
+.LEFDE10:
+.LSFDE12:
+       .long   .LEFDE12-.LASFDE12      # FDE Length
+.LASFDE12:
+       .long   .Lframe0        # FDE CIE offset
+       .long   .LFB6   # FDE initial location
+       .long   .LFE6-.LFB6     # FDE address range
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI38-.LFB6
+       .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   .LCFI39-.LCFI38
+       .byte   0xd     # DW_CFA_def_cfa_register
+       .uleb128 0x5
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI40-.LCFI39
+       .byte   0x83    # DW_CFA_offset, column 0x3
+       .uleb128 0x3
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI42-.LCFI40
+       .byte   0xc3    # DW_CFA_restore, column 0x3
+       .byte   0x4     # DW_CFA_advance_loc4
+       .long   .LCFI43-.LCFI42
+       .byte   0xc5    # DW_CFA_restore, column 0x5
+       .byte   0xc     # DW_CFA_def_cfa
+       .uleb128 0x4
+       .uleb128 0x4
+       .align 4
+.LEFDE12:
+#NO_APP
+       .text
+.Letext0:
+       .section        .debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+       .long   .LFB0-.Ltext0   # Location list begin address (*.LLST0)
+       .long   .LCFI0-.Ltext0  # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   .LCFI0-.Ltext0  # Location list begin address (*.LLST0)
+       .long   .LCFI1-.Ltext0  # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI1-.Ltext0  # Location list begin address (*.LLST0)
+       .long   .LCFI2-.Ltext0  # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x75    # DW_OP_breg5
+       .sleb128 8
+       .long   .LCFI2-.Ltext0  # Location list begin address (*.LLST0)
+       .long   .LFE0-.Ltext0   # Location list end address (*.LLST0)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   0       # Location list terminator begin (*.LLST0)
+       .long   0       # Location list terminator end (*.LLST0)
+.LLST1:
+       .long   .LFB1-.Ltext0   # Location list begin address (*.LLST1)
+       .long   .LCFI3-.Ltext0  # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   .LCFI3-.Ltext0  # Location list begin address (*.LLST1)
+       .long   .LCFI4-.Ltext0  # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI4-.Ltext0  # Location list begin address (*.LLST1)
+       .long   .LCFI8-.Ltext0  # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x75    # DW_OP_breg5
+       .sleb128 8
+       .long   .LCFI8-.Ltext0  # Location list begin address (*.LLST1)
+       .long   .LCFI9-.Ltext0  # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI9-.Ltext0  # Location list begin address (*.LLST1)
+       .long   .LFE1-.Ltext0   # Location list end address (*.LLST1)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   0       # Location list terminator begin (*.LLST1)
+       .long   0       # Location list terminator end (*.LLST1)
+.LLST2:
+       .long   .LVL1-.Ltext0   # Location list begin address (*.LLST2)
+       .long   .LVL2-.Ltext0   # Location list end address (*.LLST2)
+       .value  0x6     # Location expression size
+       .byte   0x34    # DW_OP_lit4
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   .LVL2-.Ltext0   # Location list begin address (*.LLST2)
+       .long   .LVL3-.Ltext0   # Location list end address (*.LLST2)
+       .value  0xc     # Location expression size
+       .byte   0x34    # DW_OP_lit4
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 0
+       .byte   0x6     # DW_OP_deref
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x6
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   .LVL3-.Ltext0   # Location list begin address (*.LLST2)
+       .long   .LVL4-.Ltext0   # Location list end address (*.LLST2)
+       .value  0xb     # Location expression size
+       .byte   0x53    # DW_OP_reg3
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 0
+       .byte   0x6     # DW_OP_deref
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x6
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   .LVL4-.Ltext0   # Location list begin address (*.LLST2)
+       .long   .LVL5-.Ltext0   # Location list end address (*.LLST2)
+       .value  0x6     # 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
+       .long   .LVL5-.Ltext0   # Location list begin address (*.LLST2)
+       .long   .LVL6-.Ltext0   # Location list end address (*.LLST2)
+       .value  0x5     # Location expression size
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x56    # DW_OP_reg6
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   0       # Location list terminator begin (*.LLST2)
+       .long   0       # Location list terminator end (*.LLST2)
+.LLST3:
+       .long   .LFB2-.Ltext0   # Location list begin address (*.LLST3)
+       .long   .LCFI10-.Ltext0 # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   .LCFI10-.Ltext0 # Location list begin address (*.LLST3)
+       .long   .LCFI11-.Ltext0 # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI11-.Ltext0 # Location list begin address (*.LLST3)
+       .long   .LCFI15-.Ltext0 # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x75    # DW_OP_breg5
+       .sleb128 8
+       .long   .LCFI15-.Ltext0 # Location list begin address (*.LLST3)
+       .long   .LCFI16-.Ltext0 # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI16-.Ltext0 # Location list begin address (*.LLST3)
+       .long   .LFE2-.Ltext0   # Location list end address (*.LLST3)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   0       # Location list terminator begin (*.LLST3)
+       .long   0       # Location list terminator end (*.LLST3)
+.LLST4:
+       .long   .LVL7-.Ltext0   # Location list begin address (*.LLST4)
+       .long   .LVL8-.Ltext0   # Location list end address (*.LLST4)
+       .value  0x6     # Location expression size
+       .byte   0x34    # DW_OP_lit4
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   .LVL8-.Ltext0   # Location list begin address (*.LLST4)
+       .long   .LVL9-.Ltext0   # Location list end address (*.LLST4)
+       .value  0xc     # Location expression size
+       .byte   0x34    # DW_OP_lit4
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 0
+       .byte   0x6     # DW_OP_deref
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x6
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   .LVL9-.Ltext0   # Location list begin address (*.LLST4)
+       .long   .LVL10-.Ltext0  # Location list end address (*.LLST4)
+       .value  0xb     # Location expression size
+       .byte   0x53    # DW_OP_reg3
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 0
+       .byte   0x6     # DW_OP_deref
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x6
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   .LVL10-.Ltext0  # Location list begin address (*.LLST4)
+       .long   .LVL11-.Ltext0  # Location list end address (*.LLST4)
+       .value  0x6     # 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
+       .long   .LVL11-.Ltext0  # Location list begin address (*.LLST4)
+       .long   .LVL12-.Ltext0  # Location list end address (*.LLST4)
+       .value  0x5     # Location expression size
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x56    # DW_OP_reg6
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   0       # Location list terminator begin (*.LLST4)
+       .long   0       # Location list terminator end (*.LLST4)
+.LLST5:
+       .long   .LFB3-.Ltext0   # Location list begin address (*.LLST5)
+       .long   .LCFI17-.Ltext0 # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   .LCFI17-.Ltext0 # Location list begin address (*.LLST5)
+       .long   .LCFI18-.Ltext0 # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI18-.Ltext0 # Location list begin address (*.LLST5)
+       .long   .LCFI22-.Ltext0 # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x75    # DW_OP_breg5
+       .sleb128 8
+       .long   .LCFI22-.Ltext0 # Location list begin address (*.LLST5)
+       .long   .LCFI23-.Ltext0 # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI23-.Ltext0 # Location list begin address (*.LLST5)
+       .long   .LFE3-.Ltext0   # Location list end address (*.LLST5)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   0       # Location list terminator begin (*.LLST5)
+       .long   0       # Location list terminator end (*.LLST5)
+.LLST6:
+       .long   .LVL13-.Ltext0  # Location list begin address (*.LLST6)
+       .long   .LVL14-.Ltext0  # Location list end address (*.LLST6)
+       .value  0xa     # Location expression size
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0x4
+       .uleb128 0
+       .byte   0x34    # DW_OP_lit4
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0xc
+       .uleb128 0
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x2
+       .long   .LVL14-.Ltext0  # Location list begin address (*.LLST6)
+       .long   .LVL15-.Ltext0  # Location list end address (*.LLST6)
+       .value  0x15    # Location expression size
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0x4
+       .uleb128 0
+       .byte   0x34    # DW_OP_lit4
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0xc
+       .uleb128 0
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 0
+       .byte   0x94    # DW_OP_deref_size
+       .byte   0x2
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x6
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0xc
+       .uleb128 0
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0x4
+       .uleb128 0
+       .long   .LVL15-.Ltext0  # Location list begin address (*.LLST6)
+       .long   .LVL16-1-.Ltext0        # Location list end address (*.LLST6)
+       .value  0x14    # Location expression size
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0x4
+       .uleb128 0
+       .byte   0x52    # DW_OP_reg2
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0xc
+       .uleb128 0
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 0
+       .byte   0x94    # DW_OP_deref_size
+       .byte   0x2
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x7
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0xc
+       .uleb128 0
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0x4
+       .uleb128 0
+       .long   .LVL16-1-.Ltext0        # Location list begin address (*.LLST6)
+       .long   .LVL17-.Ltext0  # Location list end address (*.LLST6)
+       .value  0x14    # Location expression size
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0x4
+       .uleb128 0
+       .byte   0x56    # DW_OP_reg6
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0xc
+       .uleb128 0
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 0
+       .byte   0x94    # DW_OP_deref_size
+       .byte   0x2
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x7
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0xc
+       .uleb128 0
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0x4
+       .uleb128 0
+       .long   .LVL17-.Ltext0  # Location list begin address (*.LLST6)
+       .long   .LFE3-.Ltext0   # Location list end address (*.LLST6)
+       .value  0xf     # Location expression size
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x2
+       .byte   0x91    # DW_OP_fbreg
+       .sleb128 0
+       .byte   0x94    # DW_OP_deref_size
+       .byte   0x2
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x7
+       .byte   0x9f    # DW_OP_stack_value
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0xc
+       .uleb128 0
+       .byte   0x9d    # DW_OP_bit_piece
+       .uleb128 0x4
+       .uleb128 0
+       .long   0       # Location list terminator begin (*.LLST6)
+       .long   0       # Location list terminator end (*.LLST6)
+.LLST7:
+       .long   .LFB4-.Ltext0   # Location list begin address (*.LLST7)
+       .long   .LCFI24-.Ltext0 # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   .LCFI24-.Ltext0 # Location list begin address (*.LLST7)
+       .long   .LCFI25-.Ltext0 # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI25-.Ltext0 # Location list begin address (*.LLST7)
+       .long   .LCFI29-.Ltext0 # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x75    # DW_OP_breg5
+       .sleb128 8
+       .long   .LCFI29-.Ltext0 # Location list begin address (*.LLST7)
+       .long   .LCFI30-.Ltext0 # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI30-.Ltext0 # Location list begin address (*.LLST7)
+       .long   .LFE4-.Ltext0   # Location list end address (*.LLST7)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   0       # Location list terminator begin (*.LLST7)
+       .long   0       # Location list terminator end (*.LLST7)
+.LLST8:
+       .long   .LVL19-.Ltext0  # Location list begin address (*.LLST8)
+       .long   .LVL20-.Ltext0  # Location list end address (*.LLST8)
+       .value  0x8     # 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
+       .long   .LVL20-.Ltext0  # Location list begin address (*.LLST8)
+       .long   .LVL21-.Ltext0  # Location list end address (*.LLST8)
+       .value  0x6     # 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
+       .long   .LVL21-.Ltext0  # Location list begin address (*.LLST8)
+       .long   .LVL22-.Ltext0  # Location list end address (*.LLST8)
+       .value  0x5     # Location expression size
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x56    # DW_OP_reg6
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   0       # Location list terminator begin (*.LLST8)
+       .long   0       # Location list terminator end (*.LLST8)
+.LLST9:
+       .long   .LFB5-.Ltext0   # Location list begin address (*.LLST9)
+       .long   .LCFI31-.Ltext0 # Location list end address (*.LLST9)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   .LCFI31-.Ltext0 # Location list begin address (*.LLST9)
+       .long   .LCFI32-.Ltext0 # Location list end address (*.LLST9)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI32-.Ltext0 # Location list begin address (*.LLST9)
+       .long   .LCFI36-.Ltext0 # Location list end address (*.LLST9)
+       .value  0x2     # Location expression size
+       .byte   0x75    # DW_OP_breg5
+       .sleb128 8
+       .long   .LCFI36-.Ltext0 # Location list begin address (*.LLST9)
+       .long   .LCFI37-.Ltext0 # Location list end address (*.LLST9)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI37-.Ltext0 # Location list begin address (*.LLST9)
+       .long   .LFE5-.Ltext0   # Location list end address (*.LLST9)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   0       # Location list terminator begin (*.LLST9)
+       .long   0       # Location list terminator end (*.LLST9)
+.LLST10:
+       .long   .LVL24-.Ltext0  # Location list begin address (*.LLST10)
+       .long   .LVL25-.Ltext0  # Location list end address (*.LLST10)
+       .value  0x8     # 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
+       .long   .LVL25-.Ltext0  # Location list begin address (*.LLST10)
+       .long   .LVL26-.Ltext0  # Location list end address (*.LLST10)
+       .value  0x6     # 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
+       .long   .LVL26-.Ltext0  # Location list begin address (*.LLST10)
+       .long   .LVL27-.Ltext0  # Location list end address (*.LLST10)
+       .value  0x5     # Location expression size
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .byte   0x56    # DW_OP_reg6
+       .byte   0x93    # DW_OP_piece
+       .uleb128 0x4
+       .long   0       # Location list terminator begin (*.LLST10)
+       .long   0       # Location list terminator end (*.LLST10)
+.LLST11:
+       .long   .LFB6-.Ltext0   # Location list begin address (*.LLST11)
+       .long   .LCFI38-.Ltext0 # Location list end address (*.LLST11)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .long   .LCFI38-.Ltext0 # Location list begin address (*.LLST11)
+       .long   .LCFI39-.Ltext0 # Location list end address (*.LLST11)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 8
+       .long   .LCFI39-.Ltext0 # Location list begin address (*.LLST11)
+       .long   .LCFI43-.Ltext0 # Location list end address (*.LLST11)
+       .value  0x2     # Location expression size
+       .byte   0x75    # DW_OP_breg5
+       .sleb128 8
+       .long   .LCFI43-.Ltext0 # Location list begin address (*.LLST11)
+       .long   .LFE6-.Ltext0   # Location list end address (*.LLST11)
+       .value  0x2     # Location expression size
+       .byte   0x74    # DW_OP_breg4
+       .sleb128 4
+       .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
+       .byte   0x53    # DW_OP_reg3
+       .long   0       # Location list terminator begin (*.LLST12)
+       .long   0       # Location list terminator end (*.LLST12)
+       .section        .debug_info
+       .long   0x1e3   # Length of Compilation Unit Info
+       .value  0x2     # DWARF version number
+       .long   .Ldebug_abbrev0 # Offset Into Abbrev. Section
+       .byte   0x4     # Pointer Size (in bytes)
+       .uleb128 0x1    # (DIE (0xb) DW_TAG_compile_unit)
+       .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/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
+       .uleb128 0x2    # (DIE (0x25) DW_TAG_structure_type)
+       .ascii "A\0"    # DW_AT_name
+       .byte   0x8     # DW_AT_byte_size
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x17    # DW_AT_decl_line
+       .long   0x48    # DW_AT_sibling
+       .uleb128 0x3    # (DIE (0x2f) DW_TAG_member)
+       .ascii "i\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x17    # 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 (0x3b) DW_TAG_member)
+       .ascii "j\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x17    # DW_AT_decl_line
+       .long   0x48    # DW_AT_type
+       .byte   0x2     # DW_AT_data_member_location
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0x4
+       .byte   0       # end of children of DIE 0x25
+       .uleb128 0x4    # (DIE (0x48) DW_TAG_base_type)
+       .byte   0x4     # DW_AT_byte_size
+       .byte   0x5     # DW_AT_encoding
+       .ascii "int\0"  # DW_AT_name
+       .uleb128 0x2    # (DIE (0x4f) DW_TAG_structure_type)
+       .ascii "B\0"    # DW_AT_name
+       .byte   0x4     # DW_AT_byte_size
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x18    # DW_AT_decl_line
+       .long   0x78    # DW_AT_sibling
+       .uleb128 0x5    # (DIE (0x59) DW_TAG_member)
+       .ascii "i\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x18    # DW_AT_decl_line
+       .long   0x48    # DW_AT_type
+       .byte   0x4     # DW_AT_byte_size
+       .byte   0xc     # DW_AT_bit_size
+       .byte   0x10    # DW_AT_bit_offset
+       .byte   0x2     # DW_AT_data_member_location
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0
+       .uleb128 0x5    # (DIE (0x68) DW_TAG_member)
+       .ascii "j\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x18    # DW_AT_decl_line
+       .long   0x48    # DW_AT_type
+       .byte   0x4     # DW_AT_byte_size
+       .byte   0xc     # DW_AT_bit_size
+       .byte   0x4     # DW_AT_bit_offset
+       .byte   0x2     # DW_AT_data_member_location
+       .byte   0x23    # DW_OP_plus_uconst
+       .uleb128 0
+       .byte   0       # end of children of DIE 0x4f
+       .uleb128 0x6    # (DIE (0x78) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .ascii "bar\0"  # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x1b    # 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)
+       .ascii "x\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x1b    # 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   0x1     # DW_AT_external
+       .ascii "f1\0"   # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x21    # 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)
+       .ascii "k\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x21    # 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)
+       .ascii "a\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x23    # 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   0x1     # DW_AT_external
+       .ascii "f2\0"   # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x2c    # 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)
+       .ascii "k\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x2c    # 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)
+       .ascii "a\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x2e    # DW_AT_decl_line
+       .long   0x10a   # DW_AT_type
+       .long   .LLST4  # DW_AT_location
+       .byte   0       # end of children of DIE 0xd4
+       .uleb128 0xa    # (DIE (0x10a) 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
+       .byte   0x1     # DW_AT_upper_bound
+       .byte   0       # end of children of DIE 0x10a
+       .uleb128 0xc    # (DIE (0x11a) DW_TAG_base_type)
+       .byte   0x4     # DW_AT_byte_size
+       .byte   0x7     # DW_AT_encoding
+       .uleb128 0x8    # (DIE (0x11d) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .ascii "f3\0"   # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x37    # 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)
+       .ascii "k\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x37    # 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)
+       .ascii "a\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x39    # 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   0x1     # DW_AT_external
+       .ascii "f4\0"   # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x42    # 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)
+       .ascii "k\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x42    # 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)
+       .ascii "a\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x44    # DW_AT_decl_line
+       .long   0x10a   # DW_AT_type
+       .long   .LLST8  # DW_AT_location
+       .byte   0       # end of children of DIE 0x153
+       .uleb128 0x8    # (DIE (0x189) DW_TAG_subprogram)
+       .byte   0x1     # DW_AT_external
+       .ascii "f5\0"   # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x4d    # 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)
+       .ascii "k\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x4d    # 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)
+       .ascii "a\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x4f    # 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   0x1     # DW_AT_external
+       .long   .LASF0  # DW_AT_name: "main"
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x58    # 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)
+       .ascii "k\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (pieces.c)
+       .byte   0x5a    # DW_AT_decl_line
+       .long   0x48    # DW_AT_type
+       .long   .LLST12 # DW_AT_location
+       .byte   0       # end of children of DIE 0x1bf
+       .byte   0       # end of children of DIE 0xb
+       .section        .debug_abbrev
+       .uleb128 0x1    # (abbrev code)
+       .uleb128 0x11   # (TAG: DW_TAG_compile_unit)
+       .byte   0x1     # DW_children_yes
+       .uleb128 0x25   # (DW_AT_producer)
+       .uleb128 0xe    # (DW_FORM_strp)
+       .uleb128 0x13   # (DW_AT_language)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x3    # (DW_AT_name)
+       .uleb128 0xe    # (DW_FORM_strp)
+       .uleb128 0x1b   # (DW_AT_comp_dir)
+       .uleb128 0xe    # (DW_FORM_strp)
+       .uleb128 0x11   # (DW_AT_low_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x12   # (DW_AT_high_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x10   # (DW_AT_stmt_list)
+       .uleb128 0x6    # (DW_FORM_data4)
+       .byte   0
+       .byte   0
+       .uleb128 0x2    # (abbrev code)
+       .uleb128 0x13   # (TAG: DW_TAG_structure_type)
+       .byte   0x1     # DW_children_yes
+       .uleb128 0x3    # (DW_AT_name)
+       .uleb128 0x8    # (DW_FORM_string)
+       .uleb128 0xb    # (DW_AT_byte_size)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x3a   # (DW_AT_decl_file)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x3b   # (DW_AT_decl_line)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x1    # (DW_AT_sibling)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .uleb128 0x3    # (abbrev code)
+       .uleb128 0xd    # (TAG: DW_TAG_member)
+       .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 0x38   # (DW_AT_data_member_location)
+       .uleb128 0xa    # (DW_FORM_block1)
+       .byte   0
+       .byte   0
+       .uleb128 0x4    # (abbrev code)
+       .uleb128 0x24   # (TAG: DW_TAG_base_type)
+       .byte   0       # DW_children_no
+       .uleb128 0xb    # (DW_AT_byte_size)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x3e   # (DW_AT_encoding)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x3    # (DW_AT_name)
+       .uleb128 0x8    # (DW_FORM_string)
+       .byte   0
+       .byte   0
+       .uleb128 0x5    # (abbrev code)
+       .uleb128 0xd    # (TAG: DW_TAG_member)
+       .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 0xb    # (DW_AT_byte_size)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0xd    # (DW_AT_bit_size)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0xc    # (DW_AT_bit_offset)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x38   # (DW_AT_data_member_location)
+       .uleb128 0xa    # (DW_FORM_block1)
+       .byte   0
+       .byte   0
+       .uleb128 0x6    # (abbrev code)
+       .uleb128 0x2e   # (TAG: DW_TAG_subprogram)
+       .byte   0x1     # DW_children_yes
+       .uleb128 0x3f   # (DW_AT_external)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .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 0x27   # (DW_AT_prototyped)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .uleb128 0x11   # (DW_AT_low_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x12   # (DW_AT_high_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x40   # (DW_AT_frame_base)
+       .uleb128 0x6    # (DW_FORM_data4)
+       .uleb128 0x1    # (DW_AT_sibling)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .uleb128 0x7    # (abbrev code)
+       .uleb128 0x5    # (TAG: DW_TAG_formal_parameter)
+       .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 0x2    # (DW_AT_location)
+       .uleb128 0xa    # (DW_FORM_block1)
+       .byte   0
+       .byte   0
+       .uleb128 0x8    # (abbrev code)
+       .uleb128 0x2e   # (TAG: DW_TAG_subprogram)
+       .byte   0x1     # DW_children_yes
+       .uleb128 0x3f   # (DW_AT_external)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .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 0x27   # (DW_AT_prototyped)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .uleb128 0x11   # (DW_AT_low_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x12   # (DW_AT_high_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x40   # (DW_AT_frame_base)
+       .uleb128 0x6    # (DW_FORM_data4)
+       .uleb128 0x1    # (DW_AT_sibling)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .uleb128 0x9    # (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 0x2    # (DW_AT_location)
+       .uleb128 0x6    # (DW_FORM_data4)
+       .byte   0
+       .byte   0
+       .uleb128 0xa    # (abbrev code)
+       .uleb128 0x1    # (TAG: DW_TAG_array_type)
+       .byte   0x1     # DW_children_yes
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .uleb128 0x1    # (DW_AT_sibling)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .byte   0
+       .byte   0
+       .uleb128 0xb    # (abbrev code)
+       .uleb128 0x21   # (TAG: DW_TAG_subrange_type)
+       .byte   0       # DW_children_no
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .uleb128 0x2f   # (DW_AT_upper_bound)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .byte   0
+       .byte   0
+       .uleb128 0xc    # (abbrev code)
+       .uleb128 0x24   # (TAG: DW_TAG_base_type)
+       .byte   0       # DW_children_no
+       .uleb128 0xb    # (DW_AT_byte_size)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x3e   # (DW_AT_encoding)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .byte   0
+       .byte   0
+       .uleb128 0xd    # (abbrev code)
+       .uleb128 0x2e   # (TAG: DW_TAG_subprogram)
+       .byte   0x1     # DW_children_yes
+       .uleb128 0x3f   # (DW_AT_external)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .uleb128 0x3    # (DW_AT_name)
+       .uleb128 0xe    # (DW_FORM_strp)
+       .uleb128 0x3a   # (DW_AT_decl_file)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x3b   # (DW_AT_decl_line)
+       .uleb128 0xb    # (DW_FORM_data1)
+       .uleb128 0x27   # (DW_AT_prototyped)
+       .uleb128 0xc    # (DW_FORM_flag)
+       .uleb128 0x49   # (DW_AT_type)
+       .uleb128 0x13   # (DW_FORM_ref4)
+       .uleb128 0x11   # (DW_AT_low_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x12   # (DW_AT_high_pc)
+       .uleb128 0x1    # (DW_FORM_addr)
+       .uleb128 0x40   # (DW_AT_frame_base)
+       .uleb128 0x6    # (DW_FORM_data4)
+       .byte   0
+       .byte   0
+       .byte   0
+       .section        .debug_pubnames,"",@progbits
+       .long   0x42    # 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
+       .ascii "bar\0"  # external name
+       .long   0x9e    # DIE offset
+       .ascii "f1\0"   # external name
+       .long   0xd4    # DIE offset
+       .ascii "f2\0"   # external name
+       .long   0x11d   # DIE offset
+       .ascii "f3\0"   # external name
+       .long   0x153   # DIE offset
+       .ascii "f4\0"   # external name
+       .long   0x189   # DIE offset
+       .ascii "f5\0"   # external name
+       .long   0x1bf   # DIE offset
+       .ascii "main\0" # external name
+       .long   0
+       .section        .debug_pubtypes,"",@progbits
+       .long   0x1a    # Length of Public Type Names Info
+       .value  0x2     # DWARF Version
+       .long   .Ldebug_info0   # Offset of Compilation Unit Info
+       .long   0x1e7   # Compilation Unit Length
+       .long   0x25    # DIE offset
+       .ascii "A\0"    # external name
+       .long   0x4f    # DIE offset
+       .ascii "B\0"    # external name
+       .long   0
+       .section        .debug_aranges,"",@progbits
+       .long   0x1c    # Length of Address Ranges Info
+       .value  0x2     # DWARF Version
+       .long   .Ldebug_info0   # Offset of Compilation Unit Info
+       .byte   0x4     # Size of Address
+       .byte   0       # Size of Segment Descriptor
+       .value  0       # Pad to 8 byte boundary
+       .value  0
+       .long   .Ltext0 # Address
+       .long   .Letext0-.Ltext0        # Length
+       .long   0
+       .long   0
+       .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]"
+.LASF0:
+       .string "main"
+       .ident  "GCC: (GNU) 4.6.0 20100506 (experimental) [trunk revision 159117]"
+       .section        .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/pieces.c b/gdb/testsuite/gdb.dwarf2/pieces.c
new file mode 100644 (file)
index 0000000..49028b0
--- /dev/null
@@ -0,0 +1,98 @@
+/* Copyright (C) 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* The original program corresponding to pieces.S.
+   This came from https://bugzilla.redhat.com/show_bug.cgi?id=589467
+   Note that it is not ever compiled, pieces.S is used instead.
+   However, it is used to extract breakpoint line numbers.  */
+
+struct A { int i; int j; };
+struct B { int : 4; int i : 12; int j : 12; int : 4; };
+
+__attribute__((noinline)) void
+bar (int x)
+{
+  asm volatile ("" : : "r" (x) : "memory");
+}
+
+__attribute__((noinline)) int
+f1 (int k)
+{
+  struct A a = { 4, k + 6 };
+  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;    /* f1 breakpoint */
+}
+
+__attribute__((noinline)) int
+f2 (int k)
+{
+  int a[2] = { 4, k + 6 };
+  asm ("" : "+r" (a[0]));
+  a[1]++;
+  bar (a[0]);          /* { dg-final { gdb-test 31 "a\[0\]" "4" } } */
+  bar (a[1]);          /* { dg-final { gdb-test 31 "a\[1\]" "14" } } */
+  return a[0] + a[1];  /* f2 breakpoint */
+}
+
+__attribute__((noinline)) int
+f3 (int k)
+{
+  struct B a = { 4, k + 6 };
+  asm ("" : "+r" (a.i));
+  a.j++;
+  bar (a.i);           /* { dg-final { gdb-test 42 "a.i" "4" } } */
+  bar (a.j);           /* { dg-final { gdb-test 42 "a.j" "14" } } */
+  return a.i + a.j;    /* f3 breakpoint */
+}
+
+__attribute__((noinline)) int
+f4 (int k)
+{
+  int a[2] = { k, k };
+  asm ("" : "+r" (a[0]));
+  a[1]++;
+  bar (a[0]);
+  bar (a[1]);
+  return a[0] + a[1];          /* f4 breakpoint */
+}
+
+__attribute__((noinline)) int
+f5 (int k)
+{
+  struct A a = { k, k };
+  asm ("" : "+r" (a.i));
+  a.j++;
+  bar (a.i);
+  bar (a.j);
+  return a.i + a.j;            /* f5 breakpoint */
+}
+
+int
+main (void)
+{
+  int k;
+  asm ("" : "=r" (k) : "0" (7));
+  f1 (k);
+  f2 (k);
+  f3 (k);
+  f4 (k);
+  f5 (k);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/pieces.exp b/gdb/testsuite/gdb.dwarf2/pieces.exp
new file mode 100644 (file)
index 0000000..bdac582
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test some DWARF piece operators.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+    && ![istarget *-*-gnu*]
+    && ![istarget *-*-elf*]
+    && ![istarget *-*-openbsd*]
+    && ![istarget arm-*-eabi*]
+    && ![istarget powerpc-*-eabi*]} {
+    return 0  
+}
+# This test can only be run on x86 targets.
+if {![istarget i?86-*]} {
+    return 0  
+}
+
+set testfile "pieces"
+set srcfile ${testfile}.S
+set csrcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}.x
+
+if {[prepare_for_testing ${testfile}.exp ${testfile}.x $srcfile]} {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+# Function f1 tests a particular gdb bug involving DW_OP_piece.
+proc pieces_test_f1 {} {
+    global csrcfile
+    set line [gdb_get_line_number "f1 breakpoint" $csrcfile]
+    gdb_test "break pieces.c:$line" "Breakpoint 2.*" \
+       "set f1 breakpoint for pieces"
+    gdb_continue_to_breakpoint "continue to f1 breakpoint for pieces"
+    gdb_test "print a" " = {i = 4, j = 14}" "print a in pieces:f1"
+    gdb_test "print a.j" " = 14" "print a.j in pieces:f1"
+}
+
+pieces_test_f1