Author: robert
Date: 2007-03-30 06:32:39 -0600 (Fri, 30 Mar 2007)
New Revision: 1785

Added:
   trunk/gcc/gcc-4.1.2-DW_CFA_val-1.patch
Log:
Added GCC-4.2 back port, to GCC-4.1, patch for new DWARF3 CFA opcodes, which 
are used by recent Binutils, Glibc, and GDB releases.

Added: trunk/gcc/gcc-4.1.2-DW_CFA_val-1.patch
===================================================================
--- trunk/gcc/gcc-4.1.2-DW_CFA_val-1.patch                              (rev 0)
+++ trunk/gcc/gcc-4.1.2-DW_CFA_val-1.patch      2007-03-30 12:32:39 UTC (rev 
1785)
@@ -0,0 +1,858 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
+Date: 2007-03-30
+Initial Package Version: 4.1.2
+Upstream Status: From Upstream
+Origin: http://cvs.archlinuxppc.org/viewcvs/base/gcc/DW_CFA_val.patch
+       Back port from gcc-4.2:
+       http://gcc.gnu.org/ml/gcc-patches/2006-03/msg00208.html
+       http://gcc.gnu.org/viewcvs?view=rev&revision=111705
+Description: This patch fixes a Glibc test 'nptl/tst-cancel1' failure. See:
+            http://sources.redhat.com/ml/libc-alpha/2006-09/msg00039.html
+
+2006-03-03  Jakub Jelinek  <[EMAIL PROTECTED]>
+
+       * unwind-dw2.h (_Unwind_FrameState): Add REG_SAVED_VAL_OFFSET
+       and REG_SAVED_VAL_EXP constants.
+       * unwind-dw2.c (struct _Unwind_Context): Add by_value array.
+       (_Unwind_GetGR, _Unwind_SetGR, _Unwind_GetGRPtr, _Unwind_SetGRPtr):
+       Handle regs stored by value.
+       (_Unwind_SetGRValue, _Unwind_GRByValue): New functions.
+       (execute_cfa_program): Handle DW_CFA_val_offset,
+       DW_CFA_val_offset_sf and DW_CFA_val_expression.
+       (uw_update_context_1): Handle REG_SAVED_REG with regs stored by
+       value specially.  Handle REG_SAVED_VAL_OFFSET and REG_SAVED_VAL_EXP.
+       (uw_install_context_1): Handle target regs stored by value.
+
+       * gcc.target/i386/cleanup-1.c: New test.
+       * gcc.target/i386/cleanup-2.c: New test.
+
+diff -Naur gcc-4.1.2.orig/gcc/dwarf2.h gcc-4.1.2/gcc/dwarf2.h
+--- gcc-4.1.2.orig/gcc/dwarf2.h        2005-06-25 02:02:01.000000000 +0000
++++ gcc-4.1.2/gcc/dwarf2.h     2007-03-30 12:08:32.000000000 +0000
+@@ -1,7 +1,7 @@
+-/* Declarations and definitions of codes relating to the DWARF2 symbolic
+-   debugging information format.
++/* Declarations and definitions of codes relating to the DWARF2 and
++   DWARF3 symbolic debugging information formats.
+    Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
+-   2003, 2004 Free Software Foundation, Inc.
++   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ 
+    Written by Gary Funck ([EMAIL PROTECTED]) The Ada Joint Program
+    Office (AJPO), Florida State University and Silicon Graphics Inc.
+@@ -187,6 +187,8 @@
+     DW_TAG_unspecified_type = 0x3b,
+     DW_TAG_partial_unit = 0x3c,
+     DW_TAG_imported_unit = 0x3d,
++    DW_TAG_condition = 0x3f,
++    DW_TAG_shared_type = 0x40,
+     /* SGI/MIPS Extensions.  */
+     DW_TAG_MIPS_loop = 0x4081,
+     /* HP extensions.  See: 
ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .  */
+@@ -317,6 +319,21 @@
+     DW_AT_call_column   = 0x57,
+     DW_AT_call_file     = 0x58,
+     DW_AT_call_line     = 0x59,
++    DW_AT_description   = 0x5a,
++    DW_AT_binary_scale  = 0x5b,
++    DW_AT_decimal_scale = 0x5c,
++    DW_AT_small         = 0x5d,
++    DW_AT_decimal_sign  = 0x5e,
++    DW_AT_digit_count   = 0x5f,
++    DW_AT_picture_string = 0x60,
++    DW_AT_mutable       = 0x61,
++    DW_AT_threads_scaled = 0x62,
++    DW_AT_explicit      = 0x63,
++    DW_AT_object_pointer = 0x64,
++    DW_AT_endianity     = 0x65,
++    DW_AT_elemental     = 0x66,
++    DW_AT_pure          = 0x67,
++    DW_AT_recursive     = 0x68,
+     /* SGI/MIPS extensions.  */
+     DW_AT_MIPS_fde = 0x2001,
+     DW_AT_MIPS_loop_begin = 0x2002,
+@@ -518,6 +535,9 @@
+     DW_OP_call2 = 0x98,
+     DW_OP_call4 = 0x99,
+     DW_OP_call_ref = 0x9a,
++    DW_OP_form_tls_address = 0x9b,
++    DW_OP_call_frame_cfa = 0x9c,
++    DW_OP_bit_piece = 0x9d,
+     /* GNU extensions.  */
+     DW_OP_GNU_push_tls_address = 0xe0,
+     /* HP extensions.  */
+@@ -547,6 +567,12 @@
+     DW_ATE_unsigned_char = 0x8,
+     /* DWARF 3.  */
+     DW_ATE_imaginary_float = 0x9,
++    DW_ATE_packed_decimal = 0xa,
++    DW_ATE_numeric_string = 0xb,
++    DW_ATE_edited = 0xc,
++    DW_ATE_signed_fixed = 0xd,
++    DW_ATE_unsigned_fixed = 0xe,
++    DW_ATE_decimal_float = 0xf,
+     /* HP extensions.  */
+     DW_ATE_HP_float80            = 0x80, /* Floating-point (80 bit).  */
+     DW_ATE_HP_complex_float80    = 0x81, /* Complex floating-point (80 bit).  
*/
+@@ -560,6 +586,29 @@
+ #define       DW_ATE_lo_user 0x80
+ #define       DW_ATE_hi_user 0xff
+ 
++/* Decimal sign encodings.  */
++enum dwarf_decimal_sign_encoding
++  {
++    /* DWARF 3.  */
++    DW_DS_unsigned = 0x01,
++    DW_DS_leading_overpunch = 0x02,
++    DW_DS_trailing_overpunch = 0x03,
++    DW_DS_leading_separate = 0x04,
++    DW_DS_trailing_separate = 0x05
++  };
++
++/* Endianity encodings.  */
++enum dwarf_endianity_encoding
++  {
++    /* DWARF 3.  */
++    DW_END_default = 0x00,
++    DW_END_big = 0x01,
++    DW_END_little = 0x02
++  };
++
++#define DW_END_lo_user 0x40
++#define DW_END_hi_user 0xff
++
+ /* Array ordering names and codes.  */
+ enum dwarf_array_dim_ordering
+   {
+@@ -666,6 +715,9 @@
+     DW_LNE_HP_define_proc              = 0x20
+   };
+ 
++#define DW_LNE_lo_user 0x80
++#define DW_LNE_hi_user 0xff
++
+ /* Call frame information.  */
+ enum dwarf_call_frame_info
+   {
+@@ -693,6 +745,9 @@
+     DW_CFA_offset_extended_sf = 0x11,
+     DW_CFA_def_cfa_sf = 0x12,
+     DW_CFA_def_cfa_offset_sf = 0x13,
++    DW_CFA_val_offset = 0x14,
++    DW_CFA_val_offset_sf = 0x15,
++    DW_CFA_val_expression = 0x16,
+     /* SGI/MIPS specific.  */
+     DW_CFA_MIPS_advance_loc8 = 0x1d,
+     /* GNU extensions.  */
+@@ -726,11 +781,16 @@
+     DW_LANG_Fortran90 = 0x0008,
+     DW_LANG_Pascal83 = 0x0009,
+     DW_LANG_Modula2 = 0x000a,
+-    DW_LANG_Java = 0x000b,
+     /* DWARF 3.  */
++    DW_LANG_Java = 0x000b,
+     DW_LANG_C99 = 0x000c,
+     DW_LANG_Ada95 = 0x000d,
+     DW_LANG_Fortran95 = 0x000e,
++    DW_LANG_PLI = 0x000f,
++    DW_LANG_ObjC = 0x0010,
++    DW_LANG_ObjC_plus_plus = 0x0011,
++    DW_LANG_UPC = 0x0012,
++    DW_LANG_D = 0x0013,
+     /* MIPS.  */
+     DW_LANG_Mips_Assembler = 0x8001,
+     /* UPC.  */
+diff -Naur gcc-4.1.2.orig/gcc/testsuite/gcc.target/i386/cleanup-1.c 
gcc-4.1.2/gcc/testsuite/gcc.target/i386/cleanup-1.c
+--- gcc-4.1.2.orig/gcc/testsuite/gcc.target/i386/cleanup-1.c   1970-01-01 
00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/testsuite/gcc.target/i386/cleanup-1.c        2007-03-30 
12:08:32.000000000 +0000
+@@ -0,0 +1,240 @@
++/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
++/* { dg-options "-fexceptions -fnon-call-exceptions 
-fasynchronous-unwind-tables -O2" } */
++/* 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;
++}
+diff -Naur gcc-4.1.2.orig/gcc/testsuite/gcc.target/i386/cleanup-2.c 
gcc-4.1.2/gcc/testsuite/gcc.target/i386/cleanup-2.c
+--- gcc-4.1.2.orig/gcc/testsuite/gcc.target/i386/cleanup-2.c   1970-01-01 
00:00:00.000000000 +0000
++++ gcc-4.1.2/gcc/testsuite/gcc.target/i386/cleanup-2.c        2007-03-30 
12:08:32.000000000 +0000
+@@ -0,0 +1,205 @@
++/* { dg-do run { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } } */
++/* { dg-options "-fexceptions -fnon-call-exceptions 
-fasynchronous-unwind-tables -O2" } */
++/* 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;
++}
+diff -Naur gcc-4.1.2.orig/gcc/unwind-dw2.c gcc-4.1.2/gcc/unwind-dw2.c
+--- gcc-4.1.2.orig/gcc/unwind-dw2.c    2005-11-18 01:19:10.000000000 +0000
++++ gcc-4.1.2/gcc/unwind-dw2.c 2007-03-30 12:08:32.000000000 +0000
+@@ -71,6 +71,7 @@
+   void *lsda;
+   struct dwarf_eh_bases bases;
+   _Unwind_Word args_size;
++  char by_value[DWARF_FRAME_REGISTERS+1];
+ };
+ 
+ /* Byte size of every register managed by these routines.  */
+@@ -117,7 +118,7 @@
+ static inline unsigned long
+ read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
+ 
+-/* Get the value of register REG as saved in CONTEXT.  */
++/* Get the value of register INDEX as saved in CONTEXT.  */
+ 
+ inline _Unwind_Word
+ _Unwind_GetGR (struct _Unwind_Context *context, int index)
+@@ -135,6 +136,9 @@
+   size = dwarf_reg_size_table[index];
+   ptr = context->reg[index];
+ 
++  if (context->by_value[index])
++    return (_Unwind_Word) (_Unwind_Internal_Ptr) ptr;
++
+   /* This will segfault if the register hasn't been saved.  */
+   if (size == sizeof(_Unwind_Ptr))
+     return * (_Unwind_Ptr *) ptr;
+@@ -159,7 +163,7 @@
+   return (_Unwind_Ptr) context->cfa;
+ }
+ 
+-/* Overwrite the saved value for register REG in CONTEXT with VAL.  */
++/* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */
+ 
+ inline void
+ _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
+@@ -170,6 +174,13 @@
+   index = DWARF_REG_TO_UNWIND_COLUMN (index);
+   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
+   size = dwarf_reg_size_table[index];
++
++  if (context->by_value[index])
++    {
++      context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
++      return;
++    }
++
+   ptr = context->reg[index];
+ 
+   if (size == sizeof(_Unwind_Ptr))
+@@ -187,6 +198,8 @@
+ _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
+ {
+   index = DWARF_REG_TO_UNWIND_COLUMN (index);
++  if (context->by_value[index])
++    return &context->reg[index];
+   return context->reg[index];
+ }
+ 
+@@ -196,9 +209,34 @@
+ _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
+ {
+   index = DWARF_REG_TO_UNWIND_COLUMN (index);
++  context->by_value[index] = 0;
+   context->reg[index] = p;
+ }
+ 
++/* Overwrite the saved value for register INDEX in CONTEXT with VAL.  */
++
++static inline void
++_Unwind_SetGRValue (struct _Unwind_Context *context, int index,
++                  _Unwind_Word val)
++{
++  index = DWARF_REG_TO_UNWIND_COLUMN (index);
++  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
++  gcc_assert (dwarf_reg_size_table[index] == sizeof (_Unwind_Ptr));
++
++  context->by_value[index] = 1;
++  context->reg[index] = (void *) (_Unwind_Internal_Ptr) val;
++}
++
++/* Return non-zero if register INDEX is stored by value rather than
++   by reference.  */
++
++static inline int
++_Unwind_GRByValue (struct _Unwind_Context *context, int index)
++{
++  index = DWARF_REG_TO_UNWIND_COLUMN (index);
++  return context->by_value[index];
++}
++
+ /* Retrieve the return address for CONTEXT.  */
+ 
+ inline _Unwind_Ptr
+@@ -902,7 +940,7 @@
+         insn_ptr += utmp;
+         break;
+ 
+-        /* From the dwarf3 draft.  */
++        /* Dwarf3.  */
+       case DW_CFA_offset_extended_sf:
+         insn_ptr = read_uleb128 (insn_ptr, &reg);
+         insn_ptr = read_sleb128 (insn_ptr, &stmp);
+@@ -925,6 +963,33 @@
+         /* cfa_how deliberately not set.  */
+         break;
+ 
++      case DW_CFA_val_offset:
++        insn_ptr = read_uleb128 (insn_ptr, &reg);
++        insn_ptr = read_uleb128 (insn_ptr, &utmp);
++        offset = (_Unwind_Sword) utmp * fs->data_align;
++        fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
++          = REG_SAVED_VAL_OFFSET;
++        fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
++        break;
++
++      case DW_CFA_val_offset_sf:
++        insn_ptr = read_uleb128 (insn_ptr, &reg);
++        insn_ptr = read_sleb128 (insn_ptr, &stmp);
++        offset = stmp * fs->data_align;
++        fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
++          = REG_SAVED_VAL_OFFSET;
++        fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
++        break;
++
++      case DW_CFA_val_expression:
++        insn_ptr = read_uleb128 (insn_ptr, &reg);
++        fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
++          = REG_SAVED_VAL_EXP;
++        fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
++        insn_ptr = read_uleb128 (insn_ptr, &utmp);
++        insn_ptr += utmp;
++        break;
++
+       case DW_CFA_GNU_window_save:
+         /* ??? Hardcoded for SPARC register window configuration.  */
+         for (reg = 16; reg < 32; ++reg)
+@@ -1092,7 +1157,7 @@
+ 
+ static inline void
+ _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
+-                     _Unwind_SpTmp *tmp_sp)
++                   _Unwind_SpTmp *tmp_sp)
+ {
+   int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
+   
+@@ -1173,9 +1238,14 @@
+       break;
+ 
+       case REG_SAVED_REG:
+-      _Unwind_SetGRPtr
+-        (context, i,
+-         _Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
++      if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
++        _Unwind_SetGRValue (context, i,
++                            _Unwind_GetGR (&orig_context,
++                                           fs->regs.reg[i].loc.reg));
++      else
++        _Unwind_SetGRPtr (context, i,
++                          _Unwind_GetGRPtr (&orig_context,
++                                            fs->regs.reg[i].loc.reg));
+       break;
+ 
+       case REG_SAVED_EXP:
+@@ -1190,6 +1260,25 @@
+         _Unwind_SetGRPtr (context, i, (void *) val);
+       }
+       break;
++
++      case REG_SAVED_VAL_OFFSET:
++      _Unwind_SetGRValue (context, i,
++                          (_Unwind_Internal_Ptr)
++                          (cfa + fs->regs.reg[i].loc.offset));
++      break;
++
++      case REG_SAVED_VAL_EXP:
++      {
++        const unsigned char *exp = fs->regs.reg[i].loc.exp;
++        _Unwind_Word len;
++        _Unwind_Ptr val;
++
++        exp = read_uleb128 (exp, &len);
++        val = execute_stack_op (exp, exp + len, &orig_context,
++                                (_Unwind_Ptr) cfa);
++        _Unwind_SetGRValue (context, i, val);
++      }
++      break;
+       }
+ 
+ #ifdef MD_FROB_UPDATE_CONTEXT
+@@ -1304,14 +1393,31 @@
+   /* If the target frame does not have a saved stack pointer,
+      then set up the target's CFA.  */
+   if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
+-      _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
++    _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
+ 
+   for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
+     {
+       void *c = current->reg[i];
+       void *t = target->reg[i];
+ 
+-      if (t && c && t != c)
++      gcc_assert (current->by_value[i] == 0);
++      if (target->by_value[i] && c)
++      {
++        _Unwind_Word w;
++        _Unwind_Ptr p;
++        if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
++          {
++            w = (_Unwind_Internal_Ptr) t;
++            memcpy (c, &w, sizeof (_Unwind_Word));
++          }
++        else
++          {
++            gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
++            p = (_Unwind_Internal_Ptr) t;
++            memcpy (c, &p, sizeof (_Unwind_Ptr));
++          }
++      }
++      else if (t && c && t != c)
+       memcpy (c, t, dwarf_reg_size_table[i]);
+     }
+ 
+diff -Naur gcc-4.1.2.orig/gcc/unwind-dw2.h gcc-4.1.2/gcc/unwind-dw2.h
+--- gcc-4.1.2.orig/gcc/unwind-dw2.h    2005-06-25 02:02:01.000000000 +0000
++++ gcc-4.1.2/gcc/unwind-dw2.h 2007-03-30 12:08:32.000000000 +0000
+@@ -53,7 +53,9 @@
+       REG_UNSAVED,
+       REG_SAVED_OFFSET,
+       REG_SAVED_REG,
+-      REG_SAVED_EXP
++      REG_SAVED_EXP,
++      REG_SAVED_VAL_OFFSET,
++      REG_SAVED_VAL_EXP
+       } how;
+     } reg[DWARF_FRAME_REGISTERS+1];
+ 

-- 
http://linuxfromscratch.org/mailman/listinfo/patches
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to