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