diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-02 17:30:07 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-02 17:30:07 +0000 |
commit | 11f8ac85df3620e926f8eb0d132fa3a71a9b433a (patch) | |
tree | 624e4795d248327ef48a277a8b18931e053892e9 | |
parent | 7e637ed2e8bb071ab74e7f2fc29926f1cdf1d240 (diff) | |
download | gcc-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.in | 12 | ||||
-rwxr-xr-x | libgo/configure | 95 | ||||
-rw-r--r-- | libgo/configure.ac | 62 | ||||
-rw-r--r-- | libgo/go/reflect/makefunc_386.S | 116 | ||||
-rw-r--r-- | libgo/go/reflect/makefunc_amd64.S | 67 |
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 |