/* * This file is part of Jehanne. * * Copyright (C) 2022 Giacomo Tesio * * Jehanne is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * Jehanne 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jehanne. If not, see . */ /* automatically generated by ksyscalls.rc.template */ #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "ureg.h" extern void fmtrwdata(Fmt* f, char* a, int n); extern void fmtuserstring(Fmt* f, const char* a); extern void fmtuserstringlist(Fmt* f, const char** argv); #! . ../$ARCH/registry-$ARCH.rc.conf #! ifs=' #! ' #! CONFIGURATION=`{sed -n '/^$/!{/^#/!p}' $JEHANNE/sys/src/sysconf/syscalls.rc.confs} #! for (line in $CONFIGURATION){ #! eval $line #! OTHERARGS=() #! if( ! ~ 1 $#ARGS){ #! OTHERARGS=(', '^$ARGS(2-)) #! } extern $RET sys$NAME($ARGS(1) $"OTHERARGS); #! } #! for (line in $CONFIGURATION){ #! eval $line #! CALLARGS=() static void wrap_$NAME^(ScRet* ret, Ureg* ureg) { #! for(idx in `{seq $#ARGS}){ #! CALLARGS=($CALLARGS a$idx) $ARGS($idx) a$idx; #! } #! for(idx in `{seq $#ARGS}){ a$idx = ($ARGS($idx))ureg->$UREG($idx); #! } #! OTHERARGS=() #! if( ! ~ 1 $#CALLARGS){ #! OTHERARGS=', '^$CALLARGS(2-) #! } ret->$$RET = sys$NAME($CALLARGS(1) $"OTHERARGS); } #! } int nsyscall = $#CONFIGURATION; ScRet default_syscall_ret(int syscall) { static ScRet zero; ScRet ret = zero; switch(syscall){ #! for (line in $CONFIGURATION){ #! eval $line case $ID: ret.$$RET = ($RET)-1; break; #! } default: ret.vl = -1; break; } return ret; } char* syscall_name(int syscall) { switch(syscall){ #! for (line in $CONFIGURATION){ #! eval $line case $ID: return "$NAME"; #! } default: return nil; } } void dispatch_syscall(int syscall, Ureg* ureg, ScRet* ret) { switch(syscall){ #! for (line in $CONFIGURATION){ #! eval $line case $ID: wrap_$NAME(ret, ureg); break; #! } default: panic("dispatch_syscall: bad sys call number %d pc %#p\n", syscall, ureg->ip); } } #! for (line in $CONFIGURATION){ #! eval $line static void enter_$NAME(Fmt* fmt, Ureg* ureg) { #! for(idx in `{seq $#ARGS}){ #! CALLARGS=($CALLARGS a$idx) $ARGS($idx) a$idx; #! } #! for(idx in `{seq $#ARGS}){ a$idx = ($ARGS($idx))ureg->$UREG($idx); #! } jehanne_fmtprint(fmt, "$NAME %#p >", ureg->ip); if(up->notified) jehanne_fmtprint(fmt, "!"); #! for(idx in `{seq $#ARGS}){ #! if( ~ $NAME pwrite && ~ $idx 2 ) { fmtrwdata(fmt, (char*)a2, MIN(a3, 64)); #! } #! if not switch($ARGS($idx)) { #! case 'int'; jehanne_fmtprint(fmt, " %d", a$idx); #! case 'int32_t'; jehanne_fmtprint(fmt, " %d", a$idx); #! case 'unsigned int'; jehanne_fmtprint(fmt, " %#ux", a$idx); #! case 'uint32_t'; jehanne_fmtprint(fmt, " %#ux", a$idx); #! case 'long'; jehanne_fmtprint(fmt, " %lld", a$idx); #! case 'int64_t'; jehanne_fmtprint(fmt, " %lld", a$idx); #! case 'unsigned long'; jehanne_fmtprint(fmt, " %#lud", a$idx); #! case 'uint64_t'; jehanne_fmtprint(fmt, " %#lud", a$idx); #! case 'void*'; jehanne_fmtprint(fmt, " %#p", a$idx); #! case 'uint8_t*'; jehanne_fmtprint(fmt, " %#p", a$idx); #! case 'const void*'; jehanne_fmtprint(fmt, " %#p", a$idx); #! case 'const uint8_t*'; jehanne_fmtprint(fmt, " %#p", a$idx); #! case 'int32_t*'; jehanne_fmtprint(fmt, " %#p(%d)", a$idx, a$idx); #! case 'int*'; jehanne_fmtprint(fmt, " %#p(%d)", a$idx, a$idx); #! case 'const int32_t*'; jehanne_fmtprint(fmt, " %#p(%d)", a$idx, a$idx); #! case 'const int*'; jehanne_fmtprint(fmt, " %#p(%d)", a$idx, a$idx); #! case 'const char*'; fmtuserstring(fmt, a$idx); #! case 'char*'; fmtuserstring(fmt, a$idx); #! case 'const char**'; fmtuserstringlist(fmt, a$idx); #! case 'char**'; fmtuserstringlist(fmt, a$idx); #! } #! } jehanne_fmtprint(fmt, "\n"); } #! } char* syscallfmt(int syscall, Ureg* ureg) { Fmt fmt; jehanne_fmtstrinit(&fmt); jehanne_fmtprint(&fmt, "%d %s ", up->pid, up->text); switch(syscall){ #! for (line in $CONFIGURATION){ #! eval $line case $ID: enter_$NAME^(&fmt, ureg); break; #! } default: panic("syscallfmt: bad sys call number %d pc %#p\n", syscall, ureg->ip); } return jehanne_fmtstrflush(&fmt); } #! for (line in $CONFIGURATION){ #! eval $line static void exit_$NAME^(Fmt* fmt, Ureg* ureg, ScRet* ret) { jehanne_fmtprint(fmt, "$NAME %#p <", ureg->ip); if(up->notified) jehanne_fmtprint(fmt, "!"); #! switch($RET) { #! case 'int': jehanne_fmtprint(fmt, " %d", ret->$$RET); #! case 'int32_t': jehanne_fmtprint(fmt, " %d", ret->$$RET); #! case 'unsigned int': jehanne_fmtprint(fmt, " %#ux", ret->$$RET); #! case 'uint32_t': jehanne_fmtprint(fmt, " %#ux", ret->$$RET); #! case 'long': jehanne_fmtprint(fmt, " %lld", ret->$$RET); #! case 'int64_t': jehanne_fmtprint(fmt, " %lld", ret->$$RET); #! case 'unsigned long': jehanne_fmtprint(fmt, " %#llud", ret->$$RET); #! case 'uint64_t': jehanne_fmtprint(fmt, " %#llud", ret->$$RET); #! case 'void': jehanne_fmtprint(fmt, " %#llud", ret->$$RET); #! case 'void*': jehanne_fmtprint(fmt, " %#p", ret->$$RET); #! case 'uintptr_t': jehanne_fmtprint(fmt, " %#p", ret->$$RET); #! case 'const void*': jehanne_fmtprint(fmt, " %#p", ret->$$RET); #! case 'const uintptr_t': jehanne_fmtprint(fmt, " %#p", ret->$$RET); #! case 'int32_t*': jehanne_fmtprint(fmt, " %#p(%d)", ret->$$RET, *ret->$$RET); #! case 'int*': jehanne_fmtprint(fmt, " %#p(%d)", ret->$$RET, *ret->$$RET); #! case 'const int32_t*': jehanne_fmtprint(fmt, " %#p(%d)", ret->$$RET, *ret->$$RET); #! case 'const int*': jehanne_fmtprint(fmt, " %#p(%d)", ret->$$RET, *ret->$$RET); #! } #! switch($NAME) { #! case pread: fmtrwdata(fmt, (char*)ureg->$UREG(2), MIN(ureg->$UREG(3), 64)); #! case fd2path: fmtrwdata(fmt, (char*)ureg->$UREG(2), MIN(ureg->$UREG(3), 64)); #! case await: fmtrwdata(fmt, (char*)ureg->$UREG(1), MIN(ureg->$UREG(2), 64)); #! case errstr: fmtrwdata(fmt, (char*)ureg->$UREG(1), MIN(ureg->$UREG(2), 64)); #! } } #! } char* sysretfmt(int syscall, Ureg* ureg, ScRet* ret, uint64_t start, uint64_t stop) { Fmt fmt; jehanne_fmtstrinit(&fmt); jehanne_fmtprint(&fmt, "%d %s ", up->pid, up->text); switch(syscall){ #! for (line in $CONFIGURATION){ #! eval $line case $ID: exit_$NAME^(&fmt, ureg, ret); break; #! } default: panic("sysretfmt: bad sys call number %d pc %#p\n", syscall, ureg->ip); } if(0 > ret->vl){ jehanne_fmtprint(&fmt, " %s %#llud %#llud\n", up->syserrstr, start, stop-start); } else { jehanne_fmtprint(&fmt, " \"\" %#llud %#llud\n", start, stop-start); } return jehanne_fmtstrflush(&fmt); }