xref: /rk3399_rockchip-uboot/tools/gdb/remote.c (revision 326ea986ac150acdc7656d57fca647db80b50158)
14a5b6a35Swdenk /*
24a5b6a35Swdenk  * taken from gdb/remote.c
34a5b6a35Swdenk  *
44a5b6a35Swdenk  * I am only interested in the write to memory stuff - everything else
54a5b6a35Swdenk  * has been ripped out
64a5b6a35Swdenk  *
74a5b6a35Swdenk  * all the copyright notices etc have been left in
84a5b6a35Swdenk  */
94a5b6a35Swdenk 
104a5b6a35Swdenk /* enough so that it will compile */
114a5b6a35Swdenk #include <stdio.h>
124a5b6a35Swdenk #include <stdlib.h>
134a5b6a35Swdenk #include <string.h>
144a5b6a35Swdenk #include <errno.h>
154a5b6a35Swdenk 
164a5b6a35Swdenk /*nicked from gcc..*/
174a5b6a35Swdenk 
184a5b6a35Swdenk #ifndef alloca
194a5b6a35Swdenk #ifdef __GNUC__
204a5b6a35Swdenk #define alloca __builtin_alloca
214a5b6a35Swdenk #else /* not GNU C.  */
224a5b6a35Swdenk #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
234a5b6a35Swdenk #include <alloca.h>
244a5b6a35Swdenk #else /* not sparc */
254a5b6a35Swdenk #if defined (MSDOS) && !defined (__TURBOC__)
264a5b6a35Swdenk #include <malloc.h>
274a5b6a35Swdenk #else /* not MSDOS, or __TURBOC__ */
284a5b6a35Swdenk #if defined(_AIX)
294a5b6a35Swdenk #include <malloc.h>
304a5b6a35Swdenk  #pragma alloca
314a5b6a35Swdenk #else /* not MSDOS, __TURBOC__, or _AIX */
324a5b6a35Swdenk #ifdef __hpux
334a5b6a35Swdenk #endif /* __hpux */
344a5b6a35Swdenk #endif /* not _AIX */
354a5b6a35Swdenk #endif /* not MSDOS, or __TURBOC__ */
364a5b6a35Swdenk #endif /* not sparc.  */
374a5b6a35Swdenk #endif /* not GNU C.  */
384a5b6a35Swdenk #ifdef __cplusplus
394a5b6a35Swdenk extern "C" {
404a5b6a35Swdenk #endif
414a5b6a35Swdenk     void* alloca(size_t);
424a5b6a35Swdenk #ifdef __cplusplus
434a5b6a35Swdenk }
444a5b6a35Swdenk #endif
454a5b6a35Swdenk #endif /* alloca not defined.  */
464a5b6a35Swdenk 
474a5b6a35Swdenk 
484a5b6a35Swdenk #include "serial.h"
494a5b6a35Swdenk #include "error.h"
504a5b6a35Swdenk #include "remote.h"
514a5b6a35Swdenk #define REGISTER_BYTES 0
524a5b6a35Swdenk #define fprintf_unfiltered fprintf
534a5b6a35Swdenk #define fprintf_filtered fprintf
544a5b6a35Swdenk #define fputs_unfiltered fputs
554a5b6a35Swdenk #define fputs_filtered fputs
564a5b6a35Swdenk #define fputc_unfiltered fputc
574a5b6a35Swdenk #define fputc_filtered fputc
584a5b6a35Swdenk #define printf_unfiltered printf
594a5b6a35Swdenk #define printf_filtered printf
604a5b6a35Swdenk #define puts_unfiltered puts
614a5b6a35Swdenk #define puts_filtered puts
624a5b6a35Swdenk #define putchar_unfiltered putchar
634a5b6a35Swdenk #define putchar_filtered putchar
644a5b6a35Swdenk #define fputstr_unfiltered(a,b,c) fputs((a), (c))
654a5b6a35Swdenk #define gdb_stdlog stderr
664a5b6a35Swdenk #define SERIAL_READCHAR(fd,timo)	serialreadchar((fd), (timo))
674a5b6a35Swdenk #define SERIAL_WRITE(fd, addr, len)	serialwrite((fd), (addr), (len))
684a5b6a35Swdenk #define error Error
694a5b6a35Swdenk #define perror_with_name Perror
704a5b6a35Swdenk #define gdb_flush fflush
714a5b6a35Swdenk #define max(a,b) (((a)>(b))?(a):(b))
724a5b6a35Swdenk #define min(a,b) (((a)<(b))?(a):(b))
734a5b6a35Swdenk #define target_mourn_inferior() {}
744a5b6a35Swdenk #define ULONGEST unsigned long
754a5b6a35Swdenk #define CORE_ADDR unsigned long
764a5b6a35Swdenk 
774a5b6a35Swdenk static int putpkt (char *);
784a5b6a35Swdenk static int putpkt_binary(char *, int);
794a5b6a35Swdenk static void getpkt (char *, int);
804a5b6a35Swdenk 
814a5b6a35Swdenk static int remote_debug = 0, remote_register_buf_size = 0, watchdog = 0;
824a5b6a35Swdenk 
834a5b6a35Swdenk int remote_desc = -1, remote_timeout = 10;
844a5b6a35Swdenk 
854a5b6a35Swdenk static void
fputstrn_unfiltered(char * s,int n,int x,FILE * fp)864a5b6a35Swdenk fputstrn_unfiltered(char *s, int n, int x, FILE *fp)
874a5b6a35Swdenk {
884a5b6a35Swdenk     while (n-- > 0)
894a5b6a35Swdenk 	fputc(*s++, fp);
904a5b6a35Swdenk }
914a5b6a35Swdenk 
924a5b6a35Swdenk void
remote_reset(void)934a5b6a35Swdenk remote_reset(void)
944a5b6a35Swdenk {
954a5b6a35Swdenk     SERIAL_WRITE(remote_desc, "+", 1);
964a5b6a35Swdenk }
974a5b6a35Swdenk 
984a5b6a35Swdenk void
remote_continue(void)994a5b6a35Swdenk remote_continue(void)
1004a5b6a35Swdenk {
1014a5b6a35Swdenk     putpkt("c");
1024a5b6a35Swdenk }
1034a5b6a35Swdenk 
1044a5b6a35Swdenk /* Remote target communications for serial-line targets in custom GDB protocol
1054a5b6a35Swdenk    Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 98, 1999
1064a5b6a35Swdenk    Free Software Foundation, Inc.
1074a5b6a35Swdenk 
1084a5b6a35Swdenk    This file is part of GDB.
1094a5b6a35Swdenk 
110*1a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
111*1a459660SWolfgang Denk  */
1124a5b6a35Swdenk /* *INDENT-OFF* */
1134a5b6a35Swdenk /* Remote communication protocol.
1144a5b6a35Swdenk 
1154a5b6a35Swdenk    A debug packet whose contents are <data>
1164a5b6a35Swdenk    is encapsulated for transmission in the form:
1174a5b6a35Swdenk 
1184a5b6a35Swdenk 	$ <data> # CSUM1 CSUM2
1194a5b6a35Swdenk 
1204a5b6a35Swdenk 	<data> must be ASCII alphanumeric and cannot include characters
1214a5b6a35Swdenk 	'$' or '#'.  If <data> starts with two characters followed by
1224a5b6a35Swdenk 	':', then the existing stubs interpret this as a sequence number.
1234a5b6a35Swdenk 
1244a5b6a35Swdenk 	CSUM1 and CSUM2 are ascii hex representation of an 8-bit
1254a5b6a35Swdenk 	checksum of <data>, the most significant nibble is sent first.
1264a5b6a35Swdenk 	the hex digits 0-9,a-f are used.
1274a5b6a35Swdenk 
1284a5b6a35Swdenk    Receiver responds with:
1294a5b6a35Swdenk 
1304a5b6a35Swdenk 	+	- if CSUM is correct and ready for next packet
1314a5b6a35Swdenk 	-	- if CSUM is incorrect
1324a5b6a35Swdenk 
1334a5b6a35Swdenk    <data> is as follows:
1344a5b6a35Swdenk    Most values are encoded in ascii hex digits.  Signal numbers are according
1354a5b6a35Swdenk    to the numbering in target.h.
1364a5b6a35Swdenk 
1374a5b6a35Swdenk 	Request		Packet
1384a5b6a35Swdenk 
1394a5b6a35Swdenk 	set thread	Hct...		Set thread for subsequent operations.
1404a5b6a35Swdenk 					c = 'c' for thread used in step and
1414a5b6a35Swdenk 					continue; t... can be -1 for all
1424a5b6a35Swdenk 					threads.
1434a5b6a35Swdenk 					c = 'g' for thread used in other
1444a5b6a35Swdenk 					operations.  If zero, pick a thread,
1454a5b6a35Swdenk 					any thread.
1464a5b6a35Swdenk 	reply		OK		for success
1474a5b6a35Swdenk 			ENN		for an error.
1484a5b6a35Swdenk 
1494a5b6a35Swdenk 	read registers  g
1504a5b6a35Swdenk 	reply		XX....X		Each byte of register data
1514a5b6a35Swdenk 					is described by two hex digits.
1524a5b6a35Swdenk 					Registers are in the internal order
1534a5b6a35Swdenk 					for GDB, and the bytes in a register
1544a5b6a35Swdenk 					are in the same order the machine uses.
1554a5b6a35Swdenk 			or ENN		for an error.
1564a5b6a35Swdenk 
1574a5b6a35Swdenk 	write regs	GXX..XX		Each byte of register data
1584a5b6a35Swdenk 					is described by two hex digits.
1594a5b6a35Swdenk 	reply		OK		for success
1604a5b6a35Swdenk 			ENN		for an error
1614a5b6a35Swdenk 
1624a5b6a35Swdenk 	write reg	Pn...=r...	Write register n... with value r...,
1634a5b6a35Swdenk 					which contains two hex digits for each
1644a5b6a35Swdenk 					byte in the register (target byte
1654a5b6a35Swdenk 					order).
1664a5b6a35Swdenk 	reply		OK		for success
1674a5b6a35Swdenk 			ENN		for an error
1684a5b6a35Swdenk 	(not supported by all stubs).
1694a5b6a35Swdenk 
1704a5b6a35Swdenk 	read mem	mAA..AA,LLLL	AA..AA is address, LLLL is length.
1714a5b6a35Swdenk 	reply		XX..XX		XX..XX is mem contents
1724a5b6a35Swdenk 					Can be fewer bytes than requested
1734a5b6a35Swdenk 					if able to read only part of the data.
1744a5b6a35Swdenk 			or ENN		NN is errno
1754a5b6a35Swdenk 
1764a5b6a35Swdenk 	write mem	MAA..AA,LLLL:XX..XX
1774a5b6a35Swdenk 					AA..AA is address,
1784a5b6a35Swdenk 					LLLL is number of bytes,
1794a5b6a35Swdenk 					XX..XX is data
1804a5b6a35Swdenk 	reply		OK		for success
1814a5b6a35Swdenk 			ENN		for an error (this includes the case
1824a5b6a35Swdenk 					where only part of the data was
1834a5b6a35Swdenk 					written).
1844a5b6a35Swdenk 
1854a5b6a35Swdenk 	write mem       XAA..AA,LLLL:XX..XX
1864a5b6a35Swdenk 	 (binary)                       AA..AA is address,
1874a5b6a35Swdenk 					LLLL is number of bytes,
1884a5b6a35Swdenk 					XX..XX is binary data
1894a5b6a35Swdenk 	reply           OK              for success
1904a5b6a35Swdenk 			ENN             for an error
1914a5b6a35Swdenk 
1924a5b6a35Swdenk 	continue	cAA..AA		AA..AA is address to resume
1934a5b6a35Swdenk 					If AA..AA is omitted,
1944a5b6a35Swdenk 					resume at same address.
1954a5b6a35Swdenk 
1964a5b6a35Swdenk 	step		sAA..AA		AA..AA is address to resume
1974a5b6a35Swdenk 					If AA..AA is omitted,
1984a5b6a35Swdenk 					resume at same address.
1994a5b6a35Swdenk 
2004a5b6a35Swdenk 	continue with	Csig;AA..AA	Continue with signal sig (hex signal
2014a5b6a35Swdenk 	signal				number).  If ;AA..AA is omitted,
2024a5b6a35Swdenk 					resume at same address.
2034a5b6a35Swdenk 
2044a5b6a35Swdenk 	step with	Ssig;AA..AA	Like 'C' but step not continue.
2054a5b6a35Swdenk 	signal
2064a5b6a35Swdenk 
2074a5b6a35Swdenk 	last signal     ?               Reply the current reason for stopping.
2084a5b6a35Swdenk 					This is the same reply as is generated
2094a5b6a35Swdenk 					for step or cont : SAA where AA is the
2104a5b6a35Swdenk 					signal number.
2114a5b6a35Swdenk 
2124a5b6a35Swdenk 	detach          D               Reply OK.
2134a5b6a35Swdenk 
2144a5b6a35Swdenk 	There is no immediate reply to step or cont.
2154a5b6a35Swdenk 	The reply comes when the machine stops.
2164a5b6a35Swdenk 	It is		SAA		AA is the signal number.
2174a5b6a35Swdenk 
2184a5b6a35Swdenk 	or...		TAAn...:r...;n...:r...;n...:r...;
2194a5b6a35Swdenk 					AA = signal number
2204a5b6a35Swdenk 					n... = register number (hex)
2214a5b6a35Swdenk 					  r... = register contents
2224a5b6a35Swdenk 					n... = `thread'
2234a5b6a35Swdenk 					  r... = thread process ID.  This is
2244a5b6a35Swdenk 						 a hex integer.
2254a5b6a35Swdenk 					n... = other string not starting
2264a5b6a35Swdenk 					    with valid hex digit.
2274a5b6a35Swdenk 					  gdb should ignore this n,r pair
2284a5b6a35Swdenk 					  and go on to the next.  This way
2294a5b6a35Swdenk 					  we can extend the protocol.
2304a5b6a35Swdenk 	or...		WAA		The process exited, and AA is
2314a5b6a35Swdenk 					the exit status.  This is only
2324a5b6a35Swdenk 					applicable for certains sorts of
2334a5b6a35Swdenk 					targets.
2344a5b6a35Swdenk 	or...		XAA		The process terminated with signal
2354a5b6a35Swdenk 					AA.
2364a5b6a35Swdenk 	or (obsolete)	NAA;tttttttt;dddddddd;bbbbbbbb
2374a5b6a35Swdenk 					AA = signal number
2384a5b6a35Swdenk 					tttttttt = address of symbol "_start"
2394a5b6a35Swdenk 					dddddddd = base of data section
2404a5b6a35Swdenk 					bbbbbbbb = base of bss  section.
2414a5b6a35Swdenk 					Note: only used by Cisco Systems
2424a5b6a35Swdenk 					targets.  The difference between this
2434a5b6a35Swdenk 					reply and the "qOffsets" query is that
2444a5b6a35Swdenk 					the 'N' packet may arrive spontaneously
2454a5b6a35Swdenk 					whereas the 'qOffsets' is a query
2464a5b6a35Swdenk 					initiated by the host debugger.
2474a5b6a35Swdenk 	or...           OXX..XX	XX..XX  is hex encoding of ASCII data. This
2484a5b6a35Swdenk 					can happen at any time while the
2494a5b6a35Swdenk 					program is running and the debugger
2504a5b6a35Swdenk 					should continue to wait for
2514a5b6a35Swdenk 					'W', 'T', etc.
2524a5b6a35Swdenk 
2534a5b6a35Swdenk 	thread alive	TXX		Find out if the thread XX is alive.
2544a5b6a35Swdenk 	reply		OK		thread is still alive
2554a5b6a35Swdenk 			ENN		thread is dead
2564a5b6a35Swdenk 
2574a5b6a35Swdenk 	remote restart	RXX		Restart the remote server
2584a5b6a35Swdenk 
2594a5b6a35Swdenk 	extended ops	!		Use the extended remote protocol.
2604a5b6a35Swdenk 					Sticky -- only needs to be set once.
2614a5b6a35Swdenk 
2624a5b6a35Swdenk 	kill request	k
2634a5b6a35Swdenk 
2644a5b6a35Swdenk 	toggle debug	d		toggle debug flag (see 386 & 68k stubs)
2654a5b6a35Swdenk 	reset		r		reset -- see sparc stub.
2664a5b6a35Swdenk 	reserved	<other>		On other requests, the stub should
2674a5b6a35Swdenk 					ignore the request and send an empty
2684a5b6a35Swdenk 					response ($#<checksum>).  This way
2694a5b6a35Swdenk 					we can extend the protocol and GDB
2704a5b6a35Swdenk 					can tell whether the stub it is
2714a5b6a35Swdenk 					talking to uses the old or the new.
2724a5b6a35Swdenk 	search		tAA:PP,MM	Search backwards starting at address
2734a5b6a35Swdenk 					AA for a match with pattern PP and
2744a5b6a35Swdenk 					mask MM.  PP and MM are 4 bytes.
2754a5b6a35Swdenk 					Not supported by all stubs.
2764a5b6a35Swdenk 
2774a5b6a35Swdenk 	general query	qXXXX		Request info about XXXX.
2784a5b6a35Swdenk 	general set	QXXXX=yyyy	Set value of XXXX to yyyy.
2794a5b6a35Swdenk 	query sect offs	qOffsets	Get section offsets.  Reply is
2804a5b6a35Swdenk 					Text=xxx;Data=yyy;Bss=zzz
2814a5b6a35Swdenk 
2824a5b6a35Swdenk 	Responses can be run-length encoded to save space.  A '*' means that
2834a5b6a35Swdenk 	the next character is an ASCII encoding giving a repeat count which
2844a5b6a35Swdenk 	stands for that many repititions of the character preceding the '*'.
2854a5b6a35Swdenk 	The encoding is n+29, yielding a printable character where n >=3
2864a5b6a35Swdenk 	(which is where rle starts to win).  Don't use an n > 126.
2874a5b6a35Swdenk 
2884a5b6a35Swdenk 	So
2894a5b6a35Swdenk 	"0* " means the same as "0000".  */
2904a5b6a35Swdenk /* *INDENT-ON* */
2914a5b6a35Swdenk 
2924a5b6a35Swdenk /* This variable (available to the user via "set remotebinarydownload")
2934a5b6a35Swdenk    dictates whether downloads are sent in binary (via the 'X' packet).
2944a5b6a35Swdenk    We assume that the stub can, and attempt to do it. This will be cleared if
2954a5b6a35Swdenk    the stub does not understand it. This switch is still needed, though
2964a5b6a35Swdenk    in cases when the packet is supported in the stub, but the connection
2974a5b6a35Swdenk    does not allow it (i.e., 7-bit serial connection only). */
2984a5b6a35Swdenk static int remote_binary_download = 1;
2994a5b6a35Swdenk 
3004a5b6a35Swdenk /* Have we already checked whether binary downloads work? */
3014a5b6a35Swdenk static int remote_binary_checked;
3024a5b6a35Swdenk 
3034a5b6a35Swdenk /* Maximum number of bytes to read/write at once.  The value here
3044a5b6a35Swdenk    is chosen to fill up a packet (the headers account for the 32).  */
3054a5b6a35Swdenk #define MAXBUFBYTES(N) (((N)-32)/2)
3064a5b6a35Swdenk 
3074a5b6a35Swdenk /* Having this larger than 400 causes us to be incompatible with m68k-stub.c
3084a5b6a35Swdenk    and i386-stub.c.  Normally, no one would notice because it only matters
3094a5b6a35Swdenk    for writing large chunks of memory (e.g. in downloads).  Also, this needs
3104a5b6a35Swdenk    to be more than 400 if required to hold the registers (see below, where
3114a5b6a35Swdenk    we round it up based on REGISTER_BYTES).  */
3124a5b6a35Swdenk /* Round up PBUFSIZ to hold all the registers, at least.  */
3134a5b6a35Swdenk #define	PBUFSIZ ((REGISTER_BYTES > MAXBUFBYTES (400)) \
3144a5b6a35Swdenk 		 ? (REGISTER_BYTES * 2 + 32) \
3154a5b6a35Swdenk 		 : 400)
3164a5b6a35Swdenk 
3174a5b6a35Swdenk 
3184a5b6a35Swdenk /* This variable sets the number of bytes to be written to the target
3194a5b6a35Swdenk    in a single packet.  Normally PBUFSIZ is satisfactory, but some
3204a5b6a35Swdenk    targets need smaller values (perhaps because the receiving end
3214a5b6a35Swdenk    is slow).  */
3224a5b6a35Swdenk 
3234a5b6a35Swdenk static int remote_write_size = 0x7fffffff;
3244a5b6a35Swdenk 
3254a5b6a35Swdenk /* This variable sets the number of bits in an address that are to be
3264a5b6a35Swdenk    sent in a memory ("M" or "m") packet.  Normally, after stripping
3274a5b6a35Swdenk    leading zeros, the entire address would be sent. This variable
3284a5b6a35Swdenk    restricts the address to REMOTE_ADDRESS_SIZE bits.  HISTORY: The
3294a5b6a35Swdenk    initial implementation of remote.c restricted the address sent in
3304a5b6a35Swdenk    memory packets to ``host::sizeof long'' bytes - (typically 32
3314a5b6a35Swdenk    bits).  Consequently, for 64 bit targets, the upper 32 bits of an
3324a5b6a35Swdenk    address was never sent.  Since fixing this bug may cause a break in
3334a5b6a35Swdenk    some remote targets this variable is principly provided to
3344a5b6a35Swdenk    facilitate backward compatibility. */
3354a5b6a35Swdenk 
3364a5b6a35Swdenk static int remote_address_size;
3374a5b6a35Swdenk 
3384a5b6a35Swdenk /* Convert hex digit A to a number.  */
3394a5b6a35Swdenk 
3404a5b6a35Swdenk static int
fromhex(int a)3414a5b6a35Swdenk fromhex (int a)
3424a5b6a35Swdenk {
3434a5b6a35Swdenk   if (a >= '0' && a <= '9')
3444a5b6a35Swdenk     return a - '0';
3454a5b6a35Swdenk   else if (a >= 'a' && a <= 'f')
3464a5b6a35Swdenk     return a - 'a' + 10;
3474a5b6a35Swdenk   else if (a >= 'A' && a <= 'F')
3484a5b6a35Swdenk     return a - 'A' + 10;
3494a5b6a35Swdenk   else {
3504a5b6a35Swdenk     error ("Reply contains invalid hex digit %d", a);
3514a5b6a35Swdenk     return -1;
3524a5b6a35Swdenk   }
3534a5b6a35Swdenk }
3544a5b6a35Swdenk 
3554a5b6a35Swdenk /* Convert number NIB to a hex digit.  */
3564a5b6a35Swdenk 
3574a5b6a35Swdenk static int
tohex(int nib)3584a5b6a35Swdenk tohex (int nib)
3594a5b6a35Swdenk {
3604a5b6a35Swdenk   if (nib < 10)
3614a5b6a35Swdenk     return '0' + nib;
3624a5b6a35Swdenk   else
3634a5b6a35Swdenk     return 'a' + nib - 10;
3644a5b6a35Swdenk }
3654a5b6a35Swdenk 
3664a5b6a35Swdenk /* Return the number of hex digits in num.  */
3674a5b6a35Swdenk 
3684a5b6a35Swdenk static int
hexnumlen(ULONGEST num)3694a5b6a35Swdenk hexnumlen (ULONGEST num)
3704a5b6a35Swdenk {
3714a5b6a35Swdenk   int i;
3724a5b6a35Swdenk 
3734a5b6a35Swdenk   for (i = 0; num != 0; i++)
3744a5b6a35Swdenk     num >>= 4;
3754a5b6a35Swdenk 
3764a5b6a35Swdenk   return max (i, 1);
3774a5b6a35Swdenk }
3784a5b6a35Swdenk 
3794a5b6a35Swdenk /* Set BUF to the hex digits representing NUM.  */
3804a5b6a35Swdenk 
3814a5b6a35Swdenk static int
hexnumstr(char * buf,ULONGEST num)3824a5b6a35Swdenk hexnumstr (char *buf, ULONGEST num)
3834a5b6a35Swdenk {
3844a5b6a35Swdenk   int i;
3854a5b6a35Swdenk   int len = hexnumlen (num);
3864a5b6a35Swdenk 
3874a5b6a35Swdenk   buf[len] = '\0';
3884a5b6a35Swdenk 
3894a5b6a35Swdenk   for (i = len - 1; i >= 0; i--)
3904a5b6a35Swdenk     {
3914a5b6a35Swdenk       buf[i] = "0123456789abcdef"[(num & 0xf)];
3924a5b6a35Swdenk       num >>= 4;
3934a5b6a35Swdenk     }
3944a5b6a35Swdenk 
3954a5b6a35Swdenk   return len;
3964a5b6a35Swdenk }
3974a5b6a35Swdenk 
3984a5b6a35Swdenk /* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
3994a5b6a35Swdenk 
4004a5b6a35Swdenk static CORE_ADDR
remote_address_masked(CORE_ADDR addr)4014a5b6a35Swdenk remote_address_masked (CORE_ADDR addr)
4024a5b6a35Swdenk {
4034a5b6a35Swdenk   if (remote_address_size > 0
4044a5b6a35Swdenk       && remote_address_size < (sizeof (ULONGEST) * 8))
4054a5b6a35Swdenk     {
4064a5b6a35Swdenk       /* Only create a mask when that mask can safely be constructed
4074a5b6a35Swdenk 	 in a ULONGEST variable. */
4084a5b6a35Swdenk       ULONGEST mask = 1;
4094a5b6a35Swdenk       mask = (mask << remote_address_size) - 1;
4104a5b6a35Swdenk       addr &= mask;
4114a5b6a35Swdenk     }
4124a5b6a35Swdenk   return addr;
4134a5b6a35Swdenk }
4144a5b6a35Swdenk 
4154a5b6a35Swdenk /* Determine whether the remote target supports binary downloading.
4164a5b6a35Swdenk    This is accomplished by sending a no-op memory write of zero length
4174a5b6a35Swdenk    to the target at the specified address. It does not suffice to send
4184a5b6a35Swdenk    the whole packet, since many stubs strip the eighth bit and subsequently
4194a5b6a35Swdenk    compute a wrong checksum, which causes real havoc with remote_write_bytes.
4204a5b6a35Swdenk 
4214a5b6a35Swdenk    NOTE: This can still lose if the serial line is not eight-bit clean. In
4224a5b6a35Swdenk    cases like this, the user should clear "remotebinarydownload". */
4234a5b6a35Swdenk static void
check_binary_download(CORE_ADDR addr)4244a5b6a35Swdenk check_binary_download (CORE_ADDR addr)
4254a5b6a35Swdenk {
4264a5b6a35Swdenk   if (remote_binary_download && !remote_binary_checked)
4274a5b6a35Swdenk     {
4284a5b6a35Swdenk       char *buf = alloca (PBUFSIZ);
4294a5b6a35Swdenk       char *p;
4304a5b6a35Swdenk       remote_binary_checked = 1;
4314a5b6a35Swdenk 
4324a5b6a35Swdenk       p = buf;
4334a5b6a35Swdenk       *p++ = 'X';
4344a5b6a35Swdenk       p += hexnumstr (p, (ULONGEST) addr);
4354a5b6a35Swdenk       *p++ = ',';
4364a5b6a35Swdenk       p += hexnumstr (p, (ULONGEST) 0);
4374a5b6a35Swdenk       *p++ = ':';
4384a5b6a35Swdenk       *p = '\0';
4394a5b6a35Swdenk 
4404a5b6a35Swdenk       putpkt_binary (buf, (int) (p - buf));
4414a5b6a35Swdenk       getpkt (buf, 0);
4424a5b6a35Swdenk 
4434a5b6a35Swdenk       if (buf[0] == '\0')
4444a5b6a35Swdenk 	remote_binary_download = 0;
4454a5b6a35Swdenk     }
4464a5b6a35Swdenk 
4474a5b6a35Swdenk   if (remote_debug)
4484a5b6a35Swdenk     {
4494a5b6a35Swdenk       if (remote_binary_download)
4504a5b6a35Swdenk 	fprintf_unfiltered (gdb_stdlog,
4514a5b6a35Swdenk 			    "binary downloading suppported by target\n");
4524a5b6a35Swdenk       else
4534a5b6a35Swdenk 	fprintf_unfiltered (gdb_stdlog,
4544a5b6a35Swdenk 			    "binary downloading NOT suppported by target\n");
4554a5b6a35Swdenk     }
4564a5b6a35Swdenk }
4574a5b6a35Swdenk 
4584a5b6a35Swdenk /* Write memory data directly to the remote machine.
4594a5b6a35Swdenk    This does not inform the data cache; the data cache uses this.
4604a5b6a35Swdenk    MEMADDR is the address in the remote memory space.
4614a5b6a35Swdenk    MYADDR is the address of the buffer in our space.
4624a5b6a35Swdenk    LEN is the number of bytes.
4634a5b6a35Swdenk 
4644a5b6a35Swdenk    Returns number of bytes transferred, or 0 for error.  */
4654a5b6a35Swdenk 
4664a5b6a35Swdenk int
remote_write_bytes(memaddr,myaddr,len)4674a5b6a35Swdenk remote_write_bytes (memaddr, myaddr, len)
4684a5b6a35Swdenk      CORE_ADDR memaddr;
4694a5b6a35Swdenk      char *myaddr;
4704a5b6a35Swdenk      int len;
4714a5b6a35Swdenk {
4724a5b6a35Swdenk   unsigned char *buf = alloca (PBUFSIZ);
4734a5b6a35Swdenk   int max_buf_size;		/* Max size of packet output buffer */
4744a5b6a35Swdenk   int origlen;
4754a5b6a35Swdenk   extern int verbose;
4764a5b6a35Swdenk 
4774a5b6a35Swdenk   /* Verify that the target can support a binary download */
4784a5b6a35Swdenk   check_binary_download (memaddr);
4794a5b6a35Swdenk 
4804a5b6a35Swdenk   /* Chop the transfer down if necessary */
4814a5b6a35Swdenk 
4824a5b6a35Swdenk   max_buf_size = min (remote_write_size, PBUFSIZ);
4834a5b6a35Swdenk   if (remote_register_buf_size != 0)
4844a5b6a35Swdenk     max_buf_size = min (max_buf_size, remote_register_buf_size);
4854a5b6a35Swdenk 
4864a5b6a35Swdenk   /* Subtract header overhead from max payload size -  $M<memaddr>,<len>:#nn */
4874a5b6a35Swdenk   max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
4884a5b6a35Swdenk 
4894a5b6a35Swdenk   origlen = len;
4904a5b6a35Swdenk   while (len > 0)
4914a5b6a35Swdenk     {
4924a5b6a35Swdenk       unsigned char *p, *plen;
4934a5b6a35Swdenk       int todo;
4944a5b6a35Swdenk       int i;
4954a5b6a35Swdenk 
4964a5b6a35Swdenk       /* construct "M"<memaddr>","<len>":" */
4974a5b6a35Swdenk       /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
4984a5b6a35Swdenk       memaddr = remote_address_masked (memaddr);
4994a5b6a35Swdenk       p = buf;
5004a5b6a35Swdenk       if (remote_binary_download)
5014a5b6a35Swdenk 	{
5024a5b6a35Swdenk 	  *p++ = 'X';
5034a5b6a35Swdenk 	  todo = min (len, max_buf_size);
5044a5b6a35Swdenk 	}
5054a5b6a35Swdenk       else
5064a5b6a35Swdenk 	{
5074a5b6a35Swdenk 	  *p++ = 'M';
5084a5b6a35Swdenk 	  todo = min (len, max_buf_size / 2);	/* num bytes that will fit */
5094a5b6a35Swdenk 	}
5104a5b6a35Swdenk 
5114a5b6a35Swdenk       p += hexnumstr ((char *)p, (ULONGEST) memaddr);
5124a5b6a35Swdenk       *p++ = ',';
5134a5b6a35Swdenk 
5144a5b6a35Swdenk       plen = p;			/* remember where len field goes */
5154a5b6a35Swdenk       p += hexnumstr ((char *)p, (ULONGEST) todo);
5164a5b6a35Swdenk       *p++ = ':';
5174a5b6a35Swdenk       *p = '\0';
5184a5b6a35Swdenk 
5194a5b6a35Swdenk       /* We send target system values byte by byte, in increasing byte
5204a5b6a35Swdenk 	 addresses, each byte encoded as two hex characters (or one
5214a5b6a35Swdenk 	 binary character).  */
5224a5b6a35Swdenk       if (remote_binary_download)
5234a5b6a35Swdenk 	{
5244a5b6a35Swdenk 	  int escaped = 0;
5254a5b6a35Swdenk 	  for (i = 0;
5264a5b6a35Swdenk 	       (i < todo) && (i + escaped) < (max_buf_size - 2);
5274a5b6a35Swdenk 	       i++)
5284a5b6a35Swdenk 	    {
5294a5b6a35Swdenk 	      switch (myaddr[i] & 0xff)
5304a5b6a35Swdenk 		{
5314a5b6a35Swdenk 		case '$':
5324a5b6a35Swdenk 		case '#':
5334a5b6a35Swdenk 		case 0x7d:
5344a5b6a35Swdenk 		  /* These must be escaped */
5354a5b6a35Swdenk 		  escaped++;
5364a5b6a35Swdenk 		  *p++ = 0x7d;
5374a5b6a35Swdenk 		  *p++ = (myaddr[i] & 0xff) ^ 0x20;
5384a5b6a35Swdenk 		  break;
5394a5b6a35Swdenk 		default:
5404a5b6a35Swdenk 		  *p++ = myaddr[i] & 0xff;
5414a5b6a35Swdenk 		  break;
5424a5b6a35Swdenk 		}
5434a5b6a35Swdenk 	    }
5444a5b6a35Swdenk 
5454a5b6a35Swdenk 	  if (i < todo)
5464a5b6a35Swdenk 	    {
5474a5b6a35Swdenk 	      /* Escape chars have filled up the buffer prematurely,
5484a5b6a35Swdenk 		 and we have actually sent fewer bytes than planned.
5494a5b6a35Swdenk 		 Fix-up the length field of the packet.  */
5504a5b6a35Swdenk 
5514a5b6a35Swdenk 	      /* FIXME: will fail if new len is a shorter string than
5524a5b6a35Swdenk 		 old len.  */
5534a5b6a35Swdenk 
5544a5b6a35Swdenk 	      plen += hexnumstr ((char *)plen, (ULONGEST) i);
5554a5b6a35Swdenk 	      *plen++ = ':';
5564a5b6a35Swdenk 	    }
5574a5b6a35Swdenk 	}
5584a5b6a35Swdenk       else
5594a5b6a35Swdenk 	{
5604a5b6a35Swdenk 	  for (i = 0; i < todo; i++)
5614a5b6a35Swdenk 	    {
5624a5b6a35Swdenk 	      *p++ = tohex ((myaddr[i] >> 4) & 0xf);
5634a5b6a35Swdenk 	      *p++ = tohex (myaddr[i] & 0xf);
5644a5b6a35Swdenk 	    }
5654a5b6a35Swdenk 	  *p = '\0';
5664a5b6a35Swdenk 	}
5674a5b6a35Swdenk 
5684a5b6a35Swdenk       putpkt_binary ((char *)buf, (int) (p - buf));
5694a5b6a35Swdenk       getpkt ((char *)buf, 0);
5704a5b6a35Swdenk 
5714a5b6a35Swdenk       if (buf[0] == 'E')
5724a5b6a35Swdenk 	{
5734a5b6a35Swdenk 	  /* There is no correspondance between what the remote protocol uses
5744a5b6a35Swdenk 	     for errors and errno codes.  We would like a cleaner way of
5754a5b6a35Swdenk 	     representing errors (big enough to include errno codes, bfd_error
5764a5b6a35Swdenk 	     codes, and others).  But for now just return EIO.  */
5774a5b6a35Swdenk 	  errno = EIO;
5784a5b6a35Swdenk 	  return 0;
5794a5b6a35Swdenk 	}
5804a5b6a35Swdenk 
5814a5b6a35Swdenk       /* Increment by i, not by todo, in case escape chars
5824a5b6a35Swdenk 	 caused us to send fewer bytes than we'd planned.  */
5834a5b6a35Swdenk       myaddr += i;
5844a5b6a35Swdenk       memaddr += i;
5854a5b6a35Swdenk       len -= i;
5864a5b6a35Swdenk 
5874a5b6a35Swdenk       if (verbose)
5884a5b6a35Swdenk 	putc('.', stderr);
5894a5b6a35Swdenk     }
5904a5b6a35Swdenk   return origlen;
5914a5b6a35Swdenk }
5924a5b6a35Swdenk 
5934a5b6a35Swdenk /* Stuff for dealing with the packets which are part of this protocol.
5944a5b6a35Swdenk    See comment at top of file for details.  */
5954a5b6a35Swdenk 
5964a5b6a35Swdenk /* Read a single character from the remote end, masking it down to 7 bits. */
5974a5b6a35Swdenk 
5984a5b6a35Swdenk static int
readchar(int timeout)5994a5b6a35Swdenk readchar (int timeout)
6004a5b6a35Swdenk {
6014a5b6a35Swdenk   int ch;
6024a5b6a35Swdenk 
6034a5b6a35Swdenk   ch = SERIAL_READCHAR (remote_desc, timeout);
6044a5b6a35Swdenk 
6054a5b6a35Swdenk   switch (ch)
6064a5b6a35Swdenk     {
6074a5b6a35Swdenk     case SERIAL_EOF:
6084a5b6a35Swdenk       error ("Remote connection closed");
6094a5b6a35Swdenk     case SERIAL_ERROR:
6104a5b6a35Swdenk       perror_with_name ("Remote communication error");
6114a5b6a35Swdenk     case SERIAL_TIMEOUT:
6124a5b6a35Swdenk       return ch;
6134a5b6a35Swdenk     default:
6144a5b6a35Swdenk       return ch & 0x7f;
6154a5b6a35Swdenk     }
6164a5b6a35Swdenk }
6174a5b6a35Swdenk 
6184a5b6a35Swdenk static int
putpkt(buf)6194a5b6a35Swdenk putpkt (buf)
6204a5b6a35Swdenk      char *buf;
6214a5b6a35Swdenk {
6224a5b6a35Swdenk   return putpkt_binary (buf, strlen (buf));
6234a5b6a35Swdenk }
6244a5b6a35Swdenk 
6254a5b6a35Swdenk /* Send a packet to the remote machine, with error checking.  The data
6264a5b6a35Swdenk    of the packet is in BUF.  The string in BUF can be at most  PBUFSIZ - 5
6274a5b6a35Swdenk    to account for the $, # and checksum, and for a possible /0 if we are
6284a5b6a35Swdenk    debugging (remote_debug) and want to print the sent packet as a string */
6294a5b6a35Swdenk 
6304a5b6a35Swdenk static int
putpkt_binary(buf,cnt)6314a5b6a35Swdenk putpkt_binary (buf, cnt)
6324a5b6a35Swdenk      char *buf;
6334a5b6a35Swdenk      int cnt;
6344a5b6a35Swdenk {
6354a5b6a35Swdenk   int i;
6364a5b6a35Swdenk   unsigned char csum = 0;
6374a5b6a35Swdenk   char *buf2 = alloca (PBUFSIZ);
6384a5b6a35Swdenk   char *junkbuf = alloca (PBUFSIZ);
6394a5b6a35Swdenk 
6404a5b6a35Swdenk   int ch;
6414a5b6a35Swdenk   int tcount = 0;
6424a5b6a35Swdenk   char *p;
6434a5b6a35Swdenk 
6444a5b6a35Swdenk   /* Copy the packet into buffer BUF2, encapsulating it
6454a5b6a35Swdenk      and giving it a checksum.  */
6464a5b6a35Swdenk 
6474a5b6a35Swdenk   if (cnt > BUFSIZ - 5)		/* Prosanity check */
6484a5b6a35Swdenk     abort ();
6494a5b6a35Swdenk 
6504a5b6a35Swdenk   p = buf2;
6514a5b6a35Swdenk   *p++ = '$';
6524a5b6a35Swdenk 
6534a5b6a35Swdenk   for (i = 0; i < cnt; i++)
6544a5b6a35Swdenk     {
6554a5b6a35Swdenk       csum += buf[i];
6564a5b6a35Swdenk       *p++ = buf[i];
6574a5b6a35Swdenk     }
6584a5b6a35Swdenk   *p++ = '#';
6594a5b6a35Swdenk   *p++ = tohex ((csum >> 4) & 0xf);
6604a5b6a35Swdenk   *p++ = tohex (csum & 0xf);
6614a5b6a35Swdenk 
6624a5b6a35Swdenk   /* Send it over and over until we get a positive ack.  */
6634a5b6a35Swdenk 
6644a5b6a35Swdenk   while (1)
6654a5b6a35Swdenk     {
6664a5b6a35Swdenk       int started_error_output = 0;
6674a5b6a35Swdenk 
6684a5b6a35Swdenk       if (remote_debug)
6694a5b6a35Swdenk 	{
6704a5b6a35Swdenk 	  *p = '\0';
6714a5b6a35Swdenk 	  fprintf_unfiltered (gdb_stdlog, "Sending packet: ");
6724a5b6a35Swdenk 	  fputstrn_unfiltered (buf2, p - buf2, 0, gdb_stdlog);
6734a5b6a35Swdenk 	  fprintf_unfiltered (gdb_stdlog, "...");
6744a5b6a35Swdenk 	  gdb_flush (gdb_stdlog);
6754a5b6a35Swdenk 	}
6764a5b6a35Swdenk       if (SERIAL_WRITE (remote_desc, buf2, p - buf2))
6774a5b6a35Swdenk 	perror_with_name ("putpkt: write failed");
6784a5b6a35Swdenk 
6794a5b6a35Swdenk       /* read until either a timeout occurs (-2) or '+' is read */
6804a5b6a35Swdenk       while (1)
6814a5b6a35Swdenk 	{
6824a5b6a35Swdenk 	  ch = readchar (remote_timeout);
6834a5b6a35Swdenk 
6844a5b6a35Swdenk 	  if (remote_debug)
6854a5b6a35Swdenk 	    {
6864a5b6a35Swdenk 	      switch (ch)
6874a5b6a35Swdenk 		{
6884a5b6a35Swdenk 		case '+':
6894a5b6a35Swdenk 		case SERIAL_TIMEOUT:
6904a5b6a35Swdenk 		case '$':
6914a5b6a35Swdenk 		  if (started_error_output)
6924a5b6a35Swdenk 		    {
6934a5b6a35Swdenk 		      putchar_unfiltered ('\n');
6944a5b6a35Swdenk 		      started_error_output = 0;
6954a5b6a35Swdenk 		    }
6964a5b6a35Swdenk 		}
6974a5b6a35Swdenk 	    }
6984a5b6a35Swdenk 
6994a5b6a35Swdenk 	  switch (ch)
7004a5b6a35Swdenk 	    {
7014a5b6a35Swdenk 	    case '+':
7024a5b6a35Swdenk 	      if (remote_debug)
7034a5b6a35Swdenk 		fprintf_unfiltered (gdb_stdlog, "Ack\n");
7044a5b6a35Swdenk 	      return 1;
7054a5b6a35Swdenk 	    case SERIAL_TIMEOUT:
7064a5b6a35Swdenk 	      tcount++;
7074a5b6a35Swdenk 	      if (tcount > 3)
7084a5b6a35Swdenk 		return 0;
7094a5b6a35Swdenk 	      break;		/* Retransmit buffer */
7104a5b6a35Swdenk 	    case '$':
7114a5b6a35Swdenk 	      {
7124a5b6a35Swdenk 		/* It's probably an old response, and we're out of sync.
7134a5b6a35Swdenk 		   Just gobble up the packet and ignore it.  */
7144a5b6a35Swdenk 		getpkt (junkbuf, 0);
7154a5b6a35Swdenk 		continue;	/* Now, go look for + */
7164a5b6a35Swdenk 	      }
7174a5b6a35Swdenk 	    default:
7184a5b6a35Swdenk 	      if (remote_debug)
7194a5b6a35Swdenk 		{
7204a5b6a35Swdenk 		  if (!started_error_output)
7214a5b6a35Swdenk 		    {
7224a5b6a35Swdenk 		      started_error_output = 1;
7234a5b6a35Swdenk 		      fprintf_unfiltered (gdb_stdlog, "putpkt: Junk: ");
7244a5b6a35Swdenk 		    }
7254a5b6a35Swdenk 		  fputc_unfiltered (ch & 0177, gdb_stdlog);
7264a5b6a35Swdenk 		}
7274a5b6a35Swdenk 	      continue;
7284a5b6a35Swdenk 	    }
7294a5b6a35Swdenk 	  break;		/* Here to retransmit */
7304a5b6a35Swdenk 	}
7314a5b6a35Swdenk 
7324a5b6a35Swdenk #if 0
7334a5b6a35Swdenk       /* This is wrong.  If doing a long backtrace, the user should be
7344a5b6a35Swdenk 	 able to get out next time we call QUIT, without anything as
7354a5b6a35Swdenk 	 violent as interrupt_query.  If we want to provide a way out of
7364a5b6a35Swdenk 	 here without getting to the next QUIT, it should be based on
7374a5b6a35Swdenk 	 hitting ^C twice as in remote_wait.  */
7384a5b6a35Swdenk       if (quit_flag)
7394a5b6a35Swdenk 	{
7404a5b6a35Swdenk 	  quit_flag = 0;
7414a5b6a35Swdenk 	  interrupt_query ();
7424a5b6a35Swdenk 	}
7434a5b6a35Swdenk #endif
7444a5b6a35Swdenk     }
7454a5b6a35Swdenk }
7464a5b6a35Swdenk 
7474a5b6a35Swdenk /* Come here after finding the start of the frame.  Collect the rest
7484a5b6a35Swdenk    into BUF, verifying the checksum, length, and handling run-length
7494a5b6a35Swdenk    compression.  Returns 0 on any error, 1 on success.  */
7504a5b6a35Swdenk 
7514a5b6a35Swdenk static int
read_frame(char * buf)7524a5b6a35Swdenk read_frame (char *buf)
7534a5b6a35Swdenk {
7544a5b6a35Swdenk   unsigned char csum;
7554a5b6a35Swdenk   char *bp;
7564a5b6a35Swdenk   int c;
7574a5b6a35Swdenk 
7584a5b6a35Swdenk   csum = 0;
7594a5b6a35Swdenk   bp = buf;
7604a5b6a35Swdenk 
7614a5b6a35Swdenk   while (1)
7624a5b6a35Swdenk     {
7634a5b6a35Swdenk       c = readchar (remote_timeout);
7644a5b6a35Swdenk 
7654a5b6a35Swdenk       switch (c)
7664a5b6a35Swdenk 	{
7674a5b6a35Swdenk 	case SERIAL_TIMEOUT:
7684a5b6a35Swdenk 	  if (remote_debug)
7694a5b6a35Swdenk 	    fputs_filtered ("Timeout in mid-packet, retrying\n", gdb_stdlog);
7704a5b6a35Swdenk 	  return 0;
7714a5b6a35Swdenk 	case '$':
7724a5b6a35Swdenk 	  if (remote_debug)
7734a5b6a35Swdenk 	    fputs_filtered ("Saw new packet start in middle of old one\n",
7744a5b6a35Swdenk 			    gdb_stdlog);
7754a5b6a35Swdenk 	  return 0;		/* Start a new packet, count retries */
7764a5b6a35Swdenk 	case '#':
7774a5b6a35Swdenk 	  {
7784a5b6a35Swdenk 	    unsigned char pktcsum;
7794a5b6a35Swdenk 
7804a5b6a35Swdenk 	    *bp = '\000';
7814a5b6a35Swdenk 
7824a5b6a35Swdenk 	    pktcsum = fromhex (readchar (remote_timeout)) << 4;
7834a5b6a35Swdenk 	    pktcsum |= fromhex (readchar (remote_timeout));
7844a5b6a35Swdenk 
7854a5b6a35Swdenk 	    if (csum == pktcsum)
7864a5b6a35Swdenk 	      {
7874a5b6a35Swdenk 		return 1;
7884a5b6a35Swdenk 	      }
7894a5b6a35Swdenk 
7904a5b6a35Swdenk 	    if (remote_debug)
7914a5b6a35Swdenk 	      {
7924a5b6a35Swdenk 		fprintf_filtered (gdb_stdlog,
7934a5b6a35Swdenk 			      "Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
7944a5b6a35Swdenk 				  pktcsum, csum);
7954a5b6a35Swdenk 		fputs_filtered (buf, gdb_stdlog);
7964a5b6a35Swdenk 		fputs_filtered ("\n", gdb_stdlog);
7974a5b6a35Swdenk 	      }
7984a5b6a35Swdenk 	    return 0;
7994a5b6a35Swdenk 	  }
8004a5b6a35Swdenk 	case '*':		/* Run length encoding */
8014a5b6a35Swdenk 	  csum += c;
8024a5b6a35Swdenk 	  c = readchar (remote_timeout);
8034a5b6a35Swdenk 	  csum += c;
8044a5b6a35Swdenk 	  c = c - ' ' + 3;	/* Compute repeat count */
8054a5b6a35Swdenk 
8064a5b6a35Swdenk 	  if (c > 0 && c < 255 && bp + c - 1 < buf + PBUFSIZ - 1)
8074a5b6a35Swdenk 	    {
8084a5b6a35Swdenk 	      memset (bp, *(bp - 1), c);
8094a5b6a35Swdenk 	      bp += c;
8104a5b6a35Swdenk 	      continue;
8114a5b6a35Swdenk 	    }
8124a5b6a35Swdenk 
8134a5b6a35Swdenk 	  *bp = '\0';
8144a5b6a35Swdenk 	  printf_filtered ("Repeat count %d too large for buffer: ", c);
8154a5b6a35Swdenk 	  puts_filtered (buf);
8164a5b6a35Swdenk 	  puts_filtered ("\n");
8174a5b6a35Swdenk 	  return 0;
8184a5b6a35Swdenk 	default:
8194a5b6a35Swdenk 	  if (bp < buf + PBUFSIZ - 1)
8204a5b6a35Swdenk 	    {
8214a5b6a35Swdenk 	      *bp++ = c;
8224a5b6a35Swdenk 	      csum += c;
8234a5b6a35Swdenk 	      continue;
8244a5b6a35Swdenk 	    }
8254a5b6a35Swdenk 
8264a5b6a35Swdenk 	  *bp = '\0';
8274a5b6a35Swdenk 	  puts_filtered ("Remote packet too long: ");
8284a5b6a35Swdenk 	  puts_filtered (buf);
8294a5b6a35Swdenk 	  puts_filtered ("\n");
8304a5b6a35Swdenk 
8314a5b6a35Swdenk 	  return 0;
8324a5b6a35Swdenk 	}
8334a5b6a35Swdenk     }
8344a5b6a35Swdenk }
8354a5b6a35Swdenk 
8364a5b6a35Swdenk /* Read a packet from the remote machine, with error checking, and
8374a5b6a35Swdenk    store it in BUF.  BUF is expected to be of size PBUFSIZ.  If
8384a5b6a35Swdenk    FOREVER, wait forever rather than timing out; this is used while
8394a5b6a35Swdenk    the target is executing user code.  */
8404a5b6a35Swdenk 
8414a5b6a35Swdenk static void
getpkt(buf,forever)8424a5b6a35Swdenk getpkt (buf, forever)
8434a5b6a35Swdenk      char *buf;
8444a5b6a35Swdenk      int forever;
8454a5b6a35Swdenk {
8464a5b6a35Swdenk   int c;
8474a5b6a35Swdenk   int tries;
8484a5b6a35Swdenk   int timeout;
8494a5b6a35Swdenk   int val;
8504a5b6a35Swdenk 
8514a5b6a35Swdenk   strcpy (buf, "timeout");
8524a5b6a35Swdenk 
8534a5b6a35Swdenk   if (forever)
8544a5b6a35Swdenk     {
8554a5b6a35Swdenk       timeout = watchdog > 0 ? watchdog : -1;
8564a5b6a35Swdenk     }
8574a5b6a35Swdenk 
8584a5b6a35Swdenk   else
8594a5b6a35Swdenk     timeout = remote_timeout;
8604a5b6a35Swdenk 
8614a5b6a35Swdenk #define MAX_TRIES 3
8624a5b6a35Swdenk 
8634a5b6a35Swdenk   for (tries = 1; tries <= MAX_TRIES; tries++)
8644a5b6a35Swdenk     {
8654a5b6a35Swdenk       /* This can loop forever if the remote side sends us characters
8664a5b6a35Swdenk 	 continuously, but if it pauses, we'll get a zero from readchar
8674a5b6a35Swdenk 	 because of timeout.  Then we'll count that as a retry.  */
8684a5b6a35Swdenk 
8694a5b6a35Swdenk       /* Note that we will only wait forever prior to the start of a packet.
8704a5b6a35Swdenk 	 After that, we expect characters to arrive at a brisk pace.  They
8714a5b6a35Swdenk 	 should show up within remote_timeout intervals.  */
8724a5b6a35Swdenk 
8734a5b6a35Swdenk       do
8744a5b6a35Swdenk 	{
8754a5b6a35Swdenk 	  c = readchar (timeout);
8764a5b6a35Swdenk 
8774a5b6a35Swdenk 	  if (c == SERIAL_TIMEOUT)
8784a5b6a35Swdenk 	    {
8794a5b6a35Swdenk 	      if (forever)	/* Watchdog went off.  Kill the target. */
8804a5b6a35Swdenk 		{
8814a5b6a35Swdenk 		  target_mourn_inferior ();
8824a5b6a35Swdenk 		  error ("Watchdog has expired.  Target detached.\n");
8834a5b6a35Swdenk 		}
8844a5b6a35Swdenk 	      if (remote_debug)
8854a5b6a35Swdenk 		fputs_filtered ("Timed out.\n", gdb_stdlog);
8864a5b6a35Swdenk 	      goto retry;
8874a5b6a35Swdenk 	    }
8884a5b6a35Swdenk 	}
8894a5b6a35Swdenk       while (c != '$');
8904a5b6a35Swdenk 
8914a5b6a35Swdenk       /* We've found the start of a packet, now collect the data.  */
8924a5b6a35Swdenk 
8934a5b6a35Swdenk       val = read_frame (buf);
8944a5b6a35Swdenk 
8954a5b6a35Swdenk       if (val == 1)
8964a5b6a35Swdenk 	{
8974a5b6a35Swdenk 	  if (remote_debug)
8984a5b6a35Swdenk 	    {
8994a5b6a35Swdenk 	      fprintf_unfiltered (gdb_stdlog, "Packet received: ");
9004a5b6a35Swdenk 	      fputstr_unfiltered (buf, 0, gdb_stdlog);
9014a5b6a35Swdenk 	      fprintf_unfiltered (gdb_stdlog, "\n");
9024a5b6a35Swdenk 	    }
9034a5b6a35Swdenk 	  SERIAL_WRITE (remote_desc, "+", 1);
9044a5b6a35Swdenk 	  return;
9054a5b6a35Swdenk 	}
9064a5b6a35Swdenk 
9074a5b6a35Swdenk       /* Try the whole thing again.  */
9084a5b6a35Swdenk     retry:
9094a5b6a35Swdenk       SERIAL_WRITE (remote_desc, "-", 1);
9104a5b6a35Swdenk     }
9114a5b6a35Swdenk 
9124a5b6a35Swdenk   /* We have tried hard enough, and just can't receive the packet.  Give up. */
9134a5b6a35Swdenk 
9144a5b6a35Swdenk   printf_unfiltered ("Ignoring packet error, continuing...\n");
9154a5b6a35Swdenk   SERIAL_WRITE (remote_desc, "+", 1);
9164a5b6a35Swdenk }
917