diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-02-08 08:47:32 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-02-08 08:47:32 +0000 |
commit | 202719501643cd8e328c4fa816b0488443eb3b1b (patch) | |
tree | 4549e98383b6d1254787cd1b5f4fc6ec589f4fae /libgo | |
parent | 2791faee3c7b39a49776e5d69dc503579137fa12 (diff) | |
download | gcc-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')
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; |