summaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-08 08:47:32 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-08 08:47:32 +0000
commit202719501643cd8e328c4fa816b0488443eb3b1b (patch)
tree4549e98383b6d1254787cd1b5f4fc6ec589f4fae /libgo
parent2791faee3c7b39a49776e5d69dc503579137fa12 (diff)
downloadgcc-202719501643cd8e328c4fa816b0488443eb3b1b.tar.gz
2012-02-08 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 183995 using svnmerge git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@183996 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r--libgo/config.h.in3
-rwxr-xr-xlibgo/configure98
-rw-r--r--libgo/configure.ac81
-rw-r--r--libgo/go/exp/terminal/util.go3
-rw-r--r--libgo/go/math/abs.go5
-rw-r--r--libgo/go/math/asin.go10
-rw-r--r--libgo/go/math/atan.go5
-rw-r--r--libgo/go/math/atan2.go5
-rw-r--r--libgo/go/math/exp.go5
-rw-r--r--libgo/go/math/expm1.go5
-rw-r--r--libgo/go/math/floor.go15
-rw-r--r--libgo/go/math/ldexp.go5
-rw-r--r--libgo/go/math/log.go5
-rw-r--r--libgo/go/math/log10.go10
-rw-r--r--libgo/go/math/log1p.go5
-rw-r--r--libgo/go/math/mod.go5
-rw-r--r--libgo/go/math/sin.go10
-rw-r--r--libgo/go/math/sqrt.go5
-rw-r--r--libgo/go/math/tan.go5
-rw-r--r--libgo/go/net/cgo_unix.go11
-rw-r--r--libgo/go/os/dir.go23
-rw-r--r--libgo/go/os/dir_largefile.go3
-rw-r--r--libgo/go/os/dir_regfile.go3
-rw-r--r--libgo/go/os/user/lookup_unix.go7
-rw-r--r--libgo/go/syscall/mksyscall.awk4
-rw-r--r--libgo/go/syscall/syscall_unix.go11
-rw-r--r--libgo/runtime/chan.c6
-rw-r--r--libgo/runtime/go-make-slice.c24
-rw-r--r--libgo/runtime/go-new-map.c14
-rw-r--r--libgo/runtime/proc.c55
30 files changed, 402 insertions, 44 deletions
diff --git a/libgo/config.h.in b/libgo/config.h.in
index c9f497d12aa..bd19873819c 100644
--- a/libgo/config.h.in
+++ b/libgo/config.h.in
@@ -189,6 +189,9 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
+/* Define if setcontext clobbers TLS variables */
+#undef SETCONTEXT_CLOBBERS_TLS
+
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
diff --git a/libgo/configure b/libgo/configure
index 94bf268f4a6..9b65c2519a2 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -14756,6 +14756,104 @@ $as_echo "$libgo_cv_c_epoll_event_fd_offset" >&6; }
STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setcontext clobbers TLS variables" >&5
+$as_echo_n "checking whether setcontext clobbers TLS variables... " >&6; }
+if test "${libgo_cv_lib_setcontext_clobbers_tls+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ LIBS_hold="$LIBS"
+LIBS="$LIBS $PTHREAD_LIBS"
+if test "$cross_compiling" = yes; then :
+ case "$target" in
+ x86_64*-*-solaris2.10) libgo_cv_lib_setcontext_clobbers_tls=yes ;;
+ *) libgo_cv_lib_setcontext_clobbers_tls=no ;;
+ esac
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+__thread int tls;
+
+static char stack[10 * 1024 * 1024];
+static ucontext_t c;
+
+/* Called via makecontext/setcontext. */
+
+static void
+cfn (void)
+{
+ exit (tls);
+}
+
+/* Called via pthread_create. */
+
+static void *
+tfn (void *dummy)
+{
+ /* The thread should still see this value after calling
+ setcontext. */
+ tls = 0;
+
+ setcontext (&c);
+
+ /* The call to setcontext should not return. */
+ abort ();
+}
+
+int
+main ()
+{
+ pthread_t tid;
+
+ /* The thread should not see this value. */
+ tls = 1;
+
+ if (getcontext (&c) < 0)
+ abort ();
+
+ c.uc_stack.ss_sp = stack;
+ c.uc_stack.ss_flags = 0;
+ c.uc_stack.ss_size = sizeof stack;
+ c.uc_link = NULL;
+ makecontext (&c, cfn, 0);
+
+ if (pthread_create (&tid, NULL, tfn, NULL) != 0)
+ abort ();
+
+ if (pthread_join (tid, NULL) != 0)
+ abort ();
+
+ /* The thread should have called exit. */
+ abort ();
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ libgo_cv_lib_setcontext_clobbers_tls=no
+else
+ libgo_cv_lib_setcontext_clobbers_tls=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+LIBS="$LIBS_hold"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_lib_setcontext_clobbers_tls" >&5
+$as_echo "$libgo_cv_lib_setcontext_clobbers_tls" >&6; }
+if test "$libgo_cv_lib_setcontext_clobbers_tls" = "yes"; then
+
+$as_echo "#define SETCONTEXT_CLOBBERS_TLS 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 e8158877b61..3de5b4a2c8b 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -549,6 +549,87 @@ AC_CACHE_CHECK([epoll_event data.fd offset],
STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
AC_SUBST(STRUCT_EPOLL_EVENT_FD_OFFSET)
+dnl See whether setcontext changes the value of TLS variables.
+AC_CACHE_CHECK([whether setcontext clobbers TLS variables],
+[libgo_cv_lib_setcontext_clobbers_tls],
+[LIBS_hold="$LIBS"
+LIBS="$LIBS $PTHREAD_LIBS"
+AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
+#include <pthread.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+__thread int tls;
+
+static char stack[[10 * 1024 * 1024]];
+static ucontext_t c;
+
+/* Called via makecontext/setcontext. */
+
+static void
+cfn (void)
+{
+ exit (tls);
+}
+
+/* Called via pthread_create. */
+
+static void *
+tfn (void *dummy)
+{
+ /* The thread should still see this value after calling
+ setcontext. */
+ tls = 0;
+
+ setcontext (&c);
+
+ /* The call to setcontext should not return. */
+ abort ();
+}
+
+int
+main ()
+{
+ pthread_t tid;
+
+ /* The thread should not see this value. */
+ tls = 1;
+
+ if (getcontext (&c) < 0)
+ abort ();
+
+ c.uc_stack.ss_sp = stack;
+ c.uc_stack.ss_flags = 0;
+ c.uc_stack.ss_size = sizeof stack;
+ c.uc_link = NULL;
+ makecontext (&c, cfn, 0);
+
+ if (pthread_create (&tid, NULL, tfn, NULL) != 0)
+ abort ();
+
+ if (pthread_join (tid, NULL) != 0)
+ abort ();
+
+ /* The thread should have called exit. */
+ abort ();
+}
+])],
+[libgo_cv_lib_setcontext_clobbers_tls=no],
+[libgo_cv_lib_setcontext_clobbers_tls=yes],
+[case "$target" in
+ x86_64*-*-solaris2.10) libgo_cv_lib_setcontext_clobbers_tls=yes ;;
+ *) libgo_cv_lib_setcontext_clobbers_tls=no ;;
+ esac
+])
+LIBS="$LIBS_hold"
+])
+if test "$libgo_cv_lib_setcontext_clobbers_tls" = "yes"; then
+ AC_DEFINE(SETCONTEXT_CLOBBERS_TLS, 1,
+ [Define if setcontext clobbers TLS variables])
+fi
+
AC_CACHE_SAVE
if test ${multilib} = yes; then
diff --git a/libgo/go/exp/terminal/util.go b/libgo/go/exp/terminal/util.go
index a5bbfca3b46..211f41d10fa 100644
--- a/libgo/go/exp/terminal/util.go
+++ b/libgo/go/exp/terminal/util.go
@@ -60,7 +60,8 @@ func Restore(fd int, state *State) error {
return err
}
-func ioctl(int, int, unsafe.Pointer) int __asm__("ioctl")
+//extern ioctl
+func ioctl(int, int, unsafe.Pointer) int
// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
diff --git a/libgo/go/math/abs.go b/libgo/go/math/abs.go
index 6818998ee91..433d0f72737 100644
--- a/libgo/go/math/abs.go
+++ b/libgo/go/math/abs.go
@@ -9,7 +9,10 @@ package math
// Special cases are:
// Abs(±Inf) = +Inf
// Abs(NaN) = NaN
-func libc_fabs(float64) float64 __asm__("fabs")
+
+//extern fabs
+func libc_fabs(float64) float64
+
func Abs(x float64) float64 {
return libc_fabs(x)
}
diff --git a/libgo/go/math/asin.go b/libgo/go/math/asin.go
index d67f32a5097..0d4fa9ebb50 100644
--- a/libgo/go/math/asin.go
+++ b/libgo/go/math/asin.go
@@ -16,7 +16,10 @@ package math
// Special cases are:
// Asin(±0) = ±0
// Asin(x) = NaN if x < -1 or x > 1
-func libc_asin(float64) float64 __asm__("asin")
+
+//extern asin
+func libc_asin(float64) float64
+
func Asin(x float64) float64 {
return libc_asin(x)
}
@@ -51,7 +54,10 @@ func asin(x float64) float64 {
//
// Special case is:
// Acos(x) = NaN if x < -1 or x > 1
-func libc_acos(float64) float64 __asm__("acos")
+
+//extern acos
+func libc_acos(float64) float64
+
func Acos(x float64) float64 {
return libc_acos(x)
}
diff --git a/libgo/go/math/atan.go b/libgo/go/math/atan.go
index ff52cf3d367..b739721e81c 100644
--- a/libgo/go/math/atan.go
+++ b/libgo/go/math/atan.go
@@ -51,7 +51,10 @@ func satan(arg float64) float64 {
// Special cases are:
// Atan(±0) = ±0
// Atan(±Inf) = ±Pi/2
-func libc_atan(float64) float64 __asm__("atan")
+
+//extern atan
+func libc_atan(float64) float64
+
func Atan(x float64) float64 {
return libc_atan(x)
}
diff --git a/libgo/go/math/atan2.go b/libgo/go/math/atan2.go
index 7260f986fad..02b045b9dc2 100644
--- a/libgo/go/math/atan2.go
+++ b/libgo/go/math/atan2.go
@@ -26,7 +26,10 @@ package math
// Atan2(y<0, -Inf) = -Pi
// Atan2(+Inf, x) = +Pi/2
// Atan2(-Inf, x) = -Pi/2
-func libc_atan2(float64, float64) float64 __asm__("atan2")
+
+//extern atan2
+func libc_atan2(float64, float64) float64
+
func Atan2(y, x float64) float64 {
return libc_atan2(y, x)
}
diff --git a/libgo/go/math/exp.go b/libgo/go/math/exp.go
index 2db691f38f1..b2da631c697 100644
--- a/libgo/go/math/exp.go
+++ b/libgo/go/math/exp.go
@@ -11,7 +11,10 @@ package math
// Exp(NaN) = NaN
// Very large values overflow to 0 or +Inf.
// Very small values underflow to 1.
-func libc_exp(float64) float64 __asm__("exp")
+
+//extern exp
+func libc_exp(float64) float64
+
func Exp(x float64) float64 {
return libc_exp(x)
}
diff --git a/libgo/go/math/expm1.go b/libgo/go/math/expm1.go
index 5bffdb323a4..e7705b06a86 100644
--- a/libgo/go/math/expm1.go
+++ b/libgo/go/math/expm1.go
@@ -121,7 +121,10 @@ package math
// Expm1(-Inf) = -1
// Expm1(NaN) = NaN
// Very large values overflow to -1 or +Inf.
-func libc_expm1(float64) float64 __asm__("expm1")
+
+//extern expm1
+func libc_expm1(float64) float64
+
func Expm1(x float64) float64 {
return libc_expm1(x)
}
diff --git a/libgo/go/math/floor.go b/libgo/go/math/floor.go
index 4d5f4a42707..abe6264d27f 100644
--- a/libgo/go/math/floor.go
+++ b/libgo/go/math/floor.go
@@ -10,7 +10,10 @@ package math
// Floor(±0) = ±0
// Floor(±Inf) = ±Inf
// Floor(NaN) = NaN
-func libc_floor(float64) float64 __asm__("floor")
+
+//extern floor
+func libc_floor(float64) float64
+
func Floor(x float64) float64 {
return libc_floor(x)
}
@@ -38,7 +41,10 @@ func floor(x float64) float64 {
// Ceil(±0) = ±0
// Ceil(±Inf) = ±Inf
// Ceil(NaN) = NaN
-func libc_ceil(float64) float64 __asm__("ceil")
+
+//extern ceil
+func libc_ceil(float64) float64
+
func Ceil(x float64) float64 {
return libc_ceil(x)
}
@@ -53,7 +59,10 @@ func ceil(x float64) float64 {
// Trunc(±0) = ±0
// Trunc(±Inf) = ±Inf
// Trunc(NaN) = NaN
-func libc_trunc(float64) float64 __asm__("trunc")
+
+//extern trunc
+func libc_trunc(float64) float64
+
func Trunc(x float64) float64 {
return libc_trunc(x)
}
diff --git a/libgo/go/math/ldexp.go b/libgo/go/math/ldexp.go
index 4601cd58cbb..d5d78318d48 100644
--- a/libgo/go/math/ldexp.go
+++ b/libgo/go/math/ldexp.go
@@ -11,7 +11,10 @@ package math
// Ldexp(±0, exp) = ±0
// Ldexp(±Inf, exp) = ±Inf
// Ldexp(NaN, exp) = NaN
-func libc_ldexp(float64, int) float64 __asm__("ldexp")
+
+//extern ldexp
+func libc_ldexp(float64, int) float64
+
func Ldexp(frac float64, exp int) float64 {
return libc_ldexp(frac, exp)
}
diff --git a/libgo/go/math/log.go b/libgo/go/math/log.go
index f06611dfdd2..5e5c427c0fa 100644
--- a/libgo/go/math/log.go
+++ b/libgo/go/math/log.go
@@ -77,7 +77,10 @@ package math
// Log(0) = -Inf
// Log(x < 0) = NaN
// Log(NaN) = NaN
-func libc_log(float64) float64 __asm__("log")
+
+//extern log
+func libc_log(float64) float64
+
func Log(x float64) float64 {
return libc_log(x)
}
diff --git a/libgo/go/math/log10.go b/libgo/go/math/log10.go
index 5204492b3c4..07ba8ca165a 100644
--- a/libgo/go/math/log10.go
+++ b/libgo/go/math/log10.go
@@ -6,7 +6,10 @@ package math
// Log10 returns the decimal logarithm of x.
// The special cases are the same as for Log.
-func libc_log10(float64) float64 __asm__("log10")
+
+//extern log10
+func libc_log10(float64) float64
+
func Log10(x float64) float64 {
return libc_log10(x)
}
@@ -17,7 +20,10 @@ func log10(x float64) float64 {
// Log2 returns the binary logarithm of x.
// The special cases are the same as for Log.
-func libc_log2(float64) float64 __asm__("log2")
+
+//extern log2
+func libc_log2(float64) float64
+
func Log2(x float64) float64 {
return libc_log2(x)
}
diff --git a/libgo/go/math/log1p.go b/libgo/go/math/log1p.go
index 39c1b40e802..15cd676ccc6 100644
--- a/libgo/go/math/log1p.go
+++ b/libgo/go/math/log1p.go
@@ -92,7 +92,10 @@ package math
// Log1p(-1) = -Inf
// Log1p(x < -1) = NaN
// Log1p(NaN) = NaN
-func libc_log1p(float64) float64 __asm__("log1p")
+
+//extern log1p
+func libc_log1p(float64) float64
+
func Log1p(x float64) float64 {
return libc_log1p(x)
}
diff --git a/libgo/go/math/mod.go b/libgo/go/math/mod.go
index 347da70f832..dbb3aa00eb4 100644
--- a/libgo/go/math/mod.go
+++ b/libgo/go/math/mod.go
@@ -18,7 +18,10 @@ package math
// Mod(x, 0) = NaN
// Mod(x, ±Inf) = x
// Mod(x, NaN) = NaN
-func libc_fmod(float64, float64) float64 __asm__("fmod")
+
+//extern fmod
+func libc_fmod(float64, float64) float64
+
func Mod(x, y float64) float64 {
return libc_fmod(x, y)
}
diff --git a/libgo/go/math/sin.go b/libgo/go/math/sin.go
index ebde7d43681..d692b3395d2 100644
--- a/libgo/go/math/sin.go
+++ b/libgo/go/math/sin.go
@@ -114,7 +114,10 @@ var _cos = [...]float64{
// Special cases are:
// Cos(±Inf) = NaN
// Cos(NaN) = NaN
-func libc_cos(float64) float64 __asm__("cos")
+
+//extern cos
+func libc_cos(float64) float64
+
func Cos(x float64) float64 {
return libc_cos(x)
}
@@ -176,7 +179,10 @@ func cos(x float64) float64 {
// Sin(±0) = ±0
// Sin(±Inf) = NaN
// Sin(NaN) = NaN
-func libc_sin(float64) float64 __asm__("sin")
+
+//extern sin
+func libc_sin(float64) float64
+
func Sin(x float64) float64 {
return libc_sin(x)
}
diff --git a/libgo/go/math/sqrt.go b/libgo/go/math/sqrt.go
index fb3aff8e4fc..4f87f4183fe 100644
--- a/libgo/go/math/sqrt.go
+++ b/libgo/go/math/sqrt.go
@@ -11,7 +11,10 @@ package math
// Sqrt(±0) = ±0
// Sqrt(x < 0) = NaN
// Sqrt(NaN) = NaN
-func libc_sqrt(float64) float64 __asm__("sqrt")
+
+//extern sqrt
+func libc_sqrt(float64) float64
+
func Sqrt(x float64) float64 {
return libc_sqrt(x)
}
diff --git a/libgo/go/math/tan.go b/libgo/go/math/tan.go
index 926bb4b227e..791ffc08e32 100644
--- a/libgo/go/math/tan.go
+++ b/libgo/go/math/tan.go
@@ -79,7 +79,10 @@ var _tanQ = [...]float64{
// Tan(±0) = ±0
// Tan(±Inf) = NaN
// Tan(NaN) = NaN
-func libc_tan(float64) float64 __asm__("tan")
+
+//extern tan
+func libc_tan(float64) float64
+
func Tan(x float64) float64 {
return libc_tan(x)
}
diff --git a/libgo/go/net/cgo_unix.go b/libgo/go/net/cgo_unix.go
index 1a0f4063c5a..e96df669f33 100644
--- a/libgo/go/net/cgo_unix.go
+++ b/libgo/go/net/cgo_unix.go
@@ -21,9 +21,14 @@ import (
"unsafe"
)
-func libc_getaddrinfo(node *byte, service *byte, hints *syscall.Addrinfo, res **syscall.Addrinfo) int __asm__ ("getaddrinfo")
-func libc_freeaddrinfo(res *syscall.Addrinfo) __asm__ ("freeaddrinfo")
-func libc_gai_strerror(errcode int) *byte __asm__ ("gai_strerror")
+//extern getaddrinfo
+func libc_getaddrinfo(node *byte, service *byte, hints *syscall.Addrinfo, res **syscall.Addrinfo) int
+
+//extern freeaddrinfo
+func libc_freeaddrinfo(res *syscall.Addrinfo)
+
+//extern gai_strerror
+func libc_gai_strerror(errcode int) *byte
// bytePtrToString takes a NUL-terminated array of bytes and convert
// it to a Go string.
diff --git a/libgo/go/os/dir.go b/libgo/go/os/dir.go
index 0e3c39976d4..f119a214639 100644
--- a/libgo/go/os/dir.go
+++ b/libgo/go/os/dir.go
@@ -10,12 +10,15 @@ import (
"unsafe"
)
-func libc_dup(fd int) int __asm__ ("dup")
-func libc_opendir(*byte) *syscall.DIR __asm__ ("opendir")
-func libc_closedir(*syscall.DIR) int __asm__ ("closedir")
+//extern opendir
+func libc_opendir(*byte) *syscall.DIR
+
+//extern closedir
+func libc_closedir(*syscall.DIR) int
// FIXME: pathconf returns long, not int.
-func libc_pathconf(*byte, int) int __asm__ ("pathconf")
+//extern pathconf
+func libc_pathconf(*byte, int) int
func clen(n []byte) int {
for i := 0; i < len(n); i++ {
@@ -26,14 +29,14 @@ func clen(n []byte) int {
return len(n)
}
-var elen int;
+var elen int
func (file *File) readdirnames(n int) (names []string, err error) {
if elen == 0 {
- var dummy syscall.Dirent;
+ var dummy syscall.Dirent
elen = (unsafe.Offsetof(dummy.Name) +
- libc_pathconf(syscall.StringBytePtr(file.name), syscall.PC_NAME_MAX) +
- 1);
+ libc_pathconf(syscall.StringBytePtr(file.name), syscall.PC_NAME_MAX) +
+ 1)
}
if file.dirinfo == nil {
@@ -55,7 +58,7 @@ func (file *File) readdirnames(n int) (names []string, err error) {
dir := file.dirinfo.dir
if dir == nil {
return names, NewSyscallError("opendir", syscall.GetErrno())
- }
+ }
for n != 0 {
var result *syscall.Dirent
@@ -67,7 +70,7 @@ func (file *File) readdirnames(n int) (names []string, err error) {
break // EOF
}
var name = string(result.Name[0:clen(result.Name[0:])])
- if name == "." || name == ".." { // Useless names
+ if name == "." || name == ".." { // Useless names
continue
}
names = append(names, name)
diff --git a/libgo/go/os/dir_largefile.go b/libgo/go/os/dir_largefile.go
index d6b4239610e..2555c7ba331 100644
--- a/libgo/go/os/dir_largefile.go
+++ b/libgo/go/os/dir_largefile.go
@@ -9,4 +9,5 @@ package os
import "syscall"
-func libc_readdir_r(*syscall.DIR, *syscall.Dirent, **syscall.Dirent) syscall.Errno __asm__ ("readdir64_r")
+//extern readdir64_r
+func libc_readdir_r(*syscall.DIR, *syscall.Dirent, **syscall.Dirent) syscall.Errno
diff --git a/libgo/go/os/dir_regfile.go b/libgo/go/os/dir_regfile.go
index 7effdf7851a..22cd33f2e20 100644
--- a/libgo/go/os/dir_regfile.go
+++ b/libgo/go/os/dir_regfile.go
@@ -9,4 +9,5 @@ package os
import "syscall"
-func libc_readdir_r(*syscall.DIR, *syscall.Dirent, **syscall.Dirent) syscall.Errno __asm__ ("readdir_r")
+// extern readdir_r
+func libc_readdir_r(*syscall.DIR, *syscall.Dirent, **syscall.Dirent) syscall.Errno
diff --git a/libgo/go/os/user/lookup_unix.go b/libgo/go/os/user/lookup_unix.go
index 602a3da2cd4..8939cebfcd8 100644
--- a/libgo/go/os/user/lookup_unix.go
+++ b/libgo/go/os/user/lookup_unix.go
@@ -26,8 +26,11 @@ static int mygetpwuid_r(int uid, struct passwd *pwd,
}
*/
-func libc_getpwnam_r(name *byte, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int __asm__ ("getpwnam_r")
-func libc_getpwuid_r(uid syscall.Uid_t, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int __asm__ ("getpwuid_r")
+//extern getpwnam_r
+func libc_getpwnam_r(name *byte, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int
+
+//extern getpwuid_r
+func libc_getpwuid_r(uid syscall.Uid_t, pwd *syscall.Passwd, buf *byte, buflen syscall.Size_t, result **syscall.Passwd) int
// bytePtrToString takes a NUL-terminated array of bytes and convert
// it to a Go string.
diff --git a/libgo/go/syscall/mksyscall.awk b/libgo/go/syscall/mksyscall.awk
index b02989cc323..8da02349e6a 100644
--- a/libgo/go/syscall/mksyscall.awk
+++ b/libgo/go/syscall/mksyscall.awk
@@ -96,8 +96,8 @@ BEGIN {
cfnresult = line
printf("// Automatically generated wrapper for %s/%s\n", gofnname, cfnname)
- printf("func c_%s(%s) %s%s__asm__(\"%s\")\n",
- cfnname, cfnparams, cfnresult, cfnresult == "" ? "" : " ", cfnname)
+ printf("//extern %s\n", cfnname)
+ printf("func c_%s(%s) %s\n", cfnname, cfnparams, cfnresult)
printf("func %s(%s) %s%s%s%s{\n",
gofnname, gofnparams, gofnresults == "" ? "" : "(", gofnresults,
gofnresults == "" ? "" : ")", gofnresults == "" ? "" : " ")
diff --git a/libgo/go/syscall/syscall_unix.go b/libgo/go/syscall/syscall_unix.go
index fb8986ce849..98e7d689f77 100644
--- a/libgo/go/syscall/syscall_unix.go
+++ b/libgo/go/syscall/syscall_unix.go
@@ -18,8 +18,11 @@ var (
Stderr = 2
)
-func c_syscall32(trap int32, a1, a2, a3, a4, a5, a6 int32) int32 __asm__ ("syscall");
-func c_syscall64(trap int64, a1, a2, a3, a4, a5, a6 int64) int64 __asm__ ("syscall");
+//extern syscall
+func c_syscall32(trap int32, a1, a2, a3, a4, a5, a6 int32) int32
+
+//extern syscall
+func c_syscall64(trap int64, a1, a2, a3, a4, a5, a6 int64) int64
const darwinAMD64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64"
@@ -46,7 +49,7 @@ func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
var r uintptr
if unsafe.Sizeof(r) == 4 {
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
- int32(a4), int32(a5), int32(a6))
+ int32(a4), int32(a5), int32(a6))
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
@@ -75,7 +78,7 @@ func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errn
var r uintptr
if unsafe.Sizeof(r) == 4 {
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
- int32(a4), int32(a5), int32(a6))
+ int32(a4), int32(a5), int32(a6))
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
diff --git a/libgo/runtime/chan.c b/libgo/runtime/chan.c
index a246992c60b..4fc2d603659 100644
--- a/libgo/runtime/chan.c
+++ b/libgo/runtime/chan.c
@@ -130,6 +130,12 @@ __go_new_channel(ChanType *t, uintptr hint)
return runtime_makechan_c(t, hint);
}
+Hchan*
+__go_new_channel_big(ChanType *t, uint64 hint)
+{
+ return runtime_makechan_c(t, hint);
+}
+
/*
* generic single channel send/recv
* if the bool pointer is nil,
diff --git a/libgo/runtime/go-make-slice.c b/libgo/runtime/go-make-slice.c
index 765e7c021b7..42b412c772b 100644
--- a/libgo/runtime/go-make-slice.c
+++ b/libgo/runtime/go-make-slice.c
@@ -57,3 +57,27 @@ __go_make_slice1 (const struct __go_type_descriptor *td, uintptr_t len)
{
return __go_make_slice2 (td, len, len);
}
+
+struct __go_open_array
+__go_make_slice2_big (const struct __go_type_descriptor *td, uint64_t len,
+ uint64_t cap)
+{
+ uintptr_t slen;
+ uintptr_t scap;
+
+ slen = (uintptr_t) len;
+ if ((uint64_t) slen != len)
+ runtime_panicstring ("makeslice: len out of range");
+
+ scap = (uintptr_t) cap;
+ if ((uint64_t) scap != cap)
+ runtime_panicstring ("makeslice: cap out of range");
+
+ return __go_make_slice2 (td, slen, scap);
+}
+
+struct __go_open_array
+__go_make_slice1_big (const struct __go_type_descriptor *td, uint64_t len)
+{
+ return __go_make_slice2_big (td, len, len);
+}
diff --git a/libgo/runtime/go-new-map.c b/libgo/runtime/go-new-map.c
index 288e1883f9d..eef71ddf47c 100644
--- a/libgo/runtime/go-new-map.c
+++ b/libgo/runtime/go-new-map.c
@@ -125,3 +125,17 @@ __go_new_map (const struct __go_map_descriptor *descriptor, uintptr_t entries)
__builtin_memset (ret->__buckets, 0, entries * sizeof (void *));
return ret;
}
+
+/* Allocate a new map when the argument to make is a large type. */
+
+struct __go_map *
+__go_new_map_big (const struct __go_map_descriptor *descriptor,
+ uint64_t entries)
+{
+ uintptr_t sentries;
+
+ sentries = (uintptr_t) entries;
+ if ((uint64_t) sentries != entries)
+ runtime_panicstring ("map size out of range");
+ return __go_new_map (descriptor, sentries);
+}
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index 9225f825b88..04412bd67e2 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -60,6 +60,54 @@ G runtime_g0; // idle goroutine for m0
static __thread G *g;
static __thread M *m;
+#ifndef SETCONTEXT_CLOBBERS_TLS
+
+static inline void
+initcontext(void)
+{
+}
+
+static inline void
+fixcontext(ucontext_t *c __attribute__ ((unused)))
+{
+}
+
+# else
+
+# if defined(__x86_64__) && defined(__sun__)
+
+// x86_64 Solaris 10 and 11 have a bug: setcontext switches the %fs
+// register to that of the thread which called getcontext. The effect
+// is that the address of all __thread variables changes. This bug
+// also affects pthread_self() and pthread_getspecific. We work
+// around it by clobbering the context field directly to keep %fs the
+// same.
+
+static __thread greg_t fs;
+
+static inline void
+initcontext(void)
+{
+ ucontext_t c;
+
+ getcontext(&c);
+ fs = c.uc_mcontext.gregs[REG_FSBASE];
+}
+
+static inline void
+fixcontext(ucontext_t* c)
+{
+ c->uc_mcontext.gregs[REG_FSBASE] = fs;
+}
+
+# else
+
+# error unknown case for SETCONTEXT_CLOBBERS_TLS
+
+# endif
+
+#endif
+
// We can not always refer to the TLS variables directly. The
// compiler will call tls_get_addr to get the address of the variable,
// and it may hold it in a register across a call to schedule. When
@@ -248,7 +296,9 @@ runtime_gogo(G* newg)
#endif
g = newg;
newg->fromgogo = true;
+ fixcontext(&newg->context);
setcontext(&newg->context);
+ runtime_throw("gogo setcontext returned");
}
// Save context and call fn passing g as a parameter. This is like
@@ -287,6 +337,7 @@ runtime_mcall(void (*pfn)(G*))
m->g0->entry = (byte*)pfn;
m->g0->param = g;
g = m->g0;
+ fixcontext(&m->g0->context);
setcontext(&m->g0->context);
runtime_throw("runtime: mcall function returned");
}
@@ -312,6 +363,8 @@ runtime_schedinit(void)
m->curg = g;
g->m = m;
+ initcontext();
+
m->nomemprof++;
runtime_mallocinit();
mcommoninit(m);
@@ -844,6 +897,8 @@ runtime_mstart(void* mp)
m = (M*)mp;
g = m->g0;
+ initcontext();
+
g->entry = nil;
g->param = nil;