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]

Re: Support Dwarf3 DW_CFA_val_* expressions


On Mar  4, 2006, Daniel Jacobowitz <drow@false.org> wrote:

> On Sat, Mar 04, 2006 at 09:01:43AM -0300, Alexandre Oliva wrote:
>> > It's also good to have a few testcases,
>> > but I don't completely understand the testcases :(
>> 
>> You're not alone in that feeling, I assure you :-)

> Like Mark, I am happier with the code than the testcases.  In fact,
> I'd rather not have the tests at all than have something quite
> so overkill.

Fair enough...  Those tests uncovered a problem with the way our
dwarf2 code identifies frames, though: it uses the function start
address and the CFA to identify a stack frame, whereas it should use
the PC and the CFA.  In some corner cases, such as the one exercised
by the i386 testcase, if you're on the second instruction of the
region covered by the hand-generated unwind info and ask for a
backtrace, GDB complains that the stack is corrupt, but the only
problem is that the dwarf2 machinery gets confused by the same-CFA,
same-function pair of stack frames.  This is fixed in the revised
patch below.

> And you're not correct that older GCCs could run them
> far enough to test; they'll fail to build because of the use of
> __attribute__((cleanup))

Oops, indeed, sorry about that.  The testcases must definitely be
amended if they're to remain.  Should they?

> You ought to be able to test this much more simply, if you wire it
> up to the bits in gdb.asm.

But that wouldn't have caught errors in processing complex dwarf
expressions, which the current testcases did in an older tree.

> I'm sure it won't work for some platforms, and we'll have to add some
> skips in the .exp file, but it ought to get enough of the current
> ELF/dwarf platforms to be interesting, don't you think?

Not sure...  You talked about signal augmentations, but that's a
different patch in a different thread.  This one is about complex
dwarf2 expressions involving newly-introduced encodings.

I'm not sure how to encode such tests with gdb.asm, but I may look
into it if dropping the tests in the following updated patch is not
good enough.

for gdb/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* dwarf2-frame.h (enum dwarf2_frame_reg_rule): Add
	DWARF2_FRAME_REG_SAVED_VAL_OFFSET and
	DWARF2_FRAME_REG_SAVED_VAL_EXP.
	* dwarf2-frame.c (execute_cfa_program): Handle val_offset,
	val_offset_sf and val_expression.
	(dwarf2_frame_prev_register): Handle the new reg rules.
	(dwarf2_frame_this_id): Use pc instead of function entry point.

for gdb/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* gdb.dwarf2/cfa-val-expr.exp: New test.
	* gdb.dwarf2/cfa-val-expr-1.c, gdb.dwarf2/cfa-val-expr-2.c:
	Its sources.

Index: gdb/dwarf2-frame.c
===================================================================
--- gdb/dwarf2-frame.c.orig	2006-03-07 02:06:03.000000000 -0300
+++ gdb/dwarf2-frame.c	2006-03-07 02:06:07.000000000 -0300
@@ -446,6 +446,34 @@ bad CFI data; mismatched DW_CFA_restore_
 	      fs->regs.reg[reg].loc.offset = offset;
 	      break;
 
+	    case DW_CFA_val_offset:
+	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
+	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
+	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
+	      offset = utmp * fs->data_align;
+	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET;
+	      fs->regs.reg[reg].loc.offset = offset;
+	      break;
+
+	    case DW_CFA_val_offset_sf:
+	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
+	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
+	      insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset);
+	      offset *= fs->data_align;
+	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET;
+	      fs->regs.reg[reg].loc.offset = offset;
+	      break;
+
+	    case DW_CFA_val_expression:
+	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &reg);
+	      dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1);
+	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
+	      fs->regs.reg[reg].loc.exp = insn_ptr;
+	      fs->regs.reg[reg].exp_len = utmp;
+	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_EXP;
+	      insn_ptr += utmp;
+	      break;
+
 	    case DW_CFA_def_cfa_sf:
 	      insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg);
 	      insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset);
@@ -828,7 +856,7 @@ dwarf2_frame_this_id (struct frame_info 
   if (cache->undefined_retaddr)
     return;
 
-  (*this_id) = frame_id_build (cache->cfa, frame_func_unwind (next_frame));
+  (*this_id) = frame_id_build (cache->cfa, frame_pc_unwind (next_frame));
 }
 
 static void
@@ -894,6 +922,28 @@ dwarf2_frame_prev_register (struct frame
 	}
       break;
 
+    case DWARF2_FRAME_REG_SAVED_VAL_OFFSET:
+      *optimizedp = 0;
+      *lvalp = not_lval;
+      *addrp = 0;
+      *realnump = -1;
+      if (valuep)
+	store_unsigned_integer (valuep, register_size (gdbarch, regnum),
+				cache->cfa + cache->reg[regnum].loc.offset);
+      break;
+
+    case DWARF2_FRAME_REG_SAVED_VAL_EXP:
+      *optimizedp = 0;
+      *lvalp = not_lval;
+      *addrp = 0;
+      *realnump = -1;
+      if (valuep)
+	store_unsigned_integer (valuep, register_size (gdbarch, regnum),
+				execute_stack_op (cache->reg[regnum].loc.exp,
+						  cache->reg[regnum].exp_len,
+						  next_frame, cache->cfa));
+      break;
+
     case DWARF2_FRAME_REG_UNSPECIFIED:
       /* GCC, in its infinite wisdom decided to not provide unwind
 	 information for registers that are "same value".  Since
Index: gdb/dwarf2-frame.h
===================================================================
--- gdb/dwarf2-frame.h.orig	2006-03-07 02:06:03.000000000 -0300
+++ gdb/dwarf2-frame.h	2006-03-07 02:06:07.000000000 -0300
@@ -51,6 +51,10 @@ enum dwarf2_frame_reg_rule
   DWARF2_FRAME_REG_SAVED_EXP,
   DWARF2_FRAME_REG_SAME_VALUE,
 
+  /* These are defined in Dwarf3.  */
+  DWARF2_FRAME_REG_SAVED_VAL_OFFSET,
+  DWARF2_FRAME_REG_SAVED_VAL_EXP,
+
   /* These aren't defined by the DWARF2 CFI specification, but are
      used internally by GDB.  */
   DWARF2_FRAME_REG_RA,		/* Return Address.  */
Index: gdb/testsuite/gdb.dwarf2/cfa-val-expr-1.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gdb/testsuite/gdb.dwarf2/cfa-val-expr-1.c	2006-03-07 02:06:07.000000000 -0300
@@ -0,0 +1,261 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2006  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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Written by Jakub Jelinek, as testcase for Dwarf3 value expression
+   support in GCC unwinders.  GDB does not need all of it, since all
+   we do is to try to get correct backtraces.  No compiler or binutils
+   support is required.  */
+
+/* Test complex CFA value expressions.  */
+
+#include <unwind.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static _Unwind_Reason_Code
+force_unwind_stop (int version, _Unwind_Action actions,
+		   _Unwind_Exception_Class exc_class,
+		   struct _Unwind_Exception *exc_obj,
+		   struct _Unwind_Context *context,
+		   void *stop_parameter)
+{
+  if (actions & _UA_END_OF_STACK)
+    abort ();
+  return _URC_NO_REASON;
+}
+
+static void
+force_unwind ()
+{
+  struct _Unwind_Exception *exc = malloc (sizeof (*exc));
+  memset (&exc->exception_class, 0, sizeof (exc->exception_class));
+  exc->exception_cleanup = 0;
+
+  _Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
+  abort ();
+}
+
+int count;
+
+static void
+counter (void *p __attribute__((unused)))
+{
+  ++count;
+}
+
+static void
+handler (void *p __attribute__((unused)))
+{
+  if (count != 2)
+    abort ();
+  _exit (0);
+}
+
+static int __attribute__((noinline))
+fn5 (void)
+{
+  char dummy __attribute__((cleanup (counter)));
+  force_unwind ();
+  return 0;
+}
+
+void
+bar (void)
+{
+  char dummy __attribute__((cleanup (counter)));
+  fn5 ();
+}
+
+void __attribute__((noinline))
+foo (int x)
+{
+  char buf[256];
+#ifdef __i386__
+  __asm (
+	"testl	%0, %0\n\t"
+	"jnz	1f\n\t"
+	".subsection 1\n\t"
+	".type	_L_mutex_lock_%=, @function\n"
+"_L_mutex_lock_%=:\n"
+"1:\t"	"leal	%1, %%ecx\n"
+"2:\t"	"call	bar\n"
+"3:\t"	"jmp	18f\n"
+"4:\t"	".size _L_mutex_lock_%=, .-_L_mutex_lock_%=\n\t"
+	".previous\n\t"
+	".section	.eh_frame,\"a\",@progbits\n"
+"5:\t"	".long	7f-6f	# Length of Common Information Entry\n"
+"6:\t"	".long	0x0	# CIE Identifier Tag\n\t"
+	".byte	0x1	# CIE Version\n\t"
+	".ascii \"zR\\0\"	# CIE Augmentation\n\t"
+	".uleb128 0x1	# CIE Code Alignment Factor\n\t"
+	".sleb128 -4	# CIE Data Alignment Factor\n\t"
+	".byte	0x8	# CIE RA Column\n\t"
+	".uleb128 0x1	# Augmentation size\n\t"
+	".byte	0x1b	# FDE Encoding (pcrel sdata4)\n\t"
+	".byte	0xc	# DW_CFA_def_cfa\n\t"
+	".uleb128 0x4\n\t"
+	".uleb128 0x0\n\t"
+	".align 4\n"
+"7:\t"	".long	17f-8f	# FDE Length\n"
+"8:\t"	".long	8b-5b	# FDE CIE offset\n\t"
+	".long	1b-.	# FDE initial location\n\t"
+	".long	4b-1b	# FDE address range\n\t"
+	".uleb128 0x0	# Augmentation size\n\t"
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x8\n\t"
+	".uleb128 10f-9f\n"
+"9:\t"	".byte	0x78	# DW_OP_breg8\n\t"
+	".sleb128 3b-1b\n"
+"10:\t"	".byte	0x40 + (2b-1b) # DW_CFA_advance_loc\n\t"
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x8\n\t"
+	".uleb128 12f-11f\n"
+"11:\t"	".byte	0x78	# DW_OP_breg8\n\t"
+	".sleb128 3b-2b\n"
+"12:\t"	".byte	0x40 + (3b-2b-1) # DW_CFA_advance_loc\n\t"
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x8\n\t"
+	".uleb128 16f-13f\n"
+"13:\t"	".byte	0x78	# DW_OP_breg8\n\t"
+	".sleb128 15f-14f\n\t"
+	".byte	0x0d	# DW_OP_const4s\n"
+"14:\t"	".4byte	3b-.\n\t"
+	".byte	0x1c	# DW_OP_minus\n\t"
+	".byte	0x0d	# DW_OP_const4s\n"
+"15:\t"	".4byte	18f-.\n\t"
+	".byte	0x22	# DW_OP_plus\n"
+"16:\t"	".align 4\n"
+"17:\t"	".previous\n"
+"18:"
+	: : "r" (x), "m" (x), "r" (buf)
+	: "memory", "eax", "edx", "ecx");
+#elif defined __x86_64__
+  __asm (
+	"testl	%0, %0\n\t"
+	"jnz	1f\n\t"
+	".subsection 1\n\t"
+	".type	_L_mutex_lock_%=, @function\n"
+"_L_mutex_lock_%=:\n"
+"1:\t"	"leaq	%1, %%rdi\n"
+"2:\t"	"subq	$128, %%rsp\n"
+"3:\t"	"call	bar\n"
+"4:\t"	"addq	$128, %%rsp\n"
+"5:\t"	"jmp	24f\n"
+"6:\t"	".size _L_mutex_lock_%=, .-_L_mutex_lock_%=\n\t"
+	".previous\n\t"
+	".section	.eh_frame,\"a\",@progbits\n"
+"7:\t"	".long	9f-8f	# Length of Common Information Entry\n"
+"8:\t"	".long	0x0	# CIE Identifier Tag\n\t"
+	".byte	0x1	# CIE Version\n\t"
+	".ascii \"zR\\0\"	# CIE Augmentation\n\t"
+	".uleb128 0x1	# CIE Code Alignment Factor\n\t"
+	".sleb128 -8	# CIE Data Alignment Factor\n\t"
+	".byte	0x10	# CIE RA Column\n\t"
+	".uleb128 0x1	# Augmentation size\n\t"
+	".byte	0x1b	# FDE Encoding (pcrel sdata4)\n\t"
+	".byte	0x12	# DW_CFA_def_cfa_sf\n\t"
+	".uleb128 0x7\n\t"
+	".sleb128 16\n\t"
+	".align 8\n"
+"9:\t"	".long	23f-10f	# FDE Length\n"
+"10:\t"	".long	10b-7b	# FDE CIE offset\n\t"
+	".long	1b-.	# FDE initial location\n\t"
+	".long	6b-1b	# FDE address range\n\t"
+	".uleb128 0x0	# Augmentation size\n\t"
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x10\n\t"
+	".uleb128 12f-11f\n"
+"11:\t"	".byte	0x80	# DW_OP_breg16\n\t"
+	".sleb128 4b-1b\n"
+"12:\t"	".byte	0x40 + (2b-1b) # DW_CFA_advance_loc\n\t"
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x10\n\t"
+	".uleb128 14f-13f\n"
+"13:\t"	".byte	0x80	# DW_OP_breg16\n\t"
+	".sleb128 4b-2b\n"
+"14:\t"	".byte	0x40 + (3b-2b) # DW_CFA_advance_loc\n\t"
+	".byte	0x0e	# DW_CFA_def_cfa_offset\n\t"
+	".uleb128 0\n\t"
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x10\n\t"
+	".uleb128 16f-15f\n"
+"15:\t"	".byte	0x80	# DW_OP_breg16\n\t"
+	".sleb128 4b-3b\n"
+"16:\t"	".byte	0x40 + (4b-3b-1) # DW_CFA_advance_loc\n\t"
+	".byte	0x0e	# DW_CFA_def_cfa_offset\n\t"
+	".uleb128 128\n\t"
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x10\n\t"
+	".uleb128 20f-17f\n"
+"17:\t"	".byte	0x80	# DW_OP_breg16\n\t"
+	".sleb128 19f-18f\n\t"
+	".byte	0x0d	# DW_OP_const4s\n"
+"18:\t"	".4byte	4b-.\n\t"
+	".byte	0x1c	# DW_OP_minus\n\t"
+	".byte	0x0d	# DW_OP_const4s\n"
+"19:\t"	".4byte	24f-.\n\t"
+	".byte	0x22	# DW_OP_plus\n"
+"20:\t"	".byte	0x40 + (5b-4b+1) # DW_CFA_advance_loc\n\t"
+	".byte	0x13	# DW_CFA_def_cfa_offset_sf\n\t"
+	".sleb128 16\n\t"
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x10\n\t"
+	".uleb128 22f-21f\n"
+"21:\t"	".byte	0x80	# DW_OP_breg16\n\t"
+	".sleb128 4b-5b\n"
+"22:\t"	".align 8\n"
+"23:\t"	".previous\n"
+"24:"
+	: : "r" (x), "m" (x), "r" (buf)
+	: "memory", "rax", "rdx", "rcx", "rsi", "rdi",
+	  "r8", "r9", "r10", "r11");
+#else
+# error Unsupported test architecture
+#endif
+}
+
+static int __attribute__((noinline))
+fn2 (void)
+{
+  foo (3);
+  return 0;
+}
+
+static int __attribute__((noinline))
+fn1 (void)
+{
+  fn2 ();
+  return 0;
+}
+
+static void *
+fn0 (void)
+{
+  char dummy __attribute__((cleanup (handler)));
+  fn1 ();
+  return 0;
+}
+
+int
+main (void)
+{
+  fn0 ();
+  return 0;
+}
Index: gdb/testsuite/gdb.dwarf2/cfa-val-expr-2.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gdb/testsuite/gdb.dwarf2/cfa-val-expr-2.c	2006-03-07 02:06:07.000000000 -0300
@@ -0,0 +1,226 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2006  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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   Written by Jakub Jelinek, as testcase for Dwarf3 value expression
+   support in GCC unwinders.  GDB does not need all of it, since all
+   we do is to try to get correct backtraces.  No compiler or binutils
+   support is required.  */
+
+/* Test complex CFA value expressions.  */
+
+#include <unwind.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static _Unwind_Reason_Code
+force_unwind_stop (int version, _Unwind_Action actions,
+		   _Unwind_Exception_Class exc_class,
+		   struct _Unwind_Exception *exc_obj,
+		   struct _Unwind_Context *context,
+		   void *stop_parameter)
+{
+  if (actions & _UA_END_OF_STACK)
+    abort ();
+  return _URC_NO_REASON;
+}
+
+static void
+force_unwind ()
+{
+  struct _Unwind_Exception *exc = malloc (sizeof (*exc));
+  memset (&exc->exception_class, 0, sizeof (exc->exception_class));
+  exc->exception_cleanup = 0;
+
+  _Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
+  abort ();
+}
+
+int count;
+
+static void
+counter (void *p __attribute__((unused)))
+{
+  ++count;
+}
+
+static void
+handler (void *p __attribute__((unused)))
+{
+  if (count != 2)
+    abort ();
+  _exit (0);
+}
+
+static int __attribute__((noinline))
+fn5 (void)
+{
+  char dummy __attribute__((cleanup (counter)));
+  force_unwind ();
+  return 0;
+}
+
+void
+bar (void)
+{
+  char dummy __attribute__((cleanup (counter)));
+  fn5 ();
+}
+
+void __attribute__((noinline))
+foo (int x)
+{
+  char buf[256];
+#ifdef __x86_64__
+  __asm (
+	"testl	%0, %0\n\t"
+	"jnz	1f\n\t"
+	".subsection 1\n\t"
+	".type	_L_mutex_lock_%=, @function\n"
+"_L_mutex_lock_%=:\n"
+"1:\t"	"leaq	%1, %%rdi\n"
+"2:\t"	"subq	$128, %%rsp\n"
+"3:\t"	"call	bar\n"
+"4:\t"	"addq	$128, %%rsp\n"
+"5:\t"	"jmp	21f\n"
+"6:\t"	".size _L_mutex_lock_%=, .-_L_mutex_lock_%=\n\t"
+	".previous\n\t"
+	".section	.eh_frame,\"a\",@progbits\n"
+"7:\t"	".long	9f-8f	# Length of Common Information Entry\n"
+"8:\t"	".long	0x0	# CIE Identifier Tag\n\t"
+	".byte	0x1	# CIE Version\n\t"
+	".ascii \"zR\\0\"	# CIE Augmentation\n\t"
+	".uleb128 0x1	# CIE Code Alignment Factor\n\t"
+	".sleb128 -8	# CIE Data Alignment Factor\n\t"
+	".byte	0x10	# CIE RA Column\n\t"
+	".uleb128 0x1	# Augmentation size\n\t"
+	".byte	0x1b	# FDE Encoding (pcrel sdata4)\n\t"
+	".byte	0xc	# DW_CFA_def_cfa\n\t"
+	".uleb128 0x7\n\t"
+	".uleb128 0x0\n\t"
+	".align 8\n"
+"9:\t"	".long	20f-10f	# FDE Length\n"
+"10:\t"	".long	10b-7b	# FDE CIE offset\n\t"
+	".long	1b-.	# FDE initial location\n\t"
+	".long	6b-1b	# FDE address range\n\t"
+	".uleb128 0x0	# Augmentation size\n\t"
+	/* This CFA expression computes the address right
+	   past the jnz instruction above, from %rip somewhere
+	   within the _L_mutex_lock_%= subsection.  */
+	".byte	0x16	# DW_CFA_val_expression\n\t"
+	".uleb128 0x10\n\t"
+	".uleb128 19f-11f\n"
+"11:\t"	".byte	0x80	# DW_OP_breg16\n\t"
+	".sleb128 0\n"
+"12:\t"	".byte	0x12	# DW_OP_dup\n\t"
+	".byte	0x94	# DW_OP_deref_size\n\t"
+	".byte	1\n\t"
+	".byte	0x12	# DW_OP_dup\n\t"
+	".byte	0x08	# DW_OP_const1u\n\t"
+	".byte	0x48\n\t"
+	".byte	0x2e	# DW_OP_ne\n\t"
+	".byte	0x28	# DW_OP_bra\n\t"
+	".2byte	16f-13f\n"
+"13:\t"	".byte	0x13	# DW_OP_drop\n\t"
+	".byte	0x23	# DW_OP_plus_uconst\n\t"
+	".uleb128 1\n\t"
+	".byte	0x12	# DW_OP_dup\n\t"
+	".byte	0x94	# DW_OP_deref_size\n\t"
+	".byte	1\n\t"
+	".byte	0x08	# DW_OP_const1u\n\t"
+	".byte	0x81\n\t"
+	".byte	0x2e	# DW_OP_ne\n\t"
+	".byte	0x28	# DW_OP_bra\n\t"
+	".2byte	15f-14f\n"
+"14:\t"	".byte	0x23	# DW_OP_plus_uconst\n\t"
+	".uleb128 3b-2b-1\n\t"
+	".byte	0x2f	# DW_OP_skip\n\t"
+	".2byte	12b-15f\n"
+"15:\t"	".byte	0x23	# DW_OP_plus_uconst\n\t"
+	".uleb128 2b-1b-1\n\t"
+	".byte	0x2f	# DW_OP_skip\n\t"
+	".2byte	12b-16f\n"
+"16:\t"	".byte	0x08	# DW_OP_const1u\n\t"
+	".byte	0xe8\n\t"
+	".byte	0x2e	# DW_OP_ne\n\t"
+	".byte	0x28	# DW_OP_bra\n\t"
+	".2byte	18f-17f\n"
+"17:\t"	".byte	0x23	# DW_OP_plus_uconst\n\t"
+	".uleb128 4b-3b\n\t"
+	".byte	0x2f	# DW_OP_skip\n\t"
+	".2byte	12b-18f\n"
+"18:\t"	".byte	0x23	# DW_OP_plus_uconst\n\t"
+	".uleb128 1\n\t"
+	".byte	0x12	# DW_OP_dup\n\t"
+	".byte	0x94	# DW_OP_deref_size\n\t"
+	".byte	4\n\t"
+	".byte	0x08	# DW_OP_const1u\n\t"
+	".byte	72 - (6b-5b) * 8 # (6b-5b) == 5 ? 32 : 56\n\t"
+	".byte	0x24	# DW_OP_shl\n\t"
+	".byte	0x08	# DW_OP_const1u\n\t"
+	".byte	72 - (6b-5b) * 8 # (6b-5b) == 5 ? 32 : 56\n\t"
+	".byte	0x26	# DW_OP_shra\n\t"
+	".byte	0x22	# DW_OP_plus\n\t"
+	".byte	0x23	# DW_OP_plus_uconst\n\t"
+	".uleb128 6b-5b-1\n"
+"19:\t"	".byte	0x40 + (3b-1b) # DW_CFA_advance_loc\n\t"
+	".byte	0xe	# DW_CFA_def_cfa_offset\n\t"
+	".uleb128 128\n\t"
+	".byte	0x40 + (5b-3b) # DW_CFA_advance_loc\n\t"
+	".byte	0xe	# DW_CFA_def_cfa_offset\n\t"
+	".uleb128 0\n\t"
+	".align 8\n"
+"20:\t"	".previous\n"
+"21:"
+	: : "r" (x), "m" (x), "r" (buf)
+	: "memory", "rax", "rdx", "rcx", "rsi", "rdi",
+	  "r8", "r9", "r10", "r11");
+#else
+# error Unsupported test architecture
+#endif
+}
+
+static int __attribute__((noinline))
+fn2 (void)
+{
+  foo (3);
+  return 0;
+}
+
+static int __attribute__((noinline))
+fn1 (void)
+{
+  fn2 ();
+  return 0;
+}
+
+static void *
+fn0 (void)
+{
+  char dummy __attribute__((cleanup (handler)));
+  fn1 ();
+  return 0;
+}
+
+int
+main (void)
+{
+  fn0 ();
+  return 0;
+}
Index: gdb/testsuite/gdb.dwarf2/cfa-val-expr.exp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gdb/testsuite/gdb.dwarf2/cfa-val-expr.exp	2006-03-07 02:06:07.000000000 -0300
@@ -0,0 +1,91 @@
+# Copyright 2006 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Alexandre Oliva <aoliva@redhat.com>
+
+if $tracelevel then {
+	strace $tracelevel
+	}
+
+set prms_id 0
+set bug_id 0
+
+# signal-augm.S needs hand-coded assembly
+if {![istarget i*86-*-linux*]
+    && ![istarget x86_64-*-linux*]} {
+    return -1;
+}
+
+if [get_compiler_info "ignored"] {
+    return -1
+}
+
+if {$gcc_compiled == 0} {
+    return -1
+}
+
+set tnum 1
+set testfile "cfa-val-expr-$tnum"
+
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcfile}" "${binfile}" executable [list debug "additional_flags=-fexceptions -fnon-call-exceptions -fasynchronous-unwind-tables -O2"]] != ""} {
+    return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+    gdb_step_for_stub;
+}
+
+gdb_test "break fn5" "Breakpoint.*at.*" "breakpoint fn5 ($tnum)"
+gdb_test "run" ".*Breakpoint 1.*" "stopped at fn5 ($tnum)"
+gdb_test "backtrace" ".*\#0 .* fn5 .*\#1 .* bar .*\#2 .* _L_mutex.* .*\#3 .* foo .*\#4 .* fn2 .*\#5 .* fn1 .*\#6 .* main.*" "backtrace ($tnum)"
+
+if {![istarget x86_64-*-linux*]} {
+    return 0;
+}
+
+set tnum 2
+set testfile "cfa-val-expr-$tnum"
+
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcfile}" "${binfile}" executable [list debug "additional_flags=-fexceptions -fnon-call-exceptions -fasynchronous-unwind-tables -O2"]] != ""} {
+    return -1;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+    gdb_step_for_stub;
+}
+
+gdb_test "break fn5" "Breakpoint.*at.*" "breakpoint fn5 ($tnum)"
+gdb_test "run" ".*Breakpoint 1.*" "stopped at fn5 ($tnum)"
+gdb_test "backtrace" ".*\#0 .* fn5 .*\#1 .* bar .*\#2 .* _L_mutex.* .*\#3 .* foo .*\#4 .* fn2 .*\#5 .* fn1 .*\#6 .* main.*" "backtrace ($tnum)"
+
+return 0
-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Secretary for FSF Latin America        http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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