daily update
[external/binutils.git] / gdb / m32r-stub.c
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
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
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
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 *
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 - 1)
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
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
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
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
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
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 *
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 *
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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