1 /****************************************************************************
2 
3 		THIS SOFTWARE IS NOT COPYRIGHTED
4 
5    HP offers the following for use in the public domain.  HP makes no
6    warranty with regard to the software or it's performance and the
7    user accepts the software "AS IS" with all faults.
8 
9    HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
10    TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
11    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12 
13 ****************************************************************************/
14 
15 /****************************************************************************
16  *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
17  *
18  *  Module name: remcom.c $
19  *  Revision: 1.34 $
20  *  Date: 91/03/09 12:29:49 $
21  *  Contributor:     Lake Stevens Instrument Division$
22  *
23  *  Description:     low level support for gdb debugger. $
24  *
25  *  Considerations:  only works on target hardware $
26  *
27  *  Written by:      Glenn Engel $
28  *  ModuleState:     Experimental $
29  *
30  *  NOTES:           See Below $
31  *
32  *  Modified for M32R by Michael Snyder, Cygnus Support.
33  *
34  *  To enable debugger support, two things need to happen.  One, a
35  *  call to set_debug_traps() is necessary in order to allow any breakpoints
36  *  or error conditions to be properly intercepted and reported to gdb.
37  *  Two, a breakpoint needs to be generated to begin communication.  This
38  *  is most easily accomplished by a call to breakpoint().  Breakpoint()
39  *  simulates a breakpoint by executing a trap #1.
40  *
41  *  The external function exceptionHandler() is
42  *  used to attach a specific handler to a specific M32R vector number.
43  *  It should use the same privilege level it runs at.  It should
44  *  install it as an interrupt gate so that interrupts are masked
45  *  while the handler runs.
46  *
47  *  Because gdb will sometimes write to the stack area to execute function
48  *  calls, this program cannot rely on using the supervisor stack so it
49  *  uses it's own stack area reserved in the int array remcomStack.
50  *
51  *************
52  *
53  *    The following gdb commands are supported:
54  *
55  * command          function                               Return value
56  *
57  *    g             return the value of the CPU registers  hex data or ENN
58  *    G             set the value of the CPU registers     OK or ENN
59  *
60  *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
61  *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
62  *    XAA..AA,LLLL: Write LLLL binary bytes at address     OK or ENN
63  *                  AA..AA
64  *
65  *    c             Resume at current address              SNN   ( signal NN)
66  *    cAA..AA       Continue at address AA..AA             SNN
67  *
68  *    s             Step one instruction                   SNN
69  *    sAA..AA       Step one instruction from AA..AA       SNN
70  *
71  *    k             kill
72  *
73  *    ?             What was the last sigval ?             SNN   (signal NN)
74  *
75  * All commands and responses are sent with a packet which includes a
76  * checksum.  A packet consists of
77  *
78  * $<packet info>#<checksum>.
79  *
80  * where
81  * <packet info> :: <characters representing the command or response>
82  * <checksum>    :: <two hex digits computed as modulo 256 sum of <packetinfo>>
83  *
84  * When a packet is received, it is first acknowledged with either '+' or '-'.
85  * '+' indicates a successful transfer.  '-' indicates a failed transfer.
86  *
87  * Example:
88  *
89  * Host:                  Reply:
90  * $m0,10#2a               +$00010203040506070809101112131415#42
91  *
92  ****************************************************************************/
93 
94 
95 /************************************************************************
96  *
97  * external low-level support routines
98  */
99 extern void putDebugChar ();	/* write a single character      */
100 extern int getDebugChar ();	/* read and return a single char */
101 extern void exceptionHandler ();	/* assign an exception handler   */
102 
103 /*****************************************************************************
104  * BUFMAX defines the maximum number of characters in inbound/outbound buffers
105  * at least NUMREGBYTES*2 are needed for register packets
106  */
107 #define BUFMAX 400
108 
109 static char initialized;	/* boolean flag. != 0 means we've been initialized */
110 
111 int remote_debug;
112 /*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
113 
114 static const unsigned char hexchars[] = "0123456789abcdef";
115 
116 #define NUMREGS 24
117 
118 /* Number of bytes of registers.  */
119 #define NUMREGBYTES (NUMREGS * 4)
120 enum regnames
121 { R0, R1, R2, R3, R4, R5, R6, R7,
122   R8, R9, R10, R11, R12, R13, R14, R15,
123   PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH
124 };
125 
126 enum SYS_calls
127 {
128   SYS_null,
129   SYS_exit,
130   SYS_open,
131   SYS_close,
132   SYS_read,
133   SYS_write,
134   SYS_lseek,
135   SYS_unlink,
136   SYS_getpid,
137   SYS_kill,
138   SYS_fstat,
139   SYS_sbrk,
140   SYS_fork,
141   SYS_execve,
142   SYS_wait4,
143   SYS_link,
144   SYS_chdir,
145   SYS_stat,
146   SYS_utime,
147   SYS_chown,
148   SYS_chmod,
149   SYS_time,
150   SYS_pipe
151 };
152 
153 static int registers[NUMREGS];
154 
155 #define STACKSIZE 8096
156 static unsigned char remcomInBuffer[BUFMAX];
157 static unsigned char remcomOutBuffer[BUFMAX];
158 static int remcomStack[STACKSIZE / sizeof (int)];
159 static int *stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
160 
161 static unsigned int save_vectors[18];	/* previous exception vectors */
162 
163 /* Indicate to caller of mem2hex or hex2mem that there has been an error. */
164 static volatile int mem_err = 0;
165 
166 /* Store the vector number here (since GDB only gets the signal
167    number through the usual means, and that's not very specific).  */
168 int gdb_m32r_vector = -1;
169 
170 #if 0
171 #include "syscall.h"		/* for SYS_exit, SYS_write etc. */
172 #endif
173 
174 /* Global entry points:
175  */
176 
177 extern void handle_exception (int);
178 extern void set_debug_traps (void);
179 extern void breakpoint (void);
180 
181 /* Local functions:
182  */
183 
184 static int computeSignal (int);
185 static void putpacket (unsigned char *);
186 static unsigned char *getpacket (void);
187 
188 static unsigned char *mem2hex (unsigned char *, unsigned char *, int, int);
189 static unsigned char *hex2mem (unsigned char *, unsigned char *, int, int);
190 static int hexToInt (unsigned char **, int *);
191 static unsigned char *bin2mem (unsigned char *, unsigned char *, int, int);
192 static void stash_registers (void);
193 static void restore_registers (void);
194 static int prepare_to_step (int);
195 static int finish_from_step (void);
196 static unsigned long crc32 (unsigned char *, int, unsigned long);
197 
198 static void gdb_error (char *, char *);
199 static int gdb_putchar (int), gdb_puts (char *), gdb_write (char *, int);
200 
201 static unsigned char *strcpy (unsigned char *, const unsigned char *);
202 static int strlen (const unsigned char *);
203 
204 /*
205  * This function does all command procesing for interfacing to gdb.
206  */
207 
208 void
handle_exception(int exceptionVector)209 handle_exception (int exceptionVector)
210 {
211   int sigval, stepping;
212   int addr, length, i;
213   unsigned char *ptr;
214   unsigned char buf[16];
215   int binary;
216 
217   if (!finish_from_step ())
218     return;			/* "false step": let the target continue */
219 
220   gdb_m32r_vector = exceptionVector;
221 
222   if (remote_debug)
223     {
224       mem2hex ((unsigned char *) &exceptionVector, buf, 4, 0);
225       gdb_error ("Handle exception %s, ", buf);
226       mem2hex ((unsigned char *) &registers[PC], buf, 4, 0);
227       gdb_error ("PC == 0x%s\n", buf);
228     }
229 
230   /* reply to host that an exception has occurred */
231   sigval = computeSignal (exceptionVector);
232 
233   ptr = remcomOutBuffer;
234 
235   *ptr++ = 'T';			/* notify gdb with signo, PC, FP and SP */
236   *ptr++ = hexchars[sigval >> 4];
237   *ptr++ = hexchars[sigval & 0xf];
238 
239   *ptr++ = hexchars[PC >> 4];
240   *ptr++ = hexchars[PC & 0xf];
241   *ptr++ = ':';
242   ptr = mem2hex ((unsigned char *) &registers[PC], ptr, 4, 0);	/* PC */
243   *ptr++ = ';';
244 
245   *ptr++ = hexchars[R13 >> 4];
246   *ptr++ = hexchars[R13 & 0xf];
247   *ptr++ = ':';
248   ptr = mem2hex ((unsigned char *) &registers[R13], ptr, 4, 0);	/* FP */
249   *ptr++ = ';';
250 
251   *ptr++ = hexchars[R15 >> 4];
252   *ptr++ = hexchars[R15 & 0xf];
253   *ptr++ = ':';
254   ptr = mem2hex ((unsigned char *) &registers[R15], ptr, 4, 0);	/* SP */
255   *ptr++ = ';';
256   *ptr++ = 0;
257 
258   if (exceptionVector == 0)	/* simulated SYS call stuff */
259     {
260       mem2hex ((unsigned char *) &registers[PC], buf, 4, 0);
261       switch (registers[R0])
262 	{
263 	case SYS_exit:
264 	  gdb_error ("Target program has exited at %s\n", buf);
265 	  ptr = remcomOutBuffer;
266 	  *ptr++ = 'W';
267 	  sigval = registers[R1] & 0xff;
268 	  *ptr++ = hexchars[sigval >> 4];
269 	  *ptr++ = hexchars[sigval & 0xf];
270 	  *ptr++ = 0;
271 	  break;
272 	case SYS_open:
273 	  gdb_error ("Target attempts SYS_open call at %s\n", buf);
274 	  break;
275 	case SYS_close:
276 	  gdb_error ("Target attempts SYS_close call at %s\n", buf);
277 	  break;
278 	case SYS_read:
279 	  gdb_error ("Target attempts SYS_read call at %s\n", buf);
280 	  break;
281 	case SYS_write:
282 	  if (registers[R1] == 1 ||	/* write to stdout  */
283 	      registers[R1] == 2)	/* write to stderr  */
284 	    {			/* (we can do that) */
285 	      registers[R0] =
286 		gdb_write ((void *) registers[R2], registers[R3]);
287 	      return;
288 	    }
289 	  else
290 	    gdb_error ("Target attempts SYS_write call at %s\n", buf);
291 	  break;
292 	case SYS_lseek:
293 	  gdb_error ("Target attempts SYS_lseek call at %s\n", buf);
294 	  break;
295 	case SYS_unlink:
296 	  gdb_error ("Target attempts SYS_unlink call at %s\n", buf);
297 	  break;
298 	case SYS_getpid:
299 	  gdb_error ("Target attempts SYS_getpid call at %s\n", buf);
300 	  break;
301 	case SYS_kill:
302 	  gdb_error ("Target attempts SYS_kill call at %s\n", buf);
303 	  break;
304 	case SYS_fstat:
305 	  gdb_error ("Target attempts SYS_fstat call at %s\n", buf);
306 	  break;
307 	default:
308 	  gdb_error ("Target attempts unknown SYS call at %s\n", buf);
309 	  break;
310 	}
311     }
312 
313   putpacket (remcomOutBuffer);
314 
315   stepping = 0;
316 
317   while (1 == 1)
318     {
319       remcomOutBuffer[0] = 0;
320       ptr = getpacket ();
321       binary = 0;
322       switch (*ptr++)
323 	{
324 	default:		/* Unknown code.  Return an empty reply message. */
325 	  break;
326 	case 'R':
327 	  if (hexToInt (&ptr, &addr))
328 	    registers[PC] = addr;
329 	  strcpy (remcomOutBuffer, "OK");
330 	  break;
331 	case '!':
332 	  strcpy (remcomOutBuffer, "OK");
333 	  break;
334 	case 'X':		/* XAA..AA,LLLL:<binary data>#cs */
335 	  binary = 1;
336 	case 'M':		/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
337 	  /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
338 	  {
339 	    if (hexToInt (&ptr, &addr))
340 	      if (*(ptr++) == ',')
341 		if (hexToInt (&ptr, &length))
342 		  if (*(ptr++) == ':')
343 		    {
344 		      mem_err = 0;
345 		      if (binary)
346 			bin2mem (ptr, (unsigned char *) addr, length, 1);
347 		      else
348 			hex2mem (ptr, (unsigned char *) addr, length, 1);
349 		      if (mem_err)
350 			{
351 			  strcpy (remcomOutBuffer, "E03");
352 			  gdb_error ("memory fault", "");
353 			}
354 		      else
355 			{
356 			  strcpy (remcomOutBuffer, "OK");
357 			}
358 		      ptr = 0;
359 		    }
360 	    if (ptr)
361 	      {
362 		strcpy (remcomOutBuffer, "E02");
363 	      }
364 	  }
365 	  break;
366 	case 'm':		/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
367 	  /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
368 	  if (hexToInt (&ptr, &addr))
369 	    if (*(ptr++) == ',')
370 	      if (hexToInt (&ptr, &length))
371 		{
372 		  ptr = 0;
373 		  mem_err = 0;
374 		  mem2hex ((unsigned char *) addr, remcomOutBuffer, length,
375 			   1);
376 		  if (mem_err)
377 		    {
378 		      strcpy (remcomOutBuffer, "E03");
379 		      gdb_error ("memory fault", "");
380 		    }
381 		}
382 	  if (ptr)
383 	    {
384 	      strcpy (remcomOutBuffer, "E01");
385 	    }
386 	  break;
387 	case '?':
388 	  remcomOutBuffer[0] = 'S';
389 	  remcomOutBuffer[1] = hexchars[sigval >> 4];
390 	  remcomOutBuffer[2] = hexchars[sigval % 16];
391 	  remcomOutBuffer[3] = 0;
392 	  break;
393 	case 'd':
394 	  remote_debug = !(remote_debug);	/* toggle debug flag */
395 	  break;
396 	case 'g':		/* return the value of the CPU registers */
397 	  mem2hex ((unsigned char *) registers, remcomOutBuffer, NUMREGBYTES,
398 		   0);
399 	  break;
400 	case 'P':		/* set the value of a single CPU register - return OK */
401 	  {
402 	    int regno;
403 
404 	    if (hexToInt (&ptr, &regno) && *ptr++ == '=')
405 	      if (regno >= 0 && regno < NUMREGS)
406 		{
407 		  int stackmode;
408 
409 		  hex2mem (ptr, (unsigned char *) &registers[regno], 4, 0);
410 		  /*
411 		   * Since we just changed a single CPU register, let's
412 		   * make sure to keep the several stack pointers consistant.
413 		   */
414 		  stackmode = registers[PSW] & 0x80;
415 		  if (regno == R15)	/* stack pointer changed */
416 		    {		/* need to change SPI or SPU */
417 		      if (stackmode == 0)
418 			registers[SPI] = registers[R15];
419 		      else
420 			registers[SPU] = registers[R15];
421 		    }
422 		  else if (regno == SPU)	/* "user" stack pointer changed */
423 		    {
424 		      if (stackmode != 0)	/* stack in user mode: copy SP */
425 			registers[R15] = registers[SPU];
426 		    }
427 		  else if (regno == SPI)	/* "interrupt" stack pointer changed */
428 		    {
429 		      if (stackmode == 0)	/* stack in interrupt mode: copy SP */
430 			registers[R15] = registers[SPI];
431 		    }
432 		  else if (regno == PSW)	/* stack mode may have changed! */
433 		    {		/* force SP to either SPU or SPI */
434 		      if (stackmode == 0)	/* stack in user mode */
435 			registers[R15] = registers[SPI];
436 		      else	/* stack in interrupt mode */
437 			registers[R15] = registers[SPU];
438 		    }
439 		  strcpy (remcomOutBuffer, "OK");
440 		  break;
441 		}
442 	    strcpy (remcomOutBuffer, "E01");
443 	    break;
444 	  }
445 	case 'G':		/* set the value of the CPU registers - return OK */
446 	  hex2mem (ptr, (unsigned char *) registers, NUMREGBYTES, 0);
447 	  strcpy (remcomOutBuffer, "OK");
448 	  break;
449 	case 's':		/* sAA..AA      Step one instruction from AA..AA(optional) */
450 	  stepping = 1;
451 	case 'c':		/* cAA..AA      Continue from address AA..AA(optional) */
452 	  /* try to read optional parameter, pc unchanged if no parm */
453 	  if (hexToInt (&ptr, &addr))
454 	    registers[PC] = addr;
455 
456 	  if (stepping)		/* single-stepping */
457 	    {
458 	      if (!prepare_to_step (0))	/* set up for single-step */
459 		{
460 		  /* prepare_to_step has already emulated the target insn:
461 		     Send SIGTRAP to gdb, don't resume the target at all.  */
462 		  ptr = remcomOutBuffer;
463 		  *ptr++ = 'T';	/* Simulate stopping with SIGTRAP */
464 		  *ptr++ = '0';
465 		  *ptr++ = '5';
466 
467 		  *ptr++ = hexchars[PC >> 4];	/* send PC */
468 		  *ptr++ = hexchars[PC & 0xf];
469 		  *ptr++ = ':';
470 		  ptr = mem2hex ((unsigned char *) &registers[PC], ptr, 4, 0);
471 		  *ptr++ = ';';
472 
473 		  *ptr++ = hexchars[R13 >> 4];	/* send FP */
474 		  *ptr++ = hexchars[R13 & 0xf];
475 		  *ptr++ = ':';
476 		  ptr =
477 		    mem2hex ((unsigned char *) &registers[R13], ptr, 4, 0);
478 		  *ptr++ = ';';
479 
480 		  *ptr++ = hexchars[R15 >> 4];	/* send SP */
481 		  *ptr++ = hexchars[R15 & 0xf];
482 		  *ptr++ = ':';
483 		  ptr =
484 		    mem2hex ((unsigned char *) &registers[R15], ptr, 4, 0);
485 		  *ptr++ = ';';
486 		  *ptr++ = 0;
487 
488 		  break;
489 		}
490 	    }
491 	  else			/* continuing, not single-stepping */
492 	    {
493 	      /* OK, about to do a "continue".  First check to see if the
494 	         target pc is on an odd boundary (second instruction in the
495 	         word).  If so, we must do a single-step first, because
496 	         ya can't jump or return back to an odd boundary!  */
497 	      if ((registers[PC] & 2) != 0)
498 		prepare_to_step (1);
499 	    }
500 
501 	  return;
502 
503 	case 'D':		/* Detach */
504 #if 0
505 	  /* I am interpreting this to mean, release the board from control
506 	     by the remote stub.  To do this, I am restoring the original
507 	     (or at least previous) exception vectors.
508 	   */
509 	  for (i = 0; i < 18; i++)
510 	    exceptionHandler (i, save_vectors[i]);
511 	  putpacket ("OK");
512 	  return;		/* continue the inferior */
513 #else
514 	  strcpy (remcomOutBuffer, "OK");
515 	  break;
516 #endif
517 	case 'q':
518 	  if (*ptr++ == 'C' &&
519 	      *ptr++ == 'R' && *ptr++ == 'C' && *ptr++ == ':')
520 	    {
521 	      unsigned long start, len, our_crc;
522 
523 	      if (hexToInt (&ptr, (int *) &start) &&
524 		  *ptr++ == ',' && hexToInt (&ptr, (int *) &len))
525 		{
526 		  remcomOutBuffer[0] = 'C';
527 		  our_crc = crc32 ((unsigned char *) start, len, 0xffffffff);
528 		  mem2hex ((char *) &our_crc,
529 			   &remcomOutBuffer[1], sizeof (long), 0);
530 		}		/* else do nothing */
531 	    }			/* else do nothing */
532 	  break;
533 
534 	case 'k':		/* kill the program */
535 	  continue;
536 	}			/* switch */
537 
538       /* reply to the request */
539       putpacket (remcomOutBuffer);
540     }
541 }
542 
543 /* qCRC support */
544 
545 /* Table used by the crc32 function to calcuate the checksum. */
546 static unsigned long crc32_table[256] = { 0, 0 };
547 
548 static unsigned long
crc32(unsigned char * buf,int len,unsigned long crc)549 crc32 (unsigned char *buf, int len, unsigned long crc)
550 {
551   if (!crc32_table[1])
552     {
553       /* Initialize the CRC table and the decoding table. */
554       int i, j;
555       unsigned long c;
556 
557       for (i = 0; i < 256; i++)
558 	{
559 	  for (c = i << 24, j = 8; j > 0; --j)
560 	    c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
561 	  crc32_table[i] = c;
562 	}
563     }
564 
565   while (len--)
566     {
567       crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
568       buf++;
569     }
570   return crc;
571 }
572 
573 static int
hex(unsigned char ch)574 hex (unsigned char ch)
575 {
576   if ((ch >= 'a') && (ch <= 'f'))
577     return (ch - 'a' + 10);
578   if ((ch >= '0') && (ch <= '9'))
579     return (ch - '0');
580   if ((ch >= 'A') && (ch <= 'F'))
581     return (ch - 'A' + 10);
582   return (-1);
583 }
584 
585 /* scan for the sequence $<data>#<checksum>     */
586 
587 unsigned char *
getpacket(void)588 getpacket (void)
589 {
590   unsigned char *buffer = &remcomInBuffer[0];
591   unsigned char checksum;
592   unsigned char xmitcsum;
593   int count;
594   char ch;
595 
596   while (1)
597     {
598       /* wait around for the start character, ignore all other characters */
599       while ((ch = getDebugChar ()) != '$')
600 	;
601 
602     retry:
603       checksum = 0;
604       xmitcsum = -1;
605       count = 0;
606 
607       /* now, read until a # or end of buffer is found */
608       while (count < BUFMAX)
609 	{
610 	  ch = getDebugChar ();
611 	  if (ch == '$')
612 	    goto retry;
613 	  if (ch == '#')
614 	    break;
615 	  checksum = checksum + ch;
616 	  buffer[count] = ch;
617 	  count = count + 1;
618 	}
619       buffer[count] = 0;
620 
621       if (ch == '#')
622 	{
623 	  ch = getDebugChar ();
624 	  xmitcsum = hex (ch) << 4;
625 	  ch = getDebugChar ();
626 	  xmitcsum += hex (ch);
627 
628 	  if (checksum != xmitcsum)
629 	    {
630 	      if (remote_debug)
631 		{
632 		  unsigned char buf[16];
633 
634 		  mem2hex ((unsigned char *) &checksum, buf, 4, 0);
635 		  gdb_error ("Bad checksum: my count = %s, ", buf);
636 		  mem2hex ((unsigned char *) &xmitcsum, buf, 4, 0);
637 		  gdb_error ("sent count = %s\n", buf);
638 		  gdb_error (" -- Bad buffer: \"%s\"\n", buffer);
639 		}
640 	      putDebugChar ('-');	/* failed checksum */
641 	    }
642 	  else
643 	    {
644 	      putDebugChar ('+');	/* successful transfer */
645 
646 	      /* if a sequence char is present, reply the sequence ID */
647 	      if (buffer[2] == ':')
648 		{
649 		  putDebugChar (buffer[0]);
650 		  putDebugChar (buffer[1]);
651 
652 		  return &buffer[3];
653 		}
654 
655 	      return &buffer[0];
656 	    }
657 	}
658     }
659 }
660 
661 /* send the packet in buffer.  */
662 
663 static void
putpacket(unsigned char * buffer)664 putpacket (unsigned char *buffer)
665 {
666   unsigned char checksum;
667   int count;
668   char ch;
669 
670   /*  $<packet info>#<checksum>. */
671   do
672     {
673       putDebugChar ('$');
674       checksum = 0;
675       count = 0;
676 
677       while (ch = buffer[count])
678 	{
679 	  putDebugChar (ch);
680 	  checksum += ch;
681 	  count += 1;
682 	}
683       putDebugChar ('#');
684       putDebugChar (hexchars[checksum >> 4]);
685       putDebugChar (hexchars[checksum % 16]);
686     }
687   while (getDebugChar () != '+');
688 }
689 
690 /* Address of a routine to RTE to if we get a memory fault.  */
691 
692 static void (*volatile mem_fault_routine) () = 0;
693 
694 static void
set_mem_err(void)695 set_mem_err (void)
696 {
697   mem_err = 1;
698 }
699 
700 /* Check the address for safe access ranges.  As currently defined,
701    this routine will reject the "expansion bus" address range(s).
702    To make those ranges useable, someone must implement code to detect
703    whether there's anything connected to the expansion bus. */
704 
705 static int
mem_safe(unsigned char * addr)706 mem_safe (unsigned char *addr)
707 {
708 #define BAD_RANGE_ONE_START	((unsigned char *) 0x600000)
709 #define BAD_RANGE_ONE_END	((unsigned char *) 0xa00000)
710 #define BAD_RANGE_TWO_START	((unsigned char *) 0xff680000)
711 #define BAD_RANGE_TWO_END	((unsigned char *) 0xff800000)
712 
713   if (addr < BAD_RANGE_ONE_START)
714     return 1;			/* safe */
715   if (addr < BAD_RANGE_ONE_END)
716     return 0;			/* unsafe */
717   if (addr < BAD_RANGE_TWO_START)
718     return 1;			/* safe */
719   if (addr < BAD_RANGE_TWO_END)
720     return 0;			/* unsafe */
721 }
722 
723 /* These are separate functions so that they are so short and sweet
724    that the compiler won't save any registers (if there is a fault
725    to mem_fault, they won't get restored, so there better not be any
726    saved).  */
727 static int
get_char(unsigned char * addr)728 get_char (unsigned char *addr)
729 {
730 #if 1
731   if (mem_fault_routine && !mem_safe (addr))
732     {
733       mem_fault_routine ();
734       return 0;
735     }
736 #endif
737   return *addr;
738 }
739 
740 static void
set_char(unsigned char * addr,unsigned char val)741 set_char (unsigned char *addr, unsigned char val)
742 {
743 #if 1
744   if (mem_fault_routine && !mem_safe (addr))
745     {
746       mem_fault_routine ();
747       return;
748     }
749 #endif
750   *addr = val;
751 }
752 
753 /* Convert the memory pointed to by mem into hex, placing result in buf.
754    Return a pointer to the last char put in buf (null).
755    If MAY_FAULT is non-zero, then we should set mem_err in response to
756    a fault; if zero treat a fault like any other fault in the stub.  */
757 
758 static unsigned char *
mem2hex(unsigned char * mem,unsigned char * buf,int count,int may_fault)759 mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
760 {
761   int i;
762   unsigned char ch;
763 
764   if (may_fault)
765     mem_fault_routine = set_mem_err;
766   for (i = 0; i < count; i++)
767     {
768       ch = get_char (mem++);
769       if (may_fault && mem_err)
770 	return (buf);
771       *buf++ = hexchars[ch >> 4];
772       *buf++ = hexchars[ch % 16];
773     }
774   *buf = 0;
775   if (may_fault)
776     mem_fault_routine = 0;
777   return (buf);
778 }
779 
780 /* Convert the hex array pointed to by buf into binary to be placed in mem.
781    Return a pointer to the character AFTER the last byte written. */
782 
783 static unsigned char *
hex2mem(unsigned char * buf,unsigned char * mem,int count,int may_fault)784 hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
785 {
786   int i;
787   unsigned char ch;
788 
789   if (may_fault)
790     mem_fault_routine = set_mem_err;
791   for (i = 0; i < count; i++)
792     {
793       ch = hex (*buf++) << 4;
794       ch = ch + hex (*buf++);
795       set_char (mem++, ch);
796       if (may_fault && mem_err)
797 	return (mem);
798     }
799   if (may_fault)
800     mem_fault_routine = 0;
801   return (mem);
802 }
803 
804 /* Convert the binary stream in BUF to memory.
805 
806    Gdb will escape $, #, and the escape char (0x7d).
807    COUNT is the total number of bytes to write into
808    memory. */
809 static unsigned char *
bin2mem(unsigned char * buf,unsigned char * mem,int count,int may_fault)810 bin2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
811 {
812   int i;
813   unsigned char ch;
814 
815   if (may_fault)
816     mem_fault_routine = set_mem_err;
817   for (i = 0; i < count; i++)
818     {
819       /* Check for any escaped characters. Be paranoid and
820          only unescape chars that should be escaped. */
821       if (*buf == 0x7d)
822 	{
823 	  switch (*(buf + 1))
824 	    {
825 	    case 0x3:		/* # */
826 	    case 0x4:		/* $ */
827 	    case 0x5d:		/* escape char */
828 	      buf++;
829 	      *buf |= 0x20;
830 	      break;
831 	    default:
832 	      /* nothing */
833 	      break;
834 	    }
835 	}
836 
837       set_char (mem++, *buf++);
838 
839       if (may_fault && mem_err)
840 	return mem;
841     }
842 
843   if (may_fault)
844     mem_fault_routine = 0;
845   return mem;
846 }
847 
848 /* this function takes the m32r exception vector and attempts to
849    translate this number into a unix compatible signal value */
850 
851 static int
computeSignal(int exceptionVector)852 computeSignal (int exceptionVector)
853 {
854   int sigval;
855   switch (exceptionVector)
856     {
857     case 0:
858       sigval = 23;
859       break;			/* I/O trap                    */
860     case 1:
861       sigval = 5;
862       break;			/* breakpoint                  */
863     case 2:
864       sigval = 5;
865       break;			/* breakpoint                  */
866     case 3:
867       sigval = 5;
868       break;			/* breakpoint                  */
869     case 4:
870       sigval = 5;
871       break;			/* breakpoint                  */
872     case 5:
873       sigval = 5;
874       break;			/* breakpoint                  */
875     case 6:
876       sigval = 5;
877       break;			/* breakpoint                  */
878     case 7:
879       sigval = 5;
880       break;			/* breakpoint                  */
881     case 8:
882       sigval = 5;
883       break;			/* breakpoint                  */
884     case 9:
885       sigval = 5;
886       break;			/* breakpoint                  */
887     case 10:
888       sigval = 5;
889       break;			/* breakpoint                  */
890     case 11:
891       sigval = 5;
892       break;			/* breakpoint                  */
893     case 12:
894       sigval = 5;
895       break;			/* breakpoint                  */
896     case 13:
897       sigval = 5;
898       break;			/* breakpoint                  */
899     case 14:
900       sigval = 5;
901       break;			/* breakpoint                  */
902     case 15:
903       sigval = 5;
904       break;			/* breakpoint                  */
905     case 16:
906       sigval = 10;
907       break;			/* BUS ERROR (alignment)       */
908     case 17:
909       sigval = 2;
910       break;			/* INTerrupt                   */
911     default:
912       sigval = 7;
913       break;			/* "software generated"        */
914     }
915   return (sigval);
916 }
917 
918 /**********************************************/
919 /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
920 /* RETURN NUMBER OF CHARS PROCESSED           */
921 /**********************************************/
922 static int
hexToInt(unsigned char ** ptr,int * intValue)923 hexToInt (unsigned char **ptr, int *intValue)
924 {
925   int numChars = 0;
926   int hexValue;
927 
928   *intValue = 0;
929   while (**ptr)
930     {
931       hexValue = hex (**ptr);
932       if (hexValue >= 0)
933 	{
934 	  *intValue = (*intValue << 4) | hexValue;
935 	  numChars++;
936 	}
937       else
938 	break;
939       (*ptr)++;
940     }
941   return (numChars);
942 }
943 
944 /*
945   Table of branch instructions:
946 
947   10B6		RTE	return from trap or exception
948   1FCr		JMP	jump
949   1ECr		JL	jump and link
950   7Fxx		BRA	branch
951   FFxxxxxx	BRA	branch (long)
952   B09rxxxx	BNEZ	branch not-equal-zero
953   Br1rxxxx	BNE	branch not-equal
954   7Dxx		BNC	branch not-condition
955   FDxxxxxx	BNC	branch not-condition (long)
956   B0Arxxxx	BLTZ	branch less-than-zero
957   B0Crxxxx	BLEZ	branch less-equal-zero
958   7Exx		BL	branch and link
959   FExxxxxx	BL	branch and link (long)
960   B0Drxxxx	BGTZ	branch greater-than-zero
961   B0Brxxxx	BGEZ	branch greater-equal-zero
962   B08rxxxx	BEQZ	branch equal-zero
963   Br0rxxxx	BEQ	branch equal
964   7Cxx		BC	branch condition
965   FCxxxxxx	BC	branch condition (long)
966   */
967 
968 static int
isShortBranch(unsigned char * instr)969 isShortBranch (unsigned char *instr)
970 {
971   unsigned char instr0 = instr[0] & 0x7F;	/* mask off high bit */
972 
973   if (instr0 == 0x10 && instr[1] == 0xB6)	/* RTE */
974     return 1;			/* return from trap or exception */
975 
976   if (instr0 == 0x1E || instr0 == 0x1F)	/* JL or JMP */
977     if ((instr[1] & 0xF0) == 0xC0)
978       return 2;			/* jump thru a register */
979 
980   if (instr0 == 0x7C || instr0 == 0x7D ||	/* BC, BNC, BL, BRA */
981       instr0 == 0x7E || instr0 == 0x7F)
982     return 3;			/* eight bit PC offset */
983 
984   return 0;
985 }
986 
987 static int
isLongBranch(unsigned char * instr)988 isLongBranch (unsigned char *instr)
989 {
990   if (instr[0] == 0xFC || instr[0] == 0xFD ||	/* BRA, BNC, BL, BC */
991       instr[0] == 0xFE || instr[0] == 0xFF)	/* 24 bit relative */
992     return 4;
993   if ((instr[0] & 0xF0) == 0xB0)	/* 16 bit relative */
994     {
995       if ((instr[1] & 0xF0) == 0x00 ||	/* BNE, BEQ */
996 	  (instr[1] & 0xF0) == 0x10)
997 	return 5;
998       if (instr[0] == 0xB0)	/* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */
999 	if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 ||
1000 	    (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 ||
1001 	    (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0)
1002 	  return 6;
1003     }
1004   return 0;
1005 }
1006 
1007 /* if address is NOT on a 4-byte boundary, or high-bit of instr is zero,
1008    then it's a 2-byte instruction, else it's a 4-byte instruction.  */
1009 
1010 #define INSTRUCTION_SIZE(addr) \
1011     ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4)
1012 
1013 static int
isBranch(unsigned char * instr)1014 isBranch (unsigned char *instr)
1015 {
1016   if (INSTRUCTION_SIZE (instr) == 2)
1017     return isShortBranch (instr);
1018   else
1019     return isLongBranch (instr);
1020 }
1021 
1022 static int
willBranch(unsigned char * instr,int branchCode)1023 willBranch (unsigned char *instr, int branchCode)
1024 {
1025   switch (branchCode)
1026     {
1027     case 0:
1028       return 0;			/* not a branch */
1029     case 1:
1030       return 1;			/* RTE */
1031     case 2:
1032       return 1;			/* JL or JMP    */
1033     case 3:			/* BC, BNC, BL, BRA (short) */
1034     case 4:			/* BC, BNC, BL, BRA (long) */
1035       switch (instr[0] & 0x0F)
1036 	{
1037 	case 0xC:		/* Branch if Condition Register */
1038 	  return (registers[CBR] != 0);
1039 	case 0xD:		/* Branch if NOT Condition Register */
1040 	  return (registers[CBR] == 0);
1041 	case 0xE:		/* Branch and Link */
1042 	case 0xF:		/* Branch (unconditional) */
1043 	  return 1;
1044 	default:		/* oops? */
1045 	  return 0;
1046 	}
1047     case 5:			/* BNE, BEQ */
1048       switch (instr[1] & 0xF0)
1049 	{
1050 	case 0x00:		/* Branch if r1 equal to r2 */
1051 	  return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]);
1052 	case 0x10:		/* Branch if r1 NOT equal to r2 */
1053 	  return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]);
1054 	default:		/* oops? */
1055 	  return 0;
1056 	}
1057     case 6:			/* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */
1058       switch (instr[1] & 0xF0)
1059 	{
1060 	case 0x80:		/* Branch if reg equal to zero */
1061 	  return (registers[instr[1] & 0x0F] == 0);
1062 	case 0x90:		/* Branch if reg NOT equal to zero */
1063 	  return (registers[instr[1] & 0x0F] != 0);
1064 	case 0xA0:		/* Branch if reg less than zero */
1065 	  return (registers[instr[1] & 0x0F] < 0);
1066 	case 0xB0:		/* Branch if reg greater or equal to zero */
1067 	  return (registers[instr[1] & 0x0F] >= 0);
1068 	case 0xC0:		/* Branch if reg less than or equal to zero */
1069 	  return (registers[instr[1] & 0x0F] <= 0);
1070 	case 0xD0:		/* Branch if reg greater than zero */
1071 	  return (registers[instr[1] & 0x0F] > 0);
1072 	default:		/* oops? */
1073 	  return 0;
1074 	}
1075     default:			/* oops? */
1076       return 0;
1077     }
1078 }
1079 
1080 static int
branchDestination(unsigned char * instr,int branchCode)1081 branchDestination (unsigned char *instr, int branchCode)
1082 {
1083   switch (branchCode)
1084     {
1085     default:
1086     case 0:			/* not a branch */
1087       return 0;
1088     case 1:			/* RTE */
1089       return registers[BPC] & ~3;	/* pop BPC into PC */
1090     case 2:			/* JL or JMP */
1091       return registers[instr[1] & 0x0F] & ~3;	/* jump thru a register */
1092     case 3:			/* BC, BNC, BL, BRA (short, 8-bit relative offset) */
1093       return (((int) instr) & ~3) + ((char) instr[1] << 2);
1094     case 4:			/* BC, BNC, BL, BRA (long, 24-bit relative offset) */
1095       return ((int) instr +
1096 	      ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) <<
1097 	       2));
1098     case 5:			/* BNE, BEQ (16-bit relative offset) */
1099     case 6:			/* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */
1100       return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2));
1101     }
1102 
1103   /* An explanatory note: in the last three return expressions, I have
1104      cast the most-significant byte of the return offset to char.
1105      What this accomplishes is sign extension.  If the other
1106      less-significant bytes were signed as well, they would get sign
1107      extended too and, if negative, their leading bits would clobber
1108      the bits of the more-significant bytes ahead of them.  There are
1109      other ways I could have done this, but sign extension from
1110      odd-sized integers is always a pain. */
1111 }
1112 
1113 static void
branchSideEffects(unsigned char * instr,int branchCode)1114 branchSideEffects (unsigned char *instr, int branchCode)
1115 {
1116   switch (branchCode)
1117     {
1118     case 1:			/* RTE */
1119       return;			/* I <THINK> this is already handled... */
1120     case 2:			/* JL (or JMP) */
1121     case 3:			/* BL (or BC, BNC, BRA) */
1122     case 4:
1123       if ((instr[0] & 0x0F) == 0x0E)	/* branch/jump and link */
1124 	registers[R14] = (registers[PC] & ~3) + 4;
1125       return;
1126     default:			/* any other branch has no side effects */
1127       return;
1128     }
1129 }
1130 
1131 static struct STEPPING_CONTEXT
1132 {
1133   int stepping;			/* true when we've started a single-step */
1134   unsigned long target_addr;	/* the instr we're trying to execute */
1135   unsigned long target_size;	/* the size of the target instr */
1136   unsigned long noop_addr;	/* where we've inserted a no-op, if any */
1137   unsigned long trap1_addr;	/* the trap following the target instr */
1138   unsigned long trap2_addr;	/* the trap at a branch destination, if any */
1139   unsigned short noop_save;	/* instruction overwritten by our no-op */
1140   unsigned short trap1_save;	/* instruction overwritten by trap1 */
1141   unsigned short trap2_save;	/* instruction overwritten by trap2 */
1142   unsigned short continue_p;	/* true if NOT returning to gdb after step */
1143 } stepping;
1144 
1145 /* Function: prepare_to_step
1146    Called from handle_exception to prepare the user program to single-step.
1147    Places a trap instruction after the target instruction, with special
1148    extra handling for branch instructions and for instructions in the
1149    second half-word of a word.
1150 
1151    Returns: True  if we should actually execute the instruction;
1152 	    False if we are going to emulate executing the instruction,
1153 	    in which case we simply report to GDB that the instruction
1154 	    has already been executed.  */
1155 
1156 #define TRAP1  0x10f1;		/* trap #1 instruction */
1157 #define NOOP   0x7000;		/* noop    instruction */
1158 
1159 static unsigned short trap1 = TRAP1;
1160 static unsigned short noop = NOOP;
1161 
1162 static int
prepare_to_step(continue_p)1163 prepare_to_step (continue_p)
1164      int continue_p;		/* if this isn't REALLY a single-step (see below) */
1165 {
1166   unsigned long pc = registers[PC];
1167   int branchCode = isBranch ((unsigned char *) pc);
1168   unsigned char *p;
1169 
1170   /* zero out the stepping context
1171      (paranoia -- it should already be zeroed) */
1172   for (p = (unsigned char *) &stepping;
1173        p < ((unsigned char *) &stepping) + sizeof (stepping); p++)
1174     *p = 0;
1175 
1176   if (branchCode != 0)		/* next instruction is a branch */
1177     {
1178       branchSideEffects ((unsigned char *) pc, branchCode);
1179       if (willBranch ((unsigned char *) pc, branchCode))
1180 	registers[PC] = branchDestination ((unsigned char *) pc, branchCode);
1181       else
1182 	registers[PC] = pc + INSTRUCTION_SIZE (pc);
1183       return 0;			/* branch "executed" -- just notify GDB */
1184     }
1185   else if (((int) pc & 2) != 0)	/* "second-slot" instruction */
1186     {
1187       /* insert no-op before pc */
1188       stepping.noop_addr = pc - 2;
1189       stepping.noop_save = *(unsigned short *) stepping.noop_addr;
1190       *(unsigned short *) stepping.noop_addr = noop;
1191       /* insert trap  after  pc */
1192       stepping.trap1_addr = pc + 2;
1193       stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
1194       *(unsigned short *) stepping.trap1_addr = trap1;
1195     }
1196   else				/* "first-slot" instruction */
1197     {
1198       /* insert trap  after  pc */
1199       stepping.trap1_addr = pc + INSTRUCTION_SIZE (pc);
1200       stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
1201       *(unsigned short *) stepping.trap1_addr = trap1;
1202     }
1203   /* "continue_p" means that we are actually doing a continue, and not
1204      being requested to single-step by GDB.  Sometimes we have to do
1205      one single-step before continuing, because the PC is on a half-word
1206      boundary.  There's no way to simply resume at such an address.  */
1207   stepping.continue_p = continue_p;
1208   stepping.stepping = 1;	/* starting a single-step */
1209   return 1;
1210 }
1211 
1212 /* Function: finish_from_step
1213    Called from handle_exception to finish up when the user program
1214    returns from a single-step.  Replaces the instructions that had
1215    been overwritten by traps or no-ops,
1216 
1217    Returns: True  if we should notify GDB that the target stopped.
1218 	    False if we only single-stepped because we had to before we
1219 	    could continue (ie. we were trying to continue at a
1220 	    half-word boundary).  In that case don't notify GDB:
1221 	    just "continue continuing".  */
1222 
1223 static int
finish_from_step(void)1224 finish_from_step (void)
1225 {
1226   if (stepping.stepping)	/* anything to do? */
1227     {
1228       int continue_p = stepping.continue_p;
1229       unsigned char *p;
1230 
1231       if (stepping.noop_addr)	/* replace instr "under" our no-op */
1232 	*(unsigned short *) stepping.noop_addr = stepping.noop_save;
1233       if (stepping.trap1_addr)	/* replace instr "under" our trap  */
1234 	*(unsigned short *) stepping.trap1_addr = stepping.trap1_save;
1235       if (stepping.trap2_addr)	/* ditto our other trap, if any    */
1236 	*(unsigned short *) stepping.trap2_addr = stepping.trap2_save;
1237 
1238       for (p = (unsigned char *) &stepping;	/* zero out the stepping context */
1239 	   p < ((unsigned char *) &stepping) + sizeof (stepping); p++)
1240 	*p = 0;
1241 
1242       return !(continue_p);
1243     }
1244   else				/* we didn't single-step, therefore this must be a legitimate stop */
1245     return 1;
1246 }
1247 
1248 struct PSWreg
1249 {				/* separate out the bit flags in the PSW register */
1250   int pad1:16;
1251   int bsm:1;
1252   int bie:1;
1253   int pad2:5;
1254   int bc:1;
1255   int sm:1;
1256   int ie:1;
1257   int pad3:5;
1258   int c:1;
1259 } *psw;
1260 
1261 /* Upon entry the value for LR to save has been pushed.
1262    We unpush that so that the value for the stack pointer saved is correct.
1263    Upon entry, all other registers are assumed to have not been modified
1264    since the interrupt/trap occured.  */
1265 
1266 asm ("\n\
1267 stash_registers:\n\
1268 	push r0\n\
1269 	push r1\n\
1270 	seth r1, #shigh(registers)\n\
1271 	add3 r1, r1, #low(registers)\n\
1272 	pop r0		; r1\n\
1273 	st r0, @(4,r1)\n\
1274 	pop r0		; r0\n\
1275 	st r0, @r1\n\
1276 	addi r1, #4	; only add 4 as subsequent saves are `pre inc'\n\
1277 	st r2, @+r1\n\
1278 	st r3, @+r1\n\
1279 	st r4, @+r1\n\
1280 	st r5, @+r1\n\
1281 	st r6, @+r1\n\
1282 	st r7, @+r1\n\
1283 	st r8, @+r1\n\
1284 	st r9, @+r1\n\
1285 	st r10, @+r1\n\
1286 	st r11, @+r1\n\
1287 	st r12, @+r1\n\
1288 	st r13, @+r1    ; fp\n\
1289 	pop r0		; lr (r14)\n\
1290 	st r0, @+r1\n\
1291 	st sp, @+r1	; sp contains right value at this point\n\
1292 	mvfc r0, cr0\n\
1293 	st r0, @+r1	; cr0 == PSW\n\
1294 	mvfc r0, cr1\n\
1295 	st r0, @+r1	; cr1 == CBR\n\
1296 	mvfc r0, cr2\n\
1297 	st r0, @+r1	; cr2 == SPI\n\
1298 	mvfc r0, cr3\n\
1299 	st r0, @+r1	; cr3 == SPU\n\
1300 	mvfc r0, cr6\n\
1301 	st r0, @+r1	; cr6 == BPC\n\
1302 	st r0, @+r1	; PC  == BPC\n\
1303 	mvfaclo r0\n\
1304 	st r0, @+r1	; ACCL\n\
1305 	mvfachi r0\n\
1306 	st r0, @+r1	; ACCH\n\
1307 	jmp lr");
1308 
1309 /* C routine to clean up what stash_registers did.
1310    It is called after calling stash_registers.
1311    This is separate from stash_registers as we want to do this in C
1312    but doing stash_registers in C isn't straightforward.  */
1313 
1314 static void
cleanup_stash(void)1315 cleanup_stash (void)
1316 {
1317   psw = (struct PSWreg *) &registers[PSW];	/* fields of PSW register */
1318   psw->sm = psw->bsm;		/* fix up pre-trap values of psw fields */
1319   psw->ie = psw->bie;
1320   psw->c = psw->bc;
1321   registers[CBR] = psw->bc;	/* fix up pre-trap "C" register */
1322 
1323 #if 0				/* FIXME: Was in previous version.  Necessary?
1324 				   (Remember that we use the "rte" insn to return from the
1325 				   trap/interrupt so the values of bsm, bie, bc are important.  */
1326   psw->bsm = psw->bie = psw->bc = 0;	/* zero post-trap values */
1327 #endif
1328 
1329   /* FIXME: Copied from previous version.  This can probably be deleted
1330      since methinks stash_registers has already done this.  */
1331   registers[PC] = registers[BPC];	/* pre-trap PC */
1332 
1333   /* FIXME: Copied from previous version.  Necessary?  */
1334   if (psw->sm)			/* copy R15 into (psw->sm ? SPU : SPI) */
1335     registers[SPU] = registers[R15];
1336   else
1337     registers[SPI] = registers[R15];
1338 }
1339 
1340 asm ("\n\
1341 restore_and_return:\n\
1342 	seth r0, #shigh(registers+8)\n\
1343 	add3 r0, r0, #low(registers+8)\n\
1344 	ld r2, @r0+	; restore r2\n\
1345 	ld r3, @r0+	; restore r3\n\
1346 	ld r4, @r0+	; restore r4\n\
1347 	ld r5, @r0+	; restore r5\n\
1348 	ld r6, @r0+	; restore r6\n\
1349 	ld r7, @r0+	; restore r7\n\
1350 	ld r8, @r0+	; restore r8\n\
1351 	ld r9, @r0+	; restore r9\n\
1352 	ld r10, @r0+	; restore r10\n\
1353 	ld r11, @r0+	; restore r11\n\
1354 	ld r12, @r0+	; restore r12\n\
1355 	ld r13, @r0+	; restore r13\n\
1356 	ld r14, @r0+	; restore r14\n\
1357 	ld r15, @r0+	; restore r15\n\
1358 	ld r1, @r0+	; restore cr0 == PSW\n\
1359 	mvtc r1, cr0\n\
1360 	ld r1, @r0+	; restore cr1 == CBR (no-op, because it's read only)\n\
1361 	mvtc r1, cr1\n\
1362 	ld r1, @r0+	; restore cr2 == SPI\n\
1363 	mvtc r1, cr2\n\
1364 	ld r1, @r0+	; restore cr3 == SPU\n\
1365 	mvtc r1, cr3\n\
1366 	addi r0, #4	; skip BPC\n\
1367 	ld r1, @r0+	; restore cr6 (BPC) == PC\n\
1368 	mvtc r1, cr6\n\
1369 	ld r1, @r0+	; restore ACCL\n\
1370 	mvtaclo r1\n\
1371 	ld r1, @r0+	; restore ACCH\n\
1372 	mvtachi r1\n\
1373 	seth r0, #shigh(registers)\n\
1374 	add3 r0, r0, #low(registers)\n\
1375 	ld r1, @(4,r0)	; restore r1\n\
1376 	ld r0, @r0	; restore r0\n\
1377 	rte");
1378 
1379 /* General trap handler, called after the registers have been stashed.
1380    NUM is the trap/exception number.  */
1381 
1382 static void
process_exception(int num)1383 process_exception (int num)
1384 {
1385   cleanup_stash ();
1386   asm volatile ("\n\
1387 	seth r1, #shigh(stackPtr)\n\
1388 	add3 r1, r1, #low(stackPtr)\n\
1389 	ld r15, @r1		; setup local stack (protect user stack)\n\
1390 	mv r0, %0\n\
1391 	bl handle_exception\n\
1392 	bl restore_and_return"::"r" (num):"r0", "r1");
1393 }
1394 
1395 void _catchException0 ();
1396 
1397 asm ("\n\
1398 _catchException0:\n\
1399 	push lr\n\
1400 	bl stash_registers\n\
1401 	; Note that at this point the pushed value of `lr' has been popped\n\
1402 	ldi r0, #0\n\
1403 	bl process_exception");
1404 
1405 void _catchException1 ();
1406 
1407 asm ("\n\
1408 _catchException1:\n\
1409 	push lr\n\
1410 	bl stash_registers\n\
1411 	; Note that at this point the pushed value of `lr' has been popped\n\
1412 	bl cleanup_stash\n\
1413 	seth r1, #shigh(stackPtr)\n\
1414 	add3 r1, r1, #low(stackPtr)\n\
1415 	ld r15, @r1		; setup local stack (protect user stack)\n\
1416 	seth r1, #shigh(registers + 21*4) ; PC\n\
1417 	add3 r1, r1, #low(registers + 21*4)\n\
1418 	ld r0, @r1\n\
1419 	addi r0, #-4		; back up PC for breakpoint trap.\n\
1420 	st r0, @r1		; FIXME: what about bp in right slot?\n\
1421 	ldi r0, #1\n\
1422 	bl handle_exception\n\
1423 	bl restore_and_return");
1424 
1425 void _catchException2 ();
1426 
1427 asm ("\n\
1428 _catchException2:\n\
1429 	push lr\n\
1430 	bl stash_registers\n\
1431 	; Note that at this point the pushed value of `lr' has been popped\n\
1432 	ldi r0, #2\n\
1433 	bl process_exception");
1434 
1435 void _catchException3 ();
1436 
1437 asm ("\n\
1438 _catchException3:\n\
1439 	push lr\n\
1440 	bl stash_registers\n\
1441 	; Note that at this point the pushed value of `lr' has been popped\n\
1442 	ldi r0, #3\n\
1443 	bl process_exception");
1444 
1445 void _catchException4 ();
1446 
1447 asm ("\n\
1448 _catchException4:\n\
1449 	push lr\n\
1450 	bl stash_registers\n\
1451 	; Note that at this point the pushed value of `lr' has been popped\n\
1452 	ldi r0, #4\n\
1453 	bl process_exception");
1454 
1455 void _catchException5 ();
1456 
1457 asm ("\n\
1458 _catchException5:\n\
1459 	push lr\n\
1460 	bl stash_registers\n\
1461 	; Note that at this point the pushed value of `lr' has been popped\n\
1462 	ldi r0, #5\n\
1463 	bl process_exception");
1464 
1465 void _catchException6 ();
1466 
1467 asm ("\n\
1468 _catchException6:\n\
1469 	push lr\n\
1470 	bl stash_registers\n\
1471 	; Note that at this point the pushed value of `lr' has been popped\n\
1472 	ldi r0, #6\n\
1473 	bl process_exception");
1474 
1475 void _catchException7 ();
1476 
1477 asm ("\n\
1478 _catchException7:\n\
1479 	push lr\n\
1480 	bl stash_registers\n\
1481 	; Note that at this point the pushed value of `lr' has been popped\n\
1482 	ldi r0, #7\n\
1483 	bl process_exception");
1484 
1485 void _catchException8 ();
1486 
1487 asm ("\n\
1488 _catchException8:\n\
1489 	push lr\n\
1490 	bl stash_registers\n\
1491 	; Note that at this point the pushed value of `lr' has been popped\n\
1492 	ldi r0, #8\n\
1493 	bl process_exception");
1494 
1495 void _catchException9 ();
1496 
1497 asm ("\n\
1498 _catchException9:\n\
1499 	push lr\n\
1500 	bl stash_registers\n\
1501 	; Note that at this point the pushed value of `lr' has been popped\n\
1502 	ldi r0, #9\n\
1503 	bl process_exception");
1504 
1505 void _catchException10 ();
1506 
1507 asm ("\n\
1508 _catchException10:\n\
1509 	push lr\n\
1510 	bl stash_registers\n\
1511 	; Note that at this point the pushed value of `lr' has been popped\n\
1512 	ldi r0, #10\n\
1513 	bl process_exception");
1514 
1515 void _catchException11 ();
1516 
1517 asm ("\n\
1518 _catchException11:\n\
1519 	push lr\n\
1520 	bl stash_registers\n\
1521 	; Note that at this point the pushed value of `lr' has been popped\n\
1522 	ldi r0, #11\n\
1523 	bl process_exception");
1524 
1525 void _catchException12 ();
1526 
1527 asm ("\n\
1528 _catchException12:\n\
1529 	push lr\n\
1530 	bl stash_registers\n\
1531 	; Note that at this point the pushed value of `lr' has been popped\n\
1532 	ldi r0, #12\n\
1533 	bl process_exception");
1534 
1535 void _catchException13 ();
1536 
1537 asm ("\n\
1538 _catchException13:\n\
1539 	push lr\n\
1540 	bl stash_registers\n\
1541 	; Note that at this point the pushed value of `lr' has been popped\n\
1542 	ldi r0, #13\n\
1543 	bl process_exception");
1544 
1545 void _catchException14 ();
1546 
1547 asm ("\n\
1548 _catchException14:\n\
1549 	push lr\n\
1550 	bl stash_registers\n\
1551 	; Note that at this point the pushed value of `lr' has been popped\n\
1552 	ldi r0, #14\n\
1553 	bl process_exception");
1554 
1555 void _catchException15 ();
1556 
1557 asm ("\n\
1558 _catchException15:\n\
1559 	push lr\n\
1560 	bl stash_registers\n\
1561 	; Note that at this point the pushed value of `lr' has been popped\n\
1562 	ldi r0, #15\n\
1563 	bl process_exception");
1564 
1565 void _catchException16 ();
1566 
1567 asm ("\n\
1568 _catchException16:\n\
1569 	push lr\n\
1570 	bl stash_registers\n\
1571 	; Note that at this point the pushed value of `lr' has been popped\n\
1572 	ldi r0, #16\n\
1573 	bl process_exception");
1574 
1575 void _catchException17 ();
1576 
1577 asm ("\n\
1578 _catchException17:\n\
1579 	push lr\n\
1580 	bl stash_registers\n\
1581 	; Note that at this point the pushed value of `lr' has been popped\n\
1582 	ldi r0, #17\n\
1583 	bl process_exception");
1584 
1585 
1586 /* this function is used to set up exception handlers for tracing and
1587    breakpoints */
1588 void
set_debug_traps(void)1589 set_debug_traps (void)
1590 {
1591   /*  extern void remcomHandler(); */
1592   int i;
1593 
1594   for (i = 0; i < 18; i++)	/* keep a copy of old vectors */
1595     if (save_vectors[i] == 0)	/* only copy them the first time */
1596       save_vectors[i] = getExceptionHandler (i);
1597 
1598   stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
1599 
1600   exceptionHandler (0, _catchException0);
1601   exceptionHandler (1, _catchException1);
1602   exceptionHandler (2, _catchException2);
1603   exceptionHandler (3, _catchException3);
1604   exceptionHandler (4, _catchException4);
1605   exceptionHandler (5, _catchException5);
1606   exceptionHandler (6, _catchException6);
1607   exceptionHandler (7, _catchException7);
1608   exceptionHandler (8, _catchException8);
1609   exceptionHandler (9, _catchException9);
1610   exceptionHandler (10, _catchException10);
1611   exceptionHandler (11, _catchException11);
1612   exceptionHandler (12, _catchException12);
1613   exceptionHandler (13, _catchException13);
1614   exceptionHandler (14, _catchException14);
1615   exceptionHandler (15, _catchException15);
1616   exceptionHandler (16, _catchException16);
1617   /*  exceptionHandler (17, _catchException17); */
1618 
1619   initialized = 1;
1620 }
1621 
1622 /* This function will generate a breakpoint exception.  It is used at the
1623    beginning of a program to sync up with a debugger and can be used
1624    otherwise as a quick means to stop program execution and "break" into
1625    the debugger. */
1626 
1627 #define BREAKPOINT() asm volatile ("	trap #2");
1628 
1629 void
breakpoint(void)1630 breakpoint (void)
1631 {
1632   if (initialized)
1633     BREAKPOINT ();
1634 }
1635 
1636 /* STDOUT section:
1637    Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
1638    Functions: gdb_putchar(char ch)
1639               gdb_puts(char *str)
1640               gdb_write(char *str, int len)
1641               gdb_error(char *format, char *parm)
1642 	      */
1643 
1644 /* Function: gdb_putchar(int)
1645    Make gdb write a char to stdout.
1646    Returns: the char */
1647 
1648 static int
gdb_putchar(int ch)1649 gdb_putchar (int ch)
1650 {
1651   char buf[4];
1652 
1653   buf[0] = 'O';
1654   buf[1] = hexchars[ch >> 4];
1655   buf[2] = hexchars[ch & 0x0F];
1656   buf[3] = 0;
1657   putpacket (buf);
1658   return ch;
1659 }
1660 
1661 /* Function: gdb_write(char *, int)
1662    Make gdb write n bytes to stdout (not assumed to be null-terminated).
1663    Returns: number of bytes written */
1664 
1665 static int
gdb_write(char * data,int len)1666 gdb_write (char *data, int len)
1667 {
1668   char *buf, *cpy;
1669   int i;
1670 
1671   buf = remcomOutBuffer;
1672   buf[0] = 'O';
1673   i = 0;
1674   while (i < len)
1675     {
1676       for (cpy = buf + 1;
1677 	   i < len && cpy < buf + sizeof (remcomOutBuffer) - 3; i++)
1678 	{
1679 	  *cpy++ = hexchars[data[i] >> 4];
1680 	  *cpy++ = hexchars[data[i] & 0x0F];
1681 	}
1682       *cpy = 0;
1683       putpacket (buf);
1684     }
1685   return len;
1686 }
1687 
1688 /* Function: gdb_puts(char *)
1689    Make gdb write a null-terminated string to stdout.
1690    Returns: the length of the string */
1691 
1692 static int
gdb_puts(char * str)1693 gdb_puts (char *str)
1694 {
1695   return gdb_write (str, strlen (str));
1696 }
1697 
1698 /* Function: gdb_error(char *, char *)
1699    Send an error message to gdb's stdout.
1700    First string may have 1 (one) optional "%s" in it, which
1701    will cause the optional second string to be inserted.  */
1702 
1703 static void
gdb_error(char * format,char * parm)1704 gdb_error (char *format, char *parm)
1705 {
1706   char buf[400], *cpy;
1707   int len;
1708 
1709   if (remote_debug)
1710     {
1711       if (format && *format)
1712 	len = strlen (format);
1713       else
1714 	return;			/* empty input */
1715 
1716       if (parm && *parm)
1717 	len += strlen (parm);
1718 
1719       for (cpy = buf; *format;)
1720 	{
1721 	  if (format[0] == '%' && format[1] == 's')	/* include second string */
1722 	    {
1723 	      format += 2;	/* advance two chars instead of just one */
1724 	      while (parm && *parm)
1725 		*cpy++ = *parm++;
1726 	    }
1727 	  else
1728 	    *cpy++ = *format++;
1729 	}
1730       *cpy = '\0';
1731       gdb_puts (buf);
1732     }
1733 }
1734 
1735 static unsigned char *
strcpy(unsigned char * dest,const unsigned char * src)1736 strcpy (unsigned char *dest, const unsigned char *src)
1737 {
1738   unsigned char *ret = dest;
1739 
1740   if (dest && src)
1741     {
1742       while (*src)
1743 	*dest++ = *src++;
1744       *dest = 0;
1745     }
1746   return ret;
1747 }
1748 
1749 static int
strlen(const unsigned char * src)1750 strlen (const unsigned char *src)
1751 {
1752   int ret;
1753 
1754   for (ret = 0; *src; src++)
1755     ret++;
1756 
1757   return ret;
1758 }
1759 
1760 #if 0
1761 void
1762 exit (code)
1763      int code;
1764 {
1765   _exit (code);
1766 }
1767 
1768 int
1769 atexit (void *p)
1770 {
1771   return 0;
1772 }
1773 
1774 void
1775 abort (void)
1776 {
1777   _exit (1);
1778 }
1779 #endif
1780