1/*#
2 *# Copyright 2017, Data61
3 *# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 *# ABN 41 687 119 230.
5 *#
6 *# This software may be distributed and modified according to the terms of
7 *# the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 *# See "LICENSE_BSD2.txt" for details.
9 *#
10 *# @TAG(DATA61_BSD)
11 #*/
12#define ZF_LOG_LEVEL ZF_LOG_ERROR
13#include <endian.h>
14#include <stdbool.h>
15#include <string.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <sel4/sel4.h>
19#include <utils/util.h>
20#include <camkes/gdb/serial.h>
21#include <camkes/gdb/gdb.h>
22
23gdb_buffer_t buf;
24
25
26static void send_message(char *message, int len);
27static int handle_command(char *command, gdb_state_t *gdb_state);
28
29static void GDB_write_register(char *command, gdb_state_t *gdb_state);
30static void GDB_read_memory(char *command);
31static void GDB_write_memory(char *command);
32static void GDB_write_memory_binary(char *command);
33static void GDB_query(char *command);
34static void GDB_set_thread(char *command);
35static void GDB_stop_reason(char *command, gdb_state_t *gdb_state);
36static void GDB_read_general_registers(char *command, gdb_state_t *gdb_state);
37static void GDB_read_register(char *command, gdb_state_t *gdb_state);
38static void GDB_vcont(char *command, gdb_state_t *gdb_state);
39static void GDB_continue(char *command, gdb_state_t *gdb_state);
40static void GDB_step(char *command, gdb_state_t *gdb_state);
41static void GDB_breakpoint(char *command, bool insert, gdb_state_t *gdb_state);
42
43// The ordering of registers as GDB expects them
44typedef enum {
45    GDBRegister_eax =    0,
46    GDBRegister_ecx =    1,
47    GDBRegister_edx =    2,
48    GDBRegister_ebx =    3,
49    GDBRegister_esp =    4,
50    GDBRegister_ebp =    5,
51    GDBRegister_esi =    6,
52    GDBRegister_edi =    7,
53    GDBRegister_eip =    8,
54    GDBRegister_eflags = 9,
55    GDBRegister_cs =     10,
56    GDBRegister_ss =     11,
57    GDBRegister_ds =     12,
58    GDBRegister_es =     13,
59    GDBRegister_fs_base = 14,
60    GDBRegister_gs_base = 15
61} x86_gdb_registers;
62
63
64#define DECLARE_GDB_TO_SEL4(NAME) [GDBRegister_##NAME] = OFFSETOF(seL4_UserContext, NAME)
65
66static size_t gdb_to_seL4_register_index[] = {
67    DECLARE_GDB_TO_SEL4(eax),
68    DECLARE_GDB_TO_SEL4(ecx),
69    DECLARE_GDB_TO_SEL4(edx),
70    DECLARE_GDB_TO_SEL4(ebx),
71    DECLARE_GDB_TO_SEL4(esp),
72    DECLARE_GDB_TO_SEL4(ebp),
73    DECLARE_GDB_TO_SEL4(esi),
74    DECLARE_GDB_TO_SEL4(edi),
75    DECLARE_GDB_TO_SEL4(eip),
76    DECLARE_GDB_TO_SEL4(eflags),
77    DECLARE_GDB_TO_SEL4(fs_base),
78    DECLARE_GDB_TO_SEL4(gs_base),
79    [GDBRegister_cs] = -1,
80    [GDBRegister_ss] = -1,
81    [GDBRegister_ds] = -1,
82    [GDBRegister_es] = -1,
83};
84
85static inline size_t x86_GDB_Register_to_seL4_UserContext(x86_gdb_registers gdb_register)
86{
87
88    size_t index = -1;
89    if (gdb_register < x86_MAX_REGISTERS) {
90        index = gdb_to_seL4_register_index[gdb_register];
91    }
92    if (index != -1) {
93        /* Turn byte offset into index */
94        index /= sizeof(seL4_Word);
95    }
96    return index;
97}
98
99
100// Compute a checksum for the GDB remote protocol
101static unsigned char compute_checksum(char *data, int length)
102{
103    unsigned char checksum = 0;
104    for (int i = 0; i < length; i++) {
105        checksum += (unsigned char) data[i];
106    }
107    return checksum;
108}
109
110static void string_to_word_data(char *string, seL4_Word *dest)
111{
112    char buf[sizeof(seL4_Word) * 2] = {0};
113    strncpy(buf, string, sizeof(seL4_Word) * 2);
114    *dest = (seL4_Word) strtoul((char *) buf, NULL, HEX_STRING);
115}
116
117static int get_breakpoint_format(gdb_BreakpointType type,
118                                 seL4_Word *break_type, seL4_Word *rw)
119{
120    int err = 0;
121    ZF_LOGD("Breakpoint type %d", type);
122    switch (type) {
123#ifdef CONFIG_HARDWARE_DEBUG_API
124    case gdb_HardwareBreakpoint:
125        *break_type = seL4_InstructionBreakpoint;
126        *rw = seL4_BreakOnRead;
127        err = 0;
128        break;
129    case gdb_WriteWatchpoint:
130        *break_type = seL4_DataBreakpoint;
131        *rw = seL4_BreakOnWrite;
132        err = 0;
133        break;
134    case gdb_ReadWatchpoint:
135        *break_type = seL4_DataBreakpoint;
136        *rw = seL4_BreakOnRead;
137        err = 0;
138        break;
139    case gdb_AccessWatchpoint:
140        *break_type = seL4_DataBreakpoint;
141        *rw = seL4_BreakOnReadWrite;
142        err = 0;
143        break;
144#endif /* CONFIG_HARDWARE_DEBUG_API */
145    default:
146        // Unknown type
147        err = 1;
148    }
149    return err;
150}
151
152int gdb_handle_fault(gdb_state_t *gdb_state)
153{
154    char watch_message[50];
155    switch (gdb_state->stop_reason) {
156    case stop_watch:
157        ZF_LOGD("Hit watchpoint");
158        snprintf(watch_message, 49, "T05thread:01;watch:%08x;", gdb_state->stop_watch_addr);
159        send_message(watch_message, 0);
160        break;
161    case stop_hw_break:
162        ZF_LOGD("Hit breakpoint");
163        send_message("T05thread:01;hwbreak:;", 0);
164        break;
165    case stop_step:
166        ZF_LOGD("Did step");
167        send_message("T05thread:01;", 0);
168        break;
169    case stop_sw_break:
170        ZF_LOGD("Software breakpoint");
171        send_message("T05thread:01;swbreak:;", 0);
172        break;
173    case stop_none:
174        ZF_LOGE("Unknown stop reason");
175        send_message("T05thread:01;", 0);
176        break;
177    default:
178        ZF_LOGF("Invalid stop reason.");
179
180    }
181    return 0;
182}
183
184int handle_gdb(gdb_state_t *gdb_state)
185{
186    // Get command and checksum
187    int command_length = buf.checksum_index - 1;
188    char *command_ptr = &buf.data[COMMAND_START];
189    char command[GETCHAR_BUFSIZ + 1] = {0};
190    strncpy(command, command_ptr, command_length);
191    char *checksum = &buf.data[buf.checksum_index + 1];
192    // Calculate checksum of data
193    ZF_LOGD("command: %s", command);
194    unsigned char computed_checksum = compute_checksum(command,
195                                                       command_length);
196    unsigned char received_checksum = (unsigned char) strtol(checksum,
197                                                             NULL,
198                                                             HEX_STRING);
199    if (computed_checksum != received_checksum) {
200        ZF_LOGD("Checksum error, computed %x,"
201                "received %x received_checksum\n",
202                computed_checksum, received_checksum);
203        // Acknowledge packet
204        gdb_printf(GDB_RESPONSE_START GDB_NACK GDB_RESPONSE_END "\n");
205    } else {
206        // Acknowledge packet
207        gdb_printf(GDB_RESPONSE_START GDB_ACK GDB_RESPONSE_END "\n");
208        // Parse the command
209        handle_command(command, gdb_state);
210    }
211
212    return 0;
213}
214
215
216// Send a message with the GDB remote protocol
217static void send_message(char *message, int len)
218{
219    int actual_len = strlen(message);
220    if (len == 0) {
221        len = actual_len + 1;
222        ZF_LOGD("Setting length %p", __builtin_return_address(0));
223    } else if ((actual_len + 1) != len) {
224        ZF_LOGE("message length invalid: %s, %d, %d, %p", message, len, actual_len, __builtin_return_address(0));
225    } else {
226        ZF_LOGD("Correct length %p", __builtin_return_address(0));
227    }
228    ZF_LOGD("message: %s", message);
229    unsigned char checksum = compute_checksum(message, len);
230    gdb_printf(GDB_RESPONSE_START "$%s#%02X\n", message, checksum);
231    gdb_printf(GDB_RESPONSE_END);
232}
233
234
235// GDB read memory command format:
236// m[addr],[length]
237static void GDB_read_memory(char *command)
238{
239    int err;
240    char *token_ptr;
241    // Get args from command
242    char *addr_string = strtok_r(command, "m,", &token_ptr);
243    char *length_string = strtok_r(NULL, ",", &token_ptr);
244    // Convert strings to values
245    seL4_Word addr = (seL4_Word) strtol(addr_string, NULL, HEX_STRING);
246    seL4_Word length = (seL4_Word) strtol(length_string, NULL,
247                                          DEC_STRING);
248    if (length >= MAX_MEM_RANGE) {
249        ZF_LOGE("Invalid read memory length %d", length);
250        send_message("E01", 0);
251        return;
252    }
253
254    if (addr == (seL4_Word) NULL) {
255        ZF_LOGE("Bad memory address 0x%08x", addr);
256        send_message("E01", 0);
257        return;
258    }
259    // Buffer for raw data
260    delegate_mem_range_t data;
261    // Buffer for data formatted as hex string
262    size_t buf_len = CHAR_HEX_SIZE * length + 1;
263    char data_string[buf_len];
264    memset(data_string, 0, buf_len);
265    // Do a read call to the GDB delegate who will read from memory
266    // on our behalf
267    err = delegate_read_memory(addr, length, &data);
268
269    if (err) {
270        send_message("E01", 0);
271    } else {
272        // Format the data
273        for (int i = 0; i < length; i++) {
274            snprintf(&data_string[CHAR_HEX_SIZE * i], 3, "%02x", data.data[i] & 0xff);
275        }
276        send_message(data_string, buf_len);
277    }
278}
279
280// GDB write memory command format:
281// M[addr],[length]:[data]
282static void GDB_write_memory(char *command)
283{
284    char *token_ptr;
285    int err;
286    // Get args from command
287    char *addr_string = strtok_r(command, "M,", &token_ptr);
288    char *length_string = strtok_r(NULL, ",:", &token_ptr);
289    char *data_string = strtok_r(NULL, ":", &token_ptr);
290    // Convert strings to values
291    seL4_Word addr = (seL4_Word) strtol(addr_string, NULL, HEX_STRING);
292    seL4_Word length = (seL4_Word) strtol(length_string, NULL, DEC_STRING);
293
294    if (length >= MAX_MEM_RANGE) {
295        ZF_LOGE("Invalid read memory length %d", length);
296        send_message("E01", 0);
297        return;
298    }
299
300    if (addr == (seL4_Word) NULL) {
301        ZF_LOGE("Bad memory address 0x%08x", addr);
302        send_message("E01", 0);
303        return;
304    }
305    // Buffer for data to be written
306    delegate_mem_range_t data;
307    memset(data.data, 0, length);
308    // Parse data to be written as raw hex
309    for (int i = 0; i < length; i++) {
310        sscanf(data_string, "%2hhx", &data.data[i]);
311        data_string += CHAR_HEX_SIZE;
312    }
313    // Do a write call to the GDB delegate who will write to memory
314    // on our behalf
315    err = delegate_write_memory(addr, length, data);
316    if (err) {
317        send_message("E01", 0);
318    } else {
319        send_message("OK", 0);
320    }
321}
322
323// GDB write binary memory command format:
324// X[addr],[length]:[data]
325static void GDB_write_memory_binary(char *command)
326{
327    char *token_ptr;
328    // Get args from command
329    char *addr_string = strtok_r(command, "X,", &token_ptr);
330    char *length_string = strtok_r(NULL, ",:", &token_ptr);
331    // Convert strings to values
332    seL4_Word addr = strtol(addr_string, NULL, HEX_STRING);
333    seL4_Word length = strtol(length_string, NULL, DEC_STRING);
334    delegate_mem_range_t data = {0};
335    if (length == 0) {
336        ZF_LOGW("Writing 0 length");
337        send_message("OK", 0);
338        return;
339    }
340
341    void *bin_data = strtok_r(NULL, ":", &token_ptr);
342    // Copy the raw data to the expected location
343    if (bin_data == NULL) {
344        ZF_LOGE("data is NULL");
345        send_message("E01", 0);
346        return;
347    }
348    memcpy(&data.data, bin_data, length);
349
350    // Do a write call to the GDB delegate who will write to memory
351    // on our behalf
352    int err = delegate_write_memory(addr, length, data);
353    if (err) {
354        send_message("E01", 0);
355    } else {
356        send_message("OK", 0);
357    }
358}
359
360// GDB query command format:
361// q[query]...
362static void GDB_query(char *command)
363{
364    char *token_ptr;
365    ZF_LOGD("query: %s", command);
366    char *query_type = strtok_r(command, "q:", &token_ptr);
367    if (strcmp("Supported", query_type) == 0) {// Setup argument storage
368        send_message("swbreak+;hwbreak+;PacketSize=100", 0);
369        // Most of these query messages can be ignored for basic functionality
370    } else if (!strcmp("TStatus", query_type)) {
371        send_message("", 0);
372    } else if (!strcmp("TfV", query_type)) {
373        send_message("", 0);
374    } else if (!strcmp("C", query_type)) {
375        send_message("QC1", 0);
376    } else if (!strcmp("Attached", query_type)) {
377        send_message("", 0);
378    } else if (!strcmp("fThreadInfo", query_type)) {
379        send_message("m01", 0);
380    } else if (!strcmp("sThreadInfo", query_type)) {
381        send_message("l", 0);
382    } else if (!strcmp("Symbol", query_type)) {
383        send_message("", 0);
384    } else if (!strcmp("Offsets", query_type)) {
385        send_message("", 0);
386    } else {
387        ZF_LOGD("Unrecognised query command");
388        send_message("E01", 0);
389    }
390}
391
392// Currently ignored
393static void GDB_set_thread(char *command)
394{
395    send_message("OK", 0);
396}
397
398// Respond with the reason the thread being debuged stopped
399static void GDB_stop_reason(char *command, gdb_state_t *gdb_state)
400{
401    switch (gdb_state->stop_reason) {
402    case stop_hw_break:
403        send_message("T05thread:01;hwbreak:;", 0);
404        break;
405    case stop_sw_break:
406        send_message("T05thread:01;swbreak:;", 0);
407        break;
408    default:
409        send_message("T05thread:01;", 0);
410    }
411}
412
413static void GDB_read_general_registers(char *command, gdb_state_t *gdb_state)
414{
415    // seL4_Word registers[x86_MAX_REGISTERS] = {0};
416    seL4_UserContext registers = {0};
417    delegate_read_registers(gdb_state->current_thread_tcb, &registers);
418    int buf_len = x86_MAX_REGISTERS * sizeof(seL4_Word) * CHAR_HEX_SIZE + 1;
419    char data[buf_len];
420    memset(data, 0, buf_len);
421    // Read the register data from the buffer and marshall into a string
422    // to send back to GDB, making sure the byte order is correct
423    for (int i = 0; i < x86_MAX_REGISTERS; i++) {
424        seL4_Word seL4_reg_num = x86_GDB_Register_to_seL4_UserContext(i);
425        seL4_Word value;
426        if (seL4_reg_num == -1) {
427            ZF_LOGW("Invalid register number");
428            value = 0;
429        } else {
430            value = ((seL4_Word *)&registers)[seL4_reg_num];
431        }
432        sprintf(data + sizeof(seL4_Word) * CHAR_HEX_SIZE * i,
433                "%0*x", seL4_WordBits / 4, BSWAP_WORD(value));
434    }
435    send_message(data, buf_len);
436}
437
438// GDB read register command format:
439// p[reg_num]
440static void GDB_read_register(char *command, gdb_state_t *gdb_state)
441{
442    seL4_Word reg;
443    char *token_ptr;
444    // Get which register we want to read
445    char *reg_string = strtok_r(&command[1], "", &token_ptr);
446    if (reg_string == NULL) {
447        send_message("E00", 0);
448        return;
449    }
450    seL4_Word reg_num = strtol(reg_string, NULL, HEX_STRING);
451    if (reg_num >= x86_INVALID_REGISTER) {
452        send_message("E00", 0);
453        return;
454    }
455    // Convert to the register order we have
456    seL4_Word seL4_reg_num = x86_GDB_Register_to_seL4_UserContext(reg_num);
457    if (seL4_reg_num == -1) {
458        ZF_LOGE("Invalid GDB register number: %d", reg_num);
459        send_message("E00", 0);
460        return;
461    } else {
462        delegate_read_register(gdb_state->current_thread_tcb, &reg, seL4_reg_num);
463    }
464    int buf_len = sizeof(seL4_Word) * CHAR_HEX_SIZE + 1;
465    char data[buf_len];
466    data[buf_len - 1] = 0;
467    // Send the register contents as a string, making sure
468    // the byte order is correct
469    sprintf(data, "%0*x", seL4_WordBits / 4, BSWAP_WORD(reg));
470    send_message(data, buf_len);
471}
472
473static void GDB_write_general_registers(char *command, gdb_state_t *gdb_state)
474{
475    char *token_ptr;
476    // Get args from command
477    char *data_string = strtok_r(&command[1], "", &token_ptr);
478    // Truncate data to register length
479    int num_regs = sizeof(seL4_UserContext) / sizeof(seL4_Word);
480    int num_regs_data = (strlen(data_string)) / (sizeof(seL4_Word) * 2);
481    if (num_regs_data > num_regs) {
482        num_regs_data = num_regs;
483    }
484    // Marshall data
485    seL4_UserContext data;
486    for (int i = 0; i < num_regs_data; i++) {
487        seL4_Word seL4_register_number = x86_GDB_Register_to_seL4_UserContext(i);
488        string_to_word_data(&data_string[2 * i * sizeof(seL4_Word)], ((seL4_Word *)&data) + seL4_register_number);
489        ((seL4_Word *)&data)[seL4_register_number] = BSWAP_WORD(((seL4_Word *)&data)[seL4_register_number]);
490    }
491    delegate_write_registers(gdb_state->current_thread_tcb, data, num_regs_data);
492    gdb_state->current_pc = data.eip;
493    send_message("OK", 0);
494}
495
496// GDB write register command format:
497// P[reg_num]=[data]
498static void GDB_write_register(char *command, gdb_state_t *gdb_state)
499{
500    char *token_ptr;
501    // Parse arguments
502    char *reg_string = strtok_r(&command[1], "=", &token_ptr);
503    char *data_string = strtok_r(NULL, "", &token_ptr);
504    // If valid register, do something, otherwise reply OK
505    seL4_Word reg_num = strtol(reg_string, NULL, HEX_STRING);
506    if (reg_num < x86_GDB_REGISTERS) {
507        // Convert arguments
508        seL4_Word data;
509        string_to_word_data(data_string, &data);
510        data = BSWAP_WORD(data);
511        // Convert to register order we have
512        seL4_Word seL4_reg_num = x86_GDB_Register_to_seL4_UserContext(reg_num);
513        if (seL4_reg_num == -1) {
514            ZF_LOGE("Invalid GDB register number: %d, ignoring write", reg_num);
515        } else {
516            delegate_write_register(gdb_state->current_thread_tcb, data, seL4_reg_num);
517            if (reg_num == GDBRegister_eip) {
518                gdb_state->current_pc = data;
519            }
520        }
521    }
522    send_message("OK", 0);
523}
524
525static void GDB_vcont(char *command, gdb_state_t *gdb_state)
526{
527    if (!strncmp(&command[7], "c", 1)) {
528        GDB_continue(command, gdb_state);
529    } else if (!strncmp(&command[7], "s", 1)) {
530        GDB_step(command, gdb_state);
531    } else {
532        send_message("", 0);
533    }
534}
535
536static void GDB_continue(char *command, gdb_state_t *gdb_state)
537{
538    int err = 0;
539    // If it's not a step exception, then we can resume
540    // Otherwise, just resume by responding on the step fault
541    if (gdb_state->current_thread_step_mode && gdb_state->stop_reason != stop_step) {
542        err = delegate_resume(gdb_state->current_thread_tcb);
543    }
544    gdb_state->current_thread_step_mode = false;
545    if (err) {
546        ZF_LOGE("delegate resume failed\n");
547        send_message("E01", 0);
548    }
549
550    gdb_state->sem_post();
551}
552
553static void GDB_step(char *command, gdb_state_t *gdb_state)
554{
555    int err = 0;
556    // If it's not a step exception, then we need to set stepping
557    // Otherwise, just step by responding on the step fault
558    if (!gdb_state->current_thread_step_mode && gdb_state->stop_reason != stop_step) {
559        ZF_LOGD("Entering step mode");
560        err = delegate_step(gdb_state->current_thread_tcb);
561    } else {
562        ZF_LOGD("Already in step mode");
563    }
564    gdb_state->current_thread_step_mode = true;
565    if (err) {
566        ZF_LOGE("delegate step failed\n");
567        send_message("E01", 0);
568    }
569    gdb_state->sem_post();
570}
571
572// GDB insert breakpoint command format:
573// Z[type],[addr],[size]
574static void GDB_breakpoint(char *command, bool insert, gdb_state_t *gdb_state)
575{
576    char *token_ptr;
577    seL4_Word break_type;
578    seL4_Word rw;
579    // Parse arguments
580    char *type_string = strtok_r(&command[1], ",", &token_ptr);
581    char *addr_string = strtok_r(NULL, ",", &token_ptr);
582    char *size_string = strtok_r(NULL, ",", &token_ptr);
583    // Convert strings to values
584    seL4_Word type = (seL4_Word) strtol(type_string, NULL, HEX_STRING);
585    seL4_Word addr = (seL4_Word) strtol(addr_string, NULL, HEX_STRING);
586    seL4_Word size = (seL4_Word) strtol(size_string, NULL, HEX_STRING);
587    ZF_LOGD("Breakpoint: %s, type: %d, addr: 0x%x, size %d", insert ? "'insert'" : "'remove'", type, addr, size);
588    // If this is a software breakpoint, then we will ignore
589    // By ignoring this command, GDB will just use the read and write
590    // memory commands to set a breakpoint itself. This can later be changed
591    // if setting software breakpoints becomes supported by the kernel.
592    if (type == gdb_SoftwareBreakpoint) {
593        send_message("", 0);
594    } else {
595        int err;
596        err = get_breakpoint_format(type, &break_type, &rw);
597        if (!err) {
598            // Hardware breakpoints can only be size 0
599            if (type == gdb_HardwareBreakpoint) {
600                size = 0;
601            }
602            if (insert) {
603                err = delegate_insert_break(gdb_state->current_thread_tcb, break_type,
604                                            addr, size,
605                                            rw);
606            } else {
607                err = delegate_remove_break(gdb_state->current_thread_tcb, break_type,
608                                            addr, size,
609                                            rw);
610            }
611        }
612        if (err) {
613            ZF_LOGE("Couldn't set breakpoint");
614            send_message("E01", 0);
615        } else {
616            send_message("OK", 0);
617        }
618    }
619}
620
621
622static int handle_command(char *command, gdb_state_t *gdb_state)
623{
624    switch (command[0]) {
625    case '!':
626        // Enable extended mode
627        ZF_LOGE("Not implemented: enable extended mode");
628        break;
629    case '?':
630        // Halt reason
631        GDB_stop_reason(command, gdb_state);
632        break;
633    case 'A':
634        // Argv
635        ZF_LOGE("Not implemented: argv");
636        break;
637    case 'b':
638        if (command[1] == 'c') {
639            // Backward continue
640            ZF_LOGE("Not implemented: backward continue");
641            break;
642        } else if (command[1] == 's') {
643            // Backward step
644            ZF_LOGE("Not implemented: backward step");
645            break;
646        } else {
647            // Set baud rate
648            ZF_LOGE("Not implemented: Set baud rate");
649            break;
650        }
651    case 'c':
652        // Continue
653        ZF_LOGD("Continuing");
654        GDB_continue(command, gdb_state);
655        break;
656    case 'C':
657        // Continue with signal
658        ZF_LOGE("Not implemented: continue with signal");
659        break;
660    case 'd':
661        ZF_LOGE("Not implemented: toggle debug");
662        break;
663    case 'D':
664        ZF_LOGE("Not implemented: detach");
665        break;
666    case 'F':
667        ZF_LOGE("Not implemented: file IO");
668        break;
669    case 'g':
670        ZF_LOGD("Reading general registers");
671        GDB_read_general_registers(command, gdb_state);
672        break;
673    case 'G':
674        ZF_LOGD("Write general registers");
675        GDB_write_general_registers(command, gdb_state);
676        break;
677    case 'H':
678        ZF_LOGD("Set thread ignored");
679        GDB_set_thread(command);
680        break;
681    case 'i':
682        ZF_LOGE("Not implemented: cycle step");
683        break;
684    case 'I':
685        ZF_LOGE("Not implemented: signal + cycle step");
686        break;
687    case 'k':
688        ZF_LOGE("Kill called.  Program will not finish");
689        break;
690    case 'm':
691        ZF_LOGD("Reading memory");
692        GDB_read_memory(command);
693        break;
694    case 'M':
695        ZF_LOGD("Writing memory");
696        GDB_write_memory(command);
697        break;
698    case 'p':
699        ZF_LOGD("Read register");
700        GDB_read_register(command, gdb_state);
701        break;
702    case 'P':
703        ZF_LOGD("Write register");
704        GDB_write_register(command, gdb_state);
705        break;
706    case 'q':
707        ZF_LOGD("Query");
708        GDB_query(command);
709        break;
710    case 'Q':
711        ZF_LOGE("Not implemented: set");
712        break;
713    case 'r':
714        ZF_LOGE("Not implemented: reset");
715        break;
716    case 'R':
717        ZF_LOGE("Not implemented: restart");
718        break;
719    case 's':
720        ZF_LOGD("Stepping");
721        GDB_step(command, gdb_state);
722        break;
723    case 'S':
724        ZF_LOGE("Not implemented: step + signal");
725        break;
726    case 't':
727        ZF_LOGE("Not implemented: search");
728        break;
729    case 'T':
730        ZF_LOGE("Not implemented: check thread");
731        break;
732    case 'v':
733        if (!strncmp(&command[1], "Cont?", 5)) {
734            send_message("vCont;c;s", 0);
735        } else if (!strncmp(&command[1], "Cont", 4)) {
736            GDB_vcont(command, gdb_state);
737        } else if (!strncmp(&command[1], "Kill", 4)) {
738            send_message("", 0);
739        } else if (!strncmp(&command[1], "MustReplyEmpty", 14)) {
740            send_message("", 0);
741        } else {
742            ZF_LOGE("Command not supported");
743        }
744        break;
745    case 'X':
746        ZF_LOGD("Writing memory, binary");
747        GDB_write_memory_binary(command);
748        break;
749    case 'z':
750        ZF_LOGD("Removing breakpoint");
751        GDB_breakpoint(command, false, gdb_state);
752        break;
753    case 'Z':
754        ZF_LOGD("Inserting breakpoint");
755        GDB_breakpoint(command, true, gdb_state);
756        break;
757    default:
758        ZF_LOGE("Unknown command");
759    }
760
761    return 0;
762}
763
764