[patch 2/2] Fix decode_locdesc for gcc-4.7.x optimized DWARF

Jan Kratochvil jan.kratochvil@redhat.com
Wed Jul 27 16:22:00 GMT 2011


Hi,

with gcc-4.7.x GDB can no longer determine struct field offset.

gcc-4.6.x: (with FSF default -gdwarf-2)
 <2><42>: Abbrev Number: 3 (DW_TAG_member)
    <43>   DW_AT_name        : b        
[...]
    <4b>   DW_AT_data_member_location: 5 byte block: 23 80 80 80 8      (DW_OP_plus_uconst: 16777216)

gcc-4.7.x: (with FSF default -gdwarf-2)
 <2><32>: Abbrev Number: 3 (DW_TAG_member)
    <33>   DW_AT_name        : b        
[...]
    <3b>   DW_AT_data_member_location: 4 byte block: 40 44 24 22        (DW_OP_lit16; DW_OP_lit20; DW_OP_shl; DW_OP_plus)

But GDB decode_locdesc cannot decode DW_OP_shl.

There is decode_locdesc_read_mem workaround which is ugly, but it was already
there in a different form.  The same may be needed for
DW_OP_GNU_push_tls_address but I haven't such a regression in the testsuite,
DW_OP_GNU_push_tls_address is more for archer-jankratochvil-vla anyway.

The right fix would be dynamic types with DWARF blocks for various type
fields.

This change no longer supports bfd_get_sign_extend_vma / signed_addr_p for
DW_OP_addr.  But neither does dwarf2expr.c so I guess it is not a concern.

No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu.
The fix is minus 140 LoC difference.


Thanks,
Jan


gdb/
2011-07-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* dwarf2expr.c (ctx_no_read_reg): New function.
	* dwarf2expr.h (ctx_no_read_reg): New declaration.
	* dwarf2read.c (read_2_signed_bytes, read_4_signed_bytes): Remove.
	(decode_locdesc_read_mem, decode_locdesc_ctx_funcs): New.
	(decode_locdesc): Replace by a caller of dwarf_expr_eval.

gdb/testsuite/
2011-07-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.dwarf2/dw2-simple-locdesc.S: New file.
	* gdb.dwarf2/dw2-simple-locdesc.exp: New file.
	* gdb.dwarf2/dw2-stack-boundary.exp (check partial symtab errors):
	Change the expected string.

--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -1280,6 +1280,14 @@ abort_expression:
   gdb_assert (ctx->recursion_depth >= 0);
 }
 
+/* Stub dwarf_expr_context_funcs.read_reg implementation.  */
+
+CORE_ADDR
+ctx_no_read_reg (void *baton, int regnum)
+{
+  error (_("Registers access is invalid in this context"));
+}
+
 /* Stub dwarf_expr_context_funcs.get_frame_base implementation.  */
 
 void
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -255,6 +255,7 @@ void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *,
 
 /* Stub dwarf_expr_context_funcs implementations.  */
 
+CORE_ADDR ctx_no_read_reg (void *baton, int regnum);
 void ctx_no_get_frame_base (void *baton, const gdb_byte **start,
 			    size_t *length);
 CORE_ADDR ctx_no_get_frame_cfa (void *baton);
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -10058,24 +10058,12 @@ read_2_bytes (bfd *abfd, gdb_byte *buf)
   return bfd_get_16 (abfd, buf);
 }
 
-static int
-read_2_signed_bytes (bfd *abfd, gdb_byte *buf)
-{
-  return bfd_get_signed_16 (abfd, buf);
-}
-
 static unsigned int
 read_4_bytes (bfd *abfd, gdb_byte *buf)
 {
   return bfd_get_32 (abfd, buf);
 }
 
-static int
-read_4_signed_bytes (bfd *abfd, gdb_byte *buf)
-{
-  return bfd_get_signed_32 (abfd, buf);
-}
-
 static ULONGEST
 read_8_bytes (bfd *abfd, gdb_byte *buf)
 {
@@ -14150,6 +14138,37 @@ read_signatured_type (struct objfile *objfile,
   dwarf2_per_objfile->read_in_chain = &type_sig->per_cu;
 }
 
+/* Workaround as dwarf_expr_context_funcs.read_mem implementation before
+   a proper runtime DWARF expressions evaluator gets implemented.
+   Otherwise gnuv3_baseclass_offset would error by:
+   Expected a negative vbase offset (old compiler?)  */
+
+static void
+decode_locdesc_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr,
+			 size_t length)
+{
+  struct dwarf_expr_context *ctx = baton;
+  struct gdbarch *gdbarch = ctx->gdbarch;
+  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+
+  memset (buf, 0, length);
+
+  if (TYPE_LENGTH (ptr_type) == length)
+    store_typed_address (buf, ptr_type, addr);
+}
+
+static const struct dwarf_expr_context_funcs decode_locdesc_ctx_funcs =
+{
+  ctx_no_read_reg,
+  decode_locdesc_read_mem,
+  ctx_no_get_frame_base,
+  ctx_no_get_frame_cfa,
+  ctx_no_get_frame_pc,
+  ctx_no_get_tls_address,
+  ctx_no_dwarf_call,
+  ctx_no_get_base_type
+};
+
 /* Decode simple location descriptions.
    Given a pointer to a dwarf block that defines a location, compute
    the location and return the value.
@@ -14175,227 +14194,50 @@ static CORE_ADDR
 decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
-  int i;
-  int size = blk->size;
-  gdb_byte *data = blk->data;
-  CORE_ADDR stack[64];
-  int stacki;
-  unsigned int bytes_read, unsnd;
-  gdb_byte op;
+  struct dwarf_expr_context *ctx;
+  struct cleanup *old_chain;
+  volatile struct gdb_exception ex;
 
-  i = 0;
-  stacki = 0;
-  stack[stacki] = 0;
-  stack[++stacki] = 0;
+  ctx = new_dwarf_expr_context ();
+  old_chain = make_cleanup_free_dwarf_expr_context (ctx);
+  make_cleanup_value_free_to_mark (value_mark ());
 
-  while (i < size)
-    {
-      op = data[i++];
-      switch (op)
-	{
-	case DW_OP_lit0:
-	case DW_OP_lit1:
-	case DW_OP_lit2:
-	case DW_OP_lit3:
-	case DW_OP_lit4:
-	case DW_OP_lit5:
-	case DW_OP_lit6:
-	case DW_OP_lit7:
-	case DW_OP_lit8:
-	case DW_OP_lit9:
-	case DW_OP_lit10:
-	case DW_OP_lit11:
-	case DW_OP_lit12:
-	case DW_OP_lit13:
-	case DW_OP_lit14:
-	case DW_OP_lit15:
-	case DW_OP_lit16:
-	case DW_OP_lit17:
-	case DW_OP_lit18:
-	case DW_OP_lit19:
-	case DW_OP_lit20:
-	case DW_OP_lit21:
-	case DW_OP_lit22:
-	case DW_OP_lit23:
-	case DW_OP_lit24:
-	case DW_OP_lit25:
-	case DW_OP_lit26:
-	case DW_OP_lit27:
-	case DW_OP_lit28:
-	case DW_OP_lit29:
-	case DW_OP_lit30:
-	case DW_OP_lit31:
-	  stack[++stacki] = op - DW_OP_lit0;
-	  break;
-
-	case DW_OP_reg0:
-	case DW_OP_reg1:
-	case DW_OP_reg2:
-	case DW_OP_reg3:
-	case DW_OP_reg4:
-	case DW_OP_reg5:
-	case DW_OP_reg6:
-	case DW_OP_reg7:
-	case DW_OP_reg8:
-	case DW_OP_reg9:
-	case DW_OP_reg10:
-	case DW_OP_reg11:
-	case DW_OP_reg12:
-	case DW_OP_reg13:
-	case DW_OP_reg14:
-	case DW_OP_reg15:
-	case DW_OP_reg16:
-	case DW_OP_reg17:
-	case DW_OP_reg18:
-	case DW_OP_reg19:
-	case DW_OP_reg20:
-	case DW_OP_reg21:
-	case DW_OP_reg22:
-	case DW_OP_reg23:
-	case DW_OP_reg24:
-	case DW_OP_reg25:
-	case DW_OP_reg26:
-	case DW_OP_reg27:
-	case DW_OP_reg28:
-	case DW_OP_reg29:
-	case DW_OP_reg30:
-	case DW_OP_reg31:
-	  stack[++stacki] = op - DW_OP_reg0;
-	  if (i < size)
-	    dwarf2_complex_location_expr_complaint ();
-	  break;
+  ctx->gdbarch = get_objfile_arch (objfile);
+  ctx->addr_size = cu->header.addr_size;
+  ctx->offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+  ctx->baton = ctx;
+  ctx->funcs = &decode_locdesc_ctx_funcs;
 
-	case DW_OP_regx:
-	  unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
-	  i += bytes_read;
-	  stack[++stacki] = unsnd;
-	  if (i < size)
-	    dwarf2_complex_location_expr_complaint ();
-	  break;
+  /* DW_AT_data_member_location expects the structure address to be pushed on
+     the stack.  Simulate the offset by address 0.  */
+  dwarf_expr_push_address (ctx, 0, 0);
 
-	case DW_OP_addr:
-	  stack[++stacki] = read_address (objfile->obfd, &data[i],
-					  cu, &bytes_read);
-	  i += bytes_read;
-	  break;
-
-	case DW_OP_const1u:
-	  stack[++stacki] = read_1_byte (objfile->obfd, &data[i]);
-	  i += 1;
-	  break;
-
-	case DW_OP_const1s:
-	  stack[++stacki] = read_1_signed_byte (objfile->obfd, &data[i]);
-	  i += 1;
-	  break;
-
-	case DW_OP_const2u:
-	  stack[++stacki] = read_2_bytes (objfile->obfd, &data[i]);
-	  i += 2;
-	  break;
-
-	case DW_OP_const2s:
-	  stack[++stacki] = read_2_signed_bytes (objfile->obfd, &data[i]);
-	  i += 2;
-	  break;
-
-	case DW_OP_const4u:
-	  stack[++stacki] = read_4_bytes (objfile->obfd, &data[i]);
-	  i += 4;
-	  break;
-
-	case DW_OP_const4s:
-	  stack[++stacki] = read_4_signed_bytes (objfile->obfd, &data[i]);
-	  i += 4;
-	  break;
-
-	case DW_OP_constu:
-	  stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
-						  &bytes_read);
-	  i += bytes_read;
-	  break;
-
-	case DW_OP_consts:
-	  stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
-	  i += bytes_read;
-	  break;
-
-	case DW_OP_dup:
-	  stack[stacki + 1] = stack[stacki];
-	  stacki++;
-	  break;
-
-	case DW_OP_plus:
-	  stack[stacki - 1] += stack[stacki];
-	  stacki--;
-	  break;
-
-	case DW_OP_plus_uconst:
-	  stack[stacki] += read_unsigned_leb128 (NULL, (data + i),
-						 &bytes_read);
-	  i += bytes_read;
-	  break;
-
-	case DW_OP_minus:
-	  stack[stacki - 1] -= stack[stacki];
-	  stacki--;
-	  break;
-
-	case DW_OP_deref:
-	  /* If we're not the last op, then we definitely can't encode
-	     this using GDB's address_class enum.  This is valid for partial
-	     global symbols, although the variable's address will be bogus
-	     in the psymtab.  */
-	  if (i < size)
-	    dwarf2_complex_location_expr_complaint ();
-	  break;
-
-        case DW_OP_GNU_push_tls_address:
-	  /* The top of the stack has the offset from the beginning
-	     of the thread control block at which the variable is located.  */
-	  /* Nothing should follow this operator, so the top of stack would
-	     be returned.  */
-	  /* This is valid for partial global symbols, but the variable's
-	     address will be bogus in the psymtab.  */
-	  if (i < size)
-	    dwarf2_complex_location_expr_complaint ();
-          break;
-
-	case DW_OP_GNU_uninit:
-	  break;
-
-	default:
-	  {
-	    const char *name = dwarf_stack_op_name (op);
-
-	    if (name)
-	      complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
-			 name);
-	    else
-	      complaint (&symfile_complaints, _("unsupported stack op: '%02x'"),
-			 op);
-	  }
-
-	  return (stack[stacki]);
-	}
-
-      /* Enforce maximum stack depth of SIZE-1 to avoid writing
-         outside of the allocated space.  Also enforce minimum>0.  */
-      if (stacki >= ARRAY_SIZE (stack) - 1)
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      dwarf_expr_eval (ctx, blk->data, blk->size);
+    }
+  if (ex.reason < 0)
+    {
+      if (ex.message)
+	complaint (&symfile_complaints, "%s", ex.message);
+    }
+  else if (ctx->num_pieces == 0)
+    switch (ctx->location)
+      {
+      case DWARF_VALUE_REGISTER:
+      case DWARF_VALUE_MEMORY:
+      case DWARF_VALUE_STACK:
 	{
-	  complaint (&symfile_complaints,
-		     _("location description stack overflow"));
-	  return 0;
-	}
+	  CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
 
-      if (stacki <= 0)
-	{
-	  complaint (&symfile_complaints,
-		     _("location description stack underflow"));
-	  return 0;
+	  do_cleanups (old_chain);
+	  return address;
 	}
-    }
-  return (stack[stacki]);
+      }
+
+  do_cleanups (old_chain);
+  dwarf2_complex_location_expr_complaint ();
+  return 0;
 }
 
 /* memory allocation interface */
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S
@@ -0,0 +1,201 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 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 source file was generated by:
+   echo 'struct s { char a[1<<24]; int b; } s;' \
+   | gcc -dA -o dw2-simple-locdesc.S -S -gdwarf-2 -x c -
+   */
+	.text
+var:
+
+	.section	.debug_info
+.Ldebug_info0:
+d:
+	.4byte	.Lcu_end - 1f	/* Length of Compilation Unit Info */
+1:
+	.value	0x2	/* DWARF version number */
+	.4byte	.Ldebug_abbrev0	/* Offset Into Abbrev. Section */
+	.byte	0x4	/* Pointer Size (in bytes) */
+	.uleb128 0x1	/* (DIE (0xb) DW_TAG_compile_unit) */
+	.4byte	.LASF2	/* DW_AT_producer: "GNU C 4.7.0 20110727 (experimental)" */
+	.byte	0x1	/* DW_AT_language */
+.Ldie19:
+	.uleb128 0x2	/* (DIE (0x19) DW_TAG_structure_type) */
+	.ascii "s\0"	/* DW_AT_name */
+	.4byte	0x1000004	/* DW_AT_byte_size */
+	.byte	0x1	/* DW_AT_decl_file (<stdin>) */
+	.byte	0x1	/* DW_AT_decl_line */
+.Ldie26:
+	.uleb128 0x3	/* (DIE (0x26) DW_TAG_member) */
+	.ascii "a\0"	/* DW_AT_name */
+	.byte	0x1	/* DW_AT_decl_file (<stdin>) */
+	.byte	0x1	/* DW_AT_decl_line */
+	.4byte	.Ldie41 - d	/* DW_AT_type */
+	.byte	0x2	/* DW_AT_data_member_location */
+	.byte	0x23	/* DW_OP_plus_uconst */
+	.uleb128 0
+.Ldie32:
+	.uleb128 0x3	/* (DIE (0x32) DW_TAG_member) */
+	.ascii "b\0"	/* DW_AT_name */
+	.byte	0x1	/* DW_AT_decl_file (<stdin>) */
+	.byte	0x1	/* DW_AT_decl_line */
+	.4byte	.Ldie62 - d	/* DW_AT_type */
+	.byte	0x4	/* DW_AT_data_member_location */
+	.byte	0x40	/* DW_OP_lit16 */
+	.byte	0x44	/* DW_OP_lit20 */
+	.byte	0x24	/* DW_OP_shl */
+	.byte	0x22	/* DW_OP_plus */
+	.byte	0	/* end of children of DIE 0x19 */
+.Ldie41:
+	.uleb128 0x4	/* (DIE (0x41) DW_TAG_array_type) */
+	.4byte	.Ldie5b - d	/* DW_AT_type */
+.Ldie4a:
+	.uleb128 0x5	/* (DIE (0x4a) DW_TAG_subrange_type) */
+	.4byte	.Ldie54 - d	/* DW_AT_type */
+	.4byte	0xffffff	/* DW_AT_upper_bound */
+	.byte	0	/* end of children of DIE 0x41 */
+.Ldie54:
+	.uleb128 0x6	/* (DIE (0x54) DW_TAG_base_type) */
+	.byte	0x8	/* DW_AT_byte_size */
+	.byte	0x7	/* DW_AT_encoding */
+	.4byte	.LASF0	/* DW_AT_name: "sizetype" */
+.Ldie5b:
+	.uleb128 0x6	/* (DIE (0x5b) DW_TAG_base_type) */
+	.byte	0x1	/* DW_AT_byte_size */
+	.byte	0x6	/* DW_AT_encoding */
+	.4byte	.LASF1	/* DW_AT_name: "char" */
+.Ldie62:
+	.uleb128 0x7	/* (DIE (0x62) DW_TAG_base_type) */
+	.byte	0x4	/* DW_AT_byte_size */
+	.byte	0x5	/* DW_AT_encoding */
+	.ascii "int\0"	/* DW_AT_name */
+.Ldie69:
+	.uleb128 0x8	/* (DIE (0x69) DW_TAG_variable) */
+	.ascii "s\0"	/* DW_AT_name */
+	.byte	0x1	/* DW_AT_decl_file (<stdin>) */
+	.byte	0x1	/* DW_AT_decl_line */
+	.4byte	.Ldie19 - d	/* DW_AT_type */
+	.byte	0x1	/* DW_AT_external */
+	.byte	2f - 1f	/* DW_AT_location */
+1:
+	.byte	0x3	/* DW_OP_addr */
+	.4byte	var
+2:
+	.byte	0	/* end of children of DIE 0xb */
+.Lcu_end:
+	.section	.debug_abbrev
+.Ldebug_abbrev0:
+	.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) */
+	.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 0x6	/* (DW_FORM_data4) */
+	.uleb128 0x3a	/* (DW_AT_decl_file) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.uleb128 0x3b	/* (DW_AT_decl_line) */
+	.uleb128 0xb	/* (DW_FORM_data1) */
+	.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 0x1	/* (TAG: DW_TAG_array_type) */
+	.byte	0x1	/* DW_children_yes */
+	.uleb128 0x49	/* (DW_AT_type) */
+	.uleb128 0x13	/* (DW_FORM_ref4) */
+	.byte	0
+	.byte	0
+	.uleb128 0x5	/* (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 0x6	/* (DW_FORM_data4) */
+	.byte	0
+	.byte	0
+	.uleb128 0x6	/* (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 0xe	/* (DW_FORM_strp) */
+	.byte	0
+	.byte	0
+	.uleb128 0x7	/* (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 0x8	/* (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 0x3f	/* (DW_AT_external) */
+	.uleb128 0xc	/* (DW_FORM_flag) */
+	.uleb128 0x2	/* (DW_AT_location) */
+	.uleb128 0xa	/* (DW_FORM_block1) */
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_str
+.LASF2:
+	.string	"GNU C 4.7.0 20110727 (experimental)"
+.LASF0:
+	.string	"sizetype"
+.LASF1:
+	.string	"char"
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.exp
@@ -0,0 +1,33 @@
+# Copyright 2011 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/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0  
+}
+
+set testfile "dw2-simple-locdesc"
+set srcfile ${testfile}.S
+set executable ${testfile}.x
+set binfile ${objdir}/${subdir}/${executable}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } {
+    return -1
+}
+
+clean_restart $executable
+
+gdb_test "p &s.b" { = \(int \*\) 0x1000000}
--- a/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.exp
@@ -41,7 +41,7 @@ if [is_remote host] {
     }
 }
 gdb_test_no_output "set complaints 100"
-gdb_test "file $binfile" {Reading symbols from .*\.\.\.location description stack underflow\.\.\.location description stack overflow\.\.\.done\.} "check partial symtab errors"
+gdb_test "file $binfile" {Reading symbols from .*\.\.\.Asked for position 0 of stack, stack only has 0 elements on it\..*\.\.\.done\.} "check partial symtab errors"
 
 gdb_test "p underflow" {Asked for position 0 of stack, stack only has 0 elements on it\.}
 gdb_test "p overflow" " = 2"



More information about the Gdb-patches mailing list