.equ a, %eax
.equ b, %ebx
.equ c, %ecx
.equ d, %edx
.equ bp, %ebp
.equ sp, %esp
.equ di, %edi
#-----------------------------------------------
# M A C R O D E C L A R A T I O N S
#-----------------------------------------------
# subroutines list
.macro SUBRLIST
SUBR _start
SUBR D.init
SUBR D.setId
SUBR D.log
SUBR D.getTs
SUBR D.subr
SUBR Node
SUBR N.bind
SUBR N.conn
SUBR N.acc
SUBR N.closeSocket
SUBR N.read
SUBR N.write
SUBR N.get
SUBR N.put
SUBR N.sslErr
SUBR Data
SUBR Da.load
SUBR Da.chk
SUBR Da.unl
SUBR Da.dttl
SUBR Da.ttl
SUBR Da.getTs
.endm
#-----------------------------------------------
# push subroutine addr, prints its name and addr
# leave subr name and addr on stack
.macro SUBR subr:req
push $\subr
push $9f
push $8f
push stderr
call fprintf
jmp 7f
9: .asciz "\subr"
8: .asciz "%-12s\t%p\n"
7: lea 8(sp), sp
.endm
#-----------------------------------------------
# prepare to define subroutine args; use macro DS to define args
.macro ARGS
ac = 40
.endm
#-----------------------------------------------
# prepare to define subroutine args; use macro DS to define args
.macro M_ARGS
ac = 40
DS thisP
.endm
#-----------------------------------------------
# declare storage
.macro DS id:req, len=4
\id = ac
ac = ac + \len
.endm
#-----------------------------------------------
# prepare to define subroutine local vars
.macro PROLOC
ac = 0
.endm
#-----------------------------------------------
# prepare to define subroutine local vars
.macro M_LOCAL
ac = 0
DL deP
.endm
#-----------------------------------------------
# declare local var
.macro DL id:req, len=4
ac = ac + \len
\id = -ac
.endm
#-----------------------------------------------
# terminate subroutine local vars definition
.macro EPILOC
locL = ac
.endm
#-----------------------------------------------
# subroutine prolog
# expects length of local storage under the name "locL"
.macro PROLOG
pusha
enter $locL, $0
.endm
#-----------------------------------------------
# subroutine prolog
# expects length of local storage under the name "locL"
.altmacro
.macro M_PROLOG m_prefix:req, m_name:req
.global \m_prefix\().\m_name
\m_prefix\().\m_name:
pusha
enter $ac, $0
mov thisP(bp), b
lea \m_prefix\().debug(b), a
mov a, deP(bp)
.endm
.noaltmacro
#-----------------------------------------------
# subroutine epilog without return value
.macro EPILOG
leave
popa
ret
.endm
#-----------------------------------------------
# subroutine epilog with return value in EAX
# expects length of local storage under the name "locL"
.macro EPILOG_R
leave
mov a, 28(sp)
popa
ret
# mov -36(sp), a
.endm
#-----------------------------------------------
# ABEND at system routine err
.macro ERR causer:req
pushl $9f
call printf
pushl $1
call exit
9: .asciz "\causer: %m\n"
.endm
#-----------------------------------------------
# ABEND at system routine err using debug structure
# expects deP(bp)-->Debug inst
.macro SYSERR causer:req
push $9f # -->format
push $0 # no. of values
push $0 # msg debug level
pushl deP(bp) # -->Debug instance
call D.log # print msg
call C.abend
9: .asciz "\causer: %m"
.endm
#-----------------------------------------------
# print SSL err msg queue and then abend
# -->Debug in deP(bp) is expected
.macro SSLERR msg:req
pushl $9f
pushl deP(bp)
call N.sslErr
9: .asciz "\msg"
.endm
#-----------------------------------------------------------
.macro SYS name:req
call \name
cmp $-1, a
jne 8f
SYSERR "\name"
8: mov thisP(bp), b
test a, a
.endm
#-----------------------------------------------
# get integer value from ENV
.macro GETINTENV key:req
pushl $9f
call C.getArg
lea 4(sp), sp
cmp $0, a
jmp 8f
9: .asciz "\key"
8:
.endm
#-----------------------------------------------
# set local debug ID
# supposed: local deP-->Debug
# expected on the stack:
# \argc values to be put in debug ID according to format
# \argc may be zero
.macro DEBID format:req, argc=0
push $9f # -->format
push $\argc # no. of values
pushl deP(bp) # -->Debug instance
call D.setId # put debug ID to Debug inst
jmp 8f
9: .asciz "\format"
8: lea 12(sp), sp
.endm
#-----------------------------------------------
# debug output
# supposed: local deP-->Debug
# expected on the stack:
# \argc values to be printed by \format at debug level \level
# \argc may be zero
# all regs are preserved
.macro LOG level:req, format:req, argc=7
push $9f # -->format
push $\argc # no. of values
push $\level # msg debug level
pushl deP(bp) # -->Debug instance
call D.log # print msg
jmp 8f
9: .asciz "\format"
8: lea 16(sp), sp
.endm
#-----------------------------------------------
# flat print
# sp, bp are preserved
.macro PR format:req
push $9f
push stderr
call fprintf
jmp 8f
9: .asciz ">>> \format\n"
8: lea 8(sp), sp
.endm
#-----------------------------------------------
# print ip, bp, sp before subroutine call
# to be placed directly before a call instruction
# expected deP(bp) as -->Debug
# all regs are preserved
.macro B_CALL level:req, label="BEFORE SUBR CALL "
push a
lea 4(sp), a
push a
push bp
pushl $7f+5
LOG \level, "\label: ip: %p, bp: %p, sp: %p", 3
lea 12(sp), sp
pop a
jmp 7f
7:
.endm
#-----------------------------------------------
# print ip, bp, sp saved in sburoutine's stack frame
# to be placed anywhere before return seq and after deP(bp) is set
# expected deP(bp) as -->Debug
# all regs are preserved
.macro B_RET level:req, label="BEFORE SUBR RETURN"
push a
lea 8(bp), a
push a
push (bp)
push 4(bp)
LOG \level, "\label: ip: %p, bp: %p, sp: %p", 3
lea 12(sp), sp
pop a
jmp 7f
7:
.endm
#-----------------------------------------------
# print ip, bp, sp retained for return from sburoutine
# all regs are preserved
.macro A_CALL label="AFTER CALL"
pusha
lea 8(bp), a
push a
push (bp)
push 4(bp)
pushl $9f
call printf
lea 16(sp), sp
popa
jmp 8f
9: .asciz "\label: ip: %p, bp: %p, sp: %p\n"
8:
.endm
#-----------------------------------------------
.macro SLEEPER time:req, ident=">>>"
pusha
LOG 7, "\ident: sleeping \time"
pushl $\time
call sleep
lea 4(sp), sp
LOG 7, "\ident: woken up"
popa
.endm
#-----------------------------------------------
# A B S T R A C T D A T A D E C L A R A T I O N S
#-----------------------------------------------
# rSA reg save area
ac = 0
DS retSA
DS regSA, 32
DS bpSA
rSAL = ac
#-----------------------------------------------
# Timeval
ac = 0
DS secs
DS usecs
timevalL = ac
#-----------------------------------------------
# AddrInfo IP family net addr block
ac = 0
DS ai_flags
DS ai_family
DS ai_socktype
DS ai_protocol
DS ai_addrlen
DS ai_addrP # -->sockaddr
DS ai_canonnameP
DS ai_nextP
AddrInfoL = ac
#-----------------------------------------------
SIGUSR2 = 12
SIG_IGN = 1
SIG_UNBLOCK = 1
# sigaction signal handler definition
ac = 0
DS sa_handler
DS sa_mask, 128
DS sa_flags
DS sa_unused
SigActionL = ac
#-----------------------------------------------
# SockAddr
ac = 0
DS sa_family, 2
DS sa_data, 14
SockAddrL = ac
#-----------------------------------------------
# timeval struct
ac = 0
DS Ti.secs
DS Ti.usecs
timevalL = ac
#-----------------------------------------------
# Debug debug info
ac = 0
D.idL = 128
DS D.id, D.idL # debug ID of process
D.msgL = 256
DS D.msg, D.msgL # debug msg workspace
DebugL = ac
.macro DebugA # returns -->Debug
push $DebugL
call malloc
cmp $0, a
ja 8f
SYSERR "malloc"
8: movl $0, D.id(a)
.endm
#-----------------------------------------------
# CS top level attributes
ac = 0
DS C.debug, DebugL
DS C.debMaxLev # max level of debug msgs to be printed
DS C.txtP # -->text to be sent in messages
DS C.ttl # TTL for circulating msgs
DS C.mp0 # TCP port of first mash node
DS C.mn # intended # of nodes in mash
DS C.rp0 # TCP port of first ring node
DS C.rn # intended # of nodes in ring
DS C.pace.tv_sec # timespec.tv_sec
DS C.pace.tv_nsec # timespec.tv_nsec
DS C.pacing # pacing indicator
# DS C.rs # random() seed
DS C.ssl # ssl mask: 01B=noSSL, 10B=SSL, 11B=both
DS C.connTh # connection retry threshhold
DS C.shP # -->shared counters
DS C.pathP # -->pathname to application home dir
DS C.cePathP # -->pathname to SSL dir
DS C.caPathP # -->pathname to SSL CA CERT dir
CSL = ac
.macro CSA # returns -->CS
push $CSL
call malloc
cmp $0, a
ja 8f
SYSERR "malloc"
8:
.endm
#-----------------------------------------------
# Share counters shared between procs or threads
ac = 0
DS S.counter_sem, 16 # semaphore for counters
DS S.conns # overall connections counter both in ring and mash
DS S.msgs # overall forewards# both in ring and mash
DS S.act # active node processes counter
DS S.mash_open_client_count # no. of opened clients in mash
DS S.mash_open_SSL_client_count # no. of opened SSL clients in mash
ShareL = ac
.macro ShareA # returns -->Share
push $0
push $-1
push $0x21 # PROT_READ | PROT_WRITE
push $0x03 # MAP_SHARED | MAP_ANONYMOUS
push $ShareL
push $0
call mmap
cmp $-1, a
jne 8f
SYSERR "mmap"
8:
.endm
#-----------------------------------------------
# Data - container for data sent through connection topology
# Container Header
ac = 0
DS H.ttl # msg TTL
DS H.ts # timestamp
DS H.lport # listening TCP port
HeaderL = ac
# Container Payload
ac = 0
# Pa.loadL = 256
DS Pa.ts # timestamp
DS Pa.text, 0 # load sent in msg
PayloadL = ac
# Container to be send
ac = 0
DS Co.hdr, HeaderL # Header
DS Co.payl, PayloadL # Payload
# ContainerL = ac
# Data instantion
ac = 0
DS Da.debug, DebugL # Debug
DS Da.contP # -->Container
DS Da.datalen # container length
DataL = ac
.macro DataA # returns -->Data
push $DataL
call malloc
cmp $0, a
ja 8f
SYSERR "malloc"
8:
.endm
#-----------------------------------------------
# Node general attributes of node
ac = 0
DS N.debug, DebugL # debug info
DS N.cnstlnP # -->Constellation block
DS N.topo # constellation topology
DS N.locPort # TCP port node binds to
DS N.first # port # of first node in constellation
DS N.last # port # of last node in constellation
DS N.nodes # number of nodes
DS N.div # random node choise divisor (MAX_INT / nodes)
DS N.kicker # kicker indicator
DS N.forwP # -->shared forward indicator
DS N.closing # closing in progress indicator
DS N.ssc # server side socket
DS N.data, DataL # data block
DS N.dataP # -->data block
DS N.srvSideP # -->array of server side Sockets
DS N.cliSideP # -->array of client side Sockets
DS N.sockArrLen # socket array length
DS N.next # next node's port#
DS N.nfds # highest FD# in FD sets
DS N.rs, 128 # read FD set
DS N.es, 128 # exceptional FD set
DS N.t, timevalL # timeval for select
DS N.ssl # SSL switch: 0=noSSL, 1=SSL
DS N.ctxP # -->SSL context
DS N.pid # process ID
DS N.ptid # closing thread ID
NodeL = ac
.macro NodeA # returns -->Node
push $NodeL
call malloc
cmp $0, a
ja 8f
SYSERR "malloc"
8:
.endm
#-----------------------------------------------
# SocketInfo comm socket info
ac = 0
DS So.remPort # TCP port on remote site
DS So.sc # comm socket#
DS So.sslP # -->SSL structure
SocketInfoL = ac
.macro SocketA # returns -->Socket
push $SocketL
call malloc
cmp $0, a
ja 8f
SYSERR "malloc"
8:
.endm
#-----------------------------------------------
# Constellation attributes of constellation of nodes (mash or ring)
ac = 0
DS Cn.debug, DebugL # debug info
DS Cn.topo # Constellation topology
Cn.ring = 0
Cn.mash = 1
DS Cn.first
DS Cn.nodes
DS Cn.div # random node choise divisor (MAX_INT / nodes)
DS Cn.ssl
DS Cn.forwP
ConstellationL = ac
.macro ConstellationA # returns -->Constellation
push $ConstellationL
call malloc
cmp $0, a
ja 8f
SYSERR "malloc"
8:
.endm