]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: darwin/amd64 library entry point
authorDavid Crawshaw <crawshaw@golang.org>
Wed, 8 Apr 2015 18:16:26 +0000 (14:16 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Wed, 8 Apr 2015 21:53:52 +0000 (21:53 +0000)
This is a practice run for darwin/arm.

Similar to the linux/amd64 shared library entry point. With several
pending linker changes I am successfully using this to implement
-buildmode=c-archive on darwin/amd64 with external linking.

The same entry point can be reused to implement -buildmode=c-shared
on darwin/amd64, however that will require further ld changes to
remove all text relocations.

One extra runtime change will follow this. According to the Go
execution modes document, -buildmode=c-archive should ignore the Go
main function. Right now it is being executed (and the process exits
if it doesn't block). I'm still searching for the right way to do
this.

Change-Id: Id97901ddd4d46970996f222bd79731dabff66a3d
Reviewed-on: https://go-review.googlesource.com/8652
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/runtime/os1_darwin.go
src/runtime/os_darwin.go
src/runtime/rt0_darwin_amd64.s
src/runtime/sys_darwin_amd64.s

index 6c79bbb204c267e50d1cf2aa4ea56564cc26faeb..9de6de9ff1245a298de496b5c595ab14c322ecce 100644 (file)
@@ -81,7 +81,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
 
        var oset uint32
        sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-       errno := bsdthread_create(stk, mp, mp.g0, funcPC(mstart))
+       errno := bsdthread_create(stk, unsafe.Pointer(mp), funcPC(mstart))
        sigprocmask(_SIG_SETMASK, &oset, nil)
 
        if errno < 0 {
@@ -90,6 +90,36 @@ func newosproc(mp *m, stk unsafe.Pointer) {
        }
 }
 
+// newosproc0 is a version of newosproc that can be called before the runtime
+// is initialized.
+//
+// As Go uses bsdthread_register when running without cgo, this function is
+// 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) {
+       var dummy uint64
+       stack := sysAlloc(stacksize, &dummy)
+       if stack == nil {
+               write(2, unsafe.Pointer(&failallocatestack[0]), int32(len(failallocatestack)))
+               exit(1)
+       }
+       stk := unsafe.Pointer(uintptr(stack) + stacksize)
+
+       var oset uint32
+       sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
+       errno := bsdthread_create(stk, fn, fnarg)
+       sigprocmask(_SIG_SETMASK, &oset, nil)
+
+       if errno < 0 {
+               write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+               exit(1)
+       }
+}
+
+var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
+var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
+
 // Called to initialize a new m (including the bootstrap m).
 // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
 func mpreinit(mp *m) {
index 15f8f44935a0bd5d926b07ac0ff72984e3e1d902..573eb13531b04945c644c4b35c29d8532a8076ad 100644 (file)
@@ -6,7 +6,7 @@ package runtime
 
 import "unsafe"
 
-func bsdthread_create(stk unsafe.Pointer, mm *m, gg *g, fn uintptr) int32
+func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32
 func bsdthread_register() int32
 
 //go:noescape
index 452d8545585a0c63104526b5b3eb968b06f243a3..8d50e96ee121e70dc575d0f6e0e2bdb5bdcc4cc8 100644 (file)
@@ -10,6 +10,40 @@ TEXT _rt0_amd64_darwin(SB),NOSPLIT,$-8
        MOVQ    $main(SB), AX
        JMP     AX
 
+// When linking with -shared, this symbol is called when the shared library
+// is loaded.
+TEXT _rt0_amd64_darwin_lib(SB),NOSPLIT,$40
+       MOVQ    DI, _rt0_amd64_darwin_lib_argc<>(SB)
+       MOVQ    SI, _rt0_amd64_darwin_lib_argv<>(SB)
+
+       // 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
+       RET
+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
+       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 main(SB),NOSPLIT,$-8
        MOVQ    $runtime·rt0_go(SB), AX
        JMP     AX
index 6ecd447edc17c356f7781e21ce18fdd059d0a9d1..d28ac856ec56dc0cb42f9f57b2a44417c9801df9 100644 (file)
@@ -303,15 +303,15 @@ TEXT runtime·usleep(SB),NOSPLIT,$16
        SYSCALL
        RET
 
-// func bsdthread_create(stk unsafe.Pointer, mm *m, gg *g, fn uintptr) int32
+// func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32
 TEXT runtime·bsdthread_create(SB),NOSPLIT,$0
        // Set up arguments to bsdthread_create system call.
        // The ones in quotes pass through to the thread callback
        // uninterpreted, so we can put whatever we want there.
-       MOVQ    fn+32(SP), DI   // "func"
-       MOVQ    mm+16(SP), SI   // "arg"
+       MOVQ    fn+24(SP), DI   // "func"
+       MOVQ    arg+16(SP), SI  // "arg"
        MOVQ    stk+8(SP), DX   // stack
-       MOVQ    gg+24(SP), R10  // "pthread"
+       MOVQ    $0, R10         // "pthread", paranoia
        MOVQ    $0x01000000, R8 // flags = PTHREAD_START_CUSTOM
        MOVQ    $0, R9  // paranoia
        MOVQ    $(0x2000000+360), AX    // bsdthread_create