|
| 1 | +from revelation.isa import decode |
| 2 | + |
| 3 | +BKPT16 = 0b0000000111000010 |
| 4 | +NOP16 = 0b0000000110100010 |
| 5 | + |
| 6 | + |
| 7 | +class BreakPointManager(object): |
| 8 | + """Manage breakpoints during GDB execution. |
| 9 | + """ |
| 10 | + |
| 11 | + def __init__(self, simulator): |
| 12 | + self.target = simulator |
| 13 | + self.breakpoints = {} # Address -> (opcode, size in bytes) |
| 14 | + |
| 15 | + def _get_global_address(self, address, coreid=0x808): |
| 16 | + """Remap any local addresses to global address. |
| 17 | + """ |
| 18 | + if (address >> 20) == 0x0: |
| 19 | + return (coreid << 20) | address |
| 20 | + return address |
| 21 | + |
| 22 | + def is_breakpoint_set(self, address): |
| 23 | + return address in self.breakpoints |
| 24 | + |
| 25 | + def set_breakpoint(self, address, coreid=0x080): |
| 26 | + """Set a breakpoint at a given address. |
| 27 | + 1. Read 32 bit current instructions at address, save in dictionary. |
| 28 | + 2. If current instruction is 16 bit, replace with bkpt16. |
| 29 | + 3. If current instruction is 32 bit, replace with bkpt16, nop16. |
| 30 | + """ |
| 31 | + global_address = self._get_global_address(address, coreid) |
| 32 | + opcode = self.target.memory.iread(global_address, 4) |
| 33 | + mnemonic, _ = decode(opcode) |
| 34 | + if mnemonic.endswith('16'): |
| 35 | + self.breakpoints[global_address] = (opcode & 0xffff, 2) |
| 36 | + self.target.memory.write(global_address, 2, BKPT16) |
| 37 | + else: |
| 38 | + self.breakpoints[global_address] = (opcode, 4) |
| 39 | + self.target.memory.write(global_address, 2, BKPT16) |
| 40 | + self.target.memory.write(global_address + 2, 2, NOP16) |
| 41 | + |
| 42 | + def remove_breakpoint(self, address, coreid=0x808): |
| 43 | + """Remove a breakpoint at a given address.""" |
| 44 | + global_address = self._get_global_address(address, coreid) |
| 45 | + opcode, size = self.breakpoints[global_address] |
| 46 | + self.target.memory.write(global_address, size, opcode) |
0 commit comments