1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/kmem.h> 30 #include <sys/errno.h> 31 #include <sys/thread.h> 32 #include <sys/systm.h> 33 #include <sys/syscall.h> 34 #include <sys/proc.h> 35 #include <sys/modctl.h> 36 #include <sys/cmn_err.h> 37 #include <sys/model.h> 38 #include <sys/brand.h> 39 #include <sys/machbrand.h> 40 #include <sys/lx_syscalls.h> 41 #include <sys/lx_brand.h> 42 #include <sys/lx_impl.h> 43 44 /* 45 * Some system calls return either a 32-bit or a 64-bit value, depending 46 * on the datamodel. 47 */ 48 #ifdef _LP64 49 #define V_RVAL SE_64RVAL 50 #else 51 #define V_RVAL SE_32RVAL1 52 #endif 53 54 /* 55 * Define system calls that return a native 'long' quantity i.e. a 32-bit 56 * or 64-bit integer - depending on how the kernel is itself compiled 57 * e.g. read(2) returns 'ssize_t' in the kernel and in userland. 58 */ 59 #define LX_CL(name, call, narg) \ 60 { V_RVAL, (name), (llfcn_t)(call), (narg) } 61 62 /* 63 * Returns a 32 bit quantity regardless of datamodel 64 */ 65 #define LX_CI(name, call, narg) \ 66 { SE_32RVAL1, (name), (llfcn_t)(call), (narg) } 67 68 extern longlong_t lx_nosys(void); 69 #define LX_NOSYS(name) \ 70 {SE_64RVAL, (name), (llfcn_t)lx_nosys, 0} 71 72 lx_sysent_t lx_sysent[] = 73 { 74 LX_NOSYS("lx_nosys"), /* 0 */ 75 LX_NOSYS("exit"), /* 0 */ 76 LX_NOSYS("lx_fork"), 77 LX_NOSYS("read"), 78 LX_NOSYS("write"), 79 LX_NOSYS("open"), 80 LX_NOSYS("close"), 81 LX_NOSYS("waitpid"), 82 LX_NOSYS("creat"), 83 LX_NOSYS("link"), 84 LX_NOSYS("unlink"), /* 10 */ 85 LX_NOSYS("exec"), 86 LX_NOSYS("chdir"), 87 LX_NOSYS("gtime"), 88 LX_NOSYS("mknod"), 89 LX_NOSYS("chmod"), 90 LX_NOSYS("lchown16"), 91 LX_NOSYS("break"), 92 LX_NOSYS("stat"), 93 LX_NOSYS("lseek"), 94 LX_CL("getpid", lx_getpid, 0), /* 20 */ 95 LX_NOSYS("mount"), 96 LX_NOSYS("umount"), 97 LX_NOSYS("setuid16"), 98 LX_NOSYS("getuid16"), 99 LX_NOSYS("stime"), 100 LX_NOSYS("ptrace"), 101 LX_NOSYS("alarm"), 102 LX_NOSYS("fstat"), 103 LX_NOSYS("pause"), 104 LX_NOSYS("utime"), /* 30 */ 105 LX_NOSYS("stty"), 106 LX_NOSYS("gtty"), 107 LX_NOSYS("access"), 108 LX_NOSYS("nice"), 109 LX_NOSYS("ftime"), 110 LX_NOSYS("sync"), 111 LX_CL("kill", lx_kill, 2), 112 LX_NOSYS("rename"), 113 LX_NOSYS("mkdir"), 114 LX_NOSYS("rmdir"), /* 40 */ 115 LX_NOSYS("dup"), 116 LX_NOSYS("pipe"), 117 LX_NOSYS("times"), 118 LX_NOSYS("prof"), 119 LX_CL("brk", lx_brk, 1), 120 LX_NOSYS("setgid16"), 121 LX_NOSYS("getgid16"), 122 LX_NOSYS("signal"), 123 LX_NOSYS("geteuid16"), 124 LX_NOSYS("getegid16"), /* 50 */ 125 LX_NOSYS("sysacct"), 126 LX_NOSYS("umount2"), 127 LX_NOSYS("lock"), 128 LX_NOSYS("ioctl"), 129 LX_NOSYS("fcntl"), 130 LX_NOSYS("mpx"), 131 LX_NOSYS("setpgid"), 132 LX_NOSYS("ulimit"), 133 LX_NOSYS("olduname"), 134 LX_NOSYS("umask"), /* 60 */ 135 LX_NOSYS("chroot"), 136 LX_NOSYS("ustat"), 137 LX_NOSYS("dup2"), 138 LX_CL("getppid", lx_getppid, 0), 139 LX_NOSYS("pgrp"), 140 LX_NOSYS("setsid"), 141 LX_NOSYS("sigaction"), 142 LX_NOSYS("sgetmask"), 143 LX_NOSYS("ssetmask"), 144 LX_NOSYS("setreuid16"), /* 70 */ 145 LX_NOSYS("setregid16"), 146 LX_NOSYS("sigsuspend"), 147 LX_NOSYS("sigpending"), 148 LX_NOSYS("sethostname"), 149 LX_NOSYS("setrlimit"), 150 LX_NOSYS("old_getrlimit"), 151 LX_NOSYS("getrusage"), 152 LX_NOSYS("gettimeofday"), 153 LX_NOSYS("settimeofday"), 154 LX_NOSYS("getgroups16"), /* 80 */ 155 LX_NOSYS("setgroups16"), 156 LX_NOSYS("old_select"), 157 LX_NOSYS("symlink"), 158 LX_NOSYS("oldlstat"), 159 LX_NOSYS("readlink"), 160 LX_NOSYS("uselib"), 161 LX_NOSYS("swapon"), 162 LX_NOSYS("reboot"), 163 LX_NOSYS("old_readdir"), 164 LX_NOSYS("old_mmap"), /* 90 */ 165 LX_NOSYS("munmap"), 166 LX_NOSYS("truncate"), 167 LX_NOSYS("ftruncate"), 168 LX_NOSYS("fchmod"), 169 LX_NOSYS("fchown16"), 170 LX_NOSYS("getpriority"), 171 LX_NOSYS("setpriority"), 172 LX_NOSYS("profil"), 173 LX_NOSYS("statfs"), 174 LX_NOSYS("fstatfs"), /* 100 */ 175 LX_NOSYS("ioperm"), 176 LX_NOSYS("socketcall"), 177 LX_NOSYS("syslog"), 178 LX_NOSYS("setitimer"), 179 LX_NOSYS("getitimer"), 180 LX_NOSYS("newstat"), 181 LX_NOSYS("newsltat"), 182 LX_NOSYS("newsftat"), 183 LX_NOSYS("uname"), 184 LX_NOSYS("oldiopl"), /* 110 */ 185 LX_NOSYS("oldvhangup"), 186 LX_NOSYS("idle"), 187 LX_NOSYS("vm86old"), 188 LX_NOSYS("wait4"), 189 LX_NOSYS("swapoff"), 190 LX_CL("sysinfo", lx_sysinfo, 1), 191 LX_NOSYS("ipc"), 192 LX_NOSYS("fsync"), 193 LX_NOSYS("sigreturn"), 194 LX_CL("clone", lx_clone, 5), /* 120 */ 195 LX_NOSYS("setdomainname"), 196 LX_NOSYS("newuname"), 197 LX_CL("modify_ldt", lx_modify_ldt, 3), 198 LX_NOSYS("adjtimex"), 199 LX_NOSYS("mprotect"), 200 LX_NOSYS("sigprocmask"), 201 LX_NOSYS("create_module"), 202 LX_NOSYS("init_module"), 203 LX_NOSYS("delete_module"), 204 LX_NOSYS("get_kernel_syms"), /* 130 */ 205 LX_NOSYS("quotactl"), 206 LX_NOSYS("getpgid"), 207 LX_NOSYS("fchdir"), 208 LX_NOSYS("bdflush"), 209 LX_NOSYS("sysfs"), 210 LX_NOSYS("personality"), 211 LX_NOSYS("afs_syscall"), 212 LX_NOSYS("setfsuid16"), 213 LX_NOSYS("setfsgid16"), 214 LX_NOSYS("llseek"), /* 140 */ 215 LX_NOSYS("getdents"), 216 LX_NOSYS("select"), 217 LX_NOSYS("flock"), 218 LX_NOSYS("msync"), 219 LX_NOSYS("readv"), 220 LX_NOSYS("writev"), 221 LX_NOSYS("getsid"), 222 LX_NOSYS("fdatasync"), 223 LX_NOSYS("sysctl"), 224 LX_NOSYS("mlock"), /* 150 */ 225 LX_NOSYS("munlock"), 226 LX_NOSYS("mlockall"), 227 LX_NOSYS("munlockall"), 228 LX_CL("sched_setparam", lx_sched_setparam, 2), 229 LX_CL("sched_getparam", lx_sched_getparam, 2), 230 LX_NOSYS("sched_setscheduler"), 231 LX_NOSYS("sched_getscheduler"), 232 LX_NOSYS("yield"), 233 LX_NOSYS("sched_get_priority_max"), 234 LX_NOSYS("sched_get_priority_min"), /* 160 */ 235 LX_CL("sched_rr_get_interval", lx_sched_rr_get_interval, 2), 236 LX_NOSYS("nanosleep"), 237 LX_NOSYS("mremap"), 238 LX_CL("setresuid16", lx_setresuid16, 3), 239 LX_NOSYS("getresuid16"), 240 LX_NOSYS("vm86"), 241 LX_NOSYS("query_module"), 242 LX_NOSYS("poll"), 243 LX_NOSYS("nfsserctl"), 244 LX_CL("setresgid16", lx_setresgid16, 3), /* 170 */ 245 LX_NOSYS("getresgid16"), 246 LX_NOSYS("prctl"), 247 LX_NOSYS("rt_sigreturn"), 248 LX_NOSYS("rt_sigaction"), 249 LX_NOSYS("rt_sigprocmask"), 250 LX_NOSYS("rt_sigpending"), 251 LX_NOSYS("rt_sigtimedwait"), 252 LX_NOSYS("rt_sigqueueinfo"), 253 LX_NOSYS("rt_sigsuspend"), 254 LX_NOSYS("pread64"), /* 180 */ 255 LX_NOSYS("pwrite64"), 256 LX_NOSYS("chown16"), 257 LX_NOSYS("getcwd"), 258 LX_NOSYS("capget"), 259 LX_NOSYS("capset"), 260 LX_NOSYS("sigaltstack"), 261 LX_NOSYS("sendfile"), 262 LX_NOSYS("getpmsg"), 263 LX_NOSYS("putpmsg"), 264 LX_NOSYS("vfork"), /* 190 */ 265 LX_NOSYS("getrlimit"), 266 LX_NOSYS("mmap2"), 267 LX_NOSYS("truncate64"), 268 LX_NOSYS("ftruncate64"), 269 LX_NOSYS("stat64"), 270 LX_NOSYS("lstat64"), 271 LX_NOSYS("fstat64"), 272 LX_NOSYS("lchown"), 273 LX_NOSYS("getuid"), 274 LX_NOSYS("getgid"), /* 200 */ 275 LX_NOSYS("geteuid"), 276 LX_NOSYS("getegid"), 277 LX_NOSYS("setreuid"), 278 LX_NOSYS("setregid"), 279 LX_NOSYS("getgroups"), 280 LX_CL("setgroups", lx_setgroups, 2), 281 LX_NOSYS("fchown"), 282 LX_CL("setresuid", lx_setresuid, 3), 283 LX_NOSYS("getresuid"), 284 LX_CL("setresgid", lx_setresgid, 3), /* 210 */ 285 LX_NOSYS("getresgid"), 286 LX_NOSYS("chown"), 287 LX_NOSYS("setuid"), 288 LX_NOSYS("setgid"), 289 LX_NOSYS("setfsuid"), 290 LX_NOSYS("setfsgid"), 291 LX_NOSYS("pivot_root"), 292 LX_NOSYS("mincore"), 293 LX_NOSYS("madvise"), 294 LX_NOSYS("getdents64"), /* 220 */ 295 LX_NOSYS("fcntl64"), 296 LX_NOSYS("lx_nosys"), 297 LX_NOSYS("security"), 298 LX_CL("gettid", lx_gettid, 0), 299 LX_NOSYS("readahead"), 300 LX_NOSYS("setxattr"), 301 LX_NOSYS("lsetxattr"), 302 LX_NOSYS("fsetxattr"), 303 LX_NOSYS("getxattr"), 304 LX_NOSYS("lgetxattr"), /* 230 */ 305 LX_NOSYS("fgetxattr"), 306 LX_NOSYS("listxattr"), 307 LX_NOSYS("llistxattr"), 308 LX_NOSYS("flistxattr"), 309 LX_NOSYS("removexattr"), 310 LX_NOSYS("lremovexattr"), 311 LX_NOSYS("fremovexattr"), 312 LX_CL("tkill", lx_tkill, 2), 313 LX_NOSYS("sendfile64"), 314 LX_CL("futex", lx_futex, 6), /* 240 */ 315 LX_NOSYS("sched_setaffinity"), 316 LX_NOSYS("sched_getaffinity"), 317 LX_CL("set_thread_area", lx_set_thread_area, 1), 318 LX_CL("get_thread_area", lx_get_thread_area, 1), 319 LX_NOSYS("io_setup"), 320 LX_NOSYS("io_destroy"), 321 LX_NOSYS("io_getevents"), 322 LX_NOSYS("io_submit"), 323 LX_NOSYS("io_cancel"), 324 LX_NOSYS("fadvise64"), /* 250 */ 325 LX_NOSYS("lx_nosys"), 326 LX_NOSYS("exit_group"), 327 LX_NOSYS("lookup_dcookie"), 328 LX_NOSYS("epoll_create"), 329 LX_NOSYS("epoll_ctl"), 330 LX_NOSYS("epoll_wait"), 331 LX_NOSYS("remap_file_pages"), 332 LX_CL("set_tid_address", lx_set_tid_address, 1), 333 LX_NOSYS("timer_create"), 334 LX_NOSYS("timer_settime"), /* 260 */ 335 LX_NOSYS("timer_gettime"), 336 LX_NOSYS("timer_getoverrun"), 337 LX_NOSYS("timer_delete"), 338 LX_NOSYS("clock_settime"), 339 LX_NOSYS("clock_gettime"), 340 LX_NOSYS("clock_getres"), 341 LX_NOSYS("clock_nanosleep"), 342 LX_NOSYS("statfs64"), 343 LX_NOSYS("fstatfs64"), 344 LX_NOSYS("tgkill"), /* 270 */ 345 /* The following are Linux 2.6 system calls */ 346 LX_NOSYS("utimes"), 347 LX_NOSYS("fadvise64_64"), 348 LX_NOSYS("vserver"), 349 LX_NOSYS("mbind"), 350 LX_NOSYS("get_mempolicy"), 351 LX_NOSYS("set_mempolicy"), 352 LX_NOSYS("mq_open"), 353 LX_NOSYS("mq_unlink"), 354 LX_NOSYS("mq_timedsend"), 355 LX_NOSYS("mq_timedreceive"), /* 280 */ 356 LX_NOSYS("mq_notify"), 357 LX_NOSYS("mq_getsetattr"), 358 LX_NOSYS("kexec_load"), 359 LX_NOSYS("waitid"), 360 LX_NOSYS("sys_setaltroot"), 361 LX_NOSYS("add_key"), 362 LX_NOSYS("request_key"), 363 LX_NOSYS("keyctl"), 364 LX_NOSYS("ioprio_set"), 365 LX_NOSYS("ioprio_get"), /* 290 */ 366 LX_NOSYS("inotify_init"), 367 LX_NOSYS("inotify_add_watch"), 368 LX_NOSYS("inotify_rm_watch"), 369 LX_NOSYS("migrate_pages"), 370 LX_NOSYS("openat"), 371 LX_NOSYS("mkdirat"), 372 LX_NOSYS("mknodat"), 373 LX_NOSYS("fchownat"), 374 LX_NOSYS("futimesat"), 375 LX_NOSYS("fstatat64"), /* 300 */ 376 LX_NOSYS("unlinkat"), 377 LX_NOSYS("renameat"), 378 LX_NOSYS("linkat"), 379 LX_NOSYS("syslinkat"), 380 LX_NOSYS("readlinkat"), 381 LX_NOSYS("fchmodat"), 382 LX_NOSYS("faccessat"), 383 LX_NOSYS("pselect6"), 384 LX_NOSYS("ppoll"), 385 LX_NOSYS("unshare"), /* 310 */ 386 LX_NOSYS("set_robust_list"), 387 LX_NOSYS("get_robust_list"), 388 LX_NOSYS("splice"), 389 LX_NOSYS("sync_file_range"), 390 LX_NOSYS("tee"), 391 LX_NOSYS("vmsplice"), 392 LX_NOSYS("move_pages"), 393 NULL /* NULL-termination is required for lx_systrace */ 394 }; 395 396 int64_t 397 lx_emulate_syscall(int num, uintptr_t arg1, uintptr_t arg2, 398 uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6) 399 { 400 struct lx_sysent *jsp; 401 int64_t rval; 402 403 rval = (int64_t)0; 404 405 jsp = &(lx_sysent[num]); 406 407 switch (jsp->sy_narg) { 408 case 0: { 409 lx_print("--> %s()\n", jsp->sy_name); 410 rval = (int64_t)jsp->sy_callc(); 411 break; 412 } 413 case 1: { 414 lx_print("--> %s(0x%lx)\n", jsp->sy_name, arg1); 415 rval = (int64_t)jsp->sy_callc(arg1); 416 break; 417 } 418 case 2: { 419 lx_print("--> %s(0x%lx, 0x%lx)\n", jsp->sy_name, arg1, arg2); 420 rval = (int64_t)jsp->sy_callc(arg1, arg2); 421 break; 422 } 423 case 3: { 424 lx_print("--> %s(0x%lx, 0x%lx, 0x%lx)\n", 425 jsp->sy_name, arg1, arg2, arg3); 426 rval = (int64_t)jsp->sy_callc(arg1, arg2, arg3); 427 break; 428 } 429 case 4: { 430 lx_print("--> %s(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", 431 jsp->sy_name, arg1, arg2, arg3, arg4); 432 rval = (int64_t)jsp->sy_callc(arg1, arg2, arg3, arg4); 433 break; 434 } 435 case 5: { 436 lx_print("--> %s(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", 437 jsp->sy_name, arg1, arg2, arg3, arg4, arg5); 438 rval = (int64_t)jsp->sy_callc(arg1, arg2, arg3, arg4, arg5); 439 break; 440 } 441 case 6: { 442 lx_print("--> %s(0x%lx, 0x%lx, 0x%lx, 0x%lx," 443 " 0x%lx, 0x%lx)\n", 444 jsp->sy_name, arg1, arg2, arg3, arg4, arg5, arg6); 445 rval = (int64_t)jsp->sy_callc(arg1, arg2, arg3, arg4, arg5, 446 arg6); 447 break; 448 } 449 default: 450 panic("Invalid syscall entry: #%d at 0x%p\n", num, (void *)jsp); 451 } 452 lx_print("----------> return (0x%llx)\n", (long long)rval); 453 return (rval); 454 }