1#!/usr/bin/env python3 2# 3# Copyright (c) 2021 Facebook, Inc. and its affiliates 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 16class RegNum(): 17 ZERO = 0 18 RA = 1 19 SP = 2 20 GP = 3 21 TP = 4 22 T0 = 5 23 T1 = 6 24 T2 = 7 25 FP = 8 26 S1 = 9 27 A0 = 10 28 A1 = 11 29 A2 = 12 30 A3 = 13 31 A4 = 14 32 A5 = 15 33 A6 = 16 34 A7 = 17 35 S2 = 18 36 S3 = 19 37 S4 = 20 38 S5 = 21 39 S6 = 22 40 S7 = 23 41 S8 = 24 42 S9 = 25 43 S10 = 26 44 S11 = 27 45 T3 = 28 46 T4 = 29 47 T5 = 30 48 T6 = 31 49 PC = 32 50 51 52class GdbStub_RISC_V(GdbStub): 53 ARCH_DATA_BLK_STRUCT = "<IIIIIIIIIIIIIIIIII" 54 ARCH_DATA_BLK_STRUCT_2 = "<QQQQQQQQQQQQQQQQQQ" 55 56 GDB_SIGNAL_DEFAULT = 7 57 58 GDB_G_PKT_NUM_REGS = 33 59 60 def __init__(self, logfile, elffile): 61 super().__init__(logfile=logfile, elffile=elffile) 62 self.registers = None 63 self.gdb_signal = self.GDB_SIGNAL_DEFAULT 64 65 self.parse_arch_data_block() 66 67 def parse_arch_data_block(self): 68 arch_data_blk = self.logfile.get_arch_data()['data'] 69 self.arch_data_ver = self.logfile.get_arch_data()['hdr_ver'] 70 71 if self.arch_data_ver == 1: 72 tu = struct.unpack(self.ARCH_DATA_BLK_STRUCT, arch_data_blk) 73 elif self.arch_data_ver == 2: 74 tu = struct.unpack(self.ARCH_DATA_BLK_STRUCT_2, arch_data_blk) 75 76 self.registers = dict() 77 78 self.registers[RegNum.RA] = tu[0] 79 self.registers[RegNum.TP] = tu[1] 80 self.registers[RegNum.T0] = tu[2] 81 self.registers[RegNum.T1] = tu[3] 82 self.registers[RegNum.T2] = tu[4] 83 self.registers[RegNum.A0] = tu[5] 84 self.registers[RegNum.A1] = tu[6] 85 self.registers[RegNum.A2] = tu[7] 86 self.registers[RegNum.A3] = tu[8] 87 self.registers[RegNum.A4] = tu[9] 88 self.registers[RegNum.A5] = tu[10] 89 self.registers[RegNum.A6] = tu[11] 90 self.registers[RegNum.A7] = tu[12] 91 self.registers[RegNum.T3] = tu[13] 92 self.registers[RegNum.T4] = tu[14] 93 self.registers[RegNum.T5] = tu[15] 94 self.registers[RegNum.T6] = tu[16] 95 self.registers[RegNum.PC] = tu[17] 96 97 def handle_register_group_read_packet(self): 98 reg_fmt = "<I" if self.arch_data_ver == 1 else "<Q" 99 100 idx = 0 101 pkt = b'' 102 103 while idx < self.GDB_G_PKT_NUM_REGS: 104 if idx in self.registers: 105 bval = struct.pack(reg_fmt, self.registers[idx]) 106 pkt += binascii.hexlify(bval) 107 else: 108 # Register not in coredump -> unknown value 109 # Send in "xxxxxxxx" 110 length = 8 if self.arch_data_ver == 1 else 16 111 pkt += b'x' * length 112 113 idx += 1 114 115 self.put_gdb_packet(pkt) 116 117 def handle_register_single_read_packet(self, pkt): 118 # Mark registers as "<unavailable>". 'p' packets are not sent for the registers 119 # currently handled in this file so we can safely reply "xxxxxxxx" here. 120 length = 8 if self.arch_data_ver == 1 else 16 121 self.put_gdb_packet(b'x' * length) 122