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