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