(
self, f, start, line, next_address, highlight_address)
| 3443 | (line, ", ".join(extra))) |
| 3444 | |
| 3445 | def format_disasm_line( |
| 3446 | self, f, start, line, next_address, highlight_address): |
| 3447 | line_address = start + line[0] |
| 3448 | address_fmt = " <td>%s</td>" |
| 3449 | if line_address == highlight_address: |
| 3450 | f.write("<tr class=highlight-line>") |
| 3451 | address_fmt = " <td><a id=highlight>%s</a></td>" |
| 3452 | elif (line_address < highlight_address and |
| 3453 | highlight_address < next_address + start): |
| 3454 | f.write("<tr class=inexact-highlight-line>") |
| 3455 | address_fmt = " <td><a id=highlight>%s</a></td>" |
| 3456 | else: |
| 3457 | f.write("<tr>") |
| 3458 | num_bytes = next_address - line[0] |
| 3459 | stack_slot = self.heap.stack_map.get(line_address) |
| 3460 | marker = "" |
| 3461 | if stack_slot: |
| 3462 | marker = "=>" |
| 3463 | |
| 3464 | code = line[1] |
| 3465 | |
| 3466 | # Some disassemblers insert spaces between each byte, |
| 3467 | # while some do not. |
| 3468 | if code[2] == " ": |
| 3469 | op_offset = 3 * num_bytes - 1 |
| 3470 | else: |
| 3471 | op_offset = 2 * num_bytes |
| 3472 | |
| 3473 | # Compute the actual call target which the disassembler is too stupid |
| 3474 | # to figure out (it adds the call offset to the disassembly offset rather |
| 3475 | # than the absolute instruction address). |
| 3476 | if self.heap.reader.arch == MD_CPU_ARCHITECTURE_X86: |
| 3477 | if code.startswith("e8"): |
| 3478 | words = code.split() |
| 3479 | if len(words) > 6 and words[5] == "call": |
| 3480 | offset = int(words[4] + words[3] + words[2] + words[1], 16) |
| 3481 | target = (line_address + offset + 5) & 0xFFFFFFFF |
| 3482 | code = code.replace(words[6], "0x%08x" % target) |
| 3483 | # TODO(jkummerow): port this hack to ARM and x64. |
| 3484 | |
| 3485 | opcodes = code[:op_offset] |
| 3486 | code = self.annotate_disasm_addresses(code[op_offset:]) |
| 3487 | f.write(" <td>") |
| 3488 | self.output_comment_box(f, "codel-", line_address) |
| 3489 | f.write("</td>") |
| 3490 | f.write(address_fmt % marker) |
| 3491 | f.write(" ") |
| 3492 | self.td_from_address(f, line_address) |
| 3493 | f.write(self.format_address(line_address)) |
| 3494 | f.write(" (+0x%x)</td>" % line[0]) |
| 3495 | f.write("<td>: %s </td>" % opcodes) |
| 3496 | f.write("<td>%s</td>" % code) |
| 3497 | f.write("</tr>") |
| 3498 | |
| 3499 | def output_comment_box(self, f, prefix, address): |
| 3500 | comment = self.comments.get_comment(address) |
no test coverage detected