From 5131deeeb2da14668a318c1b40e5d6842af06ab1 Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Tue, 5 Jun 2012 01:43:04 +1000 Subject: [PATCH] cgo: enable cgo on netbsd/386 and netbsd/amd64 R=golang-dev, rsc CC=golang-dev https://golang.org/cl/6261056 --- doc/progs/run | 5 ++ misc/cgo/stdio/stdio_netbsd.go | 16 ++++++ src/pkg/go/build/build.go | 6 +- src/pkg/net/cgo_netbsd.go | 20 +++++++ src/pkg/net/cgo_unix.go | 2 +- src/pkg/os/user/lookup_unix.go | 2 +- src/pkg/runtime/cgo/gcc_netbsd_386.c | 80 ++++++++++++++++++++++++++ src/pkg/runtime/cgo/gcc_netbsd_amd64.c | 80 ++++++++++++++++++++++++++ 8 files changed, 207 insertions(+), 4 deletions(-) create mode 100644 misc/cgo/stdio/stdio_netbsd.go create mode 100644 src/pkg/net/cgo_netbsd.go create mode 100644 src/pkg/runtime/cgo/gcc_netbsd_386.c create mode 100644 src/pkg/runtime/cgo/gcc_netbsd_amd64.c diff --git a/doc/progs/run b/doc/progs/run index 92c8da5cdc..48725d3289 100755 --- a/doc/progs/run +++ b/doc/progs/run @@ -40,6 +40,11 @@ c_go_cgo=" if [ "$goos" == "freebsd" ]; then c_go_cgo="cgo3 cgo4" fi +# cgo1 and cgo2 don't run on netbsd, srandom has a different signature +# cgo3 and cgo4 don't run on netbsd, since cgo cannot handle stdout correctly +if [ "$goos" == "netbsd" ]; then + c_go_cgo="" +fi timeout=" timeout1 diff --git a/misc/cgo/stdio/stdio_netbsd.go b/misc/cgo/stdio/stdio_netbsd.go new file mode 100644 index 0000000000..075c1d0c79 --- /dev/null +++ b/misc/cgo/stdio/stdio_netbsd.go @@ -0,0 +1,16 @@ +// Copyright 2009 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. + +package stdio + +/* +#include + +extern FILE __sF[3]; +*/ +import "C" +import "unsafe" + +var Stdout = (*File)(unsafe.Pointer(&C.__sF[1])) +var Stderr = (*File)(unsafe.Pointer(&C.__sF[2])) diff --git a/src/pkg/go/build/build.go b/src/pkg/go/build/build.go index dda4a13eb6..c3e0e8e69c 100644 --- a/src/pkg/go/build/build.go +++ b/src/pkg/go/build/build.go @@ -213,11 +213,13 @@ var Default Context = defaultContext() var cgoEnabled = map[string]bool{ "darwin/386": true, "darwin/amd64": true, + "freebsd/386": true, + "freebsd/amd64": true, "linux/386": true, "linux/amd64": true, "linux/arm": true, - "freebsd/386": true, - "freebsd/amd64": true, + "netbsd/386": true, + "netbsd/amd64": true, "windows/386": true, "windows/amd64": true, } diff --git a/src/pkg/net/cgo_netbsd.go b/src/pkg/net/cgo_netbsd.go new file mode 100644 index 0000000000..84ade5932f --- /dev/null +++ b/src/pkg/net/cgo_netbsd.go @@ -0,0 +1,20 @@ +// Copyright 2011 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. + +// +build netbsd + +package net + +/* +#include +*/ +import "C" + +func cgoAddrInfoFlags() C.int { +<<<<<<< local + return C.AI_CANONNAME +======= + return C.AI_CANONNAME | C.AI_V4MAPPED | C.AI_ALL +>>>>>>> other +} diff --git a/src/pkg/net/cgo_unix.go b/src/pkg/net/cgo_unix.go index d703df992c..393fcee88a 100644 --- a/src/pkg/net/cgo_unix.go +++ b/src/pkg/net/cgo_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin freebsd linux +// +build darwin freebsd linux netbsd package net diff --git a/src/pkg/os/user/lookup_unix.go b/src/pkg/os/user/lookup_unix.go index 241957c333..2c53c95363 100644 --- a/src/pkg/os/user/lookup_unix.go +++ b/src/pkg/os/user/lookup_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin freebsd linux +// +build darwin freebsd linux netbsd // +build cgo package user diff --git a/src/pkg/runtime/cgo/gcc_netbsd_386.c b/src/pkg/runtime/cgo/gcc_netbsd_386.c new file mode 100644 index 0000000000..3b4c75042c --- /dev/null +++ b/src/pkg/runtime/cgo/gcc_netbsd_386.c @@ -0,0 +1,80 @@ +// Copyright 2009 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. + +#include +#include +#include +#include "libcgo.h" + +static void* threadentry(void*); + +static void +xinitcgo(G *g) +{ + pthread_attr_t attr; + size_t size; + + pthread_attr_init(&attr); + pthread_attr_getstacksize(&attr, &size); + g->stackguard = (uintptr)&attr - size + 4096; + pthread_attr_destroy(&attr); +} + +void (*initcgo)(G*) = xinitcgo; + +void +libcgo_sys_thread_start(ThreadStart *ts) +{ + pthread_attr_t attr; + sigset_t ign, oset; + pthread_t p; + size_t size; + int err; + + sigfillset(&ign); + sigprocmask(SIG_SETMASK, &ign, &oset); + + pthread_attr_init(&attr); + pthread_attr_getstacksize(&attr, &size); + ts->g->stackguard = size; + err = pthread_create(&p, &attr, threadentry, ts); + + sigprocmask(SIG_SETMASK, &oset, nil); + + if (err != 0) { + fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err)); + abort(); + } +} + +static void* +threadentry(void *v) +{ + ThreadStart ts; + + ts = *(ThreadStart*)v; + free(v); + + ts.g->stackbase = (uintptr)&ts; + + /* + * libcgo_sys_thread_start set stackguard to stack size; + * change to actual guard pointer. + */ + ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096; + + /* + * Set specific keys. On NetBSD/ELF, the thread local storage + * is just before %gs:0. Our dynamic 8.out's reserve 8 bytes + * for the two words g and m at %gs:-8 and %gs:-4. + */ + asm volatile ( + "movl %0, %%gs:-8\n" // MOVL g, -8(GS) + "movl %1, %%gs:-4\n" // MOVL m, -4(GS) + :: "r"(ts.g), "r"(ts.m) + ); + + crosscall_386(ts.fn); + return nil; +} diff --git a/src/pkg/runtime/cgo/gcc_netbsd_amd64.c b/src/pkg/runtime/cgo/gcc_netbsd_amd64.c new file mode 100644 index 0000000000..2afcf0283a --- /dev/null +++ b/src/pkg/runtime/cgo/gcc_netbsd_amd64.c @@ -0,0 +1,80 @@ +// Copyright 2009 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. + +#include +#include +#include +#include "libcgo.h" + +static void* threadentry(void*); + +static void +xinitcgo(G *g) +{ + pthread_attr_t attr; + size_t size; + + pthread_attr_init(&attr); + pthread_attr_getstacksize(&attr, &size); + g->stackguard = (uintptr)&attr - size + 4096; + pthread_attr_destroy(&attr); +} + +void (*initcgo)(G*) = xinitcgo; + +void +libcgo_sys_thread_start(ThreadStart *ts) +{ + pthread_attr_t attr; + sigset_t ign, oset; + pthread_t p; + size_t size; + int err; + + sigfillset(&ign); + sigprocmask(SIG_SETMASK, &ign, &oset); + + pthread_attr_init(&attr); + pthread_attr_getstacksize(&attr, &size); + + ts->g->stackguard = size; + err = pthread_create(&p, &attr, threadentry, ts); + + sigprocmask(SIG_SETMASK, &oset, nil); + + if (err != 0) { + fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err)); + abort(); + } +} + +static void* +threadentry(void *v) +{ + ThreadStart ts; + + ts = *(ThreadStart*)v; + free(v); + + ts.g->stackbase = (uintptr)&ts; + + /* + * libcgo_sys_thread_start set stackguard to stack size; + * change to actual guard pointer. + */ + ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096; + + /* + * Set specific keys. On NetBSD/ELF, the thread local storage + * is just before %fs:0. Our dynamic 6.out's reserve 16 bytes + * for the two words g and m at %fs:-16 and %fs:-8. + */ + asm volatile ( + "movq %0, %%fs:-16\n" // MOVL g, -16(FS) + "movq %1, %%fs:-8\n" // MOVL m, -8(FS) + :: "r"(ts.g), "r"(ts.m) + ); + crosscall_amd64(ts.fn); + return nil; +}