2013-10-07 17:32:08 +02:00
|
|
|
/* Copyright 2013 The Go Authors. All rights reserved.
|
|
|
|
Use of this source code is governed by a BSD-style
|
|
|
|
license that can be found in the LICENSE file.
|
2013-09-27 23:34:24 +02:00
|
|
|
|
2013-10-07 17:32:08 +02:00
|
|
|
MakeFunc 386 assembly code. */
|
2013-09-27 23:34:24 +02:00
|
|
|
|
2013-10-02 19:30:07 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
2013-10-07 17:32:08 +02:00
|
|
|
.globl reflect.makeFuncStub
|
2013-09-27 23:34:24 +02:00
|
|
|
|
|
|
|
#ifdef __ELF__
|
|
|
|
.type reflect.makeFuncStub,@function
|
|
|
|
#endif
|
|
|
|
|
|
|
|
reflect.makeFuncStub:
|
2013-10-02 19:30:07 +02:00
|
|
|
.LFB1:
|
2013-09-27 23:34:24 +02:00
|
|
|
|
2013-10-07 17:32:08 +02:00
|
|
|
/* Go does not provide any equivalent to the regparm function
|
|
|
|
attribute, so on Go we do not need to worry about passing
|
|
|
|
parameters in registers. We just pass a pointer to the
|
|
|
|
arguments on the stack.
|
|
|
|
|
|
|
|
We do need to pick up the return values, though, so we pass
|
|
|
|
a pointer to a struct that looks like this.
|
|
|
|
struct {
|
|
|
|
esp uint32 // 0x0
|
|
|
|
eax uint32 // 0x4
|
2013-12-12 18:44:01 +01:00
|
|
|
st0 float64 // 0x8
|
|
|
|
sr bool // 0x10
|
|
|
|
sf bool // 0x11
|
2013-10-07 17:32:08 +02:00
|
|
|
}
|
2013-11-30 19:08:42 +01:00
|
|
|
The sr field is set by the function to a non-zero value if
|
2013-11-30 18:14:50 +01:00
|
|
|
the function takes a struct hidden pointer that must be
|
|
|
|
popped off the stack. */
|
2013-09-27 23:34:24 +02:00
|
|
|
|
|
|
|
pushl %ebp
|
2013-10-02 19:30:07 +02:00
|
|
|
.LCFI0:
|
2013-09-27 23:34:24 +02:00
|
|
|
movl %esp, %ebp
|
2013-10-02 19:30:07 +02:00
|
|
|
.LCFI1:
|
2013-10-07 17:32:08 +02:00
|
|
|
pushl %ebx /* In case this is PIC. */
|
|
|
|
subl $36, %esp /* Enough for args and to align stack. */
|
2013-10-02 19:30:07 +02:00
|
|
|
.LCFI2:
|
2013-09-27 23:34:24 +02:00
|
|
|
|
|
|
|
#ifdef __PIC__
|
|
|
|
call __x86.get_pc_thunk.bx
|
|
|
|
addl $_GLOBAL_OFFSET_TABLE_, %ebx
|
|
|
|
#endif
|
|
|
|
|
2013-10-07 17:32:08 +02:00
|
|
|
leal 8(%ebp), %eax /* Set esp field in struct. */
|
2013-09-27 23:34:24 +02:00
|
|
|
movl %eax, -24(%ebp)
|
|
|
|
|
2013-12-12 00:43:16 +01:00
|
|
|
/* For MakeFunc functions that call recover. */
|
|
|
|
movl 4(%ebp), %eax
|
|
|
|
movl %eax, (%esp)
|
|
|
|
#ifdef __PIC__
|
|
|
|
call __go_makefunc_can_recover@PLT
|
|
|
|
#else
|
|
|
|
call __go_makefunc_can_recover
|
|
|
|
#endif
|
|
|
|
|
2013-09-27 23:34:24 +02:00
|
|
|
#ifdef __PIC__
|
|
|
|
call __go_get_closure@PLT
|
|
|
|
#else
|
|
|
|
call __go_get_closure
|
|
|
|
#endif
|
|
|
|
|
|
|
|
movl %eax, 4(%esp)
|
|
|
|
|
|
|
|
leal -24(%ebp), %eax
|
|
|
|
movl %eax, (%esp)
|
|
|
|
|
|
|
|
#ifdef __PIC__
|
|
|
|
call reflect.MakeFuncStubGo@PLT
|
|
|
|
#else
|
|
|
|
call reflect.MakeFuncStubGo
|
|
|
|
#endif
|
|
|
|
|
2013-12-12 00:43:16 +01:00
|
|
|
/* MakeFunc functions can no longer call recover. */
|
|
|
|
#ifdef __PIC__
|
|
|
|
call __go_makefunc_returning@PLT
|
|
|
|
#else
|
|
|
|
call __go_makefunc_returning
|
|
|
|
#endif
|
|
|
|
|
2013-10-07 17:32:08 +02:00
|
|
|
/* Set return registers. */
|
2013-09-27 23:34:24 +02:00
|
|
|
|
|
|
|
movl -20(%ebp), %eax
|
2013-12-12 18:44:01 +01:00
|
|
|
|
|
|
|
cmpb $0, -7(%ebp)
|
|
|
|
je 2f
|
|
|
|
|
2013-09-27 23:34:24 +02:00
|
|
|
fldl -16(%ebp)
|
|
|
|
|
|
|
|
#ifdef __SSE2__
|
2013-10-07 17:32:08 +02:00
|
|
|
/* In case we are compiling with -msseregparm. This won't work
|
|
|
|
correctly if only SSE1 is supported, but that seems unlikely. */
|
2013-09-27 23:34:24 +02:00
|
|
|
movsd -16(%ebp), %xmm0
|
|
|
|
#endif
|
|
|
|
|
2013-12-12 18:44:01 +01:00
|
|
|
2:
|
|
|
|
movb -8(%ebp), %dl
|
2013-11-30 18:14:50 +01:00
|
|
|
|
2013-09-27 23:34:24 +02:00
|
|
|
addl $36, %esp
|
|
|
|
popl %ebx
|
2013-10-02 19:30:07 +02:00
|
|
|
.LCFI3:
|
2013-09-27 23:34:24 +02:00
|
|
|
popl %ebp
|
2013-10-02 19:30:07 +02:00
|
|
|
.LCFI4:
|
2013-11-30 18:14:50 +01:00
|
|
|
|
2013-12-12 18:44:01 +01:00
|
|
|
testb %dl,%dl
|
2013-11-30 18:14:50 +01:00
|
|
|
jne 1f
|
2013-09-27 23:34:24 +02:00
|
|
|
ret
|
2013-11-30 18:14:50 +01:00
|
|
|
1:
|
|
|
|
ret $4
|
2013-10-02 19:30:07 +02:00
|
|
|
.LFE1:
|
2013-09-27 23:34:24 +02:00
|
|
|
#ifdef __ELF__
|
|
|
|
.size reflect.makeFuncStub, . - reflect.makeFuncStub
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __PIC__
|
2013-10-02 19:30:07 +02:00
|
|
|
#ifdef HAVE_AS_COMDAT_GAS
|
2013-09-27 23:34:24 +02:00
|
|
|
.section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
|
2013-10-02 19:30:07 +02:00
|
|
|
#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
|
2013-09-27 23:34:24 +02:00
|
|
|
.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:
|
2013-10-02 19:30:07 +02:00
|
|
|
.LFB2:
|
2013-09-27 23:34:24 +02:00
|
|
|
movl (%esp), %ebx
|
|
|
|
ret
|
2013-10-02 19:30:07 +02:00
|
|
|
.LFE2:
|
2013-09-27 23:34:24 +02:00
|
|
|
#ifdef __ELF__
|
|
|
|
.size __x86.get_pc_thunk.bx, . - __x86.get_pc_thunk.bx
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __ELF__
|
2013-10-02 19:30:07 +02:00
|
|
|
#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__)
|
2013-09-27 23:34:24 +02:00
|
|
|
.section .note.GNU-stack,"",@progbits
|
|
|
|
.section .note.GNU-split-stack,"",@progbits
|
|
|
|
.section .note.GNU-no-split-stack,"",@progbits
|
|
|
|
#endif
|