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