1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #include <stdint.h> 18 #include <stddef.h> 19 #include <stdbool.h> 20 21 #include "gdbstub_target_config.h" 22 #include "esp_gdbstub_arch.h" 23 #include "sdkconfig.h" 24 25 #ifdef CONFIG_ESP_GDBSTUB_SUPPORT_TASKS 26 #include "freertos/FreeRTOS.h" 27 #include "freertos/task.h" 28 #include "freertos/task_snapshot.h" 29 #endif // CONFIG_ESP_GDBSTUB_SUPPORT_TASKS 30 31 /* Internal error codes used by the routines that parse the incoming gdb packet */ 32 #define GDBSTUB_ST_ENDPACKET -1 33 #define GDBSTUB_ST_ERR -2 34 #define GDBSTUB_ST_OK -3 35 #define GDBSTUB_ST_CONT -4 36 37 /* Special task index values */ 38 #define GDBSTUB_CUR_TASK_INDEX_UNKNOWN -1 39 40 /* Cab be set to a lower value in gdbstub_target_config.h */ 41 #ifndef GDBSTUB_CMD_BUFLEN 42 #define GDBSTUB_CMD_BUFLEN 512 43 #endif 44 45 #if CONFIG_ESP_GDBSTUB_SUPPORT_TASKS 46 typedef enum { 47 GDBSTUB_NOT_STARTED, 48 GDBSTUB_STARTED, 49 GDBSTUB_TASK_SUPPORT_DISABLED 50 } esp_gdbstub_state_t; 51 52 #define GDBSTUB_TASKS_NUM CONFIG_ESP_GDBSTUB_MAX_TASKS 53 54 #endif // CONFIG_ESP_GDBSTUB_SUPPORT_TASKS 55 56 /* gdbstub temporary run-time data, stored in .bss to reduce stack usage */ 57 typedef struct { 58 esp_gdbstub_gdb_regfile_t regfile; 59 int signal; 60 #if CONFIG_ESP_GDBSTUB_SUPPORT_TASKS 61 esp_gdbstub_state_t state; 62 int task_count; 63 int paniced_task_index; 64 int current_task_index; 65 int thread_info_index; //!< index of the last task passed to qsThreadInfo 66 esp_gdbstub_frame_t paniced_frame; 67 TaskSnapshot_t tasks[GDBSTUB_TASKS_NUM]; // TODO: add an API to get snapshots one by one 68 #endif // CONFIG_ESP_GDBSTUB_SUPPORT_TASKS 69 } esp_gdbstub_scratch_t; 70 71 72 /**** Functions provided by the architecture specific part ****/ 73 74 /** 75 * @param frame exception frame pointer 76 * @return the appropriate "signal" number for the given exception cause 77 */ 78 int esp_gdbstub_get_signal(const esp_gdbstub_frame_t *frame); 79 80 /** 81 * Write registers from the exception frame to the GDB register file 82 * @param frame exception frame to parse 83 * @param dst pointer to the GDB register file 84 */ 85 void esp_gdbstub_frame_to_regfile(const esp_gdbstub_frame_t *frame, esp_gdbstub_gdb_regfile_t *dst); 86 87 #if CONFIG_ESP_GDBSTUB_SUPPORT_TASKS 88 /** 89 * Write registers from the saved frame of a given task to the GDB register file 90 * @param tcb pointer to the TCB of the task 91 * @param dst pointer to the GDB register file 92 */ 93 void esp_gdbstub_tcb_to_regfile(TaskHandle_t tcb, esp_gdbstub_gdb_regfile_t *dst); 94 #endif // CONFIG_ESP_GDBSTUB_SUPPORT_TASKS 95 96 97 98 /**** Functions provided by the target specific part ****/ 99 100 /** 101 * Do target-specific initialization before gdbstub can start communicating. 102 * This may involve, for example, configuring the UART. 103 */ 104 void esp_gdbstub_target_init(void); 105 106 /** 107 * Receive a byte from the GDB client. Blocks until a byte is available. 108 * @return received byte 109 */ 110 int esp_gdbstub_getchar(void); 111 112 /** 113 * Send a byte to the GDB client 114 * @param c byte to send 115 */ 116 void esp_gdbstub_putchar(int c); 117 118 /** 119 * Read a byte from target memory 120 * @param ptr address 121 * @return byte value, or GDBSTUB_ST_ERR if the address is not readable 122 */ 123 int esp_gdbstub_readmem(intptr_t addr); 124 125 /** 126 * Make sure all bytes sent using putchar() end up at the host. 127 * (Usually stubbed for UART, but can be useful for other channels) 128 */ 129 void esp_gdbstub_flush(void); 130 131 /** 132 * Write a byte to target memory 133 * @param addr address 134 * @param data data byte 135 * @return 0 in case of success, -1 in case of error 136 */ 137 int esp_gdbstub_writemem(unsigned int addr, unsigned char data); 138 139 /** 140 * Read a data from fifo and detect start symbol 141 * @return 1 if break symbol was detected, or 0 if not 142 */ 143 int esp_gdbstub_getfifo(void); 144 145 /**** GDB packet related functions ****/ 146 147 /** Begin a packet */ 148 void esp_gdbstub_send_start(void); 149 150 /** Send a character as part of the packet */ 151 void esp_gdbstub_send_char(char c); 152 153 /** Send a string as part of the packet */ 154 void esp_gdbstub_send_str(const char *s); 155 156 /** Send a hex value as part of the packet */ 157 void esp_gdbstub_send_hex(int val, int bits); 158 159 /** Finish sending the packet */ 160 void esp_gdbstub_send_end(void); 161 162 /** Send a packet with a string as content */ 163 void esp_gdbstub_send_str_packet(const char *str); 164 165 /** Get a hex value from the gdb packet */ 166 uint32_t esp_gdbstub_gethex(const unsigned char **ptr, int bits); 167 168 /** Read, unescape, and validate the incoming GDB command */ 169 int esp_gdbstub_read_command(unsigned char **out_cmd, size_t *out_size); 170 171 /** Handle a command received from gdb */ 172 int esp_gdbstub_handle_command(unsigned char *cmd, int len); 173