Commit c8dc49fb by Ian Lance Taylor

syscall, internal/syscall/unix: Fix getrandom, clone on sparc64

    
    Since sparc is a valid architecture, the name of
    getrandom_linux_sparc.go means that it will be ignored on sparc64,
    even though it's whitelisted with a +build line.
    
    On SPARC, clone has a unique return value convention which requires
    some inline assembly to convert it to the normal convention.
    
    Reviewed-on: https://go-review.googlesource.com/30873

From-SVN: r241051
parent a25f5b28
03e53c928ebaa15a915eb1e1b07f193d83fc2852 d56717f8c434b3d6b753c027487681769e201e14
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -736,6 +736,12 @@ s-epoll: Makefile ...@@ -736,6 +736,12 @@ s-epoll: Makefile
$(SHELL) $(srcdir)/mvifdiff.sh epoll.go.tmp epoll.go $(SHELL) $(srcdir)/mvifdiff.sh epoll.go.tmp epoll.go
$(STAMP) $@ $(STAMP) $@
if LIBGO_IS_LINUX
syscall_lib_clone_lo = syscall/clone_linux.lo
else
syscall_lib_clone_lo =
endif
libgo_go_objs = \ libgo_go_objs = \
bufio.lo \ bufio.lo \
bytes.lo \ bytes.lo \
...@@ -767,6 +773,7 @@ libgo_go_objs = \ ...@@ -767,6 +773,7 @@ libgo_go_objs = \
strings/index.lo \ strings/index.lo \
sync.lo \ sync.lo \
syscall.lo \ syscall.lo \
$(syscall_lib_clone_lo) \
syscall/errno.lo \ syscall/errno.lo \
syscall/signame.lo \ syscall/signame.lo \
syscall/wait.lo \ syscall/wait.lo \
...@@ -2534,6 +2541,9 @@ syscall.lo.dep: $(srcdir)/go/syscall/*.go $(extra_go_files_syscall) ...@@ -2534,6 +2541,9 @@ syscall.lo.dep: $(srcdir)/go/syscall/*.go $(extra_go_files_syscall)
$(BUILDDEPS) $(BUILDDEPS)
syscall.lo: syscall.lo:
$(BUILDPACKAGE) $(BUILDPACKAGE)
syscall/clone_linux.lo: go/syscall/clone_linux.c runtime.inc
@$(MKDIR_P) syscall
$(LTCOMPILE) -c -o $@ $<
syscall/errno.lo: go/syscall/errno.c runtime.inc syscall/errno.lo: go/syscall/errno.c runtime.inc
@$(MKDIR_P) syscall @$(MKDIR_P) syscall
$(LTCOMPILE) -c -o $@ $< $(LTCOMPILE) -c -o $@ $<
......
...@@ -168,21 +168,22 @@ libnetgo_a_DEPENDENCIES = netgo.o ...@@ -168,21 +168,22 @@ libnetgo_a_DEPENDENCIES = netgo.o
am_libnetgo_a_OBJECTS = am_libnetgo_a_OBJECTS =
libnetgo_a_OBJECTS = $(am_libnetgo_a_OBJECTS) libnetgo_a_OBJECTS = $(am_libnetgo_a_OBJECTS)
LTLIBRARIES = $(toolexeclib_LTLIBRARIES) LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
am__DEPENDENCIES_1 = bufio.lo bytes.lo bytes/index.lo context.lo \ @LIBGO_IS_LINUX_TRUE@am__DEPENDENCIES_1 = syscall/clone_linux.lo
am__DEPENDENCIES_2 = bufio.lo bytes.lo bytes/index.lo context.lo \
crypto.lo encoding.lo errors.lo expvar.lo flag.lo fmt.lo \ crypto.lo encoding.lo errors.lo expvar.lo flag.lo fmt.lo \
hash.lo html.lo image.lo io.lo log.lo math.lo mime.lo net.lo \ hash.lo html.lo image.lo io.lo log.lo math.lo mime.lo net.lo \
os.lo path.lo reflect-go.lo reflect/makefunc_ffi_c.lo \ os.lo path.lo reflect-go.lo reflect/makefunc_ffi_c.lo \
regexp.lo runtime-go.lo sort.lo strconv.lo strings.lo \ regexp.lo runtime-go.lo sort.lo strconv.lo strings.lo \
strings/index.lo sync.lo syscall.lo syscall/errno.lo \ strings/index.lo sync.lo syscall.lo $(am__DEPENDENCIES_1) \
syscall/signame.lo syscall/wait.lo testing.lo time-go.lo \ syscall/errno.lo syscall/signame.lo syscall/wait.lo testing.lo \
unicode.lo archive/tar.lo archive/zip.lo compress/bzip2.lo \ time-go.lo unicode.lo archive/tar.lo archive/zip.lo \
compress/flate.lo compress/gzip.lo compress/lzw.lo \ compress/bzip2.lo compress/flate.lo compress/gzip.lo \
compress/zlib.lo container/heap.lo container/list.lo \ compress/lzw.lo compress/zlib.lo container/heap.lo \
container/ring.lo crypto/aes.lo crypto/cipher.lo crypto/des.lo \ container/list.lo container/ring.lo crypto/aes.lo \
crypto/dsa.lo crypto/ecdsa.lo crypto/elliptic.lo \ crypto/cipher.lo crypto/des.lo crypto/dsa.lo crypto/ecdsa.lo \
crypto/hmac.lo crypto/md5.lo crypto/rand.lo crypto/rc4.lo \ crypto/elliptic.lo crypto/hmac.lo crypto/md5.lo crypto/rand.lo \
crypto/rsa.lo crypto/sha1.lo crypto/sha256.lo crypto/sha512.lo \ crypto/rc4.lo crypto/rsa.lo crypto/sha1.lo crypto/sha256.lo \
crypto/subtle.lo crypto/tls.lo crypto/x509.lo \ crypto/sha512.lo crypto/subtle.lo crypto/tls.lo crypto/x509.lo \
crypto/x509/pkix.lo database/sql.lo database/sql/driver.lo \ crypto/x509/pkix.lo database/sql.lo database/sql/driver.lo \
debug/dwarf.lo debug/elf.lo debug/gosym.lo debug/macho.lo \ debug/dwarf.lo debug/elf.lo debug/gosym.lo debug/macho.lo \
debug/pe.lo debug/plan9obj.lo encoding/ascii85.lo \ debug/pe.lo debug/plan9obj.lo encoding/ascii85.lo \
...@@ -217,12 +218,12 @@ am__DEPENDENCIES_1 = bufio.lo bytes.lo bytes/index.lo context.lo \ ...@@ -217,12 +218,12 @@ am__DEPENDENCIES_1 = bufio.lo bytes.lo bytes/index.lo context.lo \
text/scanner.lo text/tabwriter.lo text/template.lo \ text/scanner.lo text/tabwriter.lo text/template.lo \
text/template/parse.lo testing/iotest.lo testing/quick.lo \ text/template/parse.lo testing/iotest.lo testing/quick.lo \
unicode/utf16.lo unicode/utf8.lo unicode/utf16.lo unicode/utf8.lo
am__DEPENDENCIES_2 = am__DEPENDENCIES_3 =
am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) \ am__DEPENDENCIES_4 = $(am__DEPENDENCIES_2) \
../libbacktrace/libbacktrace.la $(am__DEPENDENCIES_2) \ ../libbacktrace/libbacktrace.la $(am__DEPENDENCIES_3) \
$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_3) \
$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_3)
libgo_llgo_la_DEPENDENCIES = $(am__DEPENDENCIES_3) libgo_llgo_la_DEPENDENCIES = $(am__DEPENDENCIES_4)
@HAVE_SYS_MMAN_H_FALSE@am__objects_1 = mem_posix_memalign.lo @HAVE_SYS_MMAN_H_FALSE@am__objects_1 = mem_posix_memalign.lo
@HAVE_SYS_MMAN_H_TRUE@am__objects_1 = mem.lo @HAVE_SYS_MMAN_H_TRUE@am__objects_1 = mem.lo
@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_2 = netpoll_kqueue.lo @LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_2 = netpoll_kqueue.lo
...@@ -272,7 +273,7 @@ libgo_llgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ ...@@ -272,7 +273,7 @@ libgo_llgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libgo_llgo_la_LDFLAGS) $(LDFLAGS) -o $@ $(libgo_llgo_la_LDFLAGS) $(LDFLAGS) -o $@
@GOC_IS_LLGO_TRUE@am_libgo_llgo_la_rpath = -rpath $(toolexeclibdir) @GOC_IS_LLGO_TRUE@am_libgo_llgo_la_rpath = -rpath $(toolexeclibdir)
libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_3) libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_4)
am_libgo_la_OBJECTS = $(am__objects_6) am_libgo_la_OBJECTS = $(am__objects_6)
libgo_la_OBJECTS = $(am_libgo_la_OBJECTS) libgo_la_OBJECTS = $(am_libgo_la_OBJECTS)
libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
...@@ -948,6 +949,8 @@ SYSINFO_FLAGS = \ ...@@ -948,6 +949,8 @@ SYSINFO_FLAGS = \
$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(OSCFLAGS) -O $(CPPFLAGS) $(OSCFLAGS) -O
@LIBGO_IS_LINUX_FALSE@syscall_lib_clone_lo =
@LIBGO_IS_LINUX_TRUE@syscall_lib_clone_lo = syscall/clone_linux.lo
libgo_go_objs = \ libgo_go_objs = \
bufio.lo \ bufio.lo \
bytes.lo \ bytes.lo \
...@@ -979,6 +982,7 @@ libgo_go_objs = \ ...@@ -979,6 +982,7 @@ libgo_go_objs = \
strings/index.lo \ strings/index.lo \
sync.lo \ sync.lo \
syscall.lo \ syscall.lo \
$(syscall_lib_clone_lo) \
syscall/errno.lo \ syscall/errno.lo \
syscall/signame.lo \ syscall/signame.lo \
syscall/wait.lo \ syscall/wait.lo \
...@@ -5109,6 +5113,9 @@ syscall.lo.dep: $(srcdir)/go/syscall/*.go $(extra_go_files_syscall) ...@@ -5109,6 +5113,9 @@ syscall.lo.dep: $(srcdir)/go/syscall/*.go $(extra_go_files_syscall)
$(BUILDDEPS) $(BUILDDEPS)
syscall.lo: syscall.lo:
$(BUILDPACKAGE) $(BUILDPACKAGE)
syscall/clone_linux.lo: go/syscall/clone_linux.c runtime.inc
@$(MKDIR_P) syscall
$(LTCOMPILE) -c -o $@ $<
syscall/errno.lo: go/syscall/errno.c runtime.inc syscall/errno.lo: go/syscall/errno.c runtime.inc
@$(MKDIR_P) syscall @$(MKDIR_P) syscall
$(LTCOMPILE) -c -o $@ $< $(LTCOMPILE) -c -o $@ $<
......
/* clone_linux.c -- consistent wrapper around Linux clone syscall
Copyright 2016 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 <errno.h>
#include <asm/ptrace.h>
#include <sys/syscall.h>
#include "runtime.h"
long rawClone (unsigned long flags, void *child_stack, void *ptid, void *ctid, struct pt_regs *regs) __asm__ (GOSYM_PREFIX "syscall.rawClone");
long
rawClone (unsigned long flags, void *child_stack, void *ptid, void *ctid, struct pt_regs *regs)
{
#if defined(__arc__) || defined(__aarch64__) || defined(__arm__) || defined(__mips__) || defined(__hppa__) || defined(__powerpc__) || defined(__score__) || defined(__i386__) || defined(__xtensa__)
// CLONE_BACKWARDS
return syscall(__NR_clone, flags, child_stack, ptid, regs, ctid);
#elif defined(__s390__) || defined(__cris__)
// CLONE_BACKWARDS2
return syscall(__NR_clone, child_stack, flags, ptid, ctid, regs);
#elif defined(__microblaze__)
// CLONE_BACKWARDS3
return syscall(__NR_clone, flags, child_stack, 0, ptid, ctid, regs);
#elif defined(__sparc__)
/* SPARC has a unique return value convention:
Parent --> %o0 == child's pid, %o1 == 0
Child --> %o0 == parent's pid, %o1 == 1
Translate this to look like a normal clone. */
# if defined(__arch64__)
# define SYSCALL_STRING \
"ta 0x6d;" \
"bcc,pt %%xcc, 1f;" \
" mov 0, %%g1;" \
"sub %%g0, %%o0, %%o0;" \
"mov 1, %%g1;" \
"1:"
# define SYSCALL_CLOBBERS \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
"f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
"f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \
"cc", "memory"
# else /* __arch64__ */
# define SYSCALL_STRING \
"ta 0x10;" \
"bcc 1f;" \
" mov 0, %%g1;" \
"sub %%g0, %%o0, %%o0;" \
"mov 1, %%g1;" \
"1:"
# define SYSCALL_CLOBBERS \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
"cc", "memory"
# endif /* __arch64__ */
register long o0 __asm__ ("o0") = (long)flags;
register long o1 __asm__ ("o1") = (long)child_stack;
register long o2 __asm__ ("o2") = (long)ptid;
register long o3 __asm__ ("o3") = (long)ctid;
register long o4 __asm__ ("o4") = (long)regs;
register long g1 __asm__ ("g1") = __NR_clone;
__asm __volatile (SYSCALL_STRING :
"=r" (g1), "=r" (o0), "=r" (o1) :
"0" (g1), "1" (o0), "2" (o1),
"r" (o2), "r" (o3), "r" (o4) :
SYSCALL_CLOBBERS);
if (__builtin_expect(g1 != 0, 0))
{
errno = -o0;
o0 = -1L;
}
else
o0 &= (o1 - 1);
return o0;
#else
return syscall(__NR_clone, flags, child_stack, ptid, ctid, regs);
#endif
}
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
package syscall package syscall
import ( import (
"runtime"
"unsafe" "unsafe"
) )
...@@ -49,6 +48,9 @@ type SysProcAttr struct { ...@@ -49,6 +48,9 @@ type SysProcAttr struct {
func runtime_BeforeFork() func runtime_BeforeFork()
func runtime_AfterFork() func runtime_AfterFork()
// Implemented in clone_linux.c
func rawClone(flags _C_ulong, child_stack *byte, ptid *Pid_t, ctid *Pid_t, regs unsafe.Pointer) _C_long
// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child. // Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
// If a dup or exec fails, write the errno error to pipe. // If a dup or exec fails, write the errno error to pipe.
// (Pipe is close-on-exec so if exec succeeds, it will be closed.) // (Pipe is close-on-exec so if exec succeeds, it will be closed.)
...@@ -64,6 +66,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr ...@@ -64,6 +66,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
// declarations require heap allocation (e.g., err1). // declarations require heap allocation (e.g., err1).
var ( var (
r1 uintptr r1 uintptr
r2 _C_long
err1 Errno err1 Errno
err2 Errno err2 Errno
nextfd int nextfd int
...@@ -98,20 +101,16 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr ...@@ -98,20 +101,16 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
// About to call fork. // About to call fork.
// No more allocation or calls of non-assembly functions. // No more allocation or calls of non-assembly functions.
runtime_BeforeFork() runtime_BeforeFork()
if runtime.GOARCH == "s390x" || runtime.GOARCH == "s390" { r2 = rawClone(_C_ulong(uintptr(SIGCHLD)|sys.Cloneflags), nil, nil, nil, unsafe.Pointer(nil))
r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0) if r2 < 0 {
} else {
r1, _, err1 = RawSyscall6(SYS_CLONE, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0, 0)
}
if err1 != 0 {
runtime_AfterFork() runtime_AfterFork()
return 0, err1 return 0, GetErrno()
} }
if r1 != 0 { if r2 != 0 {
// parent; return PID // parent; return PID
runtime_AfterFork() runtime_AfterFork()
pid = int(r1) pid = int(r2)
if sys.UidMappings != nil || sys.GidMappings != nil { if sys.UidMappings != nil || sys.GidMappings != nil {
Close(p[0]) Close(p[0])
......
...@@ -349,8 +349,10 @@ fi ...@@ -349,8 +349,10 @@ fi
sizeof_long=`grep '^const ___SIZEOF_LONG__ = ' gen-sysinfo.go | sed -e 's/.*= //'` sizeof_long=`grep '^const ___SIZEOF_LONG__ = ' gen-sysinfo.go | sed -e 's/.*= //'`
if test "$sizeof_long" = "4"; then if test "$sizeof_long" = "4"; then
echo "type _C_long int32" >> ${OUT} echo "type _C_long int32" >> ${OUT}
echo "type _C_ulong uint32" >> ${OUT}
elif test "$sizeof_long" = "8"; then elif test "$sizeof_long" = "8"; then
echo "type _C_long int64" >> ${OUT} echo "type _C_long int64" >> ${OUT}
echo "type _C_ulong uint64" >> ${OUT}
else else
echo 1>&2 "mksysinfo.sh: could not determine size of long (got $sizeof_long)" echo 1>&2 "mksysinfo.sh: could not determine size of long (got $sizeof_long)"
exit 1 exit 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment