1 | /* |
---|
2 | * Copyright (c) 1995, 1996 Cygnus Support |
---|
3 | * |
---|
4 | * The authors hereby grant permission to use, copy, modify, distribute, |
---|
5 | * and license this software and its documentation for any purpose, provided |
---|
6 | * that existing copyright notices are retained in all copies and that this |
---|
7 | * notice is included verbatim in any distributions. No written agreement, |
---|
8 | * license, or royalty fee is required for any of the authorized uses. |
---|
9 | * Modifications to this software may be copyrighted by their authors |
---|
10 | * and need not follow the licensing terms described here, provided that |
---|
11 | * the new terms are clearly indicated on the first page of each file where |
---|
12 | * they apply. |
---|
13 | */ |
---|
14 | |
---|
15 | /* |
---|
16 | * A debug packet whose contents are <data> looks like: |
---|
17 | * |
---|
18 | * $ <data> # CSUM1 CSUM2 |
---|
19 | * |
---|
20 | * <data> must be ASCII alphanumeric and cannot include characters |
---|
21 | * '$' or '#'. If <data> starts with two characters followed by |
---|
22 | * ':', then the existing stubs interpret this as a sequence number. |
---|
23 | * |
---|
24 | * CSUM1 and CSUM2 are ascii hex representation of an 8-bit |
---|
25 | * checksum of <data>, the most significant nibble is sent first. |
---|
26 | * the hex digits 0-9,a-f are used. |
---|
27 | * |
---|
28 | * We respond with: |
---|
29 | * |
---|
30 | * + - if CSUM is correct and ready for next packet |
---|
31 | * - - if CSUM is incorrect |
---|
32 | * |
---|
33 | * <data> is as follows: |
---|
34 | * Most values are encoded in ascii hex digits. |
---|
35 | */ |
---|
36 | |
---|
37 | #include "debug.h" |
---|
38 | #include <signal.h> |
---|
39 | |
---|
40 | /* |
---|
41 | * buffers that hold the packets while they're being constructed. |
---|
42 | */ |
---|
43 | char packet_in_buf[BUFMAX]; |
---|
44 | char packet_out_buf[BUFMAX]; |
---|
45 | int packet_index; |
---|
46 | |
---|
47 | /* |
---|
48 | * indicate to caller of mem2hex or hex2mem that there has been an error. |
---|
49 | * 0 means ok, 1 means error |
---|
50 | */ |
---|
51 | volatile int mem_err = 0; |
---|
52 | |
---|
53 | /* |
---|
54 | * 1 means print debugging messages from the target, 0 means be quiet. This is |
---|
55 | * changed by gdb_debug(). |
---|
56 | */ |
---|
57 | int remote_debug = 0; |
---|
58 | |
---|
59 | /* |
---|
60 | * indicate whether the debug vectors ahave been initialized |
---|
61 | * 0 means not yet, 1 means yep, it's ready. |
---|
62 | */ |
---|
63 | int initialized = 0; |
---|
64 | |
---|
65 | /* |
---|
66 | * These variables are instantialted in the GDB stub code. |
---|
67 | */ |
---|
68 | |
---|
69 | /* this is a list of signal to exception mappings. */ |
---|
70 | extern struct trap_info hard_trap_info[]; |
---|
71 | |
---|
72 | /* this is a memory fault exception handler, used by mem2hex & hex2mem */ |
---|
73 | extern void set_mem_fault_trap(); |
---|
74 | |
---|
75 | /* |
---|
76 | * print debugging messages. This uses print, rather than one of the |
---|
77 | * stdio routines, cause if there are stack or memory problems, the |
---|
78 | * stdio routines don't work. |
---|
79 | * params are the debug level, and the string to print |
---|
80 | * it doesn't return anything. |
---|
81 | */ |
---|
82 | void |
---|
83 | debuglog(int level, char *msg) |
---|
84 | { |
---|
85 | char *p; |
---|
86 | unsigned char buf[BUFMAX]; |
---|
87 | char newmsg[BUFMAX]; |
---|
88 | int i; |
---|
89 | |
---|
90 | if (level > remote_debug) |
---|
91 | return; |
---|
92 | |
---|
93 | if ((level <0) || (level > 100)) { |
---|
94 | print ("ERROR: debug print level out of range"); |
---|
95 | return; |
---|
96 | } |
---|
97 | |
---|
98 | /* convert some characters so it'll look right in the log */ |
---|
99 | p = newmsg; |
---|
100 | for (i = 0 ; msg[i] != '\0'; i++) { |
---|
101 | if (i > BUFMAX) |
---|
102 | print ("\r\nERROR: Debug message too long\r\n"); |
---|
103 | switch (msg[i]) { |
---|
104 | case '\n': /* newlines */ |
---|
105 | *p++ = '\\'; |
---|
106 | *p++ = 'n'; |
---|
107 | continue; |
---|
108 | case '\r': /* carriage returns */ |
---|
109 | *p++ = '\\'; |
---|
110 | *p++ = 'r'; |
---|
111 | continue; |
---|
112 | case '\033': /* escape */ |
---|
113 | *p++ = '\\'; |
---|
114 | *p++ = 'e'; |
---|
115 | continue; |
---|
116 | case '\t': /* tab */ |
---|
117 | *p++ = '\\'; |
---|
118 | *p++ = 't'; |
---|
119 | continue; |
---|
120 | case '\b': /* backspace */ |
---|
121 | *p++ = '\\'; |
---|
122 | *p++ = 'b'; |
---|
123 | continue; |
---|
124 | default: /* no change */ |
---|
125 | *p++ = msg[i]; |
---|
126 | } |
---|
127 | |
---|
128 | if (msg[i] < 26) { /* modify control characters */ |
---|
129 | *p++ = '^'; |
---|
130 | *p++ = msg[i] + 'A'; |
---|
131 | continue; |
---|
132 | } |
---|
133 | if (msg[i] >= 127) { /* modify control characters */ |
---|
134 | *p++ = '!'; |
---|
135 | *p++ = msg[i] + 'A'; |
---|
136 | continue; |
---|
137 | } |
---|
138 | } |
---|
139 | *p = '\0'; /* terminate the string */ |
---|
140 | print (newmsg); |
---|
141 | print ("\r\n"); |
---|
142 | } |
---|
143 | |
---|
144 | /* |
---|
145 | * convert an ascii hex digit to a number. |
---|
146 | * param is hex digit. |
---|
147 | * returns a decimal digit. |
---|
148 | */ |
---|
149 | int |
---|
150 | hex2digit (int digit) |
---|
151 | { |
---|
152 | if (digit == 0) |
---|
153 | return 0; |
---|
154 | |
---|
155 | if (digit >= '0' && digit <= '9') |
---|
156 | return digit - '0'; |
---|
157 | if (digit >= 'a' && digit <= 'f') |
---|
158 | return digit - 'a' + 10; |
---|
159 | if (digit >= 'A' && digit <= 'F') |
---|
160 | return digit - 'A' + 10; |
---|
161 | |
---|
162 | /* shouldn't ever get this far */ |
---|
163 | return ERROR; |
---|
164 | } |
---|
165 | |
---|
166 | /* |
---|
167 | * convert number NIB to a hex digit. |
---|
168 | * param is a decimal digit. |
---|
169 | * returns a hex digit. |
---|
170 | */ |
---|
171 | char |
---|
172 | digit2hex(int digit) |
---|
173 | { |
---|
174 | if (digit < 10) |
---|
175 | return '0' + digit; |
---|
176 | else |
---|
177 | return 'a' + digit - 10; |
---|
178 | } |
---|
179 | |
---|
180 | /* |
---|
181 | * Convert the memory pointed to by mem into hex, placing result in buf. |
---|
182 | * Return a pointer to the last char put in buf (null), in case of mem fault, |
---|
183 | * return 0. |
---|
184 | * If MAY_FAULT is non-zero, then we will handle memory faults by returning |
---|
185 | * a 0, else treat a fault like any other fault in the stub. |
---|
186 | */ |
---|
187 | unsigned char * |
---|
188 | mem2hex(unsigned char *mem, unsigned char *buf, int count, int may_fault) |
---|
189 | { |
---|
190 | unsigned char ch; |
---|
191 | |
---|
192 | DEBUG (1, "In mem2hex"); |
---|
193 | |
---|
194 | set_mem_fault_trap(MAY_FAULT); |
---|
195 | |
---|
196 | while (count-- > 0) { |
---|
197 | ch = *mem++; |
---|
198 | if (mem_err) { |
---|
199 | DEBUG (1, "memory fault in mem2hex"); |
---|
200 | return 0; |
---|
201 | } |
---|
202 | *buf++ = digit2hex(ch >> 4); |
---|
203 | *buf++ = digit2hex(ch & 0xf); |
---|
204 | } |
---|
205 | |
---|
206 | *buf = 0; |
---|
207 | |
---|
208 | set_mem_fault_trap(OK); |
---|
209 | |
---|
210 | return buf; |
---|
211 | } |
---|
212 | |
---|
213 | /* |
---|
214 | * Convert the hex array pointed to by buf into binary to be placed in mem |
---|
215 | * return a pointer to the character AFTER the last byte written |
---|
216 | */ |
---|
217 | unsigned char * |
---|
218 | hex2mem(unsigned char *buf, unsigned char *mem, int count, int may_fault) |
---|
219 | { |
---|
220 | int i; |
---|
221 | unsigned char ch; |
---|
222 | |
---|
223 | DEBUG (1, "In hex2mem"); |
---|
224 | |
---|
225 | set_mem_fault_trap(may_fault); |
---|
226 | |
---|
227 | for (i=0; i<count; i++) { |
---|
228 | ch = hex2digit(*buf++) << 4; |
---|
229 | ch |= hex2digit(*buf++); |
---|
230 | *mem++ = ch; |
---|
231 | if (mem_err) |
---|
232 | return 0; |
---|
233 | } |
---|
234 | |
---|
235 | set_mem_fault_trap(0); |
---|
236 | |
---|
237 | return mem; |
---|
238 | } |
---|
239 | |
---|
240 | /* |
---|
241 | * while we find nice hex chars, build an int. |
---|
242 | * param is a pointer to the string. |
---|
243 | * returns the int in the param field, and the number of chars processed. |
---|
244 | */ |
---|
245 | int |
---|
246 | hex2int (char **ptr, int *intValue) |
---|
247 | { |
---|
248 | int numChars = 0; |
---|
249 | int hexValue; |
---|
250 | |
---|
251 | *intValue = 0; |
---|
252 | |
---|
253 | while (**ptr) |
---|
254 | { |
---|
255 | hexValue = hex2digit(**ptr); |
---|
256 | if (hexValue < 0) |
---|
257 | break; |
---|
258 | |
---|
259 | *intValue = (*intValue << 4) | hexValue; |
---|
260 | numChars ++; |
---|
261 | (*ptr)++; |
---|
262 | } |
---|
263 | return (numChars); |
---|
264 | } |
---|
265 | |
---|
266 | /* |
---|
267 | * Scan for the sequence $<data>#<checksum> |
---|
268 | */ |
---|
269 | void |
---|
270 | getpacket(unsigned char *buffer) |
---|
271 | { |
---|
272 | unsigned char checksum; |
---|
273 | unsigned char xmitcsum; |
---|
274 | int i; |
---|
275 | int count; |
---|
276 | unsigned char ch; |
---|
277 | |
---|
278 | do { |
---|
279 | /* wait around for the start character, ignore all other characters */ |
---|
280 | while ((ch = (inbyte() & 0x7f)) != '$') ; |
---|
281 | |
---|
282 | checksum = 0; |
---|
283 | xmitcsum = -1; |
---|
284 | |
---|
285 | count = 0; |
---|
286 | |
---|
287 | /* now, read until a # or end of buffer is found */ |
---|
288 | while (count < BUFMAX) { |
---|
289 | ch = inbyte() & 0x7f; |
---|
290 | if (ch == '#') |
---|
291 | break; |
---|
292 | checksum = checksum + ch; |
---|
293 | buffer[count] = ch; |
---|
294 | count = count + 1; |
---|
295 | } |
---|
296 | |
---|
297 | if (count >= BUFMAX) |
---|
298 | continue; |
---|
299 | |
---|
300 | buffer[count] = 0; |
---|
301 | |
---|
302 | if (ch == '#') { |
---|
303 | xmitcsum = hex2digit(inbyte() & 0x7f) << 4; |
---|
304 | xmitcsum |= hex2digit(inbyte() & 0x7f); |
---|
305 | #if 1 |
---|
306 | /* Humans shouldn't have to figure out checksums to type to it. */ |
---|
307 | outbyte ('+'); |
---|
308 | return; |
---|
309 | #endif |
---|
310 | if (checksum != xmitcsum) |
---|
311 | outbyte('-'); /* failed checksum */ |
---|
312 | else { |
---|
313 | outbyte('+'); /* successful transfer */ |
---|
314 | /* if a sequence char is present, reply the sequence ID */ |
---|
315 | if (buffer[2] == ':') { |
---|
316 | outbyte(buffer[0]); |
---|
317 | outbyte(buffer[1]); |
---|
318 | /* remove sequence chars from buffer */ |
---|
319 | count = strlen(buffer); |
---|
320 | for (i=3; i <= count; i++) |
---|
321 | buffer[i-3] = buffer[i]; |
---|
322 | } |
---|
323 | } |
---|
324 | } |
---|
325 | } |
---|
326 | while (checksum != xmitcsum); |
---|
327 | } |
---|
328 | |
---|
329 | /* |
---|
330 | * Send the packet in buffer. |
---|
331 | */ |
---|
332 | void |
---|
333 | putpacket(unsigned char *buffer) |
---|
334 | { |
---|
335 | unsigned char checksum; |
---|
336 | int count; |
---|
337 | unsigned char ch; |
---|
338 | |
---|
339 | /* $<packet info>#<checksum>. */ |
---|
340 | do { |
---|
341 | outbyte('$'); |
---|
342 | checksum = 0; |
---|
343 | count = 0; |
---|
344 | |
---|
345 | while (ch = buffer[count]) { |
---|
346 | if (! outbyte(ch)) |
---|
347 | return; |
---|
348 | checksum += ch; |
---|
349 | count += 1; |
---|
350 | } |
---|
351 | |
---|
352 | outbyte('#'); |
---|
353 | outbyte(digit2hex(checksum >> 4)); |
---|
354 | outbyte(digit2hex(checksum & 0xf)); |
---|
355 | |
---|
356 | } |
---|
357 | while ((inbyte() & 0x7f) != '+'); |
---|
358 | } |
---|
359 | |
---|
360 | /* |
---|
361 | * |
---|
362 | */ |
---|
363 | void |
---|
364 | gdb_event_loop(int sigval, unsigned long *registers) |
---|
365 | { |
---|
366 | int addr; |
---|
367 | int length; |
---|
368 | unsigned char *ptr; |
---|
369 | ptr = packet_out_buf; |
---|
370 | |
---|
371 | DEBUG (1, "In gdb_event_loop"); |
---|
372 | |
---|
373 | while (1) { |
---|
374 | packet_out_buf[0] = 0; |
---|
375 | |
---|
376 | getpacket(packet_in_buf); |
---|
377 | ptr = &packet_in_buf[1]; |
---|
378 | |
---|
379 | switch (packet_in_buf[0]) { |
---|
380 | case '?': /* get the last known signal */ |
---|
381 | gdb_last_signal(sigval); |
---|
382 | break; |
---|
383 | |
---|
384 | case 'd': /* toggle debug messages from the stub */ |
---|
385 | gdb_toggle(); |
---|
386 | break; |
---|
387 | |
---|
388 | case 'g': /* return the value of the CPU registers */ |
---|
389 | target_read_registers(registers); |
---|
390 | break; |
---|
391 | |
---|
392 | case 'G': /* set the value of the CPU registers - return OK */ |
---|
393 | target_write_registers(registers); |
---|
394 | break; |
---|
395 | |
---|
396 | case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ |
---|
397 | /* Try to read %x,%x. */ |
---|
398 | if (hex2int((char **)&ptr, &addr) |
---|
399 | && *ptr++ == ',' |
---|
400 | && hex2int((char **)&ptr, &length)) { |
---|
401 | gdb_read_memory(addr, length); |
---|
402 | } else { |
---|
403 | make_return_packet(1); |
---|
404 | } |
---|
405 | break; |
---|
406 | |
---|
407 | case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ |
---|
408 | /* Try to read '%x,%x:'. */ |
---|
409 | if (hex2int((char **)&ptr, &addr) |
---|
410 | && *ptr++ == ',' |
---|
411 | && hex2int((char **)&ptr, &length) |
---|
412 | && *ptr++ == ':') { |
---|
413 | gdb_write_memory (addr, length, ptr); |
---|
414 | } else { |
---|
415 | make_return_packet(2); |
---|
416 | } |
---|
417 | break; |
---|
418 | |
---|
419 | case 'c': /* cAA..AA Continue at address AA..AA(optional) */ |
---|
420 | /* try to read optional parameter, pc unchanged if no parm */ |
---|
421 | if (hex2int((char **)&ptr, &addr)) { |
---|
422 | write_pc(registers, addr); |
---|
423 | } |
---|
424 | |
---|
425 | /* |
---|
426 | * we need to flush the instruction cache here, as we may have |
---|
427 | * deposited a breakpoint, and the icache probably has no way of |
---|
428 | * knowing that a data ref to some location may have changed |
---|
429 | * something that is in the instruction cache. |
---|
430 | */ |
---|
431 | |
---|
432 | flush_i_cache(); |
---|
433 | /* by returning, we pick up execution where we left off */ |
---|
434 | return; |
---|
435 | |
---|
436 | /* kill the program */ |
---|
437 | case 'k' : |
---|
438 | gdb_kill(); |
---|
439 | break; |
---|
440 | case 'r': /* Reset */ |
---|
441 | target_reset(); |
---|
442 | break; |
---|
443 | } /* switch */ |
---|
444 | |
---|
445 | /* reply to the request */ |
---|
446 | putpacket(packet_out_buf); |
---|
447 | } |
---|
448 | DEBUG (1, "Leaving handle_exception()"); |
---|
449 | } |
---|
450 | |
---|
451 | /* Convert the hardware trap type code to a unix signal number. */ |
---|
452 | |
---|
453 | int |
---|
454 | computeSignal(int tt) |
---|
455 | { |
---|
456 | struct trap_info *ht; |
---|
457 | |
---|
458 | for (ht = hard_trap_info; ht->tt && ht->signo; ht++) |
---|
459 | if (ht->tt == tt) |
---|
460 | return ht->signo; |
---|
461 | |
---|
462 | return SIGHUP; /* default for things we don't know about */ |
---|
463 | } |
---|
464 | |
---|
465 | /* |
---|
466 | * Set up exception handlers for tracing and breakpoints |
---|
467 | */ |
---|
468 | void |
---|
469 | set_debug_traps() |
---|
470 | { |
---|
471 | struct trap_info *ht; |
---|
472 | |
---|
473 | DEBUG (1, "Entering set_debug_traps()"); |
---|
474 | |
---|
475 | if (hard_trap_info->tt == 0) { |
---|
476 | print ("ERROR: ARG#$@%^&*!! no hard trap info!!\r\n"); |
---|
477 | } |
---|
478 | |
---|
479 | for (ht = hard_trap_info; ht->tt && ht->signo; ht++) { |
---|
480 | exception_handler(ht->tt, (unsigned long)default_trap_hook); |
---|
481 | } |
---|
482 | |
---|
483 | /* In case GDB is started before us, ack any packets (presumably |
---|
484 | "$?#xx") sitting there. */ |
---|
485 | |
---|
486 | outbyte ('+'); |
---|
487 | initialized = 1; |
---|
488 | |
---|
489 | DEBUG (1, "Leaving set_debug_traps()"); |
---|
490 | } |
---|
491 | |
---|
492 | /* |
---|
493 | * make a return packet. |
---|
494 | * param is the value to return. |
---|
495 | * 0 = OK, any other value is converted to a two digit hex number. |
---|
496 | * returns a string or "OK" or "ENN", where NN is the error number. Each N |
---|
497 | * is an ASCII encoded hex digit. |
---|
498 | */ |
---|
499 | char * |
---|
500 | make_return_packet(int val) |
---|
501 | { |
---|
502 | if (val == 0) { |
---|
503 | packet_out_buf[0] = 'O'; |
---|
504 | packet_out_buf[1] = 'K'; |
---|
505 | packet_out_buf[2] = 0; |
---|
506 | } else { |
---|
507 | packet_out_buf[0] = 'E'; |
---|
508 | packet_out_buf[1] = digit2hex((val >> 4) & 0xf); |
---|
509 | packet_out_buf[2] = digit2hex(val & 0xf); |
---|
510 | packet_out_buf[3] = 0; |
---|
511 | } |
---|
512 | return(packet_out_buf); |
---|
513 | } |
---|
514 | |
---|
515 | /* |
---|
516 | * g - read registers. |
---|
517 | * no params. |
---|
518 | * returns a vector of words, size is NUM_REGS. |
---|
519 | */ |
---|
520 | char * |
---|
521 | gdb_read_registers() |
---|
522 | { |
---|
523 | } |
---|
524 | |
---|
525 | /* |
---|
526 | * G - write registers. |
---|
527 | * param is a vector of words, size is NUM_REGS. |
---|
528 | * returns an OK or an error number. |
---|
529 | */ |
---|
530 | char * |
---|
531 | gdb_write_registers(char *regs) |
---|
532 | { |
---|
533 | } |
---|
534 | |
---|
535 | /* |
---|
536 | * m - read memory. |
---|
537 | * params are the address to start the read at and the number of |
---|
538 | * bytes to read. |
---|
539 | * returns a vector of nbytes or an error number. |
---|
540 | * Can be fewer bytes than requested if able to read only part of the |
---|
541 | * data. |
---|
542 | */ |
---|
543 | char * |
---|
544 | gdb_read_memory(long addr, int nbytes) |
---|
545 | { |
---|
546 | if (mem2hex((char *)addr, packet_out_buf, nbytes, MAY_FAULT)) |
---|
547 | return(packet_out_buf); |
---|
548 | else { |
---|
549 | return(make_return_packet(3)); |
---|
550 | } |
---|
551 | } |
---|
552 | |
---|
553 | /* |
---|
554 | * M write memory |
---|
555 | * params are the address to start writing to, the number of |
---|
556 | * bytes to write, and the new values of the bytes. |
---|
557 | * returns an OK or an error number. |
---|
558 | */ |
---|
559 | char * |
---|
560 | gdb_write_memory(long addr, int nbytes, char *mem) |
---|
561 | { |
---|
562 | if (hex2mem(mem, (char *)addr, nbytes, MAY_FAULT)) |
---|
563 | return(make_return_packet(OK)); |
---|
564 | else { |
---|
565 | return(make_return_packet(3)); |
---|
566 | } |
---|
567 | } |
---|
568 | |
---|
569 | /* |
---|
570 | * c - continue at address. |
---|
571 | * param is the address to start at, and an optional signal. If |
---|
572 | * sig is zero, then ignore it. |
---|
573 | * returns an OK or an error number. |
---|
574 | */ |
---|
575 | char * |
---|
576 | gdb_continue(int sig, long addr) |
---|
577 | { |
---|
578 | } |
---|
579 | |
---|
580 | /* |
---|
581 | * s - step instruction(s) |
---|
582 | * param is the address to start at, and an optional signal. If |
---|
583 | * sig is zero, then ignore it. |
---|
584 | * returns an OK or an error number. |
---|
585 | */ |
---|
586 | char * |
---|
587 | gdb_step(int sig, long addr) |
---|
588 | { |
---|
589 | } |
---|
590 | |
---|
591 | /* |
---|
592 | * k - kill program. |
---|
593 | * no params. |
---|
594 | * returns an OK or an error number. |
---|
595 | */ |
---|
596 | char * |
---|
597 | gdb_kill() |
---|
598 | { |
---|
599 | /* generically, we can't do anything for this command */ |
---|
600 | return(make_return_packet(OK)); |
---|
601 | } |
---|
602 | |
---|
603 | /* |
---|
604 | * ? - last signal. |
---|
605 | * no params. |
---|
606 | * returns the last signal number. |
---|
607 | */ |
---|
608 | char * |
---|
609 | gdb_last_signal(int val) |
---|
610 | { |
---|
611 | DEBUG (1, "Entering gdb_last_signal()"); |
---|
612 | |
---|
613 | packet_out_buf[0] = 'S'; |
---|
614 | packet_out_buf[1] = digit2hex(val >> 4); |
---|
615 | packet_out_buf[2] = digit2hex(val & 0xf); |
---|
616 | packet_out_buf[3] = 0; |
---|
617 | |
---|
618 | DEBUG (1, "Leaving gdb_last_signal()"); |
---|
619 | return (packet_out_buf); |
---|
620 | } |
---|
621 | |
---|
622 | /* |
---|
623 | * b - change baud rate. |
---|
624 | * param is the new baudrate |
---|
625 | * returns the baud rate. |
---|
626 | */ |
---|
627 | char * |
---|
628 | gdb_baudrate(int baud) |
---|
629 | { |
---|
630 | /* generically, we can't do anything for this command */ |
---|
631 | return(make_return_packet(OK)); |
---|
632 | } |
---|
633 | |
---|
634 | /* |
---|
635 | * T - dump state. |
---|
636 | * no params. |
---|
637 | * returns the signal number, the registers, the thread ID, and |
---|
638 | * possible extensions in a vector that looks like: |
---|
639 | * TAAn...:r...;n...:r...;n...:r...; where: |
---|
640 | * AA = signal number |
---|
641 | * n... = register number (hex) |
---|
642 | * r... = register contents |
---|
643 | * n... = `thread' |
---|
644 | * r... = thread process ID. This is a hex integer. |
---|
645 | * n... = other string not starting with valid hex digit. |
---|
646 | * gdb should ignore this n,r pair and go on to |
---|
647 | * the next. This way we can extend the protocol. |
---|
648 | */ |
---|
649 | char * |
---|
650 | gdb_dump_state() |
---|
651 | { |
---|
652 | } |
---|
653 | |
---|
654 | /* |
---|
655 | * D - host requests a detach |
---|
656 | * no params. |
---|
657 | * returns either a S, T, W, or X command. |
---|
658 | * returns an OK or an error number. |
---|
659 | */ |
---|
660 | char * |
---|
661 | gdb_detach() |
---|
662 | { |
---|
663 | } |
---|
664 | |
---|
665 | /* |
---|
666 | * H - set thread. |
---|
667 | * params are the command to execute and the thread ID. |
---|
668 | * cmd = 'c' for thread used in step and continue; |
---|
669 | * cmd = 'g' for thread used in other operations. |
---|
670 | * tid = -1 for all threads. |
---|
671 | * tid = zero, pick a thread,any thread. |
---|
672 | * returns an OK or an error number. |
---|
673 | */ |
---|
674 | char * |
---|
675 | gdb_set_thread(int cmd, int tid) |
---|
676 | { |
---|
677 | /* generically, we can't do anything for this command */ |
---|
678 | return(make_return_packet(OK)); |
---|
679 | } |
---|
680 | |
---|
681 | /* |
---|
682 | * p - read one register. |
---|
683 | * param is the register number. |
---|
684 | * returns the register value or ENN. |
---|
685 | */ |
---|
686 | char * |
---|
687 | gdb_read_reg(int reg) |
---|
688 | { |
---|
689 | /* generically, we can't do anything for this command */ |
---|
690 | return(make_return_packet(OK)); |
---|
691 | } |
---|
692 | |
---|
693 | /* |
---|
694 | * P - write one register. |
---|
695 | * params are the register number, and it's new value. |
---|
696 | * returns the register value or ENN. |
---|
697 | */ |
---|
698 | char * |
---|
699 | gdb_write_reg(int reg, long val) |
---|
700 | { |
---|
701 | /* generically, we can't do anything for this command */ |
---|
702 | |
---|
703 | return(make_return_packet(OK)); |
---|
704 | } |
---|
705 | |
---|
706 | /* |
---|
707 | * W - process exited. |
---|
708 | * no params. |
---|
709 | * returns the exit status. |
---|
710 | */ |
---|
711 | char * |
---|
712 | gdb_exited() |
---|
713 | { |
---|
714 | /* generically, we can't do anything for this command */ |
---|
715 | return(make_return_packet(OK)); |
---|
716 | } |
---|
717 | |
---|
718 | /* |
---|
719 | * X - process terminated. |
---|
720 | * no params. |
---|
721 | * returns the last signal. |
---|
722 | */ |
---|
723 | char * |
---|
724 | gdb_terminated() |
---|
725 | { |
---|
726 | } |
---|
727 | |
---|
728 | /* |
---|
729 | * O - hex encoding. |
---|
730 | * params are a vector of bytes, and the number of bytes to encode. |
---|
731 | * returns a vector of ASCII encoded hex numbers. |
---|
732 | */ |
---|
733 | char * |
---|
734 | gdb_hex(char *str, int nbytes) |
---|
735 | { |
---|
736 | } |
---|
737 | |
---|
738 | /* |
---|
739 | * A - tread alive request. |
---|
740 | * param is the thread ID. |
---|
741 | * returns an OK or an error number. |
---|
742 | */ |
---|
743 | char * |
---|
744 | gdb_thread_alive(int tid) |
---|
745 | { |
---|
746 | /* generically, we can't do anything for this command */ |
---|
747 | return(make_return_packet(OK)); |
---|
748 | } |
---|
749 | |
---|
750 | /* |
---|
751 | * ! - extended protocol. |
---|
752 | * no params. |
---|
753 | * returns an OK or an error number. |
---|
754 | */ |
---|
755 | char * |
---|
756 | gdb_extended() |
---|
757 | { |
---|
758 | /* generically, we can't do anything for this command */ |
---|
759 | return(make_return_packet(OK)); |
---|
760 | } |
---|
761 | |
---|
762 | /* |
---|
763 | * d - toggle gdb stub diagnostics. |
---|
764 | * no params. |
---|
765 | * returns an OK or an error number. |
---|
766 | */ |
---|
767 | char * |
---|
768 | gdb_debug() |
---|
769 | { |
---|
770 | if (remote_debug > 0) |
---|
771 | remote_debug = 0; |
---|
772 | else |
---|
773 | remote_debug = 1; |
---|
774 | |
---|
775 | return(make_return_packet(OK)); |
---|
776 | } |
---|
777 | |
---|
778 | /* |
---|
779 | * d - toggle gdb stub. |
---|
780 | * no params. |
---|
781 | * returns an OK or an error number. |
---|
782 | */ |
---|
783 | char * |
---|
784 | gdb_toggle() |
---|
785 | { |
---|
786 | static int level = 0; |
---|
787 | |
---|
788 | if (remote_debug) { |
---|
789 | level = remote_debug; |
---|
790 | remote_debug = 0; |
---|
791 | } else { |
---|
792 | remote_debug = level; |
---|
793 | } |
---|
794 | |
---|
795 | return(make_return_packet(OK)); |
---|
796 | } |
---|
797 | |
---|
798 | /* |
---|
799 | * r - reset target |
---|
800 | * no params. |
---|
801 | * returns an OK or an error number. |
---|
802 | */ |
---|
803 | char * |
---|
804 | gdb_reset() |
---|
805 | { |
---|
806 | /* generically, we can't do anything for this command */ |
---|
807 | return(make_return_packet(OK)); |
---|
808 | } |
---|
809 | |
---|
810 | /* |
---|
811 | * t - search backwards. |
---|
812 | * params are the address to start searching from, a pattern to match, and |
---|
813 | * the mask to use. |
---|
814 | * FIXME: not entirely sure what this is supposed to return. |
---|
815 | */ |
---|
816 | char * |
---|
817 | gdb_search(long addr, long pat, long mask) |
---|
818 | { |
---|
819 | /* generically, we can't do anything for this command */ |
---|
820 | return(make_return_packet(OK)); |
---|
821 | } |
---|
822 | |
---|
823 | /* |
---|
824 | * q - general get query. |
---|
825 | * param is a string, that's the query to be executed. |
---|
826 | * FIXME: not entirely sure what this is supposed to return. |
---|
827 | */ |
---|
828 | char * |
---|
829 | gdb_get_query(char *query) |
---|
830 | { |
---|
831 | /* generically, we can't do anything for this command */ |
---|
832 | return(make_return_packet(OK)); |
---|
833 | } |
---|
834 | |
---|
835 | /* |
---|
836 | * Q - general set query |
---|
837 | * param is a string, that's the query to be executed. |
---|
838 | * FIXME: not entirely sure what this means. |
---|
839 | * returns an OK or an error number. |
---|
840 | */ |
---|
841 | char * |
---|
842 | gdb_set(char *query) |
---|
843 | { |
---|
844 | /* generically, we can't do anything for this command */ |
---|
845 | return(make_return_packet(OK)); |
---|
846 | } |
---|
847 | |
---|
848 | |
---|