diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s index 838a1681da..7c5e8e9ada 100644 --- a/src/runtime/asm_amd64.s +++ b/src/runtime/asm_amd64.s @@ -22,6 +22,68 @@ TEXT _rt0_amd64(SB),NOSPLIT,$-8 TEXT main(SB),NOSPLIT,$-8 JMP runtime·rt0_go(SB) +// _rt0_amd64_lib is common startup code for most amd64 systems when +// using -buildmode=c-archive or -buildmode=c-shared. The linker will +// arrange to invoke this function as a global constructor (for +// c-archive) or when the shared library is loaded (for c-shared). +// We expect argc and argv to be passed in the usual C ABI registers +// DI and SI. +TEXT _rt0_amd64_lib(SB),NOSPLIT,$0x50 + // Align stack per ELF ABI requirements. + MOVQ SP, AX + ANDQ $~15, SP + // Save C ABI callee-saved registers, as caller may need them. + MOVQ BX, 0x10(SP) + MOVQ BP, 0x18(SP) + MOVQ R12, 0x20(SP) + MOVQ R13, 0x28(SP) + MOVQ R14, 0x30(SP) + MOVQ R15, 0x38(SP) + MOVQ AX, 0x40(SP) + + MOVQ DI, _rt0_amd64_lib_argc<>(SB) + MOVQ SI, _rt0_amd64_lib_argv<>(SB) + + // Synchronous initialization. + CALL runtime·libpreinit(SB) + + // Create a new thread to finish Go runtime initialization. + MOVQ _cgo_sys_thread_create(SB), AX + TESTQ AX, AX + JZ nocgo + MOVQ $_rt0_amd64_lib_go(SB), DI + MOVQ $0, SI + CALL AX + JMP restore + +nocgo: + MOVQ $0x800000, 0(SP) // stacksize + MOVQ $_rt0_amd64_lib_go(SB), AX + MOVQ AX, 8(SP) // fn + CALL runtime·newosproc0(SB) + +restore: + MOVQ 0x10(SP), BX + MOVQ 0x18(SP), BP + MOVQ 0x20(SP), R12 + MOVQ 0x28(SP), R13 + MOVQ 0x30(SP), R14 + MOVQ 0x38(SP), R15 + MOVQ 0x40(SP), SP + RET + +// _rt0_amd64_lib_go initializes the Go runtime. +// This is started in a separate thread by _rt0_amd64_lib. +TEXT _rt0_amd64_lib_go(SB),NOSPLIT,$0 + MOVQ _rt0_amd64_lib_argc<>(SB), DI + MOVQ _rt0_amd64_lib_argv<>(SB), SI + JMP runtime·rt0_go(SB) + +DATA _rt0_amd64_lib_argc<>(SB)/8, $0 +GLOBL _rt0_amd64_lib_argc<>(SB),NOPTR, $8 +DATA _rt0_amd64_lib_argv<>(SB)/8, $0 +GLOBL _rt0_amd64_lib_argv<>(SB),NOPTR, $8 + TEXT runtime·rt0_go(SB),NOSPLIT,$0 // copy arguments forward on an even stack MOVQ DI, AX // argc diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index 15281674ae..635f71f126 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -135,7 +135,7 @@ func newosproc(mp *m, stk unsafe.Pointer) { // not safe to use after initialization as it does not pass an M as fnarg. // //go:nosplit -func newosproc0(stacksize uintptr, fn unsafe.Pointer, fnarg uintptr) { +func newosproc0(stacksize uintptr, fn uintptr) { stack := sysAlloc(stacksize, &memstats.stacks_sys) if stack == nil { write(2, unsafe.Pointer(&failallocatestack[0]), int32(len(failallocatestack))) @@ -145,7 +145,7 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer, fnarg uintptr) { var oset sigset sigprocmask(_SIG_SETMASK, &sigset_all, &oset) - errno := bsdthread_create(stk, fn, fnarg) + errno := bsdthread_create(stk, nil, fn) sigprocmask(_SIG_SETMASK, &oset, nil) if errno < 0 { diff --git a/src/runtime/rt0_android_amd64.s b/src/runtime/rt0_android_amd64.s index 3077cb1841..6bda3bfcc1 100644 --- a/src/runtime/rt0_android_amd64.s +++ b/src/runtime/rt0_android_amd64.s @@ -10,8 +10,7 @@ TEXT _rt0_amd64_android(SB),NOSPLIT,$-8 TEXT _rt0_amd64_android_lib(SB),NOSPLIT,$0 MOVQ $1, DI // argc MOVQ $_rt0_amd64_android_argv(SB), SI // argv - MOVQ $_rt0_amd64_linux_lib(SB), AX - JMP AX + JMP _rt0_amd64_lib(SB) DATA _rt0_amd64_android_argv+0x00(SB)/8,$_rt0_amd64_android_argv0(SB) DATA _rt0_amd64_android_argv+0x08(SB)/8,$0 // end argv diff --git a/src/runtime/rt0_darwin_amd64.s b/src/runtime/rt0_darwin_amd64.s index 2d11aa4155..ed804d47c5 100644 --- a/src/runtime/rt0_darwin_amd64.s +++ b/src/runtime/rt0_darwin_amd64.s @@ -9,64 +9,5 @@ TEXT _rt0_amd64_darwin(SB),NOSPLIT,$-8 // When linking with -shared, this symbol is called when the shared library // is loaded. -TEXT _rt0_amd64_darwin_lib(SB),NOSPLIT,$0x58 - // Align stack. We don't know whether Go is adding a frame pointer here or not. - MOVQ SP, R8 - SUBQ $16, R8 - ANDQ $~15, R8 - XCHGQ SP, R8 - - MOVQ R8, 0x48(SP) - MOVQ BX, 0x18(SP) - MOVQ BP, 0x20(SP) - MOVQ R12, 0x28(SP) - MOVQ R13, 0x30(SP) - MOVQ R14, 0x38(SP) - MOVQ R15, 0x40(SP) - - MOVQ DI, _rt0_amd64_darwin_lib_argc<>(SB) - MOVQ SI, _rt0_amd64_darwin_lib_argv<>(SB) - - // Synchronous initialization. - MOVQ $runtime·libpreinit(SB), AX - CALL AX - - // Create a new thread to do the runtime initialization and return. - MOVQ _cgo_sys_thread_create(SB), AX - TESTQ AX, AX - JZ nocgo - MOVQ $_rt0_amd64_darwin_lib_go(SB), DI - MOVQ $0, SI - CALL AX - JMP restore - -nocgo: - MOVQ $8388608, 0(SP) // stacksize - MOVQ $_rt0_amd64_darwin_lib_go(SB), AX - MOVQ AX, 8(SP) // fn - MOVQ $0, 16(SP) // fnarg - MOVQ $runtime·newosproc0(SB), AX - CALL AX - -restore: - MOVQ 0x18(SP), BX - MOVQ 0x20(SP), BP - MOVQ 0x28(SP), R12 - MOVQ 0x30(SP), R13 - MOVQ 0x38(SP), R14 - MOVQ 0x40(SP), R15 - - MOVQ 0x48(SP), R8 - MOVQ R8, SP - RET - -TEXT _rt0_amd64_darwin_lib_go(SB),NOSPLIT,$0 - MOVQ _rt0_amd64_darwin_lib_argc<>(SB), DI - MOVQ _rt0_amd64_darwin_lib_argv<>(SB), SI - MOVQ $runtime·rt0_go(SB), AX - JMP AX - -DATA _rt0_amd64_darwin_lib_argc<>(SB)/8, $0 -GLOBL _rt0_amd64_darwin_lib_argc<>(SB),NOPTR, $8 -DATA _rt0_amd64_darwin_lib_argv<>(SB)/8, $0 -GLOBL _rt0_amd64_darwin_lib_argv<>(SB),NOPTR, $8 +TEXT _rt0_amd64_darwin_lib(SB),NOSPLIT,$0 + JMP _rt0_amd64_lib(SB) diff --git a/src/runtime/rt0_dragonfly_amd64.s b/src/runtime/rt0_dragonfly_amd64.s index 166d3fafda..9f7a427d4d 100644 --- a/src/runtime/rt0_dragonfly_amd64.s +++ b/src/runtime/rt0_dragonfly_amd64.s @@ -6,3 +6,6 @@ TEXT _rt0_amd64_dragonfly(SB),NOSPLIT,$-8 JMP _rt0_amd64(SB) + +TEXT _rt0_amd64_dragonfly_lib(SB),NOSPLIT,$0 + JMP _rt0_amd64_lib(SB) diff --git a/src/runtime/rt0_freebsd_amd64.s b/src/runtime/rt0_freebsd_amd64.s index 5be2cd1301..ccc48f66b4 100644 --- a/src/runtime/rt0_freebsd_amd64.s +++ b/src/runtime/rt0_freebsd_amd64.s @@ -9,3 +9,6 @@ TEXT _rt0_amd64_freebsd(SB),NOSPLIT,$-8 LEAQ 8(DI), SI // argv MOVQ 0(DI), DI // argc JMP runtime·rt0_go(SB) + +TEXT _rt0_amd64_freebsd_lib(SB),NOSPLIT,$0 + JMP _rt0_amd64_lib(SB) diff --git a/src/runtime/rt0_linux_amd64.s b/src/runtime/rt0_linux_amd64.s index 4faa1f24d3..94ff7094d6 100644 --- a/src/runtime/rt0_linux_amd64.s +++ b/src/runtime/rt0_linux_amd64.s @@ -7,61 +7,5 @@ TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8 JMP _rt0_amd64(SB) -// When building with -buildmode=c-shared, this symbol is called when the shared -// library is loaded. -// Note: This function calls external C code, which might required 16-byte stack -// alignment after cmd/internal/obj applies its transformations. -TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0x50 - MOVQ SP, AX - ANDQ $-16, SP - MOVQ BX, 0x10(SP) - MOVQ BP, 0x18(SP) - MOVQ R12, 0x20(SP) - MOVQ R13, 0x28(SP) - MOVQ R14, 0x30(SP) - MOVQ R15, 0x38(SP) - MOVQ AX, 0x40(SP) - - MOVQ DI, _rt0_amd64_linux_lib_argc<>(SB) - MOVQ SI, _rt0_amd64_linux_lib_argv<>(SB) - - // Synchronous initialization. - MOVQ $runtime·libpreinit(SB), AX - CALL AX - - // Create a new thread to do the runtime initialization and return. - MOVQ _cgo_sys_thread_create(SB), AX - TESTQ AX, AX - JZ nocgo - MOVQ $_rt0_amd64_linux_lib_go(SB), DI - MOVQ $0, SI - CALL AX - JMP restore - -nocgo: - MOVQ $8388608, 0(SP) // stacksize - MOVQ $_rt0_amd64_linux_lib_go(SB), AX - MOVQ AX, 8(SP) // fn - MOVQ $runtime·newosproc0(SB), AX - CALL AX - -restore: - MOVQ 0x10(SP), BX - MOVQ 0x18(SP), BP - MOVQ 0x20(SP), R12 - MOVQ 0x28(SP), R13 - MOVQ 0x30(SP), R14 - MOVQ 0x38(SP), R15 - MOVQ 0x40(SP), SP - RET - -TEXT _rt0_amd64_linux_lib_go(SB),NOSPLIT,$0 - MOVQ _rt0_amd64_linux_lib_argc<>(SB), DI - MOVQ _rt0_amd64_linux_lib_argv<>(SB), SI - MOVQ $runtime·rt0_go(SB), AX - JMP AX - -DATA _rt0_amd64_linux_lib_argc<>(SB)/8, $0 -GLOBL _rt0_amd64_linux_lib_argc<>(SB),NOPTR, $8 -DATA _rt0_amd64_linux_lib_argv<>(SB)/8, $0 -GLOBL _rt0_amd64_linux_lib_argv<>(SB),NOPTR, $8 +TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0 + JMP _rt0_amd64_lib(SB) diff --git a/src/runtime/rt0_netbsd_amd64.s b/src/runtime/rt0_netbsd_amd64.s index 7736c8d0aa..77c7187bba 100644 --- a/src/runtime/rt0_netbsd_amd64.s +++ b/src/runtime/rt0_netbsd_amd64.s @@ -6,3 +6,6 @@ TEXT _rt0_amd64_netbsd(SB),NOSPLIT,$-8 JMP _rt0_amd64(SB) + +TEXT _rt0_amd64_netbsd_lib(SB),NOSPLIT,$0 + JMP _rt0_amd64_lib(SB) diff --git a/src/runtime/rt0_openbsd_amd64.s b/src/runtime/rt0_openbsd_amd64.s index 6830a81cc2..c2f3f23f37 100644 --- a/src/runtime/rt0_openbsd_amd64.s +++ b/src/runtime/rt0_openbsd_amd64.s @@ -6,3 +6,6 @@ TEXT _rt0_amd64_openbsd(SB),NOSPLIT,$-8 JMP _rt0_amd64(SB) + +TEXT _rt0_amd64_openbsd_lib(SB),NOSPLIT,$0 + JMP _rt0_amd64_lib(SB) diff --git a/src/runtime/rt0_solaris_amd64.s b/src/runtime/rt0_solaris_amd64.s index 695b4a6c8e..5c46ded3ae 100644 --- a/src/runtime/rt0_solaris_amd64.s +++ b/src/runtime/rt0_solaris_amd64.s @@ -6,3 +6,6 @@ TEXT _rt0_amd64_solaris(SB),NOSPLIT,$-8 JMP _rt0_amd64(SB) + +TEXT _rt0_amd64_solaris_lib(SB),NOSPLIT,$0 + JMP _rt0_amd64_lib(SB)