Unified · Split
| @@ -155,6 +155,11 @@ class Dis: · 154 unmodified lines | ||
| 155 | 155 | self.module_name = read_C(f) |
| 156 | 156 | |
| 157 | 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 | 164 | def read_code(self, f): |
| 160 | 165 | |
| @@ -176,10 +181,15 @@ class Dis: · 15 unmodified lines | ||
| 176 | 181 | |
| 177 | 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 | 191 | addresses = [] |
| 181 | 192 | base = 0 |
| 182 | − offset = 0 | |
| 183 | 193 | |
| 184 | 194 | while True: |
| 185 | 195 | |
| @@ -217,7 +227,12 @@ class Dis: · 31 unmodified lines | ||
| 217 | 227 | #print "Restore load address" |
| 218 | 228 | base = addresses.pop() |
| 219 | 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 | 237 | def read_link(self, f): |
| 223 | 238 | |
| @@ -228,6 +243,28 @@ class Dis: · 4 unmodified lines | ||
| 228 | 243 | self.link.append(Link(f)) |
| 229 | 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 | 268 | def list(self): |
| 232 | 269 | |
| 233 | 270 | for i, ins in enumerate(self.code): |
| @@ -246,7 +283,12 @@ class RuntimeFlag: · 12 unmodified lines | ||
| 246 | 283 | HASLDT = 0x40 |
| 247 | 284 | |
| 248 | 285 | def __init__(self, value): |
| 286 | + | |
| 249 | 287 | self.value = value |
| 288 | + | |
| 289 | + def contains(self, flags): | |
| 290 | + | |
| 291 | + return self.value & flags != 0 | |
| 250 | 292 | |
| 251 | 293 | |
| 252 | 294 | class Instruction: |
| @@ -406,6 +448,11 @@ class Data: · 153 unmodified lines | ||
| 406 | 448 | |
| 407 | 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 | 456 | def data(self): |
| 410 | 457 | |
| 411 | 458 | if self.array_type == 3: |
| @@ -413,10 +460,27 @@ class Data: · 1 unmodified line | ||
| 413 | 460 | else: |
| 414 | 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__, | |
| 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 | |
| 420 | 484 | |
| 421 | 485 | |
| 422 | 486 | class Link: |
| @@ -425,5 +489,13 @@ class Link: · 2 unmodified lines | ||
| 425 | 489 | |
| 426 | 490 | self.pc = read_OP(f) |
| 427 | 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 | 501 | self.name = read_C(f) |