History

Added code to read additional linking information. Ensured that function signature hashes are read as unsigned integers.

David Boddie committed 9 years ago

Commit 48fa6011 parent bbbabb51 file · +79 −7Browse files

Unified · Split

dis.py+79−7
@@ -155,6 +155,11 @@ class Dis: · 154 unmodified lines
155155 self.module_name = read_C(f)
156156
157157 self.read_link(f)
158+
159+ if self.runtime_flag.contains(RuntimeFlag.HASLDT):
160+ self.read_ldt(f)
161+
162+ self.path = read_C(f)
158163
159164 def read_code(self, f):
160165
@@ -176,10 +181,15 @@ class Dis: · 15 unmodified lines
176181
177182 def read_data(self, f):
178183
179− self.data = []
184+ # Use a dictionary to map pointers in the module's data area to items.
185+ self.data = {}
186+
187+ # Maintain a list of individual data items for easy inspection.
188+ self.data_items = []
189+
190+ # Use a list as a load address stack with an initial base address of 0.
180191 addresses = []
181192 base = 0
182− offset = 0
183193
184194 while True:
185195
@@ -217,7 +227,12 @@ class Dis: · 31 unmodified lines
217227 #print "Restore load address"
218228 base = addresses.pop()
219229 else:
220− self.data.append(Data(f, code, count, base + offset, array_type))
230+ address = base + offset
231+ item = Data(f, code, count, address, array_type)
232+ self.data_items.append(item)
233+ if address in self.data:
234+ print "Overwriting existing data item at %x." % address
235+ self.data[address] = item
221236
222237 def read_link(self, f):
223238
@@ -228,6 +243,28 @@ class Dis: · 4 unmodified lines
228243 self.link.append(Link(f))
229244 i += 1
230245
246+ def read_ldt(self, f):
247+
248+ self.ldt = []
249+
250+ # The Limbo compiler seems to include the number of initialised globals.
251+ self.initialised_globals = read_OP(f)
252+
253+ # There seems to be a collection of sequences. Each sequence starts
254+ # with a number and is followed by that number of definitions.
255+ while True:
256+
257+ # Read the number of definitions, stopping only when 0 is found.
258+ value = read_OP(f)
259+ if value == 0:
260+ break
261+
262+ i = 0
263+ while i < value:
264+
265+ self.ldt.append(LDT(f))
266+ i += 1
267+
231268 def list(self):
232269
233270 for i, ins in enumerate(self.code):
@@ -246,7 +283,12 @@ class RuntimeFlag: · 12 unmodified lines
246283 HASLDT = 0x40
247284
248285 def __init__(self, value):
286+
249287 self.value = value
288+
289+ def contains(self, flags):
290+
291+ return self.value & flags != 0
250292
251293
252294 class Instruction:
@@ -406,6 +448,11 @@ class Data: · 153 unmodified lines
406448
407449 i += 1
408450
451+ def __repr__(self):
452+
453+ return "<%s.%s (%s) %s>" % (self.__module__, self.__class__.__name__,
454+ self.array_types[self.array_type], repr(self.data()))
455+
409456 def data(self):
410457
411458 if self.array_type == 3:
@@ -413,10 +460,27 @@ class Data: · 1 unmodified line
413460 else:
414461 return self.array
415462
416− def __repr__(self):
463+ def encoded(self):
417464
418− return "<%s.%s (%s) %s>" % (self.__module__, self.__class__.__name__,
419− self.array_types[self.array_type], repr(self.data()))
465+ """Returns the contents of the array in the form they would take in the
466+ module area on a big-endian system."""
467+
468+ data = ""
469+
470+ for item in self.array:
471+
472+ if self.array_type == 1:
473+ data += pack(">B", item)
474+ elif self.array_type == 2:
475+ data += pack(">i", item)
476+ elif self.array_type == 3:
477+ data += item
478+ elif self.array_type == 4:
479+ data += pack(">d", item)
480+ elif self.array_type == 8:
481+ data += pack(">q", item)
482+
483+ return data
420484
421485
422486 class Link:
@@ -425,5 +489,13 @@ class Link: · 2 unmodified lines
425489
426490 self.pc = read_OP(f)
427491 self.desc_number = read_OP(f)
428− self.sig = read_W(f)
492+ self.sig = read_W(f) # unsigned for hashes
493+ self.name = read_C(f)
494+
495+
496+class LDT:
497+
498+ def __init__(self, f):
499+
500+ self.sig = _read(f, ">I") # unsigned for hashes
429501 self.name = read_C(f)