#!/usr/bin/env python3 # # Copyright (c) 2020 Intel Corporation # # SPDX-License-Identifier: Apache-2.0 import binascii import logging import struct from coredump_parser.elf_parser import ThreadInfoOffset from gdbstubs.gdbstub import GdbStub logger = logging.getLogger("gdbstub") class RegNum(): R0 = 0 R1 = 1 R2 = 2 R3 = 3 R4 = 4 R5 = 5 R6 = 6 R7 = 7 R8 = 8 R9 = 9 R10 = 10 R11 = 11 R12 = 12 SP = 13 LR = 14 PC = 15 XPSR = 16 class GdbStub_ARM_CortexM(GdbStub): ARCH_DATA_BLK_STRUCT = " 1: self.registers[RegNum.R4] = tu[9] self.registers[RegNum.R5] = tu[10] self.registers[RegNum.R6] = tu[11] self.registers[RegNum.R7] = tu[12] self.registers[RegNum.R8] = tu[13] self.registers[RegNum.R9] = tu[14] self.registers[RegNum.R10] = tu[15] self.registers[RegNum.R11] = tu[16] def send_registers_packet(self, registers): reg_fmt = " unknown value # Send in "xxxxxxxx" pkt += b'x' * 8 idx += 1 self.put_gdb_packet(pkt) def handle_register_group_read_packet(self): if not self.elffile.has_kernel_thread_info(): self.send_registers_packet(self.registers) else: self.handle_thread_register_group_read_packet() def handle_register_single_read_packet(self, pkt): # Mark registers as "". # 'p' packets are usually used for registers # other than the general ones (e.g. eax, ebx) # so we can safely reply "xxxxxxxx" here. self.put_gdb_packet(b'x' * 8) def handle_register_single_write_packet(self, pkt): pkt_str = pkt.decode("ascii") reg = int(pkt_str[1:pkt_str.index('=')], 16) self.registers[reg] = int.from_bytes(binascii.unhexlify(pkt[3:]), byteorder = 'little') self.put_gdb_packet(b'+') def arch_supports_thread_operations(self): return True def handle_thread_register_group_read_packet(self): # For selected_thread 0, use the register data retrieved from the dump's arch section if self.selected_thread == 0: self.send_registers_packet(self.registers) else: thread_ptr = self.thread_ptrs[self.selected_thread] # Get stack pointer out of thread struct t_stack_ptr_offset = self.elffile.get_kernel_thread_info_offset(ThreadInfoOffset.THREAD_INFO_OFFSET_T_STACK_PTR) size_t_size = self.elffile.get_kernel_thread_info_size_t_size() stack_ptr_bytes = self.get_memory(thread_ptr + t_stack_ptr_offset, size_t_size) thread_registers = dict() if stack_ptr_bytes is not None: # Read registers stored at top of stack stack_ptr = int.from_bytes(stack_ptr_bytes, "little") barray = self.get_memory(stack_ptr, (size_t_size * 8)) if barray is not None: tu = struct.unpack("