History

Fixed LDT generation, adding a trailing zero after an empty section and ensuring that items are padded to word boundaries. Added types, data and other information to the output of the list method. Started working on reading exceptions.

David Boddie committed 9 years ago

Commit f918dba1 parent 3740cbe1 file · +140 −2Browse files

Unified · Split

dis.py+140−2
@@ -21,7 +21,7 @@ import opcodes · 20 unmodified lines
2121 from utils import _read, read_B, read_C, read_OP, read_F, read_L, read_P, \
2222 read_W, \
2323 _write, write_B, write_C, write_OP, write_F, write_L, \
24− write_P, write_W
24+ write_P, write_W, dbl_repr
2525
2626 XMAGIC = 0x0c8030
2727 SMAGIC = 0x0e1722
@@ -86,6 +86,9 @@ class Dis: · 58 unmodified lines
8686 if self.runtime_flag.contains(RuntimeFlag.HASLDT):
8787 self.read_ldt(f)
8888
89+ if self.runtime_flag.contains(RuntimeFlag.HASEXCEPT):
90+ self.read_exceptions(f)
91+
8992 self.path = read_C(f)
9093
9194 def read_code(self, f):
@@ -180,6 +183,8 @@ class Dis: · 88 unmodified lines
180183
181184 def read_ldt(self, f):
182185
186+ # Described in the section about the load operand in the Dis Virtual
187+ # Machine Specification.
183188 self.ldt = []
184189
185190 # The Limbo compiler seems to include the number of initialised globals.
@@ -203,6 +208,24 @@ class Dis: · 17 unmodified lines
203208 i += 1
204209
205210 self.ldt.append(sequence)
211+
212+ # Discard the dummy value that occurs after an empty set of LDTs.
213+ if not self.ldt:
214+ read_OP(f)
215+
216+ def read_exceptions(self, f):
217+
218+ self.exceptions = []
219+ number = read_OP(f)
220+ i = 0
221+
222+ while i < number:
223+
224+ self.exceptions.append(ExceptionInfo().read(f))
225+ i += 1
226+
227+ # Discard the dummy value that occurs after a set of exceptions.
228+ read_OP(f)
206229
207230 def write(self, f):
208231
@@ -303,7 +326,60 @@ class Dis: · 94 unmodified lines
303326 def list(self):
304327
305328 for i, ins in enumerate(self.code):
306− print hex(i), str(ins)
329+ print hex(i) + ":", str(ins)
330+
331+ print
332+ print "entry %s, %i" % (hex(self.entry_pc), self.entry_type)
333+
334+ for type_ in self.types:
335+ print 'desc $0x%x, %i, "%s"' % (type_.desc_number, type_.size,
336+ "".join(map(lambda x: "%02x" % ord(x), type_.array)))
337+
338+ print
339+ print "var @mp, %i" % self.data_size
340+
341+ items = self.data.items()
342+ items.sort()
343+
344+ for address, item in items:
345+ if item.array_type == 3:
346+ print 'string @mp+%i, %s' % (address, dbl_repr(item.data()))
347+ else:
348+ print "?",
349+
350+ print
351+ print "module", self.module_name
352+
353+ for link in self.link:
354+ print
355+ print "link %s, %i, %s, %s" % (hex(link.pc), link.desc_number,
356+ hex(link.sig), dbl_repr(link.name))
357+
358+ if self.runtime_flag.contains(RuntimeFlag.HASLDT):
359+ print
360+ print "ldts @ldt, %i" % len(self.ldt)
361+ i = 0
362+ start = 4
363+
364+ for sequence in self.ldt:
365+ print "word @ldt+%i,%i" % (i, len(sequence))
366+ i += 1
367+
368+ j = start
369+
370+ for ldt in sequence:
371+ print "ext @ldt+%i, %s, %s" % (j, hex(ldt.sig),
372+ dbl_repr(ldt.name))
373+ size = 4 + len(ldt.name) + 1
374+ if size % 4 != 0:
375+ size += 4 - (size % 4)
376+ j += size
377+
378+ if i % 4 == 1:
379+ start += 4
380+
381+ print
382+ print "source %s" % dbl_repr(self.path)
307383
308384
309385 class RuntimeFlag:
@@ -498,6 +574,8 @@ class Link: · 188 unmodified lines
498574 self.desc_number = read_OP(f)
499575 self.sig = read_W(f) # unsigned for hashes
500576 self.name = read_C(f)
577+
578+ return self
501579
502580 def __repr__(self):
503581
@@ -523,6 +601,8 @@ class LDT: · 19 unmodified lines
523601
524602 self.sig = _read(f, ">I") # unsigned for hashes
525603 self.name = read_C(f)
604+
605+ return self
526606
527607 def __repr__(self):
528608
@@ -532,3 +612,61 @@ class LDT: · 3 unmodified lines
532612
533613 _write(f, ">I", self.sig)
534614 write_C(f, self.name)
615+
616+ # Pad to a word boundary if necessary.
617+ remainder = len(self.name) % 4
618+ if remainder != 0:
619+ f.write("\x00" * (4 - remainder))
620+
621+
622+class ExceptionInfo:
623+
624+ def __init__(self, offset = 0, p1 = 0, p2 = 0, id = -1, nlab_ne = 0,
625+ pcs = None, iwild = -1):
626+
627+ self.offset = offset
628+ self.p1 = p1
629+ self.p2 = p2
630+
631+ if id != -1:
632+ self.desc = id
633+ else:
634+ self.desc = -1
635+
636+ if pcs:
637+ self.pcs = pcs
638+ else:
639+ self.pcs = []
640+
641+ if iwild != -1:
642+ self.pc = iwild
643+ else:
644+ self.pc = -1
645+
646+ def read(self, f):
647+
648+ self.offset = read_OP(f)
649+ self.p1 = read_OP(f)
650+ self.p2 = read_OP(f)
651+
652+ id = read_OP(f)
653+ if id != -1:
654+ self.desc = id
655+ else:
656+ self.desc = -1
657+
658+ nlab_ne = read_OP(f)
659+ self.nlab = nlab_ne & 0xffff
660+ self.ne = nlab_ne >> 16
661+
662+ self.pcs = []
663+ i = 0
664+ while i < self.nlab:
665+ name = read_C(f)
666+ pc = read_OP(f)
667+ self.pcs.append((name, pc))
668+ i += 1
669+
670+ self.pc = read_OP(f)
671+
672+ return self