1 /*- 2 * Copyright (C) 2014 Nathan Whitehorn 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef _HOST_SYSCALL_H 27 #define _HOST_SYSCALL_H 28 29 #include <stand.h> 30 #include <assert.h> 31 32 long host_syscall(int number, ...); 33 34 /* 35 * Sizes taken from musl's include/alltypes.h.in and expanded for LP64 hosts 36 */ 37 typedef uint64_t host_dev_t; 38 typedef uint64_t host_ino_t; 39 typedef unsigned int host_mode_t; 40 typedef unsigned int host_uid_t; 41 typedef unsigned int host_gid_t; 42 typedef int64_t host_off_t; 43 typedef long host_blksize_t; 44 typedef int64_t host_blkcnt_t; 45 46 #include "stat_arch.h" 47 48 /* 49 * stat flags 50 * These are arch independent and match the values in nolib and uapi headers 51 * with HOST_ prepended. 52 */ 53 #define HOST_S_IFMT 0170000 54 #define HOST_S_IFIFO 0010000 55 #define HOST_S_IFCHR 0020000 56 #define HOST_S_IFDIR 0040000 57 #define HOST_S_IFBLK 0060000 58 #define HOST_S_IFREG 0100000 59 #define HOST_S_IFLNK 0120000 60 #define HOST_S_IFSOCK 0140000 61 62 #define HOST_S_ISBLK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFBLK) 63 #define HOST_S_ISCHR(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFCHR) 64 #define HOST_S_ISDIR(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFDIR) 65 #define HOST_S_ISFIFO(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFIFO) 66 #define HOST_S_ISLNK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFLNK) 67 #define HOST_S_ISREG(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFREG) 68 #define HOST_S_ISSOCK(mode) (((mode) & HOST_S_IFMT) == HOST_S_IFSOCK) 69 70 /* 71 * Constants for open, fcntl, etc 72 * 73 * Note: Some of these are arch dependent on Linux, but are the same for 74 * powerpc, x86, arm*, and riscv. We should be futureproof, though, since these 75 * are the 'generic' values and only older architectures (no longer supported by 76 * FreeBSD) vary. 77 * 78 * These are from tools/include/uapi/asm-generic/fcntl.h and use the octal 79 * notation. Beware, hex is used in other places creating potential confsion. 80 */ 81 #define HOST_O_RDONLY 0 82 #define HOST_O_WRONLY 1 83 #define HOST_O_RDWR 2 84 #define HOST_O_CREAT 00100 85 #define HOST_O_EXCL 00200 86 #define HOST_O_NOCTTY 00400 87 #define HOST_O_TRUNC 01000 88 #define HOST_O_APPEND 02000 89 #define HOST_O_NONBLOCK 04000 90 91 #define HOST_AT_FDCWD -100 /* Relative to current directory */ 92 93 /* 94 * Data types 95 */ 96 struct old_utsname { 97 char sysname[65]; 98 char nodename[65]; 99 char release[65]; 100 char version[65]; 101 char machine[65]; 102 }; 103 104 struct host_timeval { 105 time_t tv_sec; 106 long tv_usec; 107 }; 108 109 /* 110 * Must match Linux's values see linux/tools/include/uapi/asm-generic/mman-common.h 111 * and linux/tools/include/linux/mman.h 112 * 113 * And pre-pend HOST_ here. 114 */ 115 #define HOST_PROT_READ 0x1 116 #define HOST_PROT_WRITE 0x2 117 #define HOST_PROT_EXEC 0x4 118 119 #define HOST_MAP_SHARED 0x01 120 #define HOST_MAP_PRIVATE 0x02 121 #define HOST_MAP_FIXED 0x10 122 #define HOST_MAP_ANONYMOUS 0x20 123 124 #define HOST_MAP_FAILED ((void *)-1) 125 126 /* Mount flags from uapi */ 127 #define MS_RELATIME (1 << 21) 128 129 #define HOST_REBOOT_MAGIC1 0xfee1dead 130 #define HOST_REBOOT_MAGIC2 672274793 131 #define HOST_REBOOT_CMD_KEXEC 0x45584543 132 133 /* 134 * Values from linux/tools/include/uapi/linux/kexec.h 135 */ 136 137 /* 138 * Values match ELF architecture types. 139 */ 140 #define HOST_KEXEC_ARCH_X86_64 (62 << 16) 141 #define HOST_KEXEC_ARCH_PPC64 (21 << 16) 142 #define HOST_KEXEC_ARCH_ARM (40 << 16) 143 #define HOST_KEXEC_ARCH_AARCH64 (183 << 16) 144 #define HOST_KEXEC_ARCH_RISCV (243 << 16) 145 146 /* Arbitrary cap on segments */ 147 #define HOST_KEXEC_SEGMENT_MAX 16 148 149 struct host_kexec_segment { 150 void *buf; 151 int bufsz; 152 void *mem; 153 int memsz; 154 }; 155 156 struct host_dirent64 { 157 uint64_t d_ino; /* 64-bit inode number */ 158 int64_t d_off; /* 64-bit offset to next structure */ 159 unsigned short d_reclen; /* Size of this dirent */ 160 unsigned char d_type; /* File type */ 161 char d_name[]; /* Filename (null-terminated) */ 162 }; 163 164 /* d_type values */ 165 #define HOST_DT_UNKNOWN 0 166 #define HOST_DT_FIFO 1 167 #define HOST_DT_CHR 2 168 #define HOST_DT_DIR 4 169 #define HOST_DT_BLK 6 170 #define HOST_DT_REG 8 171 #define HOST_DT_LNK 10 172 #define HOST_DT_SOCK 12 173 #define HOST_DT_WHT 14 174 175 /* 176 * System Calls 177 */ 178 int host_close(int fd); 179 int host_dup(int fd); 180 int host_exit(int code); 181 int host_fstat(int fd, struct host_kstat *sb); 182 int host_getdents64(int fd, void *dirp, int count); 183 int host_getpid(void); 184 int host_gettimeofday(struct host_timeval *a, void *b); 185 int host_ioctl(int fd, unsigned long request, unsigned long arg); 186 int host_kexec_load(unsigned long entry, unsigned long nsegs, struct host_kexec_segment *segs, unsigned long flags); 187 ssize_t host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence); 188 int host_mkdir(const char *, host_mode_t); 189 void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off); 190 int host_mount(const char *src, const char *target, const char *type, 191 unsigned long flags, void *data); 192 int host_munmap(void *addr, size_t len); 193 int host_open(const char *path, int flags, int mode); 194 ssize_t host_read(int fd, void *buf, size_t nbyte); 195 int host_reboot(int, int, int, uintptr_t); 196 int host_select(int nfds, long *readfds, long *writefds, long *exceptfds, 197 struct host_timeval *timeout); 198 int host_stat(const char *path, struct host_kstat *sb); 199 int host_symlink(const char *path1, const char *path2); 200 int host_uname(struct old_utsname *); 201 ssize_t host_write(int fd, const void *buf, size_t nbyte); 202 203 /* 204 * Wrappers / one-liners 205 */ 206 #define host_getmem(size) \ 207 host_mmap(0, size, HOST_PROT_READ | HOST_PROT_WRITE, \ 208 HOST_MAP_PRIVATE | HOST_MAP_ANONYMOUS, -1, 0); 209 210 /* 211 * Translate Linux errno to FreeBSD errno. The two system have idenitcal errors 212 * for 1-34. After that, they differ. Linux also has errno that don't map 213 * exactly to FreeBSD's errno, plus the Linux errno are arch dependent > 214 * 34. Since we just need to do this for simple cases, use the simple mapping 215 * function where -1 to -34 are translated to 1 to 34 and all others are EINVAL. 216 * Pass the linux return value, which will be the -errno. 217 */ 218 static __inline int 219 host_to_stand_errno(int e) 220 { 221 assert(e < 0); 222 223 return((-e) > 34 ? EINVAL : (-e)); 224 } 225 226 #endif 227