.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