diff -r 000000000000 -r 5c129dd80d4f CSa32/Debug.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CSa32/Debug.S Thu Nov 21 14:55:10 2019 +0100 @@ -0,0 +1,273 @@ + .include "DS.S" +#----------------------------------------------- +# A B S T R A C T S T R U C T U R E S +#----------------------------------------------- +#----------------------------------------------- +# S T A T I C V A R I A B L E S +#----------------------------------------------- + .data +D.t0: .int 0 # initial timestamp in usecs +D.semP: .int 0 # -->semaphore for debug output + .globl D.prgNameP +D.prgNameP: + .int 0 # -->prog name +#----------------------------------------------- +# D E B U G I N I T +#----------------------------------------------- +# initialize static debug vars + ARGS + DS prgP # -->program name +# returns: nothing + PROLOC + EPILOC +#----------------------------------------------- + .text + .global D.init +D.init: + PROLOG + push prgP(bp) + call strlen + inc a + push a + call malloc + mov a, D.prgNameP # save -->prog name for debugging + push prgP(bp) + push a + call strcpy + movl $0, D.t0 + call D.getTs # get actual time - t0 = actual time + mov a, D.t0 # set t0 to actual time + + jmp 3f + push $0 + push $t + call gettimeofday # get initial timestamp t0 + cmp $0, a + jz 0f + ERR "gettimeofday" +0: lea t, b # compute (1000000*secs+usecs) + mov secs(b), c + mov $1000000, a + mul c # 1000000*secs + add usecs(b), a # 1000000*secs+usecs + movl a, D.t0 # save low 32 bits of timestamp in t0 +3: + push $0 # allocate semaphore for debug output + push $-1 + push $0x21 # PROT_READ | PROT_WRITE + push $0x03 # MAP_SHARED | MAP_ANONYMOUS + push $16 # semaphore size + push $0 + call mmap # get shared storage for semaphore + cmp $-1, a + jne 0f + ERR "mmap" +0: mov a, D.semP # save -->semaphore + + push $1 # initial semaphore value + push $1 # semaphore shared between processes + pushl D.semP + call sem_init # initialize semaphore + cmp $0, a + jz 0f + ERR "sem_init of debug semaphore" +0: + EPILOG +#----------------------------------------------- +# S E T D E B U G I D +#----------------------------------------------- +# sets debug ID according to format + ARGS + DS deP # -->Debug instance + DS argc # # of values to be put into deb ID + DS formP # -->format +# ... # values +# returns: nothing + PROLOC + EPILOC +#----------------------------------------------- + .global D.setId +D.setId: + PROLOG +# format debug ID + mov argc(bp), c # no. of values +0: mov formP(bp,c,4), a # push values and format + push a + dec c + jns 0b # iterate on values + pushl $D.idL # max deb ID len + mov deP(bp), b # -->Debug instance + lea D.id(b), a # -->DebId + push a + call snprintf # construct DebId + cmp $0, a + jnl 0f + ERR "DEBID snprintf" +0: + LOG 6, "debid '%s' set", 1 + EPILOG +#----------------------------------------------- +# P R I N T D E B U G M S G +#----------------------------------------------- +# outputs to stderr the synchronized debug msg with time diff from program start +# on appripriate debug level, flushes stderr + ARGS + ac = 40 + DS deP # -->Debug instance + DS level # msg debug level + DS argc # # of values to be used in msg + DS form # -->format +# ... # values +# returns: nothing + PROLOC + ac = 0 + EPILOC +#----------------------------------------------- + .global D.log +D.log: + PROLOG + + mov C.csP, c + mov level(bp), a # msg debug level + cmp C.debMaxLev(c), a # max debug level >= msg debug level ? + jg 3f # nothing to print, leave + cmp $7, C.debMaxLev(c) # on max debug level = 7 print level 7 only + jne 0f + cmp $7, a # msg debug level = 7 ? + jne 3f +# prepare output string of msg +0: mov argc(bp), c # no. of values +0: mov form(bp,c,4), a # copy values and format + push a + dec c + jns 0b + push $D.msgL # msg buffer len + mov deP(bp), b # -->Debug instance + lea D.msg(b), a # -->msg buffer + push a + call snprintf # construct msg in buffer + cmp $0, a + jnl 0f + ERR "LOG snprintf" +# synchronize with other tasks +0: pushl D.semP + call sem_wait # synchronize + cmp $0, a + jz 0f + ERR "LOG sem_wait" +# get timestamp +0: call D.getTs # time from beg of program in usecs +# print debug msg + mov deP(bp), b # -->Debug instance + lea D.msg(b), c # -->msg text + push c + lea D.id(b), c # -->instance debug ID + push c + push a # tdiff in usecs + push $1f + push stderr + call fprintf + jmp 2f +1: .ascii "%09u %s: %s\n\0" +# flush stderr +2: push stderr + call fflush # flush stderr +# free semaphore + pushl D.semP + call sem_post # free semaphore + cmp $0, a + jz 3f + ERR "LOG sem_post" +3: + EPILOG +#----------------------------------------------- +# G E T T I M E S T A M P I N U S E C S +#----------------------------------------------- +# returns timestamp in usecs from beg of program +# returns: int value + PROLOC + DL t, timevalL # timestamp buffer + EPILOC +#----------------------------------------------- + .global D.getTs +D.getTs: + PROLOG + push $0 + lea t(bp), b # -->timeval buffer + push b + call gettimeofday +# compute time delta from program start = t-t0 in usecs +# tdiff = (1000000*ts.secs+ts.usecs)-t0 + lea t(bp), b # actual timestamp + mov secs(b), c # t.secs + mov $1000000, a + mul c # 1000000*t.secs + add usecs(b), a # 1000000*t.secs+t.usecs + sub D.t0, a # 1000000*t.secs+t.usecs-t0 + EPILOG_R +#----------------------------------------------- +# S U B R O U T I N E S L I S T +#----------------------------------------------- +# print subroutines names and addresses +# localize address from env ADDR= in subroutine + PROLOC + DL wAddr # wanted addr + EPILOC +#----------------------------------------------- + .global D.subr +D.subr: + PROLOG + movl $0, wAddr(bp) + pushl $0f + call getenv # get env ADDR + lea 4(sp), sp + jmp 1f +0: .ascii "ADDR\0" +1: cmp $0, a + jz 0f # no addr wanted + pushl $16 + pushl $0 + push a + call strtol # convert str to hex + lea 12(sp), sp + mov a, wAddr(bp) # searched addr +0: + pushl $0 # end of list + SUBRLIST # print and push list of subroutines + cmp $0, wAddr(bp) # address wanted ? + je D.subrR + mov wAddr(bp), d + mov sp, b # -->beg of subr list + xor a, a + jmp 1f +0: lea 8(b), b +1: cmpl $0, (b) # end of list ? + je 2f # yes + cmp 4(b), d # -->subr > wanted addr ? + jb 0b # yes, next + cmp 4(b), a # -->subr > last found ? + jnb 0b # no, next + mov (b), c # get subr name + mov 4(b), a # get subr addr + jmp 0b # next +2: test a, a + jnz 1f + push d + push $0f + push stderr + call fprintf + jmp D.subrR +0: .ascii "addr %p not found in subroutines\n\0" +1: sub a, d + push d # offset in subr + push c # subroutine name + pushl wAddr(bp) # wanted addr + push $0f + push stderr + call fprintf + jmp D.subrR +0: .ascii "searched addr %p in subroutine %s at offset %x\n\0" +D.subrR: + EPILOG +#----------------------------------------------- + .end