summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/c-cppbuiltin.c2
-rw-r--r--gcc/config.in6
-rwxr-xr-xgcc/configure42
-rw-r--r--gcc/configure.ac14
-rw-r--r--gcc/debug.h1
-rw-r--r--gcc/dwarf2out.c36
7 files changed, 102 insertions, 9 deletions
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 <rth@redhat.com>
+
+ * 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 <joseph@codesourcery.com>
* 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