source: trunk/libs/newlib/src/libgloss/debug.c @ 607

Last change on this file since 607 was 444, checked in by satin@…, 7 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 18.2 KB
RevLine 
[444]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 */
43char packet_in_buf[BUFMAX];
44char packet_out_buf[BUFMAX];
45int 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 */
51volatile 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 */
57int 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 */
63int 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. */
70extern struct trap_info hard_trap_info[];
71
72/* this is a memory fault exception handler, used by mem2hex & hex2mem */
73extern 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 */
82void
83debuglog(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 */
149int
150hex2digit (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 */
171char
172digit2hex(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 */
187unsigned char *
188mem2hex(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 */
217unsigned char *
218hex2mem(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 */
245int
246hex2int (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 */
269void
270getpacket(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 */
332void
333putpacket(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 */
363void
364gdb_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
453int
454computeSignal(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 */
468void
469set_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 */
499char *
500make_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 */
520char *
521gdb_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 */
530char *
531gdb_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 */
543char *
544gdb_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 */
559char *
560gdb_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 */
575char *
576gdb_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 */
586char *
587gdb_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 */
596char *
597gdb_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 */
608char *
609gdb_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 */
627char *
628gdb_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 */
649char *
650gdb_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 */
660char *
661gdb_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 */
674char *
675gdb_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 */
686char *
687gdb_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 */
698char *
699gdb_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 */
711char *
712gdb_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 */
723char *
724gdb_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 */
733char *
734gdb_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 */
743char *
744gdb_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 */
755char *
756gdb_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 */
767char *
768gdb_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 */
783char *
784gdb_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 */
803char *
804gdb_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 */
816char *
817gdb_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 */
828char *
829gdb_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 */
841char *
842gdb_set(char *query)
843{
844  /* generically, we can't do anything for this command */
845  return(make_return_packet(OK));
846}
847
848
Note: See TracBrowser for help on using the repository browser.