1#!/usr/bin/env python3 2# 3# Copyright (c) 2022 Huawei Technologies SASU 4# 5# SPDX-License-Identifier: Apache-2.0 6 7import binascii 8import logging 9import struct 10 11from gdbstubs.gdbstub import GdbStub 12 13 14logger = logging.getLogger("gdbstub") 15 16 17class RegNum(): 18 X0 = 0 # X0-X29 - 30 GP registers 19 X1 = 1 20 X2 = 2 21 X3 = 3 22 X4 = 4 23 X5 = 5 24 X6 = 6 25 X7 = 7 26 X8 = 8 27 X9 = 9 28 X10 = 10 29 X11 = 11 30 X12 = 12 31 X13 = 13 32 X14 = 14 33 X15 = 15 34 X16 = 16 35 X17 = 17 36 X18 = 18 37 X19 = 19 38 X20 = 20 39 X21 = 21 40 X22 = 22 41 X23 = 23 42 X24 = 24 43 X25 = 25 44 X26 = 26 45 X27 = 27 46 X28 = 28 47 X29 = 29 # Frame pointer register 48 LR = 30 # X30 Link Register(LR) 49 SP_EL0 = 31 # Stack pointer EL0 (SP_EL0) 50 PC = 32 # Program Counter (PC) 51 52 53class GdbStub_ARM64(GdbStub): 54 ARCH_DATA_BLK_STRUCT = "<QQQQQQQQQQQQQQQQQQQQQQ" 55 56 # Default signal used by all other script, just using the same 57 GDB_SIGNAL_DEFAULT = 7 58 59 # The number of registers expected by GDB 60 GDB_G_PKT_NUM_REGS = 33 61 62 63 def __init__(self, logfile, elffile): 64 super().__init__(logfile=logfile, elffile=elffile) 65 self.registers = None 66 self.gdb_signal = self.GDB_SIGNAL_DEFAULT 67 68 self.parse_arch_data_block() 69 70 def parse_arch_data_block(self): 71 72 arch_data_blk = self.logfile.get_arch_data()['data'] 73 74 tu = struct.unpack(self.ARCH_DATA_BLK_STRUCT, arch_data_blk) 75 76 self.registers = dict() 77 78 self.registers[RegNum.X0] = tu[0] 79 self.registers[RegNum.X1] = tu[1] 80 self.registers[RegNum.X2] = tu[2] 81 self.registers[RegNum.X3] = tu[3] 82 self.registers[RegNum.X4] = tu[4] 83 self.registers[RegNum.X5] = tu[5] 84 self.registers[RegNum.X6] = tu[6] 85 self.registers[RegNum.X7] = tu[7] 86 self.registers[RegNum.X8] = tu[8] 87 self.registers[RegNum.X9] = tu[9] 88 self.registers[RegNum.X10] = tu[10] 89 self.registers[RegNum.X11] = tu[11] 90 self.registers[RegNum.X12] = tu[12] 91 self.registers[RegNum.X13] = tu[13] 92 self.registers[RegNum.X14] = tu[14] 93 self.registers[RegNum.X15] = tu[15] 94 self.registers[RegNum.X16] = tu[16] 95 self.registers[RegNum.X17] = tu[17] 96 self.registers[RegNum.X18] = tu[18] 97 98 # Callee saved registers are not provided in __esf structure 99 # So they will be omitted (set to undefined) when stub generates the 100 # packet in handle_register_group_read_packet. 101 102 self.registers[RegNum.LR] = tu[19] 103 self.registers[RegNum.SP_EL0] = tu[20] 104 self.registers[RegNum.PC] = tu[21] 105 106 107 def handle_register_group_read_packet(self): 108 reg_fmt = "<Q" 109 110 idx = 0 111 pkt = b'' 112 113 while idx < self.GDB_G_PKT_NUM_REGS: 114 if idx in self.registers: 115 bval = struct.pack(reg_fmt, self.registers[idx]) 116 pkt += binascii.hexlify(bval) 117 else: 118 # Register not in coredump -> unknown value 119 # Send in "xxxxxxxx" 120 pkt += b'x' * 16 121 122 idx += 1 123 124 self.put_gdb_packet(pkt) 125 126 def handle_register_single_read_packet(self, pkt): 127 # Mark registers as "<unavailable>". 128 # 'p' packets are usually used for registers 129 # other than the general ones (e.g. eax, ebx) 130 # so we can safely reply "xxxxxxxx" here. 131 self.put_gdb_packet(b'x' * 16) 132