gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

libc_linux_s390x.go (12395B)


      1 // Copyright 2021 The Libc 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 libc // import "modernc.org/libc"
      6 
      7 import (
      8 	"os"
      9 	"strings"
     10 	"unsafe"
     11 
     12 	"golang.org/x/sys/unix"
     13 	"modernc.org/libc/errno"
     14 	"modernc.org/libc/fcntl"
     15 	"modernc.org/libc/signal"
     16 	"modernc.org/libc/sys/types"
     17 )
     18 
     19 // int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
     20 func Xsigaction(t *TLS, signum int32, act, oldact uintptr) int32 {
     21 	// musl/src/internal/ksigaction.h
     22 	//	struct k_sigaction {
     23 	//		void (*handler)(int);
     24 	//		unsigned long flags;
     25 	//		void (*restorer)(void);
     26 	//		unsigned mask[2];
     27 	//	};
     28 	type k_sigaction struct {
     29 		handler  uintptr
     30 		flags    ulong
     31 		restorer uintptr
     32 		mask     [2]uint32
     33 	}
     34 
     35 	var kact, koldact uintptr
     36 	if act != 0 {
     37 		sz := int(unsafe.Sizeof(k_sigaction{}))
     38 		kact = t.Alloc(sz)
     39 		defer t.Free(sz)
     40 		*(*k_sigaction)(unsafe.Pointer(kact)) = k_sigaction{
     41 			handler:  (*signal.Sigaction)(unsafe.Pointer(act)).F__sigaction_handler.Fsa_handler,
     42 			flags:    ulong((*signal.Sigaction)(unsafe.Pointer(act)).Fsa_flags),
     43 			restorer: (*signal.Sigaction)(unsafe.Pointer(act)).Fsa_restorer,
     44 		}
     45 		Xmemcpy(t, kact+unsafe.Offsetof(k_sigaction{}.mask), act+unsafe.Offsetof(signal.Sigaction{}.Fsa_mask), types.Size_t(unsafe.Sizeof(k_sigaction{}.mask)))
     46 	}
     47 	if oldact != 0 {
     48 		panic(todo(""))
     49 	}
     50 
     51 	if _, _, err := unix.Syscall6(unix.SYS_RT_SIGACTION, uintptr(signum), kact, koldact, unsafe.Sizeof(k_sigaction{}.mask), 0, 0); err != 0 {
     52 		t.setErrno(err)
     53 		return -1
     54 	}
     55 
     56 	if oldact != 0 {
     57 		panic(todo(""))
     58 	}
     59 
     60 	return 0
     61 }
     62 
     63 // int fcntl(int fd, int cmd, ... /* arg */ );
     64 func Xfcntl64(t *TLS, fd, cmd int32, args uintptr) int32 {
     65 	var arg uintptr
     66 	if args != 0 {
     67 		arg = *(*uintptr)(unsafe.Pointer(args))
     68 	}
     69 	if cmd == fcntl.F_SETFL {
     70 		arg |= unix.O_LARGEFILE
     71 	}
     72 	n, _, err := unix.Syscall(unix.SYS_FCNTL, uintptr(fd), uintptr(cmd), arg)
     73 	if err != 0 {
     74 		// if dmesgs {
     75 		// 	dmesg("%v: fd %v cmd %v", origin(1), fcntlCmdStr(fd), cmd)
     76 		// }
     77 		t.setErrno(err)
     78 		return -1
     79 	}
     80 
     81 	// if dmesgs {
     82 	// 	dmesg("%v: %d %s %#x: %d", origin(1), fd, fcntlCmdStr(cmd), arg, n)
     83 	// }
     84 	return int32(n)
     85 }
     86 
     87 // int lstat(const char *pathname, struct stat *statbuf);
     88 func Xlstat64(t *TLS, pathname, statbuf uintptr) int32 {
     89 	if _, _, err := unix.Syscall(unix.SYS_LSTAT, pathname, statbuf, 0); err != 0 {
     90 		// if dmesgs {
     91 		// 	dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
     92 		// }
     93 		t.setErrno(err)
     94 		return -1
     95 	}
     96 
     97 	// if dmesgs {
     98 	// 	dmesg("%v: %q: ok", origin(1), GoString(pathname))
     99 	// }
    100 	return 0
    101 }
    102 
    103 // int stat(const char *pathname, struct stat *statbuf);
    104 func Xstat64(t *TLS, pathname, statbuf uintptr) int32 {
    105 	if _, _, err := unix.Syscall(unix.SYS_STAT, pathname, statbuf, 0); err != 0 {
    106 		// if dmesgs {
    107 		// 	dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
    108 		// }
    109 		t.setErrno(err)
    110 		return -1
    111 	}
    112 
    113 	// if dmesgs {
    114 	// 	dmesg("%v: %q: ok", origin(1), GoString(pathname))
    115 	// }
    116 	return 0
    117 }
    118 
    119 // int fstat(int fd, struct stat *statbuf);
    120 func Xfstat64(t *TLS, fd int32, statbuf uintptr) int32 {
    121 	if _, _, err := unix.Syscall(unix.SYS_FSTAT, uintptr(fd), statbuf, 0); err != 0 {
    122 		// if dmesgs {
    123 		// 	dmesg("%v: fd %d: %v", origin(1), fd, err)
    124 		// }
    125 		t.setErrno(err)
    126 		return -1
    127 	}
    128 
    129 	// if dmesgs {
    130 	// 	dmesg("%v: %d size %#x: ok\n%+v", origin(1), fd, (*stat.Stat)(unsafe.Pointer(statbuf)).Fst_size, (*stat.Stat)(unsafe.Pointer(statbuf)))
    131 	// }
    132 	return 0
    133 }
    134 
    135 func Xmmap(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
    136 	return Xmmap64(t, addr, length, prot, flags, fd, offset)
    137 }
    138 
    139 // void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
    140 func Xmmap64(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
    141 	// https://github.com/golang/go/blob/7d822af4500831d131562f17dcf53374469d823e/src/syscall/syscall_linux_s390x.go#L77
    142 	args := [6]uintptr{addr, uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)}
    143 	data, _, err := unix.Syscall(unix.SYS_MMAP, uintptr(unsafe.Pointer(&args[0])), 0, 0)
    144 	if err != 0 {
    145 		// if dmesgs {
    146 		// 	dmesg("%v: addr %#x, length %#x, prot %#x, flags %#x, fd %v, offset %#x: %v", origin(1), addr, length, prot, flags, fd, offset, err)
    147 		// }
    148 		t.setErrno(err)
    149 		return ^uintptr(0) // (void*)-1
    150 	}
    151 
    152 	// if dmesgs {
    153 	// 	dmesg("%v: addr %#x, length %#x, prot %#x, flags %#x, fd %v, offset %#x: ok", origin(1), addr, length, prot, flags, fd, offset)
    154 	// }
    155 	return data
    156 }
    157 
    158 // void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, ... /* void *new_address */);
    159 func Xmremap(t *TLS, old_address uintptr, old_size, new_size types.Size_t, flags int32, args uintptr) uintptr {
    160 	var arg uintptr
    161 	if args != 0 {
    162 		arg = *(*uintptr)(unsafe.Pointer(args))
    163 	}
    164 	data, _, err := unix.Syscall6(unix.SYS_MREMAP, old_address, uintptr(old_size), uintptr(new_size), uintptr(flags), arg, 0)
    165 	if err != 0 {
    166 		// if dmesgs {
    167 		// 	dmesg("%v: %v", origin(1), err)
    168 		// }
    169 		t.setErrno(err)
    170 		return ^uintptr(0) // (void*)-1
    171 	}
    172 
    173 	// if dmesgs {
    174 	// 	dmesg("%v: %#x", origin(1), data)
    175 	// }
    176 	return data
    177 }
    178 
    179 // int ftruncate(int fd, off_t length);
    180 func Xftruncate64(t *TLS, fd int32, length types.Off_t) int32 {
    181 	if _, _, err := unix.Syscall(unix.SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0); err != 0 {
    182 		// if dmesgs {
    183 		// 	dmesg("%v: fd %d: %v", origin(1), fd, err)
    184 		// }
    185 		t.setErrno(err)
    186 		return -1
    187 	}
    188 
    189 	// if dmesgs {
    190 	// 	dmesg("%v: %d %#x: ok", origin(1), fd, length)
    191 	// }
    192 	return 0
    193 }
    194 
    195 // off64_t lseek64(int fd, off64_t offset, int whence);
    196 func Xlseek64(t *TLS, fd int32, offset types.Off_t, whence int32) types.Off_t {
    197 	n, _, err := unix.Syscall(unix.SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
    198 	if err != 0 {
    199 		// if dmesgs {
    200 		// 	dmesg("%v: fd %v, off %#x, whence %v: %v", origin(1), fd, offset, whenceStr(whence), err)
    201 		// }
    202 		t.setErrno(err)
    203 		return -1
    204 	}
    205 
    206 	// if dmesgs {
    207 	// 	dmesg("%v: fd %v, off %#x, whence %v: %#x", origin(1), fd, offset, whenceStr(whence), n)
    208 	// }
    209 	return types.Off_t(n)
    210 }
    211 
    212 // int utime(const char *filename, const struct utimbuf *times);
    213 func Xutime(t *TLS, filename, times uintptr) int32 {
    214 	if _, _, err := unix.Syscall(unix.SYS_UTIME, filename, times, 0); err != 0 {
    215 		t.setErrno(err)
    216 		return -1
    217 	}
    218 
    219 	return 0
    220 }
    221 
    222 // unsigned int alarm(unsigned int seconds);
    223 func Xalarm(t *TLS, seconds uint32) uint32 {
    224 	n, _, err := unix.Syscall(unix.SYS_ALARM, uintptr(seconds), 0, 0)
    225 	if err != 0 {
    226 		panic(todo(""))
    227 	}
    228 
    229 	return uint32(n)
    230 }
    231 
    232 // time_t time(time_t *tloc);
    233 func Xtime(t *TLS, tloc uintptr) types.Time_t {
    234 	n, err := unix.Time((*unix.Time_t)(unsafe.Pointer(tloc)))
    235 	if err != nil {
    236 		t.setErrno(err)
    237 		return types.Time_t(-1)
    238 	}
    239 
    240 	return types.Time_t(n)
    241 }
    242 
    243 // int getrlimit(int resource, struct rlimit *rlim);
    244 func Xgetrlimit64(t *TLS, resource int32, rlim uintptr) int32 {
    245 	if _, _, err := unix.Syscall(unix.SYS_GETRLIMIT, uintptr(resource), uintptr(rlim), 0); err != 0 {
    246 		t.setErrno(err)
    247 		return -1
    248 	}
    249 
    250 	return 0
    251 }
    252 
    253 // int mkdir(const char *path, mode_t mode);
    254 func Xmkdir(t *TLS, path uintptr, mode types.Mode_t) int32 {
    255 	if _, _, err := unix.Syscall(unix.SYS_MKDIR, path, uintptr(mode), 0); err != 0 {
    256 		t.setErrno(err)
    257 		return -1
    258 	}
    259 
    260 	// if dmesgs {
    261 	// 	dmesg("%v: %q: ok", origin(1), GoString(path))
    262 	// }
    263 	return 0
    264 }
    265 
    266 // int symlink(const char *target, const char *linkpath);
    267 func Xsymlink(t *TLS, target, linkpath uintptr) int32 {
    268 	if _, _, err := unix.Syscall(unix.SYS_SYMLINK, target, linkpath, 0); err != 0 {
    269 		t.setErrno(err)
    270 		return -1
    271 	}
    272 
    273 	// if dmesgs {
    274 	// 	dmesg("%v: %q %q: ok", origin(1), GoString(target), GoString(linkpath))
    275 	// }
    276 	return 0
    277 }
    278 
    279 // int chmod(const char *pathname, mode_t mode)
    280 func Xchmod(t *TLS, pathname uintptr, mode types.Mode_t) int32 {
    281 	if _, _, err := unix.Syscall(unix.SYS_CHMOD, pathname, uintptr(mode), 0); err != 0 {
    282 		t.setErrno(err)
    283 		return -1
    284 	}
    285 
    286 	// if dmesgs {
    287 	// 	dmesg("%v: %q %#o: ok", origin(1), GoString(pathname), mode)
    288 	// }
    289 	return 0
    290 }
    291 
    292 // int utimes(const char *filename, const struct timeval times[2]);
    293 func Xutimes(t *TLS, filename, times uintptr) int32 {
    294 	if _, _, err := unix.Syscall(unix.SYS_UTIMES, filename, times, 0); err != 0 {
    295 		t.setErrno(err)
    296 		return -1
    297 	}
    298 
    299 	// if dmesgs {
    300 	// 	dmesg("%v: %q: ok", origin(1), GoString(filename))
    301 	// }
    302 	return 0
    303 }
    304 
    305 // int unlink(const char *pathname);
    306 func Xunlink(t *TLS, pathname uintptr) int32 {
    307 	if _, _, err := unix.Syscall(unix.SYS_UNLINK, pathname, 0, 0); err != 0 {
    308 		t.setErrno(err)
    309 		return -1
    310 	}
    311 
    312 	// if dmesgs {
    313 	// 	dmesg("%v: %q: ok", origin(1), GoString(pathname))
    314 	// }
    315 	return 0
    316 }
    317 
    318 // int access(const char *pathname, int mode);
    319 func Xaccess(t *TLS, pathname uintptr, mode int32) int32 {
    320 	if _, _, err := unix.Syscall(unix.SYS_ACCESS, pathname, uintptr(mode), 0); err != 0 {
    321 		// if dmesgs {
    322 		// 	dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
    323 		// }
    324 		t.setErrno(err)
    325 		return -1
    326 	}
    327 
    328 	// if dmesgs {
    329 	// 	dmesg("%v: %q %#o: ok", origin(1), GoString(pathname), mode)
    330 	// }
    331 	return 0
    332 }
    333 
    334 // int rmdir(const char *pathname);
    335 func Xrmdir(t *TLS, pathname uintptr) int32 {
    336 	if _, _, err := unix.Syscall(unix.SYS_RMDIR, pathname, 0, 0); err != 0 {
    337 		t.setErrno(err)
    338 		return -1
    339 	}
    340 
    341 	// if dmesgs {
    342 	// 	dmesg("%v: %q: ok", origin(1), GoString(pathname))
    343 	// }
    344 	return 0
    345 }
    346 
    347 // int rename(const char *oldpath, const char *newpath);
    348 func Xrename(t *TLS, oldpath, newpath uintptr) int32 {
    349 	if _, _, err := unix.Syscall(unix.SYS_RENAME, oldpath, newpath, 0); err != 0 {
    350 		t.setErrno(err)
    351 		return -1
    352 	}
    353 
    354 	return 0
    355 }
    356 
    357 // int mknod(const char *pathname, mode_t mode, dev_t dev);
    358 func Xmknod(t *TLS, pathname uintptr, mode types.Mode_t, dev types.Dev_t) int32 {
    359 	if _, _, err := unix.Syscall(unix.SYS_MKNOD, pathname, uintptr(mode), uintptr(dev)); err != 0 {
    360 		t.setErrno(err)
    361 		return -1
    362 	}
    363 
    364 	return 0
    365 }
    366 
    367 // int chown(const char *pathname, uid_t owner, gid_t group);
    368 func Xchown(t *TLS, pathname uintptr, owner types.Uid_t, group types.Gid_t) int32 {
    369 	if _, _, err := unix.Syscall(unix.SYS_CHOWN, pathname, uintptr(owner), uintptr(group)); err != 0 {
    370 		t.setErrno(err)
    371 		return -1
    372 	}
    373 
    374 	return 0
    375 }
    376 
    377 // int link(const char *oldpath, const char *newpath);
    378 func Xlink(t *TLS, oldpath, newpath uintptr) int32 {
    379 	if _, _, err := unix.Syscall(unix.SYS_LINK, oldpath, newpath, 0); err != 0 {
    380 		t.setErrno(err)
    381 		return -1
    382 	}
    383 
    384 	return 0
    385 }
    386 
    387 // int pipe(int pipefd[2]);
    388 func Xpipe(t *TLS, pipefd uintptr) int32 {
    389 	if _, _, err := unix.Syscall(unix.SYS_PIPE, pipefd, 0, 0); err != 0 {
    390 		t.setErrno(err)
    391 		return -1
    392 	}
    393 
    394 	return 0
    395 }
    396 
    397 // int dup2(int oldfd, int newfd);
    398 func Xdup2(t *TLS, oldfd, newfd int32) int32 {
    399 	n, _, err := unix.Syscall(unix.SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
    400 	if err != 0 {
    401 		t.setErrno(err)
    402 		return -1
    403 	}
    404 
    405 	return int32(n)
    406 }
    407 
    408 // ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);
    409 func Xreadlink(t *TLS, path, buf uintptr, bufsize types.Size_t) types.Ssize_t {
    410 	n, _, err := unix.Syscall(unix.SYS_READLINK, path, buf, uintptr(bufsize))
    411 	if err != 0 {
    412 		t.setErrno(err)
    413 		return -1
    414 	}
    415 
    416 	return types.Ssize_t(n)
    417 }
    418 
    419 // FILE *fopen64(const char *pathname, const char *mode);
    420 func Xfopen64(t *TLS, pathname, mode uintptr) uintptr {
    421 	m := strings.ReplaceAll(GoString(mode), "b", "")
    422 	var flags int
    423 	switch m {
    424 	case "r":
    425 		flags = os.O_RDONLY
    426 	case "r+":
    427 		flags = os.O_RDWR
    428 	case "w":
    429 		flags = os.O_WRONLY | os.O_CREATE | os.O_TRUNC
    430 	case "w+":
    431 		flags = os.O_RDWR | os.O_CREATE | os.O_TRUNC
    432 	case "a":
    433 		flags = os.O_WRONLY | os.O_CREATE | os.O_APPEND
    434 	case "a+":
    435 		flags = os.O_RDWR | os.O_CREATE | os.O_APPEND
    436 	default:
    437 		panic(m)
    438 	}
    439 	//TODO- flags |= fcntl.O_LARGEFILE
    440 	fd, _, err := unix.Syscall(unix.SYS_OPEN, pathname, uintptr(flags|unix.O_LARGEFILE), 0666)
    441 	if err != 0 {
    442 		t.setErrno(err)
    443 		return 0
    444 	}
    445 
    446 	if p := newFile(t, int32(fd)); p != 0 {
    447 		return p
    448 	}
    449 
    450 	Xclose(t, int32(fd))
    451 	t.setErrno(errno.ENOMEM)
    452 	return 0
    453 }
    454 
    455 // TODO-
    456 func __syscall1(t *TLS, trap, p1 long) long {
    457 	return __syscall(unix.Syscall(uintptr(trap), uintptr(p1), 0, 0))
    458 }
    459 
    460 func __syscall3(t *TLS, trap, p1, p2, p3 long) long {
    461 	return __syscall(unix.Syscall(uintptr(trap), uintptr(p1), uintptr(p2), uintptr(p3)))
    462 }
    463 
    464 func __syscall4(t *TLS, trap, p1, p2, p3, p4 long) long {
    465 	return __syscall(unix.Syscall6(uintptr(trap), uintptr(p1), uintptr(p2), uintptr(p3), uintptr(p4), 0, 0))
    466 }