import sys, os
from struct import unpack,calcsize,error
class argtypes:
char = "b", "0x%x"
byte = code_t = "B", "0x%x"
int = "i", "0x%x"
long = word_t = "l", "0x%x"
def stack(t):
if isinstance(t, tuple):
return t[0], "[%d]"
else:
return "", "[%s]" % t, t
def indirect(t):
return t
fn = os.path.join(os.path.dirname(__file__), '../c/ivm/prolog/insns-table.py')
execfile(fn, argtypes.__dict__, globals())
class Mode:
def __init__(self, opcode):
self.opcode = opcode
if opcode in insntable:
self.insns = insntable[opcode]
else:
self.insns = [("<%d>" % opcode,)]
if len(self.insns) == 1:
self.singleinsn = self.insns[0][0]
else:
self.singleinsn = None
self.stackpushes = stackpushes.get(opcode)
self.unpackfmt = "="
self.template = ""
self.constantargs = []
i = 0
line = '%10x\t'
for insn in self.insns:
args = []
for arg in insn[1:]:
if isinstance(arg, tuple):
self.unpackfmt += arg[0]
args.append(arg[1])
if len(arg)>2:
self.constantargs.append((i, arg[2]))
else:
args.append(str(arg))
self.constantargs.append((i, arg))
i += 1
line += '%-11s %s' % (insn[0], ', '.join(args))
self.template += line
line = '\n \t'
self.unpacksize = calcsize(self.unpackfmt)
def dump(self, data, address, position):
data = data[position:position+self.unpacksize]
args = unpack(self.unpackfmt, data)
result = self.template % ((address,) + args)
return position+self.unpacksize, result.split('\n'), args
def getargs(self, data, position):
data = data[position:position+self.unpacksize]
args = list(unpack(self.unpackfmt, data))
for i, value in self.constantargs:
args.insert(i, value)
return args
insnlist = [Mode(opcode) for opcode in range(256)]
def dump(data, originaddr):
l = len(data)
if l>8 and data[-4:] == '\x00\x00\x00\x00':
p, = unpack("l", data[-8:-4])
queue = ["", " (promotion chained list: 0x%x)" % p]
l -= 4
else:
queue = []
depth = None
result = []
p = 0
try:
while p < l:
mode = insnlist[ord(data[p])]
p, lines, args = mode.dump(data, originaddr+p, p+1)
if depth is not None:
if mode.stackpushes is None:
depth = None
else:
depth += mode.stackpushes
lines[-1] = '%-40s [%d]' % (lines[-1], depth)
if mode.singleinsn == 'assertdepth':
asserteddepth = args[0]/4
if depth is not None and asserteddepth != depth:
err = '************* assertion error **************'
lines.append(err)
print >> sys.stderr, err
print >> sys.stderr, originaddr
else:
lines = [(s+' ')[:s.find('assertdepth')] for s in lines]
depth = asserteddepth
result += lines
except error:
while p < l:
result.append(" %10x\t<%d>" % (originaddr+p, ord(data[p])))
p += 1
result += queue
return result
|