summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-02 17:30:07 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-02 17:30:07 +0000
commit11f8ac85df3620e926f8eb0d132fa3a71a9b433a (patch)
tree624e4795d248327ef48a277a8b18931e053892e9
parent7e637ed2e8bb071ab74e7f2fc29926f1cdf1d240 (diff)
downloadgcc-11f8ac85df3620e926f8eb0d132fa3a71a9b433a.tar.gz
reflect: Use hand-coded .eh_frame section rather than CFI directives.
From Rainer Orth. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203120 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libgo/config.h.in12
-rwxr-xr-xlibgo/configure95
-rw-r--r--libgo/configure.ac62
-rw-r--r--libgo/go/reflect/makefunc_386.S116
-rw-r--r--libgo/go/reflect/makefunc_amd64.S67
5 files changed, 331 insertions, 21 deletions
diff --git a/libgo/config.h.in b/libgo/config.h.in
index 349ace6a2ad..1057d9e85e4 100644
--- a/libgo/config.h.in
+++ b/libgo/config.h.in
@@ -3,6 +3,9 @@
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
+/* Define to the flags needed for the .section .eh_frame directive. */
+#undef EH_FRAME_FLAGS
+
/* Define to 1 if you have the `accept4' function. */
#undef HAVE_ACCEPT4
@@ -12,6 +15,15 @@
/* Define to 1 if you have the `asinl' function. */
#undef HAVE_ASINL
+/* Define if your assembler supports GNU comdat group syntax. */
+#undef HAVE_AS_COMDAT_GAS
+
+/* Define if your assembler supports unwind section type. */
+#undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
+
+/* Define if your assembler supports PC relative relocs. */
+#undef HAVE_AS_X86_PCREL
+
/* Define to 1 if you have the `atan2l' function. */
#undef HAVE_ATAN2L
diff --git a/libgo/configure b/libgo/configure
index a1e045cb625..40aeb0db211 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -15179,6 +15179,101 @@ $as_echo "#define SETCONTEXT_CLOBBERS_TLS 1" >>confdefs.h
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether .eh_frame section should be read-only" >&5
+$as_echo_n "checking whether .eh_frame section should be read-only... " >&6; }
+if test "${libgo_cv_ro_eh_frame+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+libgo_cv_ro_eh_frame=no
+echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+ if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+ libgo_cv_ro_eh_frame=yes
+ elif grep '.section.*eh_frame.*#alloc' conftest.c \
+ | grep -v '#write' > /dev/null; then
+ libgo_cv_ro_eh_frame=yes
+ fi
+fi
+rm -f conftest.*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_ro_eh_frame" >&5
+$as_echo "$libgo_cv_ro_eh_frame" >&6; }
+if test "x$libgo_cv_ro_eh_frame" = xyes; then
+
+$as_echo "#define EH_FRAME_FLAGS \"a\"" >>confdefs.h
+
+else
+
+$as_echo "#define EH_FRAME_FLAGS \"aw\"" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler supports GNU comdat group syntax" >&5
+$as_echo_n "checking if assembler supports GNU comdat group syntax... " >&6; }
+if test "${libgo_cv_as_comdat_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+echo '.section .text,"axG",@progbits,.foo,comdat' > conftest.s
+if $CC $CFLAGS -c conftest.s > /dev/null 2>&1; then
+ libgo_cv_as_comdat_gnu=yes
+else
+ libgo_cv_as_comdat_gnu=no
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_as_comdat_gnu" >&5
+$as_echo "$libgo_cv_as_comdat_gnu" >&6; }
+if test "x$libgo_cv_as_comdat_gnu" = xyes; then
+
+$as_echo "#define HAVE_AS_COMDAT_GAS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports pc related relocs" >&5
+$as_echo_n "checking assembler supports pc related relocs... " >&6; }
+if test "${libgo_cv_as_x86_pcrel+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+libgo_cv_as_x86_pcrel=yes
+echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
+if $CC $CFLAGS -c conftest.s 2>&1 | $EGREP -i 'illegal|warning' > /dev/null; then
+ libgo_cv_as_x86_pcrel=no
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_as_x86_pcrel" >&5
+$as_echo "$libgo_cv_as_x86_pcrel" >&6; }
+if test "x$libgo_cv_as_x86_pcrel" = xyes; then
+
+$as_echo "#define HAVE_AS_X86_PCREL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports unwind section type" >&5
+$as_echo_n "checking assembler supports unwind section type... " >&6; }
+if test "${libgo_cv_as_x86_64_unwind_section_type+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+libgo_cv_as_x86_64_unwind_section_type=yes
+echo '.section .eh_frame,"a",@unwind' > conftest.s
+if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
+ libgo_cv_as_x86_64_unwind_section_type=no
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_as_x86_64_unwind_section_type" >&5
+$as_echo "$libgo_cv_as_x86_64_unwind_section_type" >&6; }
+if test "x$libgo_cv_as_x86_64_unwind_section_type" = xyes; then
+
+$as_echo "#define HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1" >>confdefs.h
+
+fi
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
diff --git a/libgo/configure.ac b/libgo/configure.ac
index 002aa88675c..ef5ea8396dd 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -757,6 +757,68 @@ if test "$libgo_cv_lib_setcontext_clobbers_tls" = "yes"; then
[Define if setcontext clobbers TLS variables])
fi
+AC_CACHE_CHECK([whether .eh_frame section should be read-only],
+libgo_cv_ro_eh_frame, [
+libgo_cv_ro_eh_frame=no
+echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
+ if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
+ libgo_cv_ro_eh_frame=yes
+ elif grep '.section.*eh_frame.*#alloc' conftest.c \
+ | grep -v '#write' > /dev/null; then
+ libgo_cv_ro_eh_frame=yes
+ fi
+fi
+rm -f conftest.*
+])
+if test "x$libgo_cv_ro_eh_frame" = xyes; then
+ AC_DEFINE(EH_FRAME_FLAGS, "a",
+ [Define to the flags needed for the .section .eh_frame directive.])
+else
+ AC_DEFINE(EH_FRAME_FLAGS, "aw",
+ [Define to the flags needed for the .section .eh_frame directive.])
+fi
+
+AC_CACHE_CHECK([if assembler supports GNU comdat group syntax],
+libgo_cv_as_comdat_gnu, [
+echo '.section .text,"axG",@progbits,.foo,comdat' > conftest.s
+if $CC $CFLAGS -c conftest.s > /dev/null 2>&1; then
+ libgo_cv_as_comdat_gnu=yes
+else
+ libgo_cv_as_comdat_gnu=no
+fi
+])
+if test "x$libgo_cv_as_comdat_gnu" = xyes; then
+ AC_DEFINE(HAVE_AS_COMDAT_GAS, 1,
+ [Define if your assembler supports GNU comdat group syntax.])
+fi
+
+AC_CACHE_CHECK([assembler supports pc related relocs],
+libgo_cv_as_x86_pcrel, [
+libgo_cv_as_x86_pcrel=yes
+echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
+if $CC $CFLAGS -c conftest.s 2>&1 | $EGREP -i 'illegal|warning' > /dev/null; then
+ libgo_cv_as_x86_pcrel=no
+fi
+])
+if test "x$libgo_cv_as_x86_pcrel" = xyes; then
+ AC_DEFINE(HAVE_AS_X86_PCREL, 1,
+ [Define if your assembler supports PC relative relocs.])
+fi
+
+AC_CACHE_CHECK([assembler supports unwind section type],
+libgo_cv_as_x86_64_unwind_section_type, [
+libgo_cv_as_x86_64_unwind_section_type=yes
+echo '.section .eh_frame,"a",@unwind' > conftest.s
+if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
+ libgo_cv_as_x86_64_unwind_section_type=no
+fi
+])
+if test "x$libgo_cv_as_x86_64_unwind_section_type" = xyes; then
+ AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
+ [Define if your assembler supports unwind section type.])
+fi
+
AC_CACHE_SAVE
if test ${multilib} = yes; then
diff --git a/libgo/go/reflect/makefunc_386.S b/libgo/go/reflect/makefunc_386.S
index f2f2fbe1a95..fb49281e2e3 100644
--- a/libgo/go/reflect/makefunc_386.S
+++ b/libgo/go/reflect/makefunc_386.S
@@ -4,6 +4,8 @@
# MakeFunc 386 assembly code.
+#include "config.h"
+
.global reflect.makeFuncStub
#ifdef __ELF__
@@ -11,7 +13,7 @@
#endif
reflect.makeFuncStub:
- .cfi_startproc
+.LFB1:
# Go does not provide any equivalent to the regparm function
# attribute, so on Go we do not need to worry about passing
@@ -27,15 +29,12 @@ reflect.makeFuncStub:
# }
pushl %ebp
- .cfi_def_cfa_offset 8
- .cfi_offset %ebp, -8
+.LCFI0:
movl %esp, %ebp
- .cfi_def_cfa_register %ebp
-
+.LCFI1:
pushl %ebx # In case this is PIC.
-
subl $36, %esp # Enough for args and to align stack.
- .cfi_offset %ebx, -12
+.LCFI2:
#ifdef __PIC__
call __x86.get_pc_thunk.bx
@@ -75,36 +74,123 @@ reflect.makeFuncStub:
addl $36, %esp
popl %ebx
- .cfi_restore %ebx
+.LCFI3:
popl %ebp
- .cfi_restore %ebp
- .cfi_def_cfa %esp, 4
-
+.LCFI4:
ret
- .cfi_endproc
-
+.LFE1:
#ifdef __ELF__
.size reflect.makeFuncStub, . - reflect.makeFuncStub
#endif
#ifdef __PIC__
+#ifdef HAVE_AS_COMDAT_GAS
.section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+#else
+ /* Sun as needs a different syntax. */
+ .section .text.__x86.get_pc_thunk.bx%__x86.get_pc_thunk.bx,"ax",@progbits
+ .group __x86.get_pc_thunk.bx,.text.__x86.get_pc_thunk.bx%__x86.get_pc_thunk.bx,#comdat
+#endif
.globl __x86.get_pc_thunk.bx
.hidden __x86.get_pc_thunk.bx
#ifdef __ELF__
.type __x86.get_pc_thunk.bx, @function
#endif
__x86.get_pc_thunk.bx:
- .cfi_startproc
+.LFB2:
movl (%esp), %ebx
ret
- .cfi_endproc
+.LFE2:
#ifdef __ELF__
.size __x86.get_pc_thunk.bx, . - __x86.get_pc_thunk.bx
#endif
#endif
#ifdef __ELF__
+#if defined __PIC__
+# if defined __sun__ && defined __svr4__
+/* 32-bit Solaris 2/x86 uses datarel encoding for PIC. GNU ld before 2.22
+ doesn't correctly sort .eh_frame_hdr with mixed encodings, so match this. */
+# define FDE_ENCODING 0x30 /* datarel */
+# define FDE_ENCODE(X) X@GOTOFF
+# else
+# define FDE_ENCODING 0x1b /* pcrel sdata4 */
+# if defined HAVE_AS_X86_PCREL
+# define FDE_ENCODE(X) X-.
+# else
+# define FDE_ENCODE(X) X@rel
+# endif
+# endif
+#else
+# define FDE_ENCODING 0 /* absolute */
+# define FDE_ENCODE(X) X
+#endif
+
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .long 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+ .ascii "zR\0" /* CIE Augmentation */
+ .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */
+ .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
+ .byte 0x8 /* CIE RA Column */
+ .byte 0x1 /* .uleb128 0x1; Augmentation size */
+ .byte FDE_ENCODING
+ .byte 0xc /* DW_CFA_def_cfa */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .byte 0x1 /* .uleb128 0x1 */
+ .align 4
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+ .long FDE_ENCODE(.LFB1) /* FDE initial location */
+ .long .LFE1-.LFB1 /* FDE address range */
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI1-.LCFI0
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI2-.LCFI1
+ .byte 0x83 /* .DW_CFA_offset, column 0x3 */
+ .byte 0x3 /* .uleb128 0x3 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI3-.LCFI2
+ .byte 0xc3 /* DW_CFA_restore, column 0x3 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI4-.LCFI3
+ .byte 0xc5 /* DW_CFA_restore, column 0x5 */
+ .byte 0xc /* DW_CFA_def_cfa */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x4 /* .uleb128 0x4 */
+ .align 4
+.LEFDE1:
+#ifdef __PIC__
+.LSFDE2:
+ .long .LEFDE2-.LASFDE2 /* FDE Length */
+.LASFDE2:
+ .long .LASFDE2-.Lframe1 /* FDE CIE offset */
+ .long FDE_ENCODE(.LFB2) /* FDE initial location */
+ .long .LFE2-.LFB2 /* FDE address range */
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+ .align 4
+.LEFDE2:
+#endif /* __PIC__ */
+#endif /* __ELF__ */
+
+#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",@progbits
.section .note.GNU-split-stack,"",@progbits
.section .note.GNU-no-split-stack,"",@progbits
diff --git a/libgo/go/reflect/makefunc_amd64.S b/libgo/go/reflect/makefunc_amd64.S
index 319aa18505c..9d12f193f01 100644
--- a/libgo/go/reflect/makefunc_amd64.S
+++ b/libgo/go/reflect/makefunc_amd64.S
@@ -4,6 +4,8 @@
# MakeFunc amd64 assembly code.
+#include "config.h"
+
.global reflect.makeFuncStub
#ifdef __ELF__
@@ -11,7 +13,7 @@
#endif
reflect.makeFuncStub:
- .cfi_startproc
+.LFB1:
# Store all the parameter registers in a struct that looks
# like:
@@ -35,10 +37,9 @@ reflect.makeFuncStub:
# };
pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset %rbp, -16
+.LCFI0:
movq %rsp, %rbp
- .cfi_def_cfa_register %rbp
+.LCFI1:
subq $0xc0, %rsp # Space for struct on stack.
@@ -91,16 +92,70 @@ reflect.makeFuncStub:
# double type.
leave
- .cfi_def_cfa %rsp, 8
+.LCFI2:
ret
+.LFE1:
- .cfi_endproc
#ifdef __ELF__
.size reflect.makeFuncStub, . - reflect.makeFuncStub
#endif
#ifdef __ELF__
+#ifdef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
+ .section .eh_frame,"a",@unwind
+#else
+ .section .eh_frame,"a",@progbits
+#endif
+.Lframe1:
+ .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .long 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+ .ascii "zR\0" /* CIE Augmentation */
+ .uleb128 1 /* CIE Code Alignment Factor */
+ .sleb128 -8 /* CIE Data Alignment Factor */
+ .byte 0x10 /* CIE RA Column */
+ .uleb128 1 /* Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+ .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */
+ .uleb128 7
+ .uleb128 8
+ .byte 0x80+16 /* DW_CFA_offset, %rip offset 1*-8 */
+ .uleb128 1
+ .align 8
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+#if HAVE_AS_X86_PCREL
+ .long .LFB1-. /* FDE initial location */
+#else
+ .long .LFB1@rel
+#endif
+ .long .LFE1-.LFB1 /* FDE address range */
+ .uleb128 0x0 /* Augmentation size */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .uleb128 16
+ .byte 0x86 /* DW_CFA_offset, column 0x6 */
+ .uleb128 2
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI1-.LCFI0
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .uleb128 6
+ .byte 0x2 /* DW_CFA_advance_loc1 */
+ .byte .LCFI2-.LCFI1
+ .byte 0xc /* DW_CFA_def_cfa */
+ .uleb128 7
+ .uleb128 8
+ .align 8
+.LEFDE1:
+#endif /* __ELF__ */
+
+#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",@progbits
.section .note.GNU-split-stack,"",@progbits
.section .note.GNU-no-split-stack,"",@progbits