gtsocial-umbx

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

libc_linux_arm.go (11585B)


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