diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd32e35da0d..3ec7ba792c4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2008-08-07 Richard Henderson + + * configure.ac (HAVE_GAS_CFI_PERSONALITY_DIRECTIVE): New. + * configure, config.in: Rebuild. + * debug.h (dwarf2out_do_cfi_asm): Declare. + * c-cppbuiltin.c (c_cpp_builtins): Use it. + * dwarf2out.c (dwarf2out_do_cfi_asm): New. + (dwarf2out_cfi_label, add_fde_cfi, output_call_frame_info, + dwarf2out_begin_prologue, dwarf2out_end_epilogue): Use it. + 2008-08-07 Joseph Myers * config/arm/iwmmxt.md (movv8qi_internal, movv4hi_internal, diff --git a/gcc/c-cppbuiltin.c b/gcc/c-cppbuiltin.c index 01f92155fd6..cbd56b4f793 100644 --- a/gcc/c-cppbuiltin.c +++ b/gcc/c-cppbuiltin.c @@ -693,7 +693,7 @@ c_cpp_builtins (cpp_reader *pfile) #endif #ifdef DWARF2_UNWIND_INFO - if (flag_dwarf2_cfi_asm && dwarf2out_do_frame ()) + if (dwarf2out_do_cfi_asm ()) cpp_define (pfile, "__GCC_HAVE_DWARF2_CFI_ASM"); #endif diff --git a/gcc/config.in b/gcc/config.in index 47ec2ab2fe2..209da217a82 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -827,6 +827,12 @@ #endif +/* Define 0/1 if your assembler supports .cfi_personality. */ +#ifndef USED_FOR_TARGET +#undef HAVE_GAS_CFI_PERSONALITY_DIRECTIVE +#endif + + /* Define if your assembler uses the new HImode fild and fist notation. */ #ifndef USED_FOR_TARGET #undef HAVE_GAS_FILDS_FISTS diff --git a/gcc/configure b/gcc/configure index 0ad273b0cfa..3625898cc9e 100755 --- a/gcc/configure +++ b/gcc/configure @@ -20851,7 +20851,6 @@ fi .cfi_same_value 1 .cfi_def_cfa 1, 2 .cfi_escape 1, 2, 3, 4, 5 - .cfi_personality 0, symbol .cfi_endproc' > conftest.s if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 @@ -20877,6 +20876,47 @@ cat >>confdefs.h <<_ACEOF _ACEOF +echo "$as_me:$LINENO: checking assembler for cfi personality directive" >&5 +echo $ECHO_N "checking assembler for cfi personality directive... $ECHO_C" >&6 +if test "${gcc_cv_as_cfi_personality_directive+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + gcc_cv_as_cfi_personality_directive=no + if test $in_tree_gas = yes; then + if test $in_tree_gas_is_elf = yes \ + && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 17 \) \* 1000 + 0` + then gcc_cv_as_cfi_personality_directive=yes +fi + elif test x$gcc_cv_as != x; then + echo ' .text + .cfi_startproc, + .cfi_personality 0, symbol + .cfi_endproc' > conftest.s + if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } + then + gcc_cv_as_cfi_personality_directive=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +echo "$as_me:$LINENO: result: $gcc_cv_as_cfi_personality_directive" >&5 +echo "${ECHO_T}$gcc_cv_as_cfi_personality_directive" >&6 + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GAS_CFI_PERSONALITY_DIRECTIVE `if test $gcc_cv_as_cfi_personality_directive = yes; + then echo 1; else echo 0; fi` +_ACEOF + + # GAS versions up to and including 2.11.0 may mis-optimize # .eh_frame data. echo "$as_me:$LINENO: checking assembler for eh_frame optimization" >&5 diff --git a/gcc/configure.ac b/gcc/configure.ac index f2f0eea0b92..a79107fb65e 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -2189,11 +2189,21 @@ gcc_GAS_CHECK_FEATURE([cfi directives], gcc_cv_as_cfi_directive, .cfi_same_value 1 .cfi_def_cfa 1, 2 .cfi_escape 1, 2, 3, 4, 5 - .cfi_personality 0, symbol .cfi_endproc]) AC_DEFINE_UNQUOTED(HAVE_GAS_CFI_DIRECTIVE, [`if test $gcc_cv_as_cfi_directive = yes; then echo 1; else echo 0; fi`], -[Define 0/1 if your assembler supports CFI directives.]) + [Define 0/1 if your assembler supports CFI directives.]) + +gcc_GAS_CHECK_FEATURE([cfi personality directive], + gcc_cv_as_cfi_personality_directive, [elf,2,17,0],, +[ .text + .cfi_startproc, + .cfi_personality 0, symbol + .cfi_endproc]) +AC_DEFINE_UNQUOTED(HAVE_GAS_CFI_PERSONALITY_DIRECTIVE, + [`if test $gcc_cv_as_cfi_personality_directive = yes; + then echo 1; else echo 0; fi`], + [Define 0/1 if your assembler supports .cfi_personality.]) # GAS versions up to and including 2.11.0 may mis-optimize # .eh_frame data. diff --git a/gcc/debug.h b/gcc/debug.h index cab1e2603e2..6cdf7863a25 100644 --- a/gcc/debug.h +++ b/gcc/debug.h @@ -160,6 +160,7 @@ extern void dwarf2out_frame_finish (void); /* Decide whether we want to emit frame unwind information for the current translation unit. */ extern int dwarf2out_do_frame (void); +extern int dwarf2out_do_cfi_asm (void); extern void dwarf2out_switch_text_section (void); extern void debug_flush_symbol_queue (void); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index ad09949cc15..ced629dfda7 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -130,6 +130,32 @@ dwarf2out_do_frame (void) ); } +/* Decide whether to emit frame unwind via assembler directives. */ + +int +dwarf2out_do_cfi_asm (void) +{ + int enc; + + if (!flag_dwarf2_cfi_asm || !dwarf2out_do_frame ()) + return false; + if (!eh_personality_libfunc) + return true; + if (!HAVE_GAS_CFI_PERSONALITY_DIRECTIVE) + return false; + + /* Make sure the personality encoding is one the assembler can support. + In particular, aligned addresses can't be handled. */ + enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2,/*global=*/1); + if ((enc & 0x70) != 0 && (enc & 0x70) != DW_EH_PE_pcrel) + return false; + enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0,/*global=*/0); + if ((enc & 0x70) != 0 && (enc & 0x70) != DW_EH_PE_pcrel) + return false; + + return true; +} + /* The size of the target's pointer type. */ #ifndef PTR_SIZE #define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT) @@ -667,7 +693,7 @@ dwarf2out_cfi_label (void) { static char label[20]; - if (flag_dwarf2_cfi_asm) + if (dwarf2out_do_cfi_asm ()) { /* In this case, we will be emitting the asm directive instead of the label, so just return a placeholder to keep the rest of the @@ -691,7 +717,7 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi) { dw_cfi_ref *list_head = &cie_cfi_head; - if (flag_dwarf2_cfi_asm) + if (dwarf2out_do_cfi_asm ()) { if (label) { @@ -2767,7 +2793,7 @@ output_call_frame_info (int for_eh) return; /* Nothing to do if the assembler's doing it all. */ - if (flag_dwarf2_cfi_asm) + if (dwarf2out_do_cfi_asm ()) return; /* If we make FDEs linkonce, we may have to emit an empty label for @@ -3187,7 +3213,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, dwarf2out_source_line (line, file); #endif - if (flag_dwarf2_cfi_asm) + if (dwarf2out_do_cfi_asm ()) { int enc; rtx ref; @@ -3242,7 +3268,7 @@ dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED, dw_fde_ref fde; char label[MAX_ARTIFICIAL_LABEL_BYTES]; - if (flag_dwarf2_cfi_asm) + if (dwarf2out_do_cfi_asm ()) fprintf (asm_out_file, "\t.cfi_endproc\n"); /* Output a label to mark the endpoint of the code generated for this