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 }