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


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

RFC: implement DW_OP_stack_value and DW_OP_implicit_value


This patch implements the new DWARF 4 opcodes DW_OP_stack_value and
DW_OP_implicit_value.  The svn trunk GCC can generate these under some
conditions.

Built and regtested on x86-64 (compile farm).  There's an x86 test case
included, made with some random VTA branch snapshot -- I verified by
hand that it uses both operators in question.

Tom

2009-09-02  Tom Tromey  <tromey@redhat.com>

	* dwarf2loc.c (dwarf2_evaluate_loc_desc): Update.
	(dwarf2_loc_desc_needs_frame): Likewise.
	* dwarf2expr.h (enum dwarf_value_location): New.
	(struct dwarf_expr_context) <in_reg>: Remove.
	<location, len, data>: New fields.
	(struct dwarf_expr_piece) <in_reg, value>: Remove.
	<location, v>: New fields.
	* dwarf2expr.c (add_piece): Remove in_reg, value arguments.
	Update.
	(require_composition): New function.
	(execute_stack_op): Update.
	<DW_OP_implicit_value, DW_OP_stack_value>: New cases.
	<DW_OP_reg0>: Set location, not in_reg.
	<DW_OP_regx>: Likewise.  Use require_composition.
	<DW_OP_fbreg>: Update.
	<DW_OP_piece>: Likewise.
	* dwarf2-frame.c (execute_stack_op): Update.

2009-09-02  Tom Tromey  <tromey@redhat.com>

	* gdb.dwarf2/valop.S: New file.
	* gdb.dwarf2/valop.exp: New file.

Index: dwarf2-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
retrieving revision 1.97
diff -u -r1.97 dwarf2-frame.c
--- dwarf2-frame.c	2 Sep 2009 14:53:55 -0000	1.97
+++ dwarf2-frame.c	2 Sep 2009 21:56:50 -0000
@@ -379,8 +379,15 @@
   dwarf_expr_eval (ctx, exp, len);
   result = dwarf_expr_fetch (ctx, 0);
 
-  if (ctx->in_reg)
+  if (ctx->location == DWARF_VALUE_REGISTER)
     result = read_reg (this_frame, result);
+  else if (ctx->location != DWARF_VALUE_MEMORY)
+    {
+      /* This is actually invalid DWARF, but if we ever do run across
+	 it somehow, we might as well support it.  So, instead, report
+	 it as unimplemented.  */
+      error (_("Not implemented: computing unwound register using explicit value operator"));
+    }
 
   do_cleanups (old_chain);
 
Index: dwarf2expr.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.c,v
retrieving revision 1.35
diff -u -r1.35 dwarf2expr.c
--- dwarf2expr.c	2 Sep 2009 14:53:55 -0000	1.35
+++ dwarf2expr.c	2 Sep 2009 21:56:50 -0000
@@ -125,8 +125,7 @@
 
 /* Add a new piece to CTX's piece list.  */
 static void
-add_piece (struct dwarf_expr_context *ctx,
-           int in_reg, CORE_ADDR value, ULONGEST size)
+add_piece (struct dwarf_expr_context *ctx, ULONGEST size)
 {
   struct dwarf_expr_piece *p;
 
@@ -141,9 +140,15 @@
                            * sizeof (struct dwarf_expr_piece));
 
   p = &ctx->pieces[ctx->num_pieces - 1];
-  p->in_reg = in_reg;
-  p->value = value;
+  p->location = ctx->location;
   p->size = size;
+  if (p->location == DWARF_VALUE_LITERAL)
+    {
+      p->v.literal.data = ctx->data;
+      p->v.literal.length = ctx->len;
+    }
+  else
+    p->v.value = dwarf_expr_fetch (ctx, 0);
 }
 
 /* Evaluate the expression at ADDR (LEN bytes long) using the context
@@ -287,6 +292,23 @@
     }
 }
 
+
+/* Check that the current operator is either at the end of an
+   expression, or that it is followed by a composition operator.  */
+
+static void
+require_composition (gdb_byte *op_ptr, gdb_byte *op_end, const char *op_name)
+{
+  /* It seems like DW_OP_GNU_uninit should be handled here.  However,
+     it doesn't seem to make sense for DW_OP_*_value, and it was not
+     checked at the other place that this function is called.  */
+  if (op_ptr != op_end && *op_ptr != DW_OP_piece && *op_ptr != DW_OP_bit_piece)
+    error (_("DWARF-2 expression error: `%s' operations must be "
+	     "used either alone or in conjuction with DW_OP_piece "
+	     "or DW_OP_bit_piece."),
+	   op_name);
+}
+
 /* The engine for the expression evaluator.  Using the context in CTX,
    evaluate the expression between OP_PTR and OP_END.  */
 
@@ -295,8 +317,7 @@
 		  gdb_byte *op_ptr, gdb_byte *op_end)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (ctx->gdbarch);
-
-  ctx->in_reg = 0;
+  ctx->location = DWARF_VALUE_MEMORY;
   ctx->initialized = 1;  /* Default is initialized.  */
 
   if (ctx->recursion_depth > ctx->max_recursion_depth)
@@ -436,20 +457,36 @@
 		   "used either alone or in conjuction with DW_OP_piece."));
 
 	  result = op - DW_OP_reg0;
-	  ctx->in_reg = 1;
-
+	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
 	case DW_OP_regx:
 	  op_ptr = read_uleb128 (op_ptr, op_end, &reg);
-	  if (op_ptr != op_end && *op_ptr != DW_OP_piece)
-	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
-		   "used either alone or in conjuction with DW_OP_piece."));
+	  require_composition (op_ptr, op_end, "DW_OP_regx");
 
 	  result = reg;
-	  ctx->in_reg = 1;
+	  ctx->location = DWARF_VALUE_REGISTER;
 	  break;
 
+	case DW_OP_implicit_value:
+	  {
+	    ULONGEST len;
+	    op_ptr = read_uleb128 (op_ptr, op_end, &len);
+	    if (op_ptr + len > op_end)
+	      error (_("DW_OP_implicit_value: too few bytes available."));
+	    ctx->len = len;
+	    ctx->data = op_ptr;
+	    ctx->location = DWARF_VALUE_LITERAL;
+	    op_ptr += len;
+	    require_composition (op_ptr, op_end, "DW_OP_implicit_value");
+	  }
+	  goto no_push;
+
+	case DW_OP_stack_value:
+	  ctx->location = DWARF_VALUE_STACK;
+	  require_composition (op_ptr, op_end, "DW_OP_stack_value");
+	  goto no_push;
+
 	case DW_OP_breg0:
 	case DW_OP_breg1:
 	case DW_OP_breg2:
@@ -513,12 +550,15 @@
                specific this_base method.  */
 	    (ctx->get_frame_base) (ctx->baton, &datastart, &datalen);
 	    dwarf_expr_eval (ctx, datastart, datalen);
+	    if (ctx->location == DWARF_VALUE_LITERAL
+		|| ctx->location == DWARF_VALUE_STACK)
+	      error (_("Not implemented: computing frame base using explicit value operator"));
 	    result = dwarf_expr_fetch (ctx, 0);
-	    if (ctx->in_reg)
+	    if (ctx->location == DWARF_VALUE_REGISTER)
 	      result = (ctx->read_reg) (ctx->baton, result);
 	    result = result + offset;
 	    ctx->stack_len = before_stack_len;
-	    ctx->in_reg = 0;
+	    ctx->location = DWARF_VALUE_MEMORY;
 	  }
 	  break;
 	case DW_OP_dup:
@@ -758,12 +798,13 @@
 
             /* Record the piece.  */
             op_ptr = read_uleb128 (op_ptr, op_end, &size);
-            addr_or_regnum = dwarf_expr_fetch (ctx, 0);
-            add_piece (ctx, ctx->in_reg, addr_or_regnum, size);
+	    add_piece (ctx, size);
 
-            /* Pop off the address/regnum, and clear the in_reg flag.  */
-            dwarf_expr_pop (ctx);
-            ctx->in_reg = 0;
+            /* Pop off the address/regnum, and reset the location
+	       type.  */
+	    if (ctx->location != DWARF_VALUE_LITERAL)
+	      dwarf_expr_pop (ctx);
+            ctx->location = DWARF_VALUE_MEMORY;
           }
           goto no_push;
 
Index: dwarf2expr.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.h,v
retrieving revision 1.17
diff -u -r1.17 dwarf2expr.h
--- dwarf2expr.h	2 Sep 2009 14:53:55 -0000	1.17
+++ dwarf2expr.h	2 Sep 2009 21:56:50 -0000
@@ -23,6 +23,19 @@
 #if !defined (DWARF2EXPR_H)
 #define DWARF2EXPR_H
 
+/* The location of a value.  */
+enum dwarf_value_location
+{
+  /* The piece is in memory.  */
+  DWARF_VALUE_MEMORY,
+  /* The piece is in a register.  */
+  DWARF_VALUE_REGISTER,
+  /* The piece is on the stack.  */
+  DWARF_VALUE_STACK,
+  /* The piece is a literal.  */
+  DWARF_VALUE_LITERAL
+};
+
 /* The expression evaluator works with a dwarf_expr_context, describing
    its current state and its callbacks.  */
 struct dwarf_expr_context
@@ -80,9 +93,13 @@
      depth we'll tolerate before raising an error.  */
   int recursion_depth, max_recursion_depth;
 
-  /* Non-zero if the result is in a register.  The register number
-     will be on the expression stack.  */
-  int in_reg;
+  /* Location of the value.  */
+  enum dwarf_value_location location;
+
+  /* For VALUE_LITERAL, a the current literal value's length and
+     data.  */
+  ULONGEST len;
+  gdb_byte *data;
 
   /* Initialization status of variable: Non-zero if variable has been
      initialized; zero otherwise.  */
@@ -93,9 +110,9 @@
 
      Each time DW_OP_piece is executed, we add a new element to the
      end of this array, recording the current top of the stack, the
-     current in_reg flag, and the size given as the operand to
-     DW_OP_piece.  We then pop the top value from the stack, clear the
-     in_reg flag, and resume evaluation.
+     current location, and the size given as the operand to
+     DW_OP_piece.  We then pop the top value from the stack, rest the
+     location, and resume evaluation.
 
      The Dwarf spec doesn't say whether DW_OP_piece pops the top value
      from the stack.  We do, ensuring that clients of this interface
@@ -106,12 +123,11 @@
 
      If an expression never uses DW_OP_piece, num_pieces will be zero.
      (It would be nice to present these cases as expressions yielding
-     a single piece, with in_reg clear, so that callers need not
-     distinguish between the no-DW_OP_piece and one-DW_OP_piece cases.
-     But expressions with no DW_OP_piece operations have no value to
-     place in a piece's 'size' field; the size comes from the
-     surrounding data.  So the two cases need to be handled
-     separately.)  */
+     a single piece, so that callers need not distinguish between the
+     no-DW_OP_piece and one-DW_OP_piece cases.  But expressions with
+     no DW_OP_piece operations have no value to place in a piece's
+     'size' field; the size comes from the surrounding data.  So the
+     two cases need to be handled separately.)  */
   int num_pieces;
   struct dwarf_expr_piece *pieces;
 };
@@ -120,13 +136,22 @@
 /* A piece of an object, as recorded by DW_OP_piece.  */
 struct dwarf_expr_piece
 {
-  /* If IN_REG is zero, then the piece is in memory, and VALUE is its address.
-     If IN_REG is non-zero, then the piece is in a register, and VALUE
-     is the register number.  */
-  int in_reg;
+  enum dwarf_value_location location;
 
-  /* This piece's address or register number.  */
-  CORE_ADDR value;
+  union
+  {
+    /* This piece's address or register number.  */
+    CORE_ADDR value;
+
+    struct
+    {
+      /* A pointer to the data making up this piece, for literal
+	 pieces.  */
+      gdb_byte *data;
+      /* The length of the available data.  */
+      ULONGEST length;
+    } literal;
+  } v;
 
   /* The length of the piece, in bytes.  */
   ULONGEST size;
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.65
diff -u -r1.65 dwarf2loc.c
--- dwarf2loc.c	2 Sep 2009 14:53:55 -0000	1.65
+++ dwarf2loc.c	2 Sep 2009 21:56:50 -0000
@@ -263,37 +263,111 @@
       for (i = 0; i < ctx->num_pieces; i++)
 	{
 	  struct dwarf_expr_piece *p = &ctx->pieces[i];
-	  if (p->in_reg)
+	  switch (p->location)
 	    {
-	      struct gdbarch *arch = get_frame_arch (frame);
-	      bfd_byte regval[MAX_REGISTER_SIZE];
-	      int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->value);
-	      get_frame_register (frame, gdb_regnum, regval);
-	      memcpy (contents + offset, regval, p->size);
-	    }
-	  else /* In memory?  */
-	    {
-	      read_memory (p->value, contents + offset, p->size);
+	    case DWARF_VALUE_REGISTER:
+	      {
+		struct gdbarch *arch = get_frame_arch (frame);
+		bfd_byte regval[MAX_REGISTER_SIZE];
+		int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch,
+							       p->v.value);
+		get_frame_register (frame, gdb_regnum, regval);
+		memcpy (contents + offset, regval, p->size);
+	      }
+	      break;
+
+	    case DWARF_VALUE_MEMORY:
+	      read_memory (p->v.value, contents + offset, p->size);
+	      break;
+
+	    case DWARF_VALUE_STACK:
+	      {
+		gdb_byte bytes[sizeof (ULONGEST)];
+		size_t n;
+		store_unsigned_integer (bytes, ctx->addr_size,
+					gdbarch_byte_order (ctx->gdbarch),
+					p->v.value);
+		n = p->size;
+		if (n > ctx->addr_size)
+		  n = ctx->addr_size;
+		memcpy (contents + offset, bytes, 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);
+	      }
+	      break;
+
+	    default:
+	      internal_error (__FILE__, __LINE__, _("invalid location type"));
 	    }
 	  offset += p->size;
 	}
     }
-  else if (ctx->in_reg)
-    {
-      struct gdbarch *arch = get_frame_arch (frame);
-      CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0);
-      int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
-      retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame);
-    }
   else
     {
-      CORE_ADDR address = dwarf_expr_fetch (ctx, 0);
+      switch (ctx->location)
+	{
+	case DWARF_VALUE_REGISTER:
+	  {
+	    struct gdbarch *arch = get_frame_arch (frame);
+	    CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0);
+	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
+	    retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame);
+	  }
+	  break;
+
+	case DWARF_VALUE_MEMORY:
+	  {
+	    CORE_ADDR address = dwarf_expr_fetch (ctx, 0);
+
+	    retval = allocate_value (SYMBOL_TYPE (var));
+	    VALUE_LVAL (retval) = lval_memory;
+	    set_value_lazy (retval, 1);
+	    set_value_stack (retval, 1);
+	    set_value_address (retval, address);
+	  }
+	  break;
+
+	case DWARF_VALUE_STACK:
+	  {
+	    gdb_byte bytes[sizeof (ULONGEST)];
+	    ULONGEST value = (ULONGEST) dwarf_expr_fetch (ctx, 0);
+	    bfd_byte *contents;
+	    size_t n = ctx->addr_size;
+
+	    store_unsigned_integer (bytes, ctx->addr_size,
+				    gdbarch_byte_order (ctx->gdbarch),
+				    value);
+	    retval = allocate_value (SYMBOL_TYPE (var));
+	    contents = value_contents_raw (retval);
+	    if (n > TYPE_LENGTH (SYMBOL_TYPE (var)))
+	      n = TYPE_LENGTH (SYMBOL_TYPE (var));
+	    memcpy (contents, bytes, n);
+	  }
+	  break;
+
+	case DWARF_VALUE_LITERAL:
+	  {
+	    bfd_byte *contents;
+	    size_t n = ctx->len;
+
+	    retval = allocate_value (SYMBOL_TYPE (var));
+	    contents = value_contents_raw (retval);
+	    if (n > TYPE_LENGTH (SYMBOL_TYPE (var)))
+	      n = TYPE_LENGTH (SYMBOL_TYPE (var));
+	    memcpy (contents, ctx->data, n);
+	  }
+	  break;
 
-      retval = allocate_value (SYMBOL_TYPE (var));
-      VALUE_LVAL (retval) = lval_memory;
-      set_value_lazy (retval, 1);
-      set_value_stack (retval, 1);
-      set_value_address (retval, address);
+	default:
+	  internal_error (__FILE__, __LINE__, _("invalid location type"));
+	}
     }
 
   set_value_initialized (retval, ctx->initialized);
@@ -390,7 +464,7 @@
 
   dwarf_expr_eval (ctx, data, size);
 
-  in_reg = ctx->in_reg;
+  in_reg = ctx->location == DWARF_VALUE_REGISTER;
 
   if (ctx->num_pieces > 0)
     {
@@ -399,7 +473,7 @@
       /* If the location has several pieces, and any of them are in
          registers, then we will need a frame to fetch them from.  */
       for (i = 0; i < ctx->num_pieces; i++)
-        if (ctx->pieces[i].in_reg)
+        if (ctx->pieces[i].location == DWARF_VALUE_REGISTER)
           in_reg = 1;
     }
 
Index: testsuite/gdb.dwarf2/valop.S
===================================================================
RCS file: testsuite/gdb.dwarf2/valop.S
diff -N testsuite/gdb.dwarf2/valop.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/valop.S	2 Sep 2009 21:56:51 -0000
@@ -0,0 +1,505 @@
+/*
+   Copyright 2009 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 from a trivial program just to test the
+   DW_OP_stack_value and DW_OP_implicit_value operators:
+
+    unsigned int func (unsigned int arg) __attribute__ ((__noinline__));
+
+    unsigned int func (unsigned int arg)
+    {
+      unsigned int uses_stack_op = 23;
+      unsigned int uses_lit_op = 0x7fffffff;
+      unsigned int result = arg;
+
+      if (arg % 2)
+	result += uses_lit_op + uses_stack_op;
+      else
+	{
+	  ++uses_stack_op;
+	  ++uses_lit_op;
+
+	  result -= uses_stack_op + uses_lit_op;
+	}
+
+      return result * uses_stack_op;  // line 19, see the .exp file
+    }
+
+    int main (int argc, char *argv[])
+    {
+      return func (1024);
+    }
+
+  Then it was compiled with:
+	
+	gcc -fvar-tracking{,-assignments} -gdwarf-3
+	-fno-inline{,-functions,-small-functions,-functions-called-once}
+	-O2
+
+*/
+
+	.file	"valop.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 func
+	.type	func, @function
+func:
+.LFB0:
+	.file 1 "valop.c"
+	.loc 1 4 0
+	.cfi_startproc
+.LVL0:
+	pushl	%ebp
+	.cfi_def_cfa_offset 8
+	movl	%esp, %ebp
+	.cfi_offset 5, -8
+	.cfi_def_cfa_register 5
+	.loc 1 4 0
+	movl	8(%ebp), %eax
+.LVL1:
+	.loc 1 9 0
+	testb	$1, %al
+	jne	.L5
+.LVL2:
+	.loc 1 16 0
+	addl	$2147483624, %eax
+.LVL3:
+	.loc 1 13 0
+	movl	$24, %edx
+.LVL4:
+	.loc 1 16 0
+	imull	%edx, %eax
+.LVL5:
+	.loc 1 20 0
+	popl	%ebp
+	.cfi_remember_state
+	.cfi_restore 5
+	.cfi_def_cfa 4, 4
+	ret
+.LVL6:
+	.p2align 4,,7
+	.p2align 3
+.L5:
+	.cfi_restore_state
+	.loc 1 10 0
+	subl	$2147483626, %eax
+.LVL7:
+	.loc 1 5 0
+	movl	$23, %edx
+.LVL8:
+	.loc 1 16 0
+	imull	%edx, %eax
+.LVL9:
+	.loc 1 20 0
+	popl	%ebp
+	.cfi_def_cfa 4, 4
+	.cfi_restore 5
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	func, .-func
+	.p2align 4,,15
+.globl _start
+	.type	_start, @function
+_start:
+.LFB1:
+	.loc 1 23 0
+	.cfi_startproc
+.LVL10:
+	pushl	%ebp
+	.cfi_def_cfa_offset 8
+	movl	%esp, %ebp
+	.cfi_offset 5, -8
+	.cfi_def_cfa_register 5
+	subl	$4, %esp
+	.loc 1 24 0
+	movl	$1024, (%esp)
+	call	func
+.LVL11:
+	.loc 1 25 0
+	leave
+	.cfi_restore 5
+	.cfi_def_cfa 4, 4
+	ret
+	.cfi_endproc
+.LFE1:
+	.size	_start, .-_start
+.Letext0:
+	.section	.debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+	.long	.LVL0-.Ltext0
+	.long	.LVL2-.Ltext0
+	.value	0x4
+	.byte	0x47
+	.byte	0x9f
+	.byte	0x93
+	.uleb128 0x4
+	.long	.LVL2-.Ltext0
+	.long	.LVL4-.Ltext0
+	.value	0x4
+	.byte	0x48
+	.byte	0x9f
+	.byte	0x93
+	.uleb128 0x4
+	.long	.LVL4-.Ltext0
+	.long	.LVL6-.Ltext0
+	.value	0x1
+	.byte	0x52
+	.long	.LVL6-.Ltext0
+	.long	.LVL8-.Ltext0
+	.value	0x4
+	.byte	0x47
+	.byte	0x9f
+	.byte	0x93
+	.uleb128 0x4
+	.long	.LVL8-.Ltext0
+	.long	.LFE0-.Ltext0
+	.value	0x1
+	.byte	0x52
+	.long	0x0
+	.long	0x0
+.LLST1:
+	.long	.LVL0-.Ltext0
+	.long	.LVL2-.Ltext0
+	.value	0x6
+	.byte	0x9e
+	.uleb128 0x4
+	.long	0x7fffffff
+	.long	.LVL2-.Ltext0
+	.long	.LVL6-.Ltext0
+	.value	0x6
+	.byte	0x9e
+	.uleb128 0x4
+	.long	0x80000000
+	.long	.LVL6-.Ltext0
+	.long	.LFE0-.Ltext0
+	.value	0x6
+	.byte	0x9e
+	.uleb128 0x4
+	.long	0x7fffffff
+	.long	0x0
+	.long	0x0
+.LLST2:
+	.long	.LVL1-.Ltext0
+	.long	.LVL3-.Ltext0
+	.value	0x1
+	.byte	0x50
+	.long	.LVL3-.Ltext0
+	.long	.LVL5-.Ltext0
+	.value	0x1
+	.byte	0x50
+	.long	.LVL6-.Ltext0
+	.long	.LVL7-.Ltext0
+	.value	0x1
+	.byte	0x50
+	.long	.LVL7-.Ltext0
+	.long	.LVL9-.Ltext0
+	.value	0x1
+	.byte	0x50
+	.long	0x0
+	.long	0x0
+.LLST3:
+	.long	.LVL10-.Ltext0
+	.long	.LVL11-1-.Ltext0
+	.value	0x2
+	.byte	0x91
+	.sleb128 0
+	.long	0x0
+	.long	0x0
+.LLST4:
+	.long	.LVL10-.Ltext0
+	.long	.LVL11-1-.Ltext0
+	.value	0x2
+	.byte	0x91
+	.sleb128 4
+	.long	0x0
+	.long	0x0
+	.section	.debug_info
+	.long	0xd4
+	.value	0x3
+	.long	.Ldebug_abbrev0
+	.byte	0x4
+	.uleb128 0x1
+	.long	.LASF9
+	.byte	0x1
+	.long	.LASF10
+	.long	.LASF11
+	.long	.Ltext0
+	.long	.Letext0
+	.long	.Ldebug_line0
+	.uleb128 0x2
+	.byte	0x1
+	.long	.LASF3
+	.byte	0x1
+	.byte	0x3
+	.byte	0x1
+	.long	0x7c
+	.long	.LFB0
+	.long	.LFE0
+	.byte	0x1
+	.byte	0x9c
+	.long	0x7c
+	.uleb128 0x3
+	.string	"arg"
+	.byte	0x1
+	.byte	0x3
+	.long	0x7c
+	.byte	0x2
+	.byte	0x91
+	.sleb128 0
+	.uleb128 0x4
+	.long	.LASF0
+	.byte	0x1
+	.byte	0x5
+	.long	0x7c
+	.long	.LLST0
+	.uleb128 0x4
+	.long	.LASF1
+	.byte	0x1
+	.byte	0x6
+	.long	0x7c
+	.long	.LLST1
+	.uleb128 0x4
+	.long	.LASF2
+	.byte	0x1
+	.byte	0x7
+	.long	0x7c
+	.long	.LLST2
+	.byte	0x0
+	.uleb128 0x5
+	.byte	0x4
+	.byte	0x7
+	.long	.LASF7
+	.uleb128 0x2
+	.byte	0x1
+	.long	.LASF4
+	.byte	0x1
+	.byte	0x16
+	.byte	0x1
+	.long	0xbd
+	.long	.LFB1
+	.long	.LFE1
+	.byte	0x1
+	.byte	0x9c
+	.long	0xbd
+	.uleb128 0x6
+	.long	.LASF5
+	.byte	0x1
+	.byte	0x16
+	.long	0xbd
+	.long	.LLST3
+	.uleb128 0x6
+	.long	.LASF6
+	.byte	0x1
+	.byte	0x16
+	.long	0xc4
+	.long	.LLST4
+	.byte	0x0
+	.uleb128 0x7
+	.byte	0x4
+	.byte	0x5
+	.string	"int"
+	.uleb128 0x8
+	.byte	0x4
+	.long	0xca
+	.uleb128 0x8
+	.byte	0x4
+	.long	0xd0
+	.uleb128 0x5
+	.byte	0x1
+	.byte	0x6
+	.long	.LASF8
+	.byte	0x0
+	.section	.debug_abbrev
+	.uleb128 0x1
+	.uleb128 0x11
+	.byte	0x1
+	.uleb128 0x25
+	.uleb128 0xe
+	.uleb128 0x13
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x1b
+	.uleb128 0xe
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x1
+	.uleb128 0x10
+	.uleb128 0x6
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x2
+	.uleb128 0x2e
+	.byte	0x1
+	.uleb128 0x3f
+	.uleb128 0xc
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x27
+	.uleb128 0xc
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x1
+	.uleb128 0x40
+	.uleb128 0xa
+	.uleb128 0x1
+	.uleb128 0x13
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x3
+	.uleb128 0x5
+	.byte	0x0
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x2
+	.uleb128 0xa
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x4
+	.uleb128 0x34
+	.byte	0x0
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x2
+	.uleb128 0x6
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x5
+	.uleb128 0x24
+	.byte	0x0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x3e
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0xe
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x6
+	.uleb128 0x5
+	.byte	0x0
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x2
+	.uleb128 0x6
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x7
+	.uleb128 0x24
+	.byte	0x0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x3e
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0x8
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x8
+	.uleb128 0xf
+	.byte	0x0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.byte	0x0
+	.byte	0x0
+	.byte	0x0
+	.section	.debug_pubnames,"",@progbits
+	.long	0x20
+	.value	0x2
+	.long	.Ldebug_info0
+	.long	0xd8
+	.long	0x25
+	.string	"func"
+	.long	0x83
+	.string	"main"
+	.long	0x0
+	.section	.debug_aranges,"",@progbits
+	.long	0x1c
+	.value	0x2
+	.long	.Ldebug_info0
+	.byte	0x4
+	.byte	0x0
+	.value	0x0
+	.value	0x0
+	.long	.Ltext0
+	.long	.Letext0-.Ltext0
+	.long	0x0
+	.long	0x0
+	.section	.debug_str,"MS",@progbits,1
+.LASF7:
+	.string	"unsigned int"
+.LASF3:
+	.string	"func"
+.LASF0:
+	.string	"uses_stack_op"
+.LASF5:
+	.string	"argc"
+.LASF10:
+	.string	"valop.c"
+.LASF2:
+	.string	"result"
+.LASF8:
+	.string	"char"
+.LASF9:
+	.string	"GNU C 4.5.0 20090818 (experimental) [var-tracking-assignments-branch revision 150964]"
+.LASF4:
+	.string	"main"
+.LASF11:
+	.string	"/tmp"
+.LASF1:
+	.string	"uses_lit_op"
+.LASF6:
+	.string	"argv"
+	.ident	"GCC: (GNU) 4.5.0 20090818 (experimental) [var-tracking-assignments-branch revision 150964]"
+	.section	.note.GNU-stack,"",@progbits
Index: testsuite/gdb.dwarf2/valop.exp
===================================================================
RCS file: testsuite/gdb.dwarf2/valop.exp
diff -N testsuite/gdb.dwarf2/valop.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/valop.exp	2 Sep 2009 21:56:51 -0000
@@ -0,0 +1,55 @@
+# Copyright 2009 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 DW_OP_stack_value and DW_OP_implicit_value.
+
+# 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 "valop"
+set srcfile ${testfile}.S
+set binfile ${objdir}/${subdir}/${testfile}.x
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
+       [list {additional_flags=-nostdlib}]] != "" } {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_test "break valop.c:19" "Breakpoint 2.*" "set breakpoint for valop"
+gdb_continue_to_breakpoint "continue to breakpoint for valop"
+
+gdb_test "print uses_stack_op" " = 24" "print uses_stack_op"
+gdb_test "print uses_lit_op" " = 2147483648" "print uses_lit_op"


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