12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235 |
- /* Copyright (C) 2014 Stony Brook University
- This file is part of Graphene Library OS.
- Graphene Library OS is free software: you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License
- as published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- Graphene Library OS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- /*
- * shim_parser.c
- *
- * This file contains codes for parsing system call arguements for debug
- * purpose.
- */
- #include <asm/fcntl.h>
- #include <asm/ioctls.h>
- #include <asm/mman.h>
- #include <asm/prctl.h>
- #include <asm/unistd.h>
- #include <errno.h>
- #include <linux/fcntl.h>
- #include <linux/futex.h>
- #include <linux/in.h>
- #include <linux/in6.h>
- #include <linux/sched.h>
- #include <linux/stat.h>
- #include <linux/un.h>
- #include <linux/wait.h>
- #include <pal.h>
- #include <pal_error.h>
- #include <shim_internal.h>
- #include <shim_table.h>
- #include <shim_thread.h>
- #include <shim_tcb.h>
- #include <shim_utils.h>
- static void parse_open_flags(va_list);
- static void parse_open_mode(va_list);
- static void parse_access_mode(va_list);
- static void parse_clone_flags(va_list);
- static void parse_mmap_prot(va_list);
- static void parse_mmap_flags(va_list);
- static void parse_exec_args(va_list);
- static void parse_exec_envp(va_list);
- static void parse_pipe_fds(va_list);
- static void parse_signum(va_list);
- static void parse_sigmask(va_list);
- static void parse_sigprocmask_how(va_list);
- static void parse_timespec(va_list);
- static void parse_sockaddr(va_list);
- static void parse_domain(va_list);
- static void parse_socktype(va_list);
- static void parse_futexop(va_list);
- static void parse_ioctlop(va_list);
- static void parse_fcntlop(va_list);
- static void parse_seek(va_list);
- static void parse_at_fdcwd(va_list);
- static void parse_wait_option(va_list);
- struct parser_table {
- int slow;
- int stop;
- void (*parser[6])(va_list);
- } syscall_parser_table[LIBOS_SYSCALL_BOUND] =
- {
- {.slow = 1, .parser = {NULL}}, /* read */
- {.slow = 1, .parser = {NULL}}, /* write */
- {.slow = 1, /* open */
- .parser = {NULL, &parse_open_flags, &parse_open_mode}},
- {.slow = 0, .parser = {NULL}}, /* close */
- {.slow = 0, .parser = {NULL}}, /* stat */
- {.slow = 0, .parser = {NULL}}, /* fstat */
- {.slow = 0, .parser = {NULL}}, /* lstat */
- {.slow = 1, .parser = {NULL}}, /* poll */
- {.slow = 0, .parser = {NULL, NULL, &parse_seek}}, /* lseek */
- {.slow = 1, /* mmap */
- .parser = {NULL, NULL, &parse_mmap_prot, &parse_mmap_flags}},
- {.slow = 1, /* mprotect */
- .parser = {NULL, NULL, &parse_mmap_prot}},
- {.slow = 1, .parser = {NULL}}, /* munmap */
- {.slow = 0, .parser = {NULL}}, /* brk */
- {.slow = 0, .parser = {&parse_signum}}, /* rt_sigaction */
- {.slow = 0, /* rt_sigprocmask */
- .parser = {&parse_sigprocmask_how, &parse_sigmask, &parse_sigmask}},
- {.slow = 0, .parser = {NULL}}, /* rt_sigreturn */
- {.slow = 1, .parser = {NULL, &parse_ioctlop}}, /* ioctl */
- {.slow = 1, .parser = {NULL}}, /* pread64 */
- {.slow = 0, .parser = {NULL}}, /* pwrite64 */
- {.slow = 1, .parser = {NULL}}, /* readv */
- {.slow = 0, .parser = {NULL}}, /* writev */
- {.slow = 0, /* access */
- .parser = {NULL, &parse_access_mode}},
- {.slow = 0, /* pipe */
- .parser = {&parse_pipe_fds}},
- {.slow = 0, .parser = {NULL}}, /* select */
- {.slow = 0, .parser = {NULL}}, /* sched_yield */
- {.slow = 0, .parser = {NULL}}, /* mremap */
- {.slow = 0, .parser = {NULL}}, /* msync */
- {.slow = 0, .parser = {NULL}}, /* mincore */
- {.slow = 0, .parser = {NULL}}, /* madvise */
- {.slow = 0, .parser = {NULL}}, /* shmget */
- {.slow = 0, .parser = {NULL}}, /* shmat */
- {.slow = 0, .parser = {NULL}}, /* shmctl */
- {.slow = 0, .parser = {NULL}}, /* dup */
- {.slow = 0, .parser = {NULL}}, /* dup2 */
- {.slow = 1, .parser = {NULL}}, /* pause */
- {.slow = 1, .parser = {&parse_timespec}}, /* nanosleep */
- {.slow = 0, .parser = {NULL}}, /* getitimer */
- {.slow = 0, .parser = {NULL}}, /* alarm */
- {.slow = 0, .parser = {NULL}}, /* setitimer */
- {.slow = 0, .parser = {NULL}}, /* getpid */
- {.slow = 0, .parser = {NULL}}, /* sendfile */
- {.slow = 0, .parser = {&parse_domain, &parse_socktype}}, /* socket */
- {.slow = 1, .parser = {NULL, &parse_sockaddr}}, /* connect */
- {.slow = 1, .parser = {NULL}}, /* accept */
- {.slow = 0, .parser = {NULL}}, /* sendto */
- {.slow = 0, .parser = {NULL}}, /* recvfrom */
- {.slow = 0, .parser = {NULL}}, /* sendmsg */
- {.slow = 1, .parser = {NULL}}, /* recvmsg */
- {.slow = 0, .parser = {NULL}}, /* shutdown */
- {.slow = 0, .parser = {NULL}}, /* bind */
- {.slow = 0, .parser = {NULL}}, /* listen */
- {.slow = 0, .parser = {NULL}}, /* getsockname */
- {.slow = 0, .parser = {NULL}}, /* getpeername */
- {.slow = 0, /* socketpair */
- .stop = 3,
- .parser = {&parse_domain, &parse_socktype, NULL, &parse_pipe_fds}},
- {.slow = 0, .parser = {NULL}}, /* setsockopt */
- {.slow = 0, .parser = {NULL}}, /* getsockopt */
- {.slow = 1, .parser = {&parse_clone_flags}}, /* clone */
- {.slow = 1, .parser = {NULL}}, /* fork */
- {.slow = 1, .parser = {NULL}}, /* vfork */
- {.slow = 1, /* execve */
- .parser = {NULL, &parse_exec_args, &parse_exec_envp}},
- {.slow = 0, .parser = {NULL}}, /* exit */
- {.slow = 1, .parser = {NULL, NULL, &parse_wait_option, NULL}}, /* wait4 */
- {.slow = 0, /* kill */
- .parser = {NULL, &parse_signum, }},
- {.slow = 0, .parser = {NULL}}, /* uname */
- {.slow = 0, .parser = {NULL}}, /* semget */
- {.slow = 1, .parser = {NULL}}, /* semop */
- {.slow = 0, .parser = {NULL}}, /* semctl */
- {.slow = 0, .parser = {NULL}}, /* shmdt */
- {.slow = 1, .parser = {NULL}}, /* msgget */
- {.slow = 1, .parser = {NULL}}, /* msgsnd */
- {.slow = 1, .parser = {NULL}}, /* msgrcv */
- {.slow = 1, .parser = {NULL}}, /* msgctl */
- {.slow = 0, .parser = {NULL, &parse_fcntlop}}, /* fcntl */
- {.slow = 0, .parser = {NULL}}, /* flock */
- {.slow = 0, .parser = {NULL}}, /* fsync */
- {.slow = 0, .parser = {NULL}}, /* fdatasync */
- {.slow = 0, .parser = {NULL}}, /* truncate */
- {.slow = 0, .parser = {NULL}}, /* ftruncate */
- {.slow = 0, .parser = {NULL}}, /* getdents */
- {.slow = 0, .parser = {NULL}}, /* getcwd */
- {.slow = 0, .parser = {NULL}}, /* chdir */
- {.slow = 0, .parser = {NULL}}, /* fchdir */
- {.slow = 0, .parser = {NULL}}, /* rename */
- {.slow = 0, .parser = {NULL}}, /* mkdir */
- {.slow = 0, .parser = {NULL}}, /* rmdir */
- {.slow = 0, .parser = {NULL, &parse_open_mode}}, /* creat */
- {.slow = 0, .parser = {NULL}}, /* link */
- {.slow = 0, .parser = {NULL}}, /* unlink */
- {.slow = 0, .parser = {NULL}}, /* symlink */
- {.slow = 0, .parser = {NULL}}, /* readlink */
- {.slow = 0, .parser = {NULL}}, /* chmod */
- {.slow = 0, .parser = {NULL}}, /* fchmod */
- {.slow = 0, .parser = {NULL}}, /* chown */
- {.slow = 0, .parser = {NULL}}, /* fchown */
- {.slow = 0, .parser = {NULL}}, /* lchown */
- {.slow = 0, .parser = {NULL}}, /* umask */
- {.slow = 0, .parser = {NULL}}, /* gettimeofday */
- {.slow = 0, .parser = {NULL}}, /* getrlimit */
- {.slow = 0, .parser = {NULL}}, /* getrusage */
- {.slow = 0, .parser = {NULL}}, /* sysinfo */
- {.slow = 0, .parser = {NULL}}, /* times */
- {.slow = 0, .parser = {NULL}}, /* ptrace */
- {.slow = 0, .parser = {NULL}}, /* getuid */
- {.slow = 0, .parser = {NULL}}, /* syslog */
- {.slow = 0, .parser = {NULL}}, /* getgid */
- {.slow = 0, .parser = {NULL}}, /* setuid */
- {.slow = 0, .parser = {NULL}}, /* setgid */
- {.slow = 0, .parser = {NULL}}, /* geteuid */
- {.slow = 0, .parser = {NULL}}, /* getegid */
- {.slow = 0, .parser = {NULL}}, /* setpgid */
- {.slow = 0, .parser = {NULL}}, /* getppid */
- {.slow = 0, .parser = {NULL}}, /* getpgrp */
- {.slow = 0, .parser = {NULL}}, /* setsid */
- {.slow = 0, .parser = {NULL}}, /* setreuid */
- {.slow = 0, .parser = {NULL}}, /* setregid */
- {.slow = 0, .parser = {NULL}}, /* getgroups */
- {.slow = 0, .parser = {NULL}}, /* setgroups */
- {.slow = 0, .parser = {NULL}}, /* setresuid */
- {.slow = 0, .parser = {NULL}}, /* getresuid */
- {.slow = 0, .parser = {NULL}}, /* setresgid */
- {.slow = 0, .parser = {NULL}}, /* getresgid */
- {.slow = 0, .parser = {NULL}}, /* getpgid */
- {.slow = 0, .parser = {NULL}}, /* setfsuid */
- {.slow = 0, .parser = {NULL}}, /* setfsgid */
- {.slow = 0, .parser = {NULL}}, /* getsid */
- {.slow = 0, .parser = {NULL}}, /* capget */
- {.slow = 0, .parser = {NULL}}, /* capset */
- {.slow = 0, .parser = {NULL}}, /* rt_sigpending */
- {.slow = 0, .parser = {NULL}}, /* rt_sigtimedwait */
- {.slow = 0, .parser = {NULL}}, /* rt_sigqueueinfo */
- {.slow = 1, .parser = {NULL}}, /* rt_sigsuspend */
- {.slow = 0, .parser = {NULL}}, /* sigaltstack */
- {.slow = 0, .parser = {NULL}}, /* utime */
- {.slow = 0, .parser = {NULL}}, /* mknod */
- {.slow = 0, .parser = {NULL}}, /* uselib */
- {.slow = 0, .parser = {NULL}}, /* personality */
- {.slow = 0, .parser = {NULL}}, /* ustat */
- {.slow = 0, .parser = {NULL}}, /* statfs */
- {.slow = 0, .parser = {NULL}}, /* fstatfs */
- {.slow = 0, .parser = {NULL}}, /* sysfs */
- {.slow = 0, .parser = {NULL}}, /* getpriority */
- {.slow = 0, .parser = {NULL}}, /* setpriority */
- {.slow = 0, .parser = {NULL}}, /* sched_setparam */
- {.slow = 0, .parser = {NULL}}, /* sched_getparam */
- {.slow = 0, .parser = {NULL}}, /* sched_setscheduler */
- {.slow = 0, .parser = {NULL}}, /* sched_getscheduler */
- {.slow = 0, .parser = {NULL}}, /* sched_get_priority_max */
- {.slow = 0, .parser = {NULL}}, /* sched_get_priority_min */
- {.slow = 0, .parser = {NULL}}, /* sched_rr_get_interval */
- {.slow = 0, .parser = {NULL}}, /* mlock */
- {.slow = 0, .parser = {NULL}}, /* munlock */
- {.slow = 0, .parser = {NULL}}, /* mlockall */
- {.slow = 0, .parser = {NULL}}, /* munlockall */
- {.slow = 0, .parser = {NULL}}, /* vhangup */
- {.slow = 0, .parser = {NULL}}, /* modify_ldt */
- {.slow = 0, .parser = {NULL}}, /* pivot_root */
- {.slow = 0, .parser = {NULL}}, /* _sysctl */
- {.slow = 0, .parser = {NULL}}, /* prctl */
- {.slow = 0, .parser = {NULL}}, /* arch_prctl */
- {.slow = 0, .parser = {NULL}}, /* adjtimex */
- {.slow = 0, .parser = {NULL}}, /* setrlimit */
- {.slow = 0, .parser = {NULL}}, /* chroot */
- {.slow = 0, .parser = {NULL}}, /* sync */
- {.slow = 0, .parser = {NULL}}, /* acct */
- {.slow = 0, .parser = {NULL}}, /* settimeofday */
- {.slow = 0, .parser = {NULL}}, /* mount */
- {.slow = 0, .parser = {NULL}}, /* umount2 */
- {.slow = 0, .parser = {NULL}}, /* swapon */
- {.slow = 0, .parser = {NULL}}, /* swapoff */
- {.slow = 0, .parser = {NULL}}, /* reboot */
- {.slow = 0, .parser = {NULL}}, /* sethostname */
- {.slow = 0, .parser = {NULL}}, /* setdomainname */
- {.slow = 0, .parser = {NULL}}, /* iopl */
- {.slow = 0, .parser = {NULL}}, /* ioperm */
- {.slow = 0, .parser = {NULL}}, /* create_module */
- {.slow = 0, .parser = {NULL}}, /* init_module */
- {.slow = 0, .parser = {NULL}}, /* delete_module */
- {.slow = 0, .parser = {NULL}}, /* get_kernel_syms */
- {.slow = 0, .parser = {NULL}}, /* query_module */
- {.slow = 0, .parser = {NULL}}, /* quotactl */
- {.slow = 0, .parser = {NULL}}, /* nfsservctl */
- {.slow = 0, .parser = {NULL}}, /* getpmsg */
- {.slow = 0, .parser = {NULL}}, /* putpmsg */
- {.slow = 0, .parser = {NULL}}, /* afs_syscall */
- {.slow = 0, .parser = {NULL}}, /* tuxcall */
- {.slow = 0, .parser = {NULL}}, /* security */
- {.slow = 0, .parser = {NULL}}, /* gettid */
- {.slow = 0, .parser = {NULL}}, /* readahead */
- {.slow = 0, .parser = {NULL}}, /* setxattr */
- {.slow = 0, .parser = {NULL}}, /* lsetxattr */
- {.slow = 0, .parser = {NULL}}, /* fsetxattr */
- {.slow = 0, .parser = {NULL}}, /* getxattr */
- {.slow = 0, .parser = {NULL}}, /* lgetxattr */
- {.slow = 0, .parser = {NULL}}, /* fgetxattr */
- {.slow = 0, .parser = {NULL}}, /* listxattr */
- {.slow = 0, .parser = {NULL}}, /* llistxattr */
- {.slow = 0, .parser = {NULL}}, /* flistxattr */
- {.slow = 0, .parser = {NULL}}, /* removexattr */
- {.slow = 0, .parser = {NULL}}, /* lremovexattr */
- {.slow = 0, .parser = {NULL}}, /* fremovexattr */
- {.slow = 0, .parser = {NULL, &parse_signum}}, /* tkill */
- {.slow = 0, .parser = {NULL}}, /* time */
- {.slow = 1, .parser = {NULL, &parse_futexop}}, /* futex */
- {.slow = 0, .parser = {NULL}}, /* sched_setaffinity */
- {.slow = 0, .parser = {NULL}}, /* sched_getaffinity */
- {.slow = 0, .parser = {NULL}}, /* set_thread_area */
- {.slow = 0, .parser = {NULL}}, /* io_setup */
- {.slow = 0, .parser = {NULL}}, /* io_destroy */
- {.slow = 0, .parser = {NULL}}, /* io_getevents */
- {.slow = 0, .parser = {NULL}}, /* io_submit */
- {.slow = 0, .parser = {NULL}}, /* io_cancel */
- {.slow = 0, .parser = {NULL}}, /* get_thread_area */
- {.slow = 0, .parser = {NULL}}, /* lookup_dcookie */
- {.slow = 0, .parser = {NULL}}, /* epoll_create */
- {.slow = 0, .parser = {NULL}}, /* epoll_ctl_old */
- {.slow = 0, .parser = {NULL}}, /* epoll_wait_old */
- {.slow = 0, .parser = {NULL}}, /* remap_file_pages */
- {.slow = 0, .parser = {NULL}}, /* getdents64 */
- {.slow = 0, .parser = {NULL}}, /* set_tid_address */
- {.slow = 0, .parser = {NULL}}, /* restart_syscall */
- {.slow = 0, .parser = {NULL}}, /* semtimedop */
- {.slow = 0, .parser = {NULL}}, /* fadvise64 */
- {.slow = 0, .parser = {NULL}}, /* timer_create */
- {.slow = 0, .parser = {NULL}}, /* timer_settime */
- {.slow = 0, .parser = {NULL}}, /* timer_gettime */
- {.slow = 0, .parser = {NULL}}, /* timer_getoverrun */
- {.slow = 0, .parser = {NULL}}, /* timer_delete */
- {.slow = 0, .parser = {NULL}}, /* clock_settime */
- {.slow = 0, .parser = {NULL}}, /* clock_gettime */
- {.slow = 0, .parser = {NULL}}, /* clock_getres */
- {.slow = 0, .parser = {NULL}}, /* clock_nanosleep */
- {.slow = 0, .parser = {NULL}}, /* exit_group */
- {.slow = 1, .parser = {NULL}}, /* epoll_wait */
- {.slow = 0, .parser = {NULL}}, /* epoll_ctl */
- {.slow = 0, .parser = {NULL, NULL, &parse_signum}}, /* tgkill */
- {.slow = 0, .parser = {NULL}}, /* utimes */
- {.slow = 0, .parser = {NULL}}, /* vserver */
- {.slow = 0, .parser = {NULL}}, /* mbind */
- {.slow = 0, .parser = {NULL}}, /* set_mempolicy */
- {.slow = 0, .parser = {NULL}}, /* get_mempolicy */
- {.slow = 0, .parser = {NULL}}, /* mq_open */
- {.slow = 0, .parser = {NULL}}, /* mq_unlink */
- {.slow = 0, .parser = {NULL}}, /* mq_timedsend */
- {.slow = 0, .parser = {NULL}}, /* mq_timedreceive */
- {.slow = 0, .parser = {NULL}}, /* mq_notify */
- {.slow = 0, .parser = {NULL}}, /* mq_getsetattr */
- {.slow = 0, .parser = {NULL}}, /* kexec_load */
- {.slow = 1, .parser = {NULL}}, /* waitid */
- {.slow = 0, .parser = {NULL}}, /* add_key */
- {.slow = 0, .parser = {NULL}}, /* request_key */
- {.slow = 0, .parser = {NULL}}, /* keyctl */
- {.slow = 0, .parser = {NULL}}, /* ioprio_set */
- {.slow = 0, .parser = {NULL}}, /* ioprio_get */
- {.slow = 0, .parser = {NULL}}, /* inotify_init */
- {.slow = 0, .parser = {NULL}}, /* inotify_add_watch */
- {.slow = 0, .parser = {NULL}}, /* inotify_rm_watch */
- {.slow = 0, .parser = {NULL}}, /* migrate_pages */
- {.slow = 0,
- .parser = {&parse_at_fdcwd, NULL, &parse_open_flags, &parse_open_mode}}, /* openat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* mkdirat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* mknodat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* fchownat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* futimesat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* newfstatat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* unlinkat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* renameat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* linkat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* symlinkat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* readlinkat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* fchmodat */
- {.slow = 0, .parser = {&parse_at_fdcwd}}, /* faccessat */
- {.slow = 0, .parser = {NULL}}, /* pselect6 */
- {.slow = 1, .parser = {NULL}}, /* ppoll */
- {.slow = 0, .parser = {NULL}}, /* unshare */
- {.slow = 0, .parser = {NULL}}, /* set_robust_list */
- {.slow = 0, .parser = {NULL}}, /* get_robust_list */
- {.slow = 0, .parser = {NULL}}, /* splice */
- {.slow = 0, .parser = {NULL}}, /* tee */
- {.slow = 0, .parser = {NULL}}, /* sync_file_range */
- {.slow = 0, .parser = {NULL}}, /* vmsplice */
- {.slow = 0, .parser = {NULL}}, /* move_pages */
- {.slow = 0, .parser = {NULL}}, /* utimensat */
- {.slow = 1, .parser = {NULL}}, /* epoll_pwait */
- {.slow = 0, .parser = {NULL}}, /* signalfd */
- {.slow = 0, .parser = {NULL}}, /* timerfd_create */
- {.slow = 0, .parser = {NULL}}, /* eventfd */
- {.slow = 0, .parser = {NULL}}, /* fallocate */
- {.slow = 0, .parser = {NULL}}, /* timerfd_settime */
- {.slow = 0, .parser = {NULL}}, /* timerfd_gettime */
- {.slow = 1, .parser = {NULL}}, /* accept4 */
- {.slow = 0, .parser = {NULL}}, /* signalfd4 */
- {.slow = 0, .parser = {NULL}}, /* eventfd2 */
- {.slow = 0, .parser = {NULL}}, /* epoll_create1 */
- {.slow = 0, .parser = {NULL}}, /* dup3 */
- {.slow = 0, .parser = {NULL}}, /* pipe2 */
- {.slow = 0, .parser = {NULL}}, /* inotify_init1 */
- {.slow = 0, .parser = {NULL}}, /* preadv */
- {.slow = 0, .parser = {NULL}}, /* pwritev */
- {.slow = 0, .parser = {NULL}}, /* rt_tgsigqueueinfo */
- {.slow = 0, .parser = {NULL}}, /* perf_event_open */
- {.slow = 0, .parser = {NULL}}, /* recvmmsg */
- [LIBOS_SYSCALL_BASE] = {.slow = 0, .parser = {NULL}},
- {.slow = 1, .parser = {NULL}}, /* checkpoint */
- {.slow = 1, .parser = {NULL}}, /* restore */
- {.slow = 1, .parser = {NULL}}, /* msgpersist */
- {.slow = 1, .parser = {NULL}}, /* benchmark_ipc */
- {.slow = 1, .parser = {NULL}}, /* send_rpc */
- {.slow = 1, .parser = {NULL}}, /* recv_rpc */
- };
- static inline int is_pointer(const char* type) {
- return type[strlen(type) - 1] == '*' || !strcmp_static(type, "long") ||
- !strcmp_static(type, "unsigned long");
- }
- #define PRINTF(fmt, ...) \
- do { \
- debug_printf(fmt, __VA_ARGS__); \
- } while (0)
- #define PUTS(str) \
- do { \
- debug_puts(str); \
- } while (0)
- #define PUTCH(ch) \
- do { \
- debug_putch(ch); \
- } while (0)
- #define VPRINTF(fmt, ap) \
- do { \
- debug_vprintf(fmt, ap); \
- } while (0)
- static inline void parse_string_arg(va_list ap) {
- va_list ap_test_arg;
- va_copy(ap_test_arg, ap);
- const char* test_arg = va_arg(ap_test_arg, const char*);
- if (!test_user_string(test_arg)) {
- VPRINTF("\"%s\"", ap);
- } else {
- /* invalid memory region, print arg as ptr not string */
- VPRINTF("\"(invalid-addr %p)\"", ap);
- }
- va_end(ap_test_arg);
- }
- static inline void parse_pointer_arg(va_list ap) {
- VPRINTF("%p", ap);
- }
- static inline void parse_integer_arg(va_list ap) {
- VPRINTF("%d", ap);
- }
- static inline void parse_syscall_args(va_list ap) {
- const char* arg_type = va_arg(ap, const char*);
- if (!strcmp_static(arg_type, "const char *") || !strcmp_static(arg_type, "const char*"))
- parse_string_arg(ap);
- else if (is_pointer(arg_type))
- parse_pointer_arg(ap);
- else
- parse_integer_arg(ap);
- }
- static inline void skip_syscall_args(va_list ap) {
- const char* arg_type = va_arg(ap, const char*);
- if (!strcmp_static(arg_type, "const char *") || !strcmp_static(arg_type, "const char*"))
- va_arg(ap, const char*);
- else if (is_pointer(arg_type))
- va_arg(ap, void*);
- else
- va_arg(ap, int);
- }
- void sysparser_printf(const char* fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- VPRINTF(fmt, ap);
- va_end(ap);
- }
- void parse_syscall_before(int sysno, const char* name, int nr, ...) {
- if (!debug_handle)
- return;
- struct parser_table* parser = &syscall_parser_table[sysno];
- if (!parser->slow && !parser->stop)
- return;
- va_list ap;
- va_start(ap, nr);
- PRINTF("---- shim_%s(", name);
- for (int i = 0; i < nr; i++) {
- if (parser->stop && parser->stop == i)
- goto dotdotdot;
- if (i)
- PUTCH(',');
- if (parser->parser[i]) {
- const char* type = va_arg(ap, const char*);
- __UNUSED(type); // type not needed on this path
- (*parser->parser[i])(ap);
- } else {
- parse_syscall_args(ap);
- }
- }
- PUTCH(')');
- dotdotdot:
- PRINTF(" ... %s\n", name);
- va_end(ap);
- }
- void parse_syscall_after(int sysno, const char* name, int nr, ...) {
- if (!debug_handle)
- return;
- struct parser_table* parser = &syscall_parser_table[sysno];
- va_list ap;
- va_start(ap, nr);
- const char* ret_type = va_arg(ap, const char*);
- if (parser->slow || parser->stop)
- PRINTF("---- return from shim_%s(...", name);
- else
- PRINTF("---- shim_%s(", name);
- unsigned long ret_ptr = 0;
- int ret_val = 0;
- if (is_pointer(ret_type))
- ret_ptr = (unsigned long)va_arg(ap, void*);
- else
- ret_val = va_arg(ap, int);
- if (!parser->slow || parser->stop)
- for (int i = 0; i < nr; i++) {
- if (parser->stop && i < parser->stop) {
- skip_syscall_args(ap);
- continue;
- }
- if (i)
- PUTCH(',');
- if (parser->parser[i]) {
- const char* type = va_arg(ap, const char*);
- __UNUSED(type); // type not needed on this path
- (*parser->parser[i])(ap);
- } else {
- parse_syscall_args(ap);
- }
- }
- if (is_pointer(ret_type)) {
- if ((uint64_t)ret_ptr < (uint64_t)-4095L)
- PRINTF(") = 0x%08lx\n", ret_ptr);
- else
- PRINTF(") = %ld\n", (long)ret_ptr);
- } else {
- PRINTF(") = %d\n", ret_val);
- }
- va_end(ap);
- }
- static void parse_open_flags(va_list ap) {
- int flags = va_arg(ap, int);
- if (flags & O_WRONLY) {
- PUTS("O_WRONLY");
- flags &= ~O_WRONLY;
- } else if (flags & O_RDWR) {
- PUTS("O_RDWR");
- flags &= ~O_RDWR;
- } else {
- PUTS("O_RDONLY");
- }
- if (flags & O_APPEND) {
- PUTS("|O_APPEND");
- flags &= ~O_APPEND;
- }
- if (flags & O_CREAT) {
- PUTS("|O_CREAT");
- flags &= ~O_CREAT;
- }
- if (flags & O_TRUNC) {
- PUTS("|O_TRUNC");
- flags &= ~O_TRUNC;
- }
- if (flags & O_EXCL) {
- PUTS("|O_EXCL");
- flags &= ~O_EXCL;
- }
- if (flags)
- PRINTF("|%o", flags);
- }
- static void parse_open_mode(va_list ap) {
- VPRINTF("%04o", ap);
- }
- static void parse_access_mode(va_list ap) {
- int mode = va_arg(ap, int);
- PUTS("F_OK");
- if (mode) {
- if (mode & R_OK)
- PUTS("|R_OK");
- if (mode & W_OK)
- PUTS("|W_OK");
- if (mode & X_OK)
- PUTS("|X_OK");
- }
- }
- static void parse_clone_flags(va_list ap) {
- int flags = va_arg(ap, int);
- #define FLG(n) \
- { "CLONE_" #n, CLONE_##n, }
- const struct {
- const char* name;
- int flag;
- } all_flags[] = {
- FLG(VM),
- FLG(FS),
- FLG(FILES),
- FLG(SIGHAND),
- FLG(PTRACE),
- FLG(VFORK),
- FLG(PARENT),
- FLG(THREAD),
- FLG(NEWNS),
- FLG(SYSVSEM),
- FLG(SETTLS),
- FLG(PARENT_SETTID),
- FLG(CHILD_CLEARTID),
- FLG(DETACHED),
- FLG(UNTRACED),
- FLG(CHILD_SETTID),
- FLG(NEWUTS),
- FLG(NEWIPC),
- FLG(NEWUSER),
- FLG(NEWPID),
- FLG(NEWNET),
- FLG(IO),
- };
- #undef FLG
- bool printed = false;
- for (size_t i = 0; i < ARRAY_SIZE(all_flags); i++)
- if (flags & all_flags[i].flag) {
- if (printed)
- PUTCH('|');
- else
- printed = true;
- PUTS(all_flags[i].name);
- flags &= ~all_flags[i].flag;
- }
- #define CLONE_SIGNAL_MASK 0xff
- int exit_signal = flags & CLONE_SIGNAL_MASK;
- flags &= ~CLONE_SIGNAL_MASK;
- if (exit_signal) {
- if (exit_signal >= 0 && exit_signal <= NUM_KNOWN_SIGS)
- PRINTF("|%s", signal_name(exit_signal));
- else
- PRINTF("|[SIG %d]", exit_signal);
- }
- if (flags)
- PRINTF("|0x%x", flags);
- }
- static void parse_mmap_prot(va_list ap) {
- int prot = va_arg(ap, int);
- int nflags = 0;
- if (prot == PROT_NONE) {
- PUTS("PROT_NONE");
- return;
- }
- if (prot & PROT_READ) {
- if (nflags++)
- PUTS("|");
- PUTS("PROT_READ");
- }
- if (prot & PROT_WRITE) {
- if (nflags++)
- PUTS("|");
- PUTS("PROT_WRITE");
- }
- if (prot & PROT_EXEC) {
- if (nflags++)
- PUTS("|");
- PUTS("PROT_EXEC");
- }
- }
- static void parse_mmap_flags(va_list ap) {
- int flags = va_arg(ap, int);
- if (flags & MAP_SHARED) {
- PUTS("MAP_SHARED");
- flags &= ~MAP_SHARED;
- }
- if (flags & MAP_PRIVATE) {
- PUTS("MAP_PRIVATE");
- flags &= ~MAP_PRIVATE;
- }
- if (flags & MAP_ANONYMOUS) {
- PUTS("|MAP_ANON");
- flags &= ~MAP_ANONYMOUS;
- }
- if (flags & MAP_FILE) {
- PUTS("|MAP_FILE");
- flags &= ~MAP_FILE;
- }
- if (flags & MAP_FIXED) {
- PUTS("|MAP_FIXED");
- flags &= ~MAP_FIXED;
- }
- #ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED
- if (flags & MAP_UNINITIALIZED) {
- PUTS("|MAP_UNINITIALIZED");
- flags &= ~MAP_UNINITIALIZED;
- }
- #endif
- if (flags)
- PRINTF("|0x%x", flags);
- }
- static void parse_exec_args(va_list ap) {
- const char** args = va_arg(ap, const char**);
- PUTS("[");
- for (;; args++) {
- if (test_user_memory(args, sizeof(*args), false)) {
- PRINTF("(invalid-argv %p)", args);
- break;
- }
- if (*args == NULL)
- break;
- if (test_user_string(*args)) {
- PRINTF("(invalid-addr %p),", *args);
- continue;
- }
- PUTS(*args);
- PUTS(",");
- }
- PUTS("]");
- }
- static void parse_exec_envp(va_list ap) {
- const char** envp = va_arg(ap, const char**);
- if (!envp) {
- PUTS("NULL");
- return;
- }
- PUTS("[");
- int cnt = 0;
- for (; cnt < 2; cnt++, envp++) {
- if (test_user_memory(envp, sizeof(*envp), false)) {
- PRINTF("(invalid-envp %p)", envp);
- break;
- }
- if (*envp == NULL)
- break;
- if (test_user_string(*envp)) {
- PRINTF("(invalid-addr %p),", *envp);
- continue;
- }
- PUTS(*envp);
- PUTS(",");
- }
- if (cnt > 2)
- PRINTF("(%d more)", cnt);
- PUTS("]");
- }
- static void parse_pipe_fds(va_list ap) {
- int* fds = va_arg(ap, int*);
- if (test_user_memory(fds, 2 * sizeof(*fds), false)) {
- PRINTF("[invalid-addr %p]", fds);
- return;
- }
- PRINTF("[%d, %d]", fds[0], fds[1]);
- }
- #define S(sig) #sig
- const char* const siglist[NUM_KNOWN_SIGS + 1] = {
- S(SIGUNUSED), S(SIGHUP), S(SIGINT), S(SIGQUIT), S(SIGILL), S(SIGTRAP), S(SIGABRT),
- S(SIGBUS), S(SIGFPE), S(SIGKILL), S(SIGUSR1), S(SIGSEGV), S(SIGUSR2), S(SIGPIPE),
- S(SIGALRM), S(SIGTERM), S(SIGSTKFLT), S(SIGCHLD), S(SIGCONT), S(SIGSTOP), S(SIGTSTP),
- S(SIGTTIN), S(SIGTTOU), S(SIGURG), S(SIGXCPU), S(SIGXFSZ), S(SIGVTALRM), S(SIGPROF),
- S(SIGWINCH), S(SIGIO), S(SIGPWR), S(SIGSYS), S(SIGRTMIN),
- };
- static void parse_signum(va_list ap) {
- int signum = va_arg(ap, int);
- if (signum >= 0 && signum <= NUM_KNOWN_SIGS)
- PUTS(signal_name(signum));
- else
- PRINTF("[SIG %d]", signum);
- }
- static void parse_sigmask(va_list ap) {
- __sigset_t* sigset = va_arg(ap, __sigset_t*);
- if (!sigset) {
- PUTS("NULL");
- return;
- }
- if (test_user_memory(sigset, sizeof(*sigset), false)) {
- PRINTF("(invalid-addr %p)", sigset);
- return;
- }
- PUTS("[");
- for (size_t signum = 1; signum <= sizeof(sigset) * 8; signum++)
- if (__sigismember(sigset, signum)) {
- PUTS(signal_name(signum));
- PUTS(",");
- }
- PUTS("]");
- }
- static void parse_sigprocmask_how(va_list ap) {
- int how = va_arg(ap, int);
- switch (how) {
- case SIG_BLOCK:
- PUTS("BLOCK");
- break;
- case SIG_UNBLOCK:
- PUTS("UNBLOCK");
- break;
- case SIG_SETMASK:
- PUTS("SETMASK");
- break;
- default:
- PUTS("<unknown>");
- break;
- }
- }
- static void parse_timespec(va_list ap) {
- const struct timespec* tv = va_arg(ap, const struct timespec*);
- if (!tv) {
- PUTS("NULL");
- return;
- }
- if (test_user_memory((void*)tv, sizeof(*tv), false)) {
- PRINTF("(invalid-addr %p)", tv);
- return;
- }
- PRINTF("[%ld,%ld]", tv->tv_sec, tv->tv_nsec);
- }
- static void parse_sockaddr(va_list ap) {
- const struct sockaddr* addr = va_arg(ap, const struct sockaddr*);
- if (!addr) {
- PUTS("NULL");
- return;
- }
- if (test_user_memory((void*)addr, sizeof(*addr), false)) {
- PRINTF("(invalid-addr %p)", addr);
- return;
- }
- switch (addr->sa_family) {
- case AF_INET: {
- struct sockaddr_in* a = (void*)addr;
- unsigned char* ip = (void*)&a->sin_addr.s_addr;
- PRINTF("{family=INET,ip=%u.%u.%u.%u,port=htons(%u)}", ip[0], ip[1], ip[2], ip[3],
- __ntohs(a->sin_port));
- break;
- }
- case AF_INET6: {
- struct sockaddr_in6* a = (void*)addr;
- unsigned short* ip = (void*)&a->sin6_addr.s6_addr;
- PRINTF(
- "{family=INET,ip=[%x:%x:%x:%x:%x:%x:%x:%x],"
- "port=htons(%u)}",
- __ntohs(ip[0]), __ntohs(ip[1]), __ntohs(ip[2]), __ntohs(ip[3]), __ntohs(ip[4]),
- __ntohs(ip[5]), __ntohs(ip[6]), __ntohs(ip[7]), __ntohs(a->sin6_port));
- break;
- }
- case AF_UNIX: {
- struct sockaddr_un* a = (void*)addr;
- PRINTF("{family=UNIX,path=%s}", a->sun_path);
- break;
- }
- default:
- PUTS("UNKNOWN");
- break;
- }
- }
- static void parse_domain(va_list ap) {
- int domain = va_arg(ap, int);
- #define PF_UNSPEC 0 /* Unspecified. */
- #define PF_INET 2 /* IP protocol family. */
- #define PF_AX25 3 /* Amateur Radio AX.25. */
- #define PF_IPX 4 /* Novell Internet Protocol. */
- #define PF_APPLETALK 5 /* Appletalk DDP. */
- #define PF_ATMPVC 8 /* ATM PVCs. */
- #define PF_X25 9 /* Reserved for X.25 project. */
- #define PF_INET6 10 /* IP version 6. */
- #define PF_NETLINK 16
- #define PF_PACKET 17 /* Packet family. */
- switch (domain) {
- case PF_UNSPEC:
- PUTS("UNSPEC");
- break;
- case PF_UNIX:
- PUTS("UNIX");
- break;
- case PF_INET:
- PUTS("INET");
- break;
- case PF_INET6:
- PUTS("INET6");
- break;
- case PF_IPX:
- PUTS("IPX");
- break;
- case PF_NETLINK:
- PUTS("NETLINK");
- break;
- case PF_X25:
- PUTS("X25");
- break;
- case PF_AX25:
- PUTS("AX25");
- break;
- case PF_ATMPVC:
- PUTS("ATMPVC");
- break;
- case PF_APPLETALK:
- PUTS("APPLETALK");
- break;
- case PF_PACKET:
- PUTS("PACKET");
- break;
- default:
- PUTS("UNKNOWN");
- break;
- }
- }
- static void parse_socktype(va_list ap) {
- int socktype = va_arg(ap, int);
- if (socktype & SOCK_NONBLOCK) {
- socktype &= ~SOCK_NONBLOCK;
- PUTS("SOCK_NONBLOCK|");
- }
- if (socktype & SOCK_CLOEXEC) {
- socktype &= ~SOCK_CLOEXEC;
- PUTS("SOCK_CLOEXEC|");
- }
- #define SOCK_RAW 3 /* Raw protocol interface. */
- #define SOCK_RDM 4 /* Reliably-delivered messages. */
- #define SOCK_SEQPACKET 5 /* Sequenced, reliable, connection-based, */
- #define SOCK_DCCP 6 /* Datagram Congestion Control Protocol. */
- #define SOCK_PACKET 10 /* Linux specific way of getting packets */
- switch (socktype) {
- case SOCK_STREAM:
- PUTS("STREAM");
- break;
- case SOCK_DGRAM:
- PUTS("DGRAM");
- break;
- case SOCK_SEQPACKET:
- PUTS("SEQPACKET");
- break;
- case SOCK_RAW:
- PUTS("RAW");
- break;
- case SOCK_RDM:
- PUTS("RDM");
- break;
- case SOCK_PACKET:
- PUTS("PACKET");
- break;
- default:
- PUTS("UNKNOWN");
- break;
- }
- }
- static void parse_futexop(va_list ap) {
- int op = va_arg(ap, int);
- #ifdef FUTEX_PRIVATE_FLAG
- if (op & FUTEX_PRIVATE_FLAG) {
- PUTS("FUTEX_PRIVATE|");
- op &= ~FUTEX_PRIVATE_FLAG;
- }
- #endif
- #ifdef FUTEX_CLOCK_REALTIME
- if (op & FUTEX_CLOCK_REALTIME) {
- PUTS("FUTEX_CLOCK_REALTIME|");
- op &= ~FUTEX_CLOCK_REALTIME;
- }
- #endif
- op &= FUTEX_CMD_MASK;
- switch (op) {
- case FUTEX_WAIT:
- PUTS("FUTEX_WAIT");
- break;
- case FUTEX_WAIT_BITSET:
- PUTS("FUTEX_WAIT_BITSET");
- break;
- case FUTEX_WAKE:
- PUTS("FUTEX_WAKE");
- break;
- case FUTEX_WAKE_BITSET:
- PUTS("FUTEX_WAKE_BITSET");
- break;
- case FUTEX_FD:
- PUTS("FUTEX_FD");
- break;
- case FUTEX_REQUEUE:
- PUTS("FUTEX_REQUEUE");
- break;
- case FUTEX_CMP_REQUEUE:
- PUTS("FUTEX_CMP_REQUEUE");
- break;
- case FUTEX_WAKE_OP:
- PUTS("FUTEX_WAKE_OP");
- break;
- default:
- PRINTF("OP %d", op);
- break;
- }
- }
- static void parse_fcntlop(va_list ap) {
- int op = va_arg(ap, int);
- switch (op) {
- case F_DUPFD:
- PUTS("F_DUPFD");
- break;
- case F_GETFD:
- PUTS("F_GETFD");
- break;
- case F_SETFD:
- PUTS("F_SETFD");
- break;
- case F_GETFL:
- PUTS("F_GETFL");
- break;
- case F_SETFL:
- PUTS("F_SETFL");
- break;
- case F_GETLK:
- PUTS("F_GETLK");
- break;
- case F_SETLK:
- PUTS("F_SETLK");
- break;
- case F_SETLKW:
- PUTS("F_SETLKW");
- break;
- case F_SETOWN:
- PUTS("F_SETOWN");
- break;
- case F_GETOWN:
- PUTS("F_GETOWN");
- break;
- case F_SETSIG:
- PUTS("F_SETSIG");
- break;
- case F_GETSIG:
- PUTS("F_GETSIG");
- break;
- case F_GETLK64:
- PUTS("F_GETLK64");
- break;
- case F_SETLK64:
- PUTS("F_SETLK64");
- break;
- case F_SETLKW64:
- PUTS("F_SETLKW64");
- break;
- case F_SETOWN_EX:
- PUTS("F_SETOWN_EX");
- break;
- case F_GETOWN_EX:
- PUTS("F_GETOWN_EX");
- break;
- case F_GETOWNER_UIDS:
- PUTS("F_GETOWNER_UIDS");
- break;
- default:
- PRINTF("OP %d", op);
- break;
- }
- }
- static void parse_ioctlop(va_list ap) {
- int op = va_arg(ap, int);
- if (op >= TCGETS && op <= TIOCVHANGUP) {
- const char* opnames[] = {
- "TCGETS", /* 0x5401 */ "TCSETS", /* 0x5402 */
- "TCSETSW", /* 0x5403 */ "TCSETSF", /* 0x5404 */
- "TCGETA", /* 0x5405 */ "TCSETA", /* 0x5406 */
- "TCSETAW", /* 0x5407 */ "TCSETAF", /* 0x5408 */
- "TCSBRK", /* 0x5409 */ "TCXONC", /* 0x540A */
- "TCFLSH", /* 0x540B */ "TIOCEXCL", /* 0x540C */
- "TIOCNXCL", /* 0x540D */ "TIOCSCTTY", /* 0x540E */
- "TIOCGPGRP", /* 0x540F */ "TIOCSPGRP", /* 0x5410 */
- "TIOCOUTQ", /* 0x5411 */ "TIOCSTI", /* 0x5412 */
- "TIOCGWINSZ", /* 0x5413 */ "TIOCSWINSZ", /* 0x5414 */
- "TIOCMGET", /* 0x5415 */ "TIOCMBIS", /* 0x5416 */
- "TIOCMBIC", /* 0x5417 */ "TIOCMSET", /* 0x5418 */
- "TIOCGSOFTCAR", /* 0x5419 */ "TIOCSSOFTCAR", /* 0x541A */
- "FIONREAD", /* 0x541B */ "TIOCLINUX", /* 0x541C */
- "TIOCCONS", /* 0x541D */ "TIOCGSERIAL", /* 0x541E */
- "TIOCSSERIAL", /* 0x541F */ "TIOCPKT", /* 0x5420 */
- "FIONBIO", /* 0x5421 */ "TIOCNOTTY", /* 0x5422 */
- "TIOCSETD", /* 0x5423 */ "TIOCGETD", /* 0x5424 */
- "TCSBRKP", /* 0x5425 */ "",
- "TIOCSBRK", /* 0x5427 */ "TIOCCBRK", /* 0x5428 */
- "TIOCGSID", /* 0x5429 */ "TCGETS2", /* 0x542A */
- "TCSETS2", /* 0x542B */ "TCSETSW2", /* 0x542C */
- "TCSETSF2", /* 0x542D */ "TIOCGRS485", /* 0x542E */
- "TIOCSRS485", /* 0x542F */ "TIOCGPTN", /* 0x5430 */
- "TIOCSPTLCK", /* 0x5431 */ "TCGETX", /* 0x5432 */
- "TCSETX", /* 0x5433 */ "TCSETXF", /* 0x5434 */
- "TCSETXW", /* 0x5435 */ "TIOCSIG", /* 0x5436 */
- "TIOCVHANGUP", /* 0x5437 */
- };
- PUTS(opnames[op - TCGETS]);
- return;
- }
- if (op >= FIONCLEX && op <= TIOCSERSETMULTI) {
- const char* opnames[] = {
- "FIONCLEX", /* 0x5450 */ "FIOCLEX", /* 0x5451 */
- "FIOASYNC", /* 0x5452 */ "TIOCSERCONFIG", /* 0x5453 */
- "TIOCSERGWILD", /* 0x5454 */ "TIOCSERSWILD", /* 0x5455 */
- "TIOCGLCKTRMIOS", /* 0x5456 */ "TIOCSLCKTRMIOS", /* 0x5457 */
- "TIOCSERGSTRUCT", /* 0x5458 */ "TIOCSERGETLSR", /* 0x5459 */
- "TIOCSERGETMULTI", /* 0x545A */ "TIOCSERSETMULTI", /* 0x545B */
- };
- PUTS(opnames[op - FIONCLEX]);
- return;
- }
- #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
- #define TIOCGICOUNT 0x545D /* read serial port __inline__ interrupt counts */
- PRINTF("OP 0x%04x", op);
- }
- static void parse_seek(va_list ap) {
- int seek = va_arg(ap, int);
- switch (seek) {
- case SEEK_CUR:
- PUTS("SEEK_CUR");
- break;
- case SEEK_SET:
- PUTS("SEEK_SET");
- break;
- case SEEK_END:
- PUTS("SEEK_END");
- break;
- default:
- PRINTF("%d", seek);
- break;
- }
- }
- static void parse_at_fdcwd(va_list ap) {
- int fd = va_arg(ap, int);
- switch (fd) {
- case AT_FDCWD:
- PUTS("AT_FDCWD");
- break;
- default:
- PRINTF("%d", fd);
- break;
- }
- }
- static void parse_wait_option(va_list ap) {
- int option = va_arg(ap, int);
- if (option & WNOHANG)
- PUTS("WNOHANG");
- }
|