github.com/afumu/libc@v0.0.6/libc_linux_ppc64le.go (about)

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