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, ®); + 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, ®); ++ 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, ®); ++ 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, ®); ++ 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
