1
2
3
4
5
6
7
8
9
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <errno.h>
15
16
17
18#ifndef alloca
19#ifdef __GNUC__
20#define alloca __builtin_alloca
21#else
22#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
23#include <alloca.h>
24#else
25#if defined (MSDOS) && !defined (__TURBOC__)
26#include <malloc.h>
27#else
28#if defined(_AIX)
29#include <malloc.h>
30 #pragma alloca
31#else
32#ifdef __hpux
33#endif
34#endif
35#endif
36#endif
37#endif
38#ifdef __cplusplus
39extern "C" {
40#endif
41 void* alloca(size_t);
42#ifdef __cplusplus
43}
44#endif
45#endif
46
47
48#include "serial.h"
49#include "error.h"
50#include "remote.h"
51#define REGISTER_BYTES 0
52#define fprintf_unfiltered fprintf
53#define fprintf_filtered fprintf
54#define fputs_unfiltered fputs
55#define fputs_filtered fputs
56#define fputc_unfiltered fputc
57#define fputc_filtered fputc
58#define printf_unfiltered printf
59#define printf_filtered printf
60#define puts_unfiltered puts
61#define puts_filtered puts
62#define putchar_unfiltered putchar
63#define putchar_filtered putchar
64#define fputstr_unfiltered(a,b,c) fputs((a), (c))
65#define gdb_stdlog stderr
66#define SERIAL_READCHAR(fd,timo) serialreadchar((fd), (timo))
67#define SERIAL_WRITE(fd, addr, len) serialwrite((fd), (addr), (len))
68#define error Error
69#define perror_with_name Perror
70#define gdb_flush fflush
71#define max(a,b) (((a)>(b))?(a):(b))
72#define min(a,b) (((a)<(b))?(a):(b))
73#define target_mourn_inferior() {}
74#define ULONGEST unsigned long
75#define CORE_ADDR unsigned long
76
77static int putpkt (char *);
78static int putpkt_binary(char *, int);
79static void getpkt (char *, int);
80
81static int remote_debug = 0, remote_register_buf_size = 0, watchdog = 0;
82
83int remote_desc = -1, remote_timeout = 10;
84
85static void
86fputstrn_unfiltered(char *s, int n, int x, FILE *fp)
87{
88 while (n-- > 0)
89 fputc(*s++, fp);
90}
91
92void
93remote_reset(void)
94{
95 SERIAL_WRITE(remote_desc, "+", 1);
96}
97
98void
99remote_continue(void)
100{
101 putpkt("c");
102}
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298static int remote_binary_download = 1;
299
300
301static int remote_binary_checked;
302
303
304
305#define MAXBUFBYTES(N) (((N)-32)/2)
306
307
308
309
310
311
312
313#define PBUFSIZ ((REGISTER_BYTES > MAXBUFBYTES (400)) \
314 ? (REGISTER_BYTES * 2 + 32) \
315 : 400)
316
317
318
319
320
321
322
323static int remote_write_size = 0x7fffffff;
324
325
326
327
328
329
330
331
332
333
334
335
336static int remote_address_size;
337
338
339
340static int
341fromhex (int a)
342{
343 if (a >= '0' && a <= '9')
344 return a - '0';
345 else if (a >= 'a' && a <= 'f')
346 return a - 'a' + 10;
347 else if (a >= 'A' && a <= 'F')
348 return a - 'A' + 10;
349 else {
350 error ("Reply contains invalid hex digit %d", a);
351 return -1;
352 }
353}
354
355
356
357static int
358tohex (int nib)
359{
360 if (nib < 10)
361 return '0' + nib;
362 else
363 return 'a' + nib - 10;
364}
365
366
367
368static int
369hexnumlen (ULONGEST num)
370{
371 int i;
372
373 for (i = 0; num != 0; i++)
374 num >>= 4;
375
376 return max (i, 1);
377}
378
379
380
381static int
382hexnumstr (char *buf, ULONGEST num)
383{
384 int i;
385 int len = hexnumlen (num);
386
387 buf[len] = '\0';
388
389 for (i = len - 1; i >= 0; i--)
390 {
391 buf[i] = "0123456789abcdef"[(num & 0xf)];
392 num >>= 4;
393 }
394
395 return len;
396}
397
398
399
400static CORE_ADDR
401remote_address_masked (CORE_ADDR addr)
402{
403 if (remote_address_size > 0
404 && remote_address_size < (sizeof (ULONGEST) * 8))
405 {
406
407
408 ULONGEST mask = 1;
409 mask = (mask << remote_address_size) - 1;
410 addr &= mask;
411 }
412 return addr;
413}
414
415
416
417
418
419
420
421
422
423static void
424check_binary_download (CORE_ADDR addr)
425{
426 if (remote_binary_download && !remote_binary_checked)
427 {
428 char *buf = alloca (PBUFSIZ);
429 char *p;
430 remote_binary_checked = 1;
431
432 p = buf;
433 *p++ = 'X';
434 p += hexnumstr (p, (ULONGEST) addr);
435 *p++ = ',';
436 p += hexnumstr (p, (ULONGEST) 0);
437 *p++ = ':';
438 *p = '\0';
439
440 putpkt_binary (buf, (int) (p - buf));
441 getpkt (buf, 0);
442
443 if (buf[0] == '\0')
444 remote_binary_download = 0;
445 }
446
447 if (remote_debug)
448 {
449 if (remote_binary_download)
450 fprintf_unfiltered (gdb_stdlog,
451 "binary downloading suppported by target\n");
452 else
453 fprintf_unfiltered (gdb_stdlog,
454 "binary downloading NOT suppported by target\n");
455 }
456}
457
458
459
460
461
462
463
464
465
466int
467remote_write_bytes (memaddr, myaddr, len)
468 CORE_ADDR memaddr;
469 char *myaddr;
470 int len;
471{
472 unsigned char *buf = alloca (PBUFSIZ);
473 int max_buf_size;
474 int origlen;
475 extern int verbose;
476
477
478 check_binary_download (memaddr);
479
480
481
482 max_buf_size = min (remote_write_size, PBUFSIZ);
483 if (remote_register_buf_size != 0)
484 max_buf_size = min (max_buf_size, remote_register_buf_size);
485
486
487 max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
488
489 origlen = len;
490 while (len > 0)
491 {
492 unsigned char *p, *plen;
493 int todo;
494 int i;
495
496
497
498 memaddr = remote_address_masked (memaddr);
499 p = buf;
500 if (remote_binary_download)
501 {
502 *p++ = 'X';
503 todo = min (len, max_buf_size);
504 }
505 else
506 {
507 *p++ = 'M';
508 todo = min (len, max_buf_size / 2);
509 }
510
511 p += hexnumstr ((char *)p, (ULONGEST) memaddr);
512 *p++ = ',';
513
514 plen = p;
515 p += hexnumstr ((char *)p, (ULONGEST) todo);
516 *p++ = ':';
517 *p = '\0';
518
519
520
521
522 if (remote_binary_download)
523 {
524 int escaped = 0;
525 for (i = 0;
526 (i < todo) && (i + escaped) < (max_buf_size - 2);
527 i++)
528 {
529 switch (myaddr[i] & 0xff)
530 {
531 case '$':
532 case '#':
533 case 0x7d:
534
535 escaped++;
536 *p++ = 0x7d;
537 *p++ = (myaddr[i] & 0xff) ^ 0x20;
538 break;
539 default:
540 *p++ = myaddr[i] & 0xff;
541 break;
542 }
543 }
544
545 if (i < todo)
546 {
547
548
549
550
551
552
553
554 plen += hexnumstr ((char *)plen, (ULONGEST) i);
555 *plen++ = ':';
556 }
557 }
558 else
559 {
560 for (i = 0; i < todo; i++)
561 {
562 *p++ = tohex ((myaddr[i] >> 4) & 0xf);
563 *p++ = tohex (myaddr[i] & 0xf);
564 }
565 *p = '\0';
566 }
567
568 putpkt_binary ((char *)buf, (int) (p - buf));
569 getpkt ((char *)buf, 0);
570
571 if (buf[0] == 'E')
572 {
573
574
575
576
577 errno = EIO;
578 return 0;
579 }
580
581
582
583 myaddr += i;
584 memaddr += i;
585 len -= i;
586
587 if (verbose)
588 putc('.', stderr);
589 }
590 return origlen;
591}
592
593
594
595
596
597
598static int
599readchar (int timeout)
600{
601 int ch;
602
603 ch = SERIAL_READCHAR (remote_desc, timeout);
604
605 switch (ch)
606 {
607 case SERIAL_EOF:
608 error ("Remote connection closed");
609 case SERIAL_ERROR:
610 perror_with_name ("Remote communication error");
611 case SERIAL_TIMEOUT:
612 return ch;
613 default:
614 return ch & 0x7f;
615 }
616}
617
618static int
619putpkt (buf)
620 char *buf;
621{
622 return putpkt_binary (buf, strlen (buf));
623}
624
625
626
627
628
629
630static int
631putpkt_binary (buf, cnt)
632 char *buf;
633 int cnt;
634{
635 int i;
636 unsigned char csum = 0;
637 char *buf2 = alloca (PBUFSIZ);
638 char *junkbuf = alloca (PBUFSIZ);
639
640 int ch;
641 int tcount = 0;
642 char *p;
643
644
645
646
647 if (cnt > BUFSIZ - 5)
648 abort ();
649
650 p = buf2;
651 *p++ = '$';
652
653 for (i = 0; i < cnt; i++)
654 {
655 csum += buf[i];
656 *p++ = buf[i];
657 }
658 *p++ = '#';
659 *p++ = tohex ((csum >> 4) & 0xf);
660 *p++ = tohex (csum & 0xf);
661
662
663
664 while (1)
665 {
666 int started_error_output = 0;
667
668 if (remote_debug)
669 {
670 *p = '\0';
671 fprintf_unfiltered (gdb_stdlog, "Sending packet: ");
672 fputstrn_unfiltered (buf2, p - buf2, 0, gdb_stdlog);
673 fprintf_unfiltered (gdb_stdlog, "...");
674 gdb_flush (gdb_stdlog);
675 }
676 if (SERIAL_WRITE (remote_desc, buf2, p - buf2))
677 perror_with_name ("putpkt: write failed");
678
679
680 while (1)
681 {
682 ch = readchar (remote_timeout);
683
684 if (remote_debug)
685 {
686 switch (ch)
687 {
688 case '+':
689 case SERIAL_TIMEOUT:
690 case '$':
691 if (started_error_output)
692 {
693 putchar_unfiltered ('\n');
694 started_error_output = 0;
695 }
696 }
697 }
698
699 switch (ch)
700 {
701 case '+':
702 if (remote_debug)
703 fprintf_unfiltered (gdb_stdlog, "Ack\n");
704 return 1;
705 case SERIAL_TIMEOUT:
706 tcount++;
707 if (tcount > 3)
708 return 0;
709 break;
710 case '$':
711 {
712
713
714 getpkt (junkbuf, 0);
715 continue;
716 }
717 default:
718 if (remote_debug)
719 {
720 if (!started_error_output)
721 {
722 started_error_output = 1;
723 fprintf_unfiltered (gdb_stdlog, "putpkt: Junk: ");
724 }
725 fputc_unfiltered (ch & 0177, gdb_stdlog);
726 }
727 continue;
728 }
729 break;
730 }
731
732#if 0
733
734
735
736
737
738 if (quit_flag)
739 {
740 quit_flag = 0;
741 interrupt_query ();
742 }
743#endif
744 }
745}
746
747
748
749
750
751static int
752read_frame (char *buf)
753{
754 unsigned char csum;
755 char *bp;
756 int c;
757
758 csum = 0;
759 bp = buf;
760
761 while (1)
762 {
763 c = readchar (remote_timeout);
764
765 switch (c)
766 {
767 case SERIAL_TIMEOUT:
768 if (remote_debug)
769 fputs_filtered ("Timeout in mid-packet, retrying\n", gdb_stdlog);
770 return 0;
771 case '$':
772 if (remote_debug)
773 fputs_filtered ("Saw new packet start in middle of old one\n",
774 gdb_stdlog);
775 return 0;
776 case '#':
777 {
778 unsigned char pktcsum;
779
780 *bp = '\000';
781
782 pktcsum = fromhex (readchar (remote_timeout)) << 4;
783 pktcsum |= fromhex (readchar (remote_timeout));
784
785 if (csum == pktcsum)
786 {
787 return 1;
788 }
789
790 if (remote_debug)
791 {
792 fprintf_filtered (gdb_stdlog,
793 "Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
794 pktcsum, csum);
795 fputs_filtered (buf, gdb_stdlog);
796 fputs_filtered ("\n", gdb_stdlog);
797 }
798 return 0;
799 }
800 case '*':
801 csum += c;
802 c = readchar (remote_timeout);
803 csum += c;
804 c = c - ' ' + 3;
805
806 if (c > 0 && c < 255 && bp + c - 1 < buf + PBUFSIZ - 1)
807 {
808 memset (bp, *(bp - 1), c);
809 bp += c;
810 continue;
811 }
812
813 *bp = '\0';
814 printf_filtered ("Repeat count %d too large for buffer: ", c);
815 puts_filtered (buf);
816 puts_filtered ("\n");
817 return 0;
818 default:
819 if (bp < buf + PBUFSIZ - 1)
820 {
821 *bp++ = c;
822 csum += c;
823 continue;
824 }
825
826 *bp = '\0';
827 puts_filtered ("Remote packet too long: ");
828 puts_filtered (buf);
829 puts_filtered ("\n");
830
831 return 0;
832 }
833 }
834}
835
836
837
838
839
840
841static void
842getpkt (buf, forever)
843 char *buf;
844 int forever;
845{
846 int c;
847 int tries;
848 int timeout;
849 int val;
850
851 strcpy (buf, "timeout");
852
853 if (forever)
854 {
855 timeout = watchdog > 0 ? watchdog : -1;
856 }
857
858 else
859 timeout = remote_timeout;
860
861#define MAX_TRIES 3
862
863 for (tries = 1; tries <= MAX_TRIES; tries++)
864 {
865
866
867
868
869
870
871
872
873 do
874 {
875 c = readchar (timeout);
876
877 if (c == SERIAL_TIMEOUT)
878 {
879 if (forever)
880 {
881 target_mourn_inferior ();
882 error ("Watchdog has expired. Target detached.\n");
883 }
884 if (remote_debug)
885 fputs_filtered ("Timed out.\n", gdb_stdlog);
886 goto retry;
887 }
888 }
889 while (c != '$');
890
891
892
893 val = read_frame (buf);
894
895 if (val == 1)
896 {
897 if (remote_debug)
898 {
899 fprintf_unfiltered (gdb_stdlog, "Packet received: ");
900 fputstr_unfiltered (buf, 0, gdb_stdlog);
901 fprintf_unfiltered (gdb_stdlog, "\n");
902 }
903 SERIAL_WRITE (remote_desc, "+", 1);
904 return;
905 }
906
907
908 retry:
909 SERIAL_WRITE (remote_desc, "-", 1);
910 }
911
912
913
914 printf_unfiltered ("Ignoring packet error, continuing...\n");
915 SERIAL_WRITE (remote_desc, "+", 1);
916}
917