Unified · Split
| @@ -155,6 +155,11 @@ class Dis: · 154 unmodified lines | |||
| 155 | self.module_name = read_C(f) | 155 | self.module_name = read_C(f) |
| 156 | 156 | ||
| 157 | self.read_link(f) | 157 | 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) | ||
| 158 | 163 | ||
| 159 | def read_code(self, f): | 164 | def read_code(self, f): |
| 160 | 165 | ||
| @@ -176,10 +181,15 @@ class Dis: · 15 unmodified lines | |||
| 176 | 181 | ||
| 177 | def read_data(self, f): | 182 | def read_data(self, f): |
| 178 | 183 | ||
| 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. | ||
| 180 | addresses = [] | 191 | addresses = [] |
| 181 | base = 0 | 192 | base = 0 |
| 182 | offset = 0 | ||
| 183 | 193 | ||
| 184 | while True: | 194 | while True: |
| 185 | 195 | ||
| @@ -217,7 +227,12 @@ class Dis: · 31 unmodified lines | |||
| 217 | #print "Restore load address" | 227 | #print "Restore load address" |
| 218 | base = addresses.pop() | 228 | base = addresses.pop() |
| 219 | else: | 229 | 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 | ||
| 221 | 236 | ||
| 222 | def read_link(self, f): | 237 | def read_link(self, f): |
| 223 | 238 | ||
| @@ -228,6 +243,28 @@ class Dis: · 4 unmodified lines | |||
| 228 | self.link.append(Link(f)) | 243 | self.link.append(Link(f)) |
| 229 | i += 1 | 244 | i += 1 |
| 230 | 245 | ||
| 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 | |||
| 231 | def list(self): | 268 | def list(self): |
| 232 | 269 | ||
| 233 | for i, ins in enumerate(self.code): | 270 | for i, ins in enumerate(self.code): |
| @@ -246,7 +283,12 @@ class RuntimeFlag: · 12 unmodified lines | |||
| 246 | HASLDT = 0x40 | 283 | HASLDT = 0x40 |
| 247 | 284 | ||
| 248 | def __init__(self, value): | 285 | def __init__(self, value): |
| 286 | |||
| 249 | self.value = value | 287 | self.value = value |
| 288 | |||
| 289 | def contains(self, flags): | ||
| 290 | |||
| 291 | return self.value & flags != 0 | ||
| 250 | 292 | ||
| 251 | 293 | ||
| 252 | class Instruction: | 294 | class Instruction: |
| @@ -406,6 +448,11 @@ class Data: · 153 unmodified lines | |||
| 406 | 448 | ||
| 407 | i += 1 | 449 | i += 1 |
| 408 | 450 | ||
| 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 | |||
| 409 | def data(self): | 456 | def data(self): |
| 410 | 457 | ||
| 411 | if self.array_type == 3: | 458 | if self.array_type == 3: |
| @@ -413,10 +460,27 @@ class Data: · 1 unmodified line | |||
| 413 | else: | 460 | else: |
| 414 | return self.array | 461 | return self.array |
| 415 | 462 | ||
| 416 | def __repr__(self): | 463 | def encoded(self): |
| 417 | 464 | ||
| 418 | return "<%s.%s (%s) %s>" % (self.__module__, self.__class__.__name__, | 465 | """Returns the contents of the array in the form they would take in the |
| 419 | self.array_types[self.array_type], repr(self.data())) | 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 | ||
| 420 | 484 | ||
| 421 | 485 | ||
| 422 | class Link: | 486 | class Link: |
| @@ -425,5 +489,13 @@ class Link: · 2 unmodified lines | |||
| 425 | 489 | ||
| 426 | self.pc = read_OP(f) | 490 | self.pc = read_OP(f) |
| 427 | self.desc_number = read_OP(f) | 491 | 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 | ||
| 429 | self.name = read_C(f) | 501 | self.name = read_C(f) |