Black Lives Matter. Support the Equal Justice Initiative.

Source file src/runtime/syscall_solaris.go

Documentation: runtime

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import "unsafe"
     8  
     9  var (
    10  	libc_chdir,
    11  	libc_chroot,
    12  	libc_close,
    13  	libc_execve,
    14  	libc_fcntl,
    15  	libc_forkx,
    16  	libc_gethostname,
    17  	libc_getpid,
    18  	libc_ioctl,
    19  	libc_setgid,
    20  	libc_setgroups,
    21  	libc_setsid,
    22  	libc_setuid,
    23  	libc_setpgid,
    24  	libc_syscall,
    25  	libc_wait4 libcFunc
    26  )
    27  
    28  //go:linkname pipe1x runtime.pipe1
    29  var pipe1x libcFunc // name to take addr of pipe1
    30  
    31  func pipe1() // declared for vet; do NOT call
    32  
    33  // Many of these are exported via linkname to assembly in the syscall
    34  // package.
    35  
    36  //go:nosplit
    37  //go:linkname syscall_sysvicall6
    38  func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
    39  	call := libcall{
    40  		fn:   fn,
    41  		n:    nargs,
    42  		args: uintptr(unsafe.Pointer(&a1)),
    43  	}
    44  	entersyscallblock()
    45  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
    46  	exitsyscall()
    47  	return call.r1, call.r2, call.err
    48  }
    49  
    50  //go:nosplit
    51  //go:linkname syscall_rawsysvicall6
    52  func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
    53  	call := libcall{
    54  		fn:   fn,
    55  		n:    nargs,
    56  		args: uintptr(unsafe.Pointer(&a1)),
    57  	}
    58  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
    59  	return call.r1, call.r2, call.err
    60  }
    61  
    62  // TODO(aram): Once we remove all instances of C calling sysvicallN, make
    63  // sysvicallN return errors and replace the body of the following functions
    64  // with calls to sysvicallN.
    65  
    66  //go:nosplit
    67  //go:linkname syscall_chdir
    68  func syscall_chdir(path uintptr) (err uintptr) {
    69  	call := libcall{
    70  		fn:   uintptr(unsafe.Pointer(&libc_chdir)),
    71  		n:    1,
    72  		args: uintptr(unsafe.Pointer(&path)),
    73  	}
    74  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
    75  	return call.err
    76  }
    77  
    78  //go:nosplit
    79  //go:linkname syscall_chroot
    80  func syscall_chroot(path uintptr) (err uintptr) {
    81  	call := libcall{
    82  		fn:   uintptr(unsafe.Pointer(&libc_chroot)),
    83  		n:    1,
    84  		args: uintptr(unsafe.Pointer(&path)),
    85  	}
    86  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
    87  	return call.err
    88  }
    89  
    90  // like close, but must not split stack, for forkx.
    91  //go:nosplit
    92  //go:linkname syscall_close
    93  func syscall_close(fd int32) int32 {
    94  	return int32(sysvicall1(&libc_close, uintptr(fd)))
    95  }
    96  
    97  const _F_DUP2FD = 0x9
    98  
    99  //go:nosplit
   100  //go:linkname syscall_dup2
   101  func syscall_dup2(oldfd, newfd uintptr) (val, err uintptr) {
   102  	return syscall_fcntl(oldfd, _F_DUP2FD, newfd)
   103  }
   104  
   105  //go:nosplit
   106  //go:linkname syscall_execve
   107  func syscall_execve(path, argv, envp uintptr) (err uintptr) {
   108  	call := libcall{
   109  		fn:   uintptr(unsafe.Pointer(&libc_execve)),
   110  		n:    3,
   111  		args: uintptr(unsafe.Pointer(&path)),
   112  	}
   113  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   114  	return call.err
   115  }
   116  
   117  // like exit, but must not split stack, for forkx.
   118  //go:nosplit
   119  //go:linkname syscall_exit
   120  func syscall_exit(code uintptr) {
   121  	sysvicall1(&libc_exit, code)
   122  }
   123  
   124  //go:nosplit
   125  //go:linkname syscall_fcntl
   126  func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) {
   127  	call := libcall{
   128  		fn:   uintptr(unsafe.Pointer(&libc_fcntl)),
   129  		n:    3,
   130  		args: uintptr(unsafe.Pointer(&fd)),
   131  	}
   132  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   133  	return call.r1, call.err
   134  }
   135  
   136  //go:nosplit
   137  //go:linkname syscall_forkx
   138  func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
   139  	call := libcall{
   140  		fn:   uintptr(unsafe.Pointer(&libc_forkx)),
   141  		n:    1,
   142  		args: uintptr(unsafe.Pointer(&flags)),
   143  	}
   144  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   145  	if int(call.r1) != -1 {
   146  		call.err = 0
   147  	}
   148  	return call.r1, call.err
   149  }
   150  
   151  //go:linkname syscall_gethostname
   152  func syscall_gethostname() (name string, err uintptr) {
   153  	cname := new([_MAXHOSTNAMELEN]byte)
   154  	var args = [2]uintptr{uintptr(unsafe.Pointer(&cname[0])), _MAXHOSTNAMELEN}
   155  	call := libcall{
   156  		fn:   uintptr(unsafe.Pointer(&libc_gethostname)),
   157  		n:    2,
   158  		args: uintptr(unsafe.Pointer(&args[0])),
   159  	}
   160  	entersyscallblock()
   161  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   162  	exitsyscall()
   163  	if call.r1 != 0 {
   164  		return "", call.err
   165  	}
   166  	cname[_MAXHOSTNAMELEN-1] = 0
   167  	return gostringnocopy(&cname[0]), 0
   168  }
   169  
   170  //go:nosplit
   171  //go:linkname syscall_getpid
   172  func syscall_getpid() (pid, err uintptr) {
   173  	call := libcall{
   174  		fn:   uintptr(unsafe.Pointer(&libc_getpid)),
   175  		n:    0,
   176  		args: uintptr(unsafe.Pointer(&libc_getpid)), // it's unused but must be non-nil, otherwise crashes
   177  	}
   178  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   179  	return call.r1, call.err
   180  }
   181  
   182  //go:nosplit
   183  //go:linkname syscall_ioctl
   184  func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
   185  	call := libcall{
   186  		fn:   uintptr(unsafe.Pointer(&libc_ioctl)),
   187  		n:    3,
   188  		args: uintptr(unsafe.Pointer(&fd)),
   189  	}
   190  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   191  	return call.err
   192  }
   193  
   194  //go:linkname syscall_pipe
   195  func syscall_pipe() (r, w, err uintptr) {
   196  	call := libcall{
   197  		fn:   uintptr(unsafe.Pointer(&pipe1x)),
   198  		n:    0,
   199  		args: uintptr(unsafe.Pointer(&pipe1x)), // it's unused but must be non-nil, otherwise crashes
   200  	}
   201  	entersyscallblock()
   202  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   203  	exitsyscall()
   204  	return call.r1, call.r2, call.err
   205  }
   206  
   207  // This is syscall.RawSyscall, it exists to satisfy some build dependency,
   208  // but it doesn't work.
   209  //
   210  //go:linkname syscall_rawsyscall
   211  func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
   212  	panic("RawSyscall not available on Solaris")
   213  }
   214  
   215  // This is syscall.RawSyscall6, it exists to avoid a linker error because
   216  // syscall.RawSyscall6 is already declared. See golang.org/issue/24357
   217  //
   218  //go:linkname syscall_rawsyscall6
   219  func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
   220  	panic("RawSyscall6 not available on Solaris")
   221  }
   222  
   223  //go:nosplit
   224  //go:linkname syscall_setgid
   225  func syscall_setgid(gid uintptr) (err uintptr) {
   226  	call := libcall{
   227  		fn:   uintptr(unsafe.Pointer(&libc_setgid)),
   228  		n:    1,
   229  		args: uintptr(unsafe.Pointer(&gid)),
   230  	}
   231  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   232  	return call.err
   233  }
   234  
   235  //go:nosplit
   236  //go:linkname syscall_setgroups
   237  func syscall_setgroups(ngid, gid uintptr) (err uintptr) {
   238  	call := libcall{
   239  		fn:   uintptr(unsafe.Pointer(&libc_setgroups)),
   240  		n:    2,
   241  		args: uintptr(unsafe.Pointer(&ngid)),
   242  	}
   243  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   244  	return call.err
   245  }
   246  
   247  //go:nosplit
   248  //go:linkname syscall_setsid
   249  func syscall_setsid() (pid, err uintptr) {
   250  	call := libcall{
   251  		fn:   uintptr(unsafe.Pointer(&libc_setsid)),
   252  		n:    0,
   253  		args: uintptr(unsafe.Pointer(&libc_setsid)), // it's unused but must be non-nil, otherwise crashes
   254  	}
   255  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   256  	return call.r1, call.err
   257  }
   258  
   259  //go:nosplit
   260  //go:linkname syscall_setuid
   261  func syscall_setuid(uid uintptr) (err uintptr) {
   262  	call := libcall{
   263  		fn:   uintptr(unsafe.Pointer(&libc_setuid)),
   264  		n:    1,
   265  		args: uintptr(unsafe.Pointer(&uid)),
   266  	}
   267  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   268  	return call.err
   269  }
   270  
   271  //go:nosplit
   272  //go:linkname syscall_setpgid
   273  func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
   274  	call := libcall{
   275  		fn:   uintptr(unsafe.Pointer(&libc_setpgid)),
   276  		n:    2,
   277  		args: uintptr(unsafe.Pointer(&pid)),
   278  	}
   279  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   280  	return call.err
   281  }
   282  
   283  //go:linkname syscall_syscall
   284  func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
   285  	call := libcall{
   286  		fn:   uintptr(unsafe.Pointer(&libc_syscall)),
   287  		n:    4,
   288  		args: uintptr(unsafe.Pointer(&trap)),
   289  	}
   290  	entersyscallblock()
   291  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   292  	exitsyscall()
   293  	return call.r1, call.r2, call.err
   294  }
   295  
   296  //go:linkname syscall_wait4
   297  func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.Pointer) (wpid int, err uintptr) {
   298  	call := libcall{
   299  		fn:   uintptr(unsafe.Pointer(&libc_wait4)),
   300  		n:    4,
   301  		args: uintptr(unsafe.Pointer(&pid)),
   302  	}
   303  	entersyscallblock()
   304  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   305  	exitsyscall()
   306  	return int(call.r1), call.err
   307  }
   308  
   309  //go:nosplit
   310  //go:linkname syscall_write
   311  func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) {
   312  	call := libcall{
   313  		fn:   uintptr(unsafe.Pointer(&libc_write)),
   314  		n:    3,
   315  		args: uintptr(unsafe.Pointer(&fd)),
   316  	}
   317  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&call))
   318  	return call.r1, call.err
   319  }
   320  

View as plain text