reflect: Use hand-coded .eh_frame section rather than CFI directives.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Oct 2013 17:30:07 +0000 (17:30 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Oct 2013 17:30:07 +0000 (17:30 +0000)
From Rainer Orth.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203120 138bc75d-0d04-0410-961f-82ee72b054a4

libgo/config.h.in
libgo/configure
libgo/configure.ac
libgo/go/reflect/makefunc_386.S
libgo/go/reflect/makefunc_amd64.S

index 349ace6..1057d9e 100644 (file)
@@ -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
 
 /* 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
 
index a1e045c..40aeb0d 100755 (executable)
@@ -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
index 002aa88..ef5ea83 100644 (file)
@@ -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
index f2f2fbe..fb49281 100644 (file)
@@ -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
index 319aa18..9d12f19 100644 (file)
@@ -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