#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "/sys/src/libc/9syscall/sys.h" #include #include static DTProbe **dtpsysentry, **dtpsysreturn; typedef uintptr Syscall(va_list); extern Syscall *systab[]; #define WRAP0(x,y,z)\ Syscall z; uintptr x(va_list va){\ uintptr rc;\ DTTrigInfo info;\ memset(&info, 0, sizeof(info));\ dtptrigger(dtpsysentry[y], &info);\ rc = z(va);\ info.arg[9] = (uvlong) rc;\ dtptrigger(dtpsysreturn[y], &info);\ return rc;\ } #define WRAP1(x,y,z,type0)\ Syscall z; uintptr x(va_list va){\ uintptr rc;\ va_list vb = va;\ DTTrigInfo info;\ memset(&info, 0, sizeof(info));\ info.arg[0] = (uvlong) va_arg(vb, type0);\ dtptrigger(dtpsysentry[y], &info);\ rc = z(va);\ info.arg[9] = (uvlong) rc;\ dtptrigger(dtpsysreturn[y], &info);\ return rc;\ } #define WRAP2(x,y,z,type0,type1)\ Syscall z; uintptr x(va_list va){\ uintptr rc;\ va_list vb = va;\ DTTrigInfo info;\ memset(&info, 0, sizeof(info));\ info.arg[0] = (uvlong) va_arg(vb, type0);\ info.arg[1] = (uvlong) va_arg(vb, type1);\ dtptrigger(dtpsysentry[y], &info);\ rc = z(va);\ info.arg[9] = (uvlong) rc;\ dtptrigger(dtpsysreturn[y], &info);\ return rc;\ } #define WRAP3(x,y,z,type0,type1,type2)\ Syscall z; uintptr x(va_list va){\ uintptr rc;\ va_list vb = va;\ DTTrigInfo info;\ memset(&info, 0, sizeof(info));\ info.arg[0] = (uvlong) va_arg(vb, type0);\ info.arg[1] = (uvlong) va_arg(vb, type1);\ info.arg[2] = (uvlong) va_arg(vb, type2);\ dtptrigger(dtpsysentry[y], &info);\ rc = z(va);\ info.arg[9] = (uvlong) rc;\ dtptrigger(dtpsysreturn[y], &info);\ return rc;\ } #define WRAP4(x,y,z,type0,type1,type2,type3)\ Syscall z; uintptr x(va_list va){\ uintptr rc;\ va_list vb = va;\ DTTrigInfo info;\ memset(&info, 0, sizeof(info));\ info.arg[0] = (uvlong) va_arg(vb, type0);\ info.arg[1] = (uvlong) va_arg(vb, type1);\ info.arg[2] = (uvlong) va_arg(vb, type2);\ info.arg[3] = (uvlong) va_arg(vb, type3);\ dtptrigger(dtpsysentry[y], &info);\ rc = z(va);\ info.arg[9] = (uvlong) rc;\ dtptrigger(dtpsysreturn[y], &info);\ return rc;\ } /*TODO*/ #define WRAP5(x,y,z,type0,type1,type2,type3,type4)\ Syscall z; uintptr x(va_list va){\ uintptr rc;\ va_list vb = va;\ DTTrigInfo info;\ memset(&info, 0, sizeof(info));\ info.arg[0] = (uvlong) va_arg(vb, type0);\ info.arg[1] = (uvlong) va_arg(vb, type1);\ info.arg[2] = (uvlong) va_arg(vb, type2);\ info.arg[3] = (uvlong) va_arg(vb, type3);\ info.arg[4] = (uvlong) va_arg(vb, type4);\ dtptrigger(dtpsysentry[y], &info);\ rc = z(va);\ info.arg[9] = (uvlong) rc;\ dtptrigger(dtpsysreturn[y], &info);\ return rc;\ } WRAP0(dtwrap_sysr1, SYSR1, sysr1) WRAP1(dtwrap_sys_errstr, _ERRSTR, sys_errstr, char*) WRAP3(dtwrap_sysbind, BIND, sysbind, char*, char*, int) WRAP1(dtwrap_syschdir, CHDIR, syschdir, char*) WRAP1(dtwrap_sysclose, CLOSE, sysclose, int) WRAP2(dtwrap_sysdup, DUP, sysdup, int, int) WRAP1(dtwrap_sysalarm, ALARM, sysalarm, ulong) WRAP2(dtwrap_sysexec, EXEC, sysexec, char *, char **) WRAP1(dtwrap_sysexits, EXITS, sysexits, char *) WRAP3(dtwrap_sys_fsession, _FSESSION, sys_fsession, int, char *, uint) WRAP2(dtwrap_sysfauth, FAUTH, sysfauth, int, char *) WRAP2(dtwrap_sys_fstat, _FSTAT, sys_fstat, int, uchar *) WRAP1(dtwrap_syssegbrk, SEGBRK, syssegbrk, void *) WRAP4(dtwrap_sys_mount, _MOUNT, sys_mount, int, char *, int, char *) WRAP2(dtwrap_sysopen, OPEN, sysopen, char *, int) WRAP3(dtwrap_sys_read, _READ, sys_read, int, void*, long) WRAP3(dtwrap_sysoseek, OSEEK, sysoseek, int, long, int) WRAP1(dtwrap_syssleep, SLEEP, syssleep, long) WRAP2(dtwrap_sys_stat, _STAT, sys_stat, char *, uchar *) WRAP1(dtwrap_sysrfork, RFORK, sysrfork, int) WRAP3(dtwrap_sys_write, _WRITE, sys_write, int, void *, long) WRAP1(dtwrap_syspipe, PIPE, syspipe, int*) WRAP3(dtwrap_syscreate, CREATE, syscreate, char*, int, int) WRAP3(dtwrap_sysfd2path, FD2PATH, sysfd2path, int, char*, uint) WRAP1(dtwrap_sysbrk_, BRK_, sysbrk_, uintptr) WRAP1(dtwrap_sysremove, REMOVE, sysremove, char *) WRAP0(dtwrap_sys_wstat, _WSTAT, sys_wstat) WRAP0(dtwrap_sys_fwstat, _FWSTAT, sys_fwstat) WRAP2(dtwrap_sysnotify, NOTIFY, sysnotify, char *, void *) WRAP1(dtwrap_sysnoted, NOTED, sysnoted, int) WRAP4(dtwrap_syssegattach, SEGATTACH, syssegattach, int, char *, uintptr, ulong) WRAP1(dtwrap_syssegdetach, SEGDETACH, syssegdetach, uintptr) WRAP2(dtwrap_syssegfree, SEGFREE, syssegfree, uintptr, ulong) WRAP2(dtwrap_syssegflush, SEGFLUSH, syssegflush, void*, ulong) WRAP2(dtwrap_sysrendezvous, RENDEZVOUS, sysrendezvous, uintptr, uintptr) WRAP2(dtwrap_sysunmount, UNMOUNT, sysunmount, char *, char *) WRAP1(dtwrap_sys_wait, _WAIT, sys_wait, void*) WRAP2(dtwrap_syssemacquire, SEMACQUIRE, syssemacquire, long*, int) WRAP2(dtwrap_syssemrelease, SEMRELEASE, syssemrelease, long*, long) WRAP4(dtwrap_sysfversion, FVERSION, sysfversion, int, int, char *, int) WRAP2(dtwrap_syserrstr, ERRSTR, syserrstr, char *, uint) WRAP3(dtwrap_sysstat, STAT, sysstat, char *, uchar *, uint) WRAP3(dtwrap_sysfstat, FSTAT, sysfstat, int, uchar *, uint) WRAP3(dtwrap_syswstat, WSTAT, syswstat, char *, uchar *, uint) WRAP3(dtwrap_sysfwstat, FWSTAT, sysfwstat, int, uchar *, uint) WRAP5(dtwrap_sysmount, MOUNT, sysmount, int, int, char *, int, char *) WRAP2(dtwrap_sysawait, AWAIT, sysawait, char *, uint) WRAP4(dtwrap_syspread, PREAD, syspread, int, void *, long, vlong) WRAP4(dtwrap_syspwrite, PWRITE, syspwrite, int, void *, long, vlong) WRAP2(dtwrap_systsemacquire, TSEMACQUIRE, systsemacquire, long *, ulong) /* TODO: amd64 */ WRAP4(dtwrap_sysseek, SEEK, sysseek, vlong*, int, vlong, int) WRAP1(dtwrap_sys_nsec, _NSEC, sys_nsec, vlong*) static Syscall *wraptab[]={ [SYSR1] dtwrap_sysr1, [_ERRSTR] dtwrap_sys_errstr, [BIND] dtwrap_sysbind, [CHDIR] dtwrap_syschdir, [CLOSE] dtwrap_sysclose, [DUP] dtwrap_sysdup, [ALARM] dtwrap_sysalarm, [EXEC] dtwrap_sysexec, [EXITS] dtwrap_sysexits, [_FSESSION] dtwrap_sys_fsession, [FAUTH] dtwrap_sysfauth, [_FSTAT] dtwrap_sys_fstat, [SEGBRK] dtwrap_syssegbrk, [_MOUNT] dtwrap_sys_mount, [OPEN] dtwrap_sysopen, [_READ] dtwrap_sys_read, [OSEEK] dtwrap_sysoseek, [SLEEP] dtwrap_syssleep, [_STAT] dtwrap_sys_stat, [RFORK] dtwrap_sysrfork, [_WRITE] dtwrap_sys_write, [PIPE] dtwrap_syspipe, [CREATE] dtwrap_syscreate, [FD2PATH] dtwrap_sysfd2path, [BRK_] dtwrap_sysbrk_, [REMOVE] dtwrap_sysremove, [_WSTAT] dtwrap_sys_wstat, [_FWSTAT] dtwrap_sys_fwstat, [NOTIFY] dtwrap_sysnotify, [NOTED] dtwrap_sysnoted, [SEGATTACH] dtwrap_syssegattach, [SEGDETACH] dtwrap_syssegdetach, [SEGFREE] dtwrap_syssegfree, [SEGFLUSH] dtwrap_syssegflush, [RENDEZVOUS] dtwrap_sysrendezvous, [UNMOUNT] dtwrap_sysunmount, [_WAIT] dtwrap_sys_wait, [SEMACQUIRE] dtwrap_syssemacquire, [SEMRELEASE] dtwrap_syssemrelease, [SEEK] dtwrap_sysseek, [FVERSION] dtwrap_sysfversion, [ERRSTR] dtwrap_syserrstr, [STAT] dtwrap_sysstat, [FSTAT] dtwrap_sysfstat, [WSTAT] dtwrap_syswstat, [FWSTAT] dtwrap_sysfwstat, [MOUNT] dtwrap_sysmount, [AWAIT] dtwrap_sysawait, [PREAD] dtwrap_syspread, [PWRITE] dtwrap_syspwrite, [TSEMACQUIRE] dtwrap_systsemacquire, [_NSEC] dtwrap_sys_nsec, }; static void sysprovide(DTProvider *prov) { char buf[32], pname[32]; int i; dtpsysentry = smalloc(sizeof(Syscall *) * nsyscall); dtpsysreturn = smalloc(sizeof(Syscall *) * nsyscall); for(i = 0; i < nsyscall; i++){ if(systab[i] == nil || sysctab[i] == nil) continue; strecpy(buf, buf + sizeof(buf), sysctab[i]); if(isupper(buf[0])) buf[0] += 'a' - 'A'; if(i == SYSR1) strcpy(buf, "r1"); snprint(pname, sizeof(pname), "sys:%s:entry", buf); dtpsysentry[i] = dtpnew(pname, prov, (void *) i); snprint(pname, sizeof(pname), "sys:%s:return", buf); dtpsysreturn[i] = dtpnew(pname, prov, (void *) i); } } static int sysenable(DTProbe *p) { int i; Syscall *z; i = (int)(uintptr)p->aux; assert(i >= 0 && i < nsyscall); if(dtpsysentry[i]->nenable + dtpsysreturn[i]->nenable == 0) z = systab[i], systab[i] = wraptab[i], wraptab[i] = z; return 0; } static void sysdisable(DTProbe *p) { int i; Syscall *z; i = (int)(uintptr)p->aux; assert(i >= 0 && i < nsyscall); if(dtpsysentry[i]->nenable + dtpsysreturn[i]->nenable == 0) z = systab[i], systab[i] = wraptab[i], wraptab[i] = z; } DTProvider dtracysysprov = { .name = "sys", .provide = sysprovide, .enable = sysenable, .disable = sysdisable, };