119370Spst/* Remote utility routines for the remote server for GDB. 298944Sobrien Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 3130803Smarcel 2002, 2003, 2004 498944Sobrien Free Software Foundation, Inc. 519370Spst 698944Sobrien This file is part of GDB. 719370Spst 898944Sobrien This program is free software; you can redistribute it and/or modify 998944Sobrien it under the terms of the GNU General Public License as published by 1098944Sobrien the Free Software Foundation; either version 2 of the License, or 1198944Sobrien (at your option) any later version. 1219370Spst 1398944Sobrien This program is distributed in the hope that it will be useful, 1498944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1598944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1698944Sobrien GNU General Public License for more details. 1719370Spst 1898944Sobrien You should have received a copy of the GNU General Public License 1998944Sobrien along with this program; if not, write to the Free Software 2098944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2198944Sobrien Boston, MA 02111-1307, USA. */ 2219370Spst 2319370Spst#include "server.h" 2446283Sdfr#include "terminal.h" 2519370Spst#include <stdio.h> 2646283Sdfr#include <string.h> 2746283Sdfr#include <sys/ioctl.h> 2819370Spst#include <sys/file.h> 2919370Spst#include <netinet/in.h> 3019370Spst#include <sys/socket.h> 3119370Spst#include <netdb.h> 3219370Spst#include <netinet/tcp.h> 3319370Spst#include <sys/ioctl.h> 3419370Spst#include <signal.h> 3546283Sdfr#include <fcntl.h> 3698944Sobrien#include <sys/time.h> 3798944Sobrien#include <unistd.h> 38130803Smarcel#include <arpa/inet.h> 3919370Spst 4046283Sdfrint remote_debug = 0; 4198944Sobrienstruct ui_file *gdb_stdlog; 4246283Sdfr 4319370Spststatic int remote_desc; 4419370Spst 45130803Smarcel/* FIXME headerize? */ 46130803Smarcelextern int using_threads; 47130803Smarcelextern int debug_threads; 48130803Smarcel 4919370Spst/* Open a connection to a remote debugger. 5019370Spst NAME is the filename used for communication. */ 5119370Spst 5219370Spstvoid 5398944Sobrienremote_open (char *name) 5419370Spst{ 5546283Sdfr int save_fcntl_flags; 5698944Sobrien 5719370Spst if (!strchr (name, ':')) 5819370Spst { 5919370Spst remote_desc = open (name, O_RDWR); 6019370Spst if (remote_desc < 0) 6119370Spst perror_with_name ("Could not open remote device"); 6219370Spst 6346283Sdfr#ifdef HAVE_TERMIOS 6446283Sdfr { 6546283Sdfr struct termios termios; 6698944Sobrien tcgetattr (remote_desc, &termios); 6746283Sdfr 6846283Sdfr termios.c_iflag = 0; 6946283Sdfr termios.c_oflag = 0; 7046283Sdfr termios.c_lflag = 0; 7198944Sobrien termios.c_cflag &= ~(CSIZE | PARENB); 7246283Sdfr termios.c_cflag |= CLOCAL | CS8; 7398944Sobrien termios.c_cc[VMIN] = 1; 7446283Sdfr termios.c_cc[VTIME] = 0; 7546283Sdfr 7698944Sobrien tcsetattr (remote_desc, TCSANOW, &termios); 7746283Sdfr } 7846283Sdfr#endif 7946283Sdfr 8046283Sdfr#ifdef HAVE_TERMIO 8146283Sdfr { 8246283Sdfr struct termio termio; 8346283Sdfr ioctl (remote_desc, TCGETA, &termio); 8446283Sdfr 8546283Sdfr termio.c_iflag = 0; 8646283Sdfr termio.c_oflag = 0; 8746283Sdfr termio.c_lflag = 0; 8898944Sobrien termio.c_cflag &= ~(CSIZE | PARENB); 8946283Sdfr termio.c_cflag |= CLOCAL | CS8; 9098944Sobrien termio.c_cc[VMIN] = 1; 9146283Sdfr termio.c_cc[VTIME] = 0; 9246283Sdfr 9346283Sdfr ioctl (remote_desc, TCSETA, &termio); 9446283Sdfr } 9546283Sdfr#endif 9646283Sdfr 9746283Sdfr#ifdef HAVE_SGTTY 9846283Sdfr { 9946283Sdfr struct sgttyb sg; 10046283Sdfr 10146283Sdfr ioctl (remote_desc, TIOCGETP, &sg); 10246283Sdfr sg.sg_flags = RAW; 10346283Sdfr ioctl (remote_desc, TIOCSETP, &sg); 10446283Sdfr } 10546283Sdfr#endif 10646283Sdfr 10798944Sobrien fprintf (stderr, "Remote debugging using %s\n", name); 10819370Spst } 10919370Spst else 11019370Spst { 11119370Spst char *port_str; 11219370Spst int port; 11319370Spst struct sockaddr_in sockaddr; 11419370Spst int tmp; 11519370Spst int tmp_desc; 11619370Spst 11719370Spst port_str = strchr (name, ':'); 11819370Spst 11919370Spst port = atoi (port_str + 1); 12019370Spst 12119370Spst tmp_desc = socket (PF_INET, SOCK_STREAM, 0); 12219370Spst if (tmp_desc < 0) 12319370Spst perror_with_name ("Can't open socket"); 12419370Spst 12519370Spst /* Allow rapid reuse of this port. */ 12619370Spst tmp = 1; 12798944Sobrien setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, 12898944Sobrien sizeof (tmp)); 12919370Spst 13019370Spst sockaddr.sin_family = PF_INET; 13198944Sobrien sockaddr.sin_port = htons (port); 13219370Spst sockaddr.sin_addr.s_addr = INADDR_ANY; 13319370Spst 13498944Sobrien if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) 13519370Spst || listen (tmp_desc, 1)) 13619370Spst perror_with_name ("Can't bind address"); 13719370Spst 138130803Smarcel fprintf (stderr, "Listening on port %d\n", port); 139130803Smarcel 14019370Spst tmp = sizeof (sockaddr); 14198944Sobrien remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp); 14219370Spst if (remote_desc == -1) 14319370Spst perror_with_name ("Accept failed"); 14419370Spst 14519370Spst /* Enable TCP keep alive process. */ 14619370Spst tmp = 1; 14798944Sobrien setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp)); 14819370Spst 14919370Spst /* Tell TCP not to delay small packets. This greatly speeds up 15098944Sobrien interactive response. */ 15119370Spst tmp = 1; 15298944Sobrien setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY, 15398944Sobrien (char *) &tmp, sizeof (tmp)); 15419370Spst 15519370Spst close (tmp_desc); /* No longer need this */ 15619370Spst 15798944Sobrien signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply 15898944Sobrien exits when the remote side dies. */ 15998944Sobrien 16098944Sobrien /* Convert IP address to string. */ 16198944Sobrien fprintf (stderr, "Remote debugging from host %s\n", 16298944Sobrien inet_ntoa (sockaddr.sin_addr)); 16319370Spst } 16419370Spst 16546283Sdfr#if defined(F_SETFL) && defined (FASYNC) 16646283Sdfr save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0); 16746283Sdfr fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC); 16898944Sobrien#if defined (F_SETOWN) 16998944Sobrien fcntl (remote_desc, F_SETOWN, getpid ()); 17098944Sobrien#endif 17198944Sobrien#endif 17246283Sdfr disable_async_io (); 17319370Spst} 17419370Spst 17519370Spstvoid 17698944Sobrienremote_close (void) 17719370Spst{ 17819370Spst close (remote_desc); 17919370Spst} 18019370Spst 18119370Spst/* Convert hex digit A to a number. */ 18219370Spst 18319370Spststatic int 18498944Sobrienfromhex (int a) 18519370Spst{ 18619370Spst if (a >= '0' && a <= '9') 18719370Spst return a - '0'; 18819370Spst else if (a >= 'a' && a <= 'f') 18919370Spst return a - 'a' + 10; 19019370Spst else 19119370Spst error ("Reply contains invalid hex digit"); 19298944Sobrien return 0; 19319370Spst} 19419370Spst 195130803Smarcelint 196130803Smarcelunhexify (char *bin, const char *hex, int count) 197130803Smarcel{ 198130803Smarcel int i; 199130803Smarcel 200130803Smarcel for (i = 0; i < count; i++) 201130803Smarcel { 202130803Smarcel if (hex[0] == 0 || hex[1] == 0) 203130803Smarcel { 204130803Smarcel /* Hex string is short, or of uneven length. 205130803Smarcel Return the count that has been converted so far. */ 206130803Smarcel return i; 207130803Smarcel } 208130803Smarcel *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]); 209130803Smarcel hex += 2; 210130803Smarcel } 211130803Smarcel return i; 212130803Smarcel} 213130803Smarcel 214130803Smarcelstatic void 215130803Smarceldecode_address (CORE_ADDR *addrp, const char *start, int len) 216130803Smarcel{ 217130803Smarcel CORE_ADDR addr; 218130803Smarcel char ch; 219130803Smarcel int i; 220130803Smarcel 221130803Smarcel addr = 0; 222130803Smarcel for (i = 0; i < len; i++) 223130803Smarcel { 224130803Smarcel ch = start[i]; 225130803Smarcel addr = addr << 4; 226130803Smarcel addr = addr | (fromhex (ch) & 0x0f); 227130803Smarcel } 228130803Smarcel *addrp = addr; 229130803Smarcel} 230130803Smarcel 23119370Spst/* Convert number NIB to a hex digit. */ 23219370Spst 23319370Spststatic int 23498944Sobrientohex (int nib) 23519370Spst{ 23619370Spst if (nib < 10) 23719370Spst return '0' + nib; 23819370Spst else 23919370Spst return 'a' + nib - 10; 24019370Spst} 24119370Spst 242130803Smarcelint 243130803Smarcelhexify (char *hex, const char *bin, int count) 244130803Smarcel{ 245130803Smarcel int i; 246130803Smarcel 247130803Smarcel /* May use a length, or a nul-terminated string as input. */ 248130803Smarcel if (count == 0) 249130803Smarcel count = strlen (bin); 250130803Smarcel 251130803Smarcel for (i = 0; i < count; i++) 252130803Smarcel { 253130803Smarcel *hex++ = tohex ((*bin >> 4) & 0xf); 254130803Smarcel *hex++ = tohex (*bin++ & 0xf); 255130803Smarcel } 256130803Smarcel *hex = 0; 257130803Smarcel return i; 258130803Smarcel} 259130803Smarcel 26019370Spst/* Send a packet to the remote machine, with error checking. 26119370Spst The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */ 26219370Spst 26319370Spstint 26498944Sobrienputpkt (char *buf) 26519370Spst{ 26619370Spst int i; 26719370Spst unsigned char csum = 0; 26898944Sobrien char *buf2; 26919370Spst char buf3[1]; 27019370Spst int cnt = strlen (buf); 27119370Spst char *p; 27219370Spst 27398944Sobrien buf2 = malloc (PBUFSIZ); 27498944Sobrien 27519370Spst /* Copy the packet into buffer BUF2, encapsulating it 27619370Spst and giving it a checksum. */ 27719370Spst 27819370Spst p = buf2; 27919370Spst *p++ = '$'; 28019370Spst 28119370Spst for (i = 0; i < cnt; i++) 28219370Spst { 28319370Spst csum += buf[i]; 28419370Spst *p++ = buf[i]; 28519370Spst } 28619370Spst *p++ = '#'; 28719370Spst *p++ = tohex ((csum >> 4) & 0xf); 28819370Spst *p++ = tohex (csum & 0xf); 28919370Spst 29046283Sdfr *p = '\0'; 29146283Sdfr 29219370Spst /* Send it over and over until we get a positive ack. */ 29319370Spst 29419370Spst do 29519370Spst { 29619370Spst int cc; 29719370Spst 29819370Spst if (write (remote_desc, buf2, p - buf2) != p - buf2) 29919370Spst { 30019370Spst perror ("putpkt(write)"); 30119370Spst return -1; 30219370Spst } 30319370Spst 30446283Sdfr if (remote_debug) 305130803Smarcel { 306130803Smarcel fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2); 307130803Smarcel fflush (stderr); 308130803Smarcel } 30919370Spst cc = read (remote_desc, buf3, 1); 31046283Sdfr if (remote_debug) 311130803Smarcel { 312130803Smarcel fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]); 313130803Smarcel fflush (stderr); 314130803Smarcel } 315130803Smarcel 31619370Spst if (cc <= 0) 31719370Spst { 31819370Spst if (cc == 0) 31919370Spst fprintf (stderr, "putpkt(read): Got EOF\n"); 32019370Spst else 32119370Spst perror ("putpkt(read)"); 32219370Spst 32398944Sobrien free (buf2); 32419370Spst return -1; 32519370Spst } 326130803Smarcel 327130803Smarcel /* Check for an input interrupt while we're here. */ 328130803Smarcel if (buf3[0] == '\003') 329130803Smarcel (*the_target->send_signal) (SIGINT); 33019370Spst } 33119370Spst while (buf3[0] != '+'); 33219370Spst 33398944Sobrien free (buf2); 33419370Spst return 1; /* Success! */ 33519370Spst} 33619370Spst 33719370Spst/* Come here when we get an input interrupt from the remote side. This 33819370Spst interrupt should only be active while we are waiting for the child to do 33919370Spst something. About the only thing that should come through is a ^C, which 34019370Spst will cause us to send a SIGINT to the child. */ 34119370Spst 34219370Spststatic void 34398944Sobrieninput_interrupt (int unused) 34419370Spst{ 34598944Sobrien fd_set readset; 34698944Sobrien struct timeval immediate = { 0, 0 }; 34719370Spst 34898944Sobrien /* Protect against spurious interrupts. This has been observed to 34998944Sobrien be a problem under NetBSD 1.4 and 1.5. */ 35019370Spst 35198944Sobrien FD_ZERO (&readset); 35298944Sobrien FD_SET (remote_desc, &readset); 35398944Sobrien if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0) 35419370Spst { 35598944Sobrien int cc; 35698944Sobrien char c; 35798944Sobrien 35898944Sobrien cc = read (remote_desc, &c, 1); 35998944Sobrien 36098944Sobrien if (cc != 1 || c != '\003') 36198944Sobrien { 36298944Sobrien fprintf (stderr, "input_interrupt, cc = %d c = %d\n", cc, c); 36398944Sobrien return; 36498944Sobrien } 36598944Sobrien 366130803Smarcel (*the_target->send_signal) (SIGINT); 36719370Spst } 36819370Spst} 36919370Spst 37019370Spstvoid 371130803Smarcelblock_async_io (void) 372130803Smarcel{ 373130803Smarcel sigset_t sigio_set; 374130803Smarcel sigemptyset (&sigio_set); 375130803Smarcel sigaddset (&sigio_set, SIGIO); 376130803Smarcel sigprocmask (SIG_BLOCK, &sigio_set, NULL); 377130803Smarcel} 378130803Smarcel 379130803Smarcelvoid 380130803Smarcelunblock_async_io (void) 381130803Smarcel{ 382130803Smarcel sigset_t sigio_set; 383130803Smarcel sigemptyset (&sigio_set); 384130803Smarcel sigaddset (&sigio_set, SIGIO); 385130803Smarcel sigprocmask (SIG_UNBLOCK, &sigio_set, NULL); 386130803Smarcel} 387130803Smarcel 388130803Smarcelvoid 38998944Sobrienenable_async_io (void) 39019370Spst{ 39119370Spst signal (SIGIO, input_interrupt); 39219370Spst} 39319370Spst 39419370Spstvoid 39598944Sobriendisable_async_io (void) 39619370Spst{ 39719370Spst signal (SIGIO, SIG_IGN); 39819370Spst} 39919370Spst 40019370Spst/* Returns next char from remote GDB. -1 if error. */ 40119370Spst 40219370Spststatic int 40398944Sobrienreadchar (void) 40419370Spst{ 40519370Spst static char buf[BUFSIZ]; 40619370Spst static int bufcnt = 0; 40719370Spst static char *bufp; 40819370Spst 40919370Spst if (bufcnt-- > 0) 41019370Spst return *bufp++ & 0x7f; 41119370Spst 41219370Spst bufcnt = read (remote_desc, buf, sizeof (buf)); 41319370Spst 41419370Spst if (bufcnt <= 0) 41519370Spst { 41619370Spst if (bufcnt == 0) 41719370Spst fprintf (stderr, "readchar: Got EOF\n"); 41819370Spst else 41919370Spst perror ("readchar"); 42019370Spst 42119370Spst return -1; 42219370Spst } 42319370Spst 42419370Spst bufp = buf; 42519370Spst bufcnt--; 42619370Spst return *bufp++ & 0x7f; 42719370Spst} 42819370Spst 42919370Spst/* Read a packet from the remote machine, with error checking, 43019370Spst and store it in BUF. Returns length of packet, or negative if error. */ 43119370Spst 43219370Spstint 43398944Sobriengetpkt (char *buf) 43419370Spst{ 43519370Spst char *bp; 43619370Spst unsigned char csum, c1, c2; 43719370Spst int c; 43819370Spst 43919370Spst while (1) 44019370Spst { 44119370Spst csum = 0; 44219370Spst 44319370Spst while (1) 44419370Spst { 44519370Spst c = readchar (); 44619370Spst if (c == '$') 44719370Spst break; 44846283Sdfr if (remote_debug) 449130803Smarcel { 450130803Smarcel fprintf (stderr, "[getpkt: discarding char '%c']\n", c); 451130803Smarcel fflush (stderr); 452130803Smarcel } 453130803Smarcel 45419370Spst if (c < 0) 45519370Spst return -1; 45619370Spst } 45719370Spst 45819370Spst bp = buf; 45919370Spst while (1) 46019370Spst { 46119370Spst c = readchar (); 46219370Spst if (c < 0) 46319370Spst return -1; 46419370Spst if (c == '#') 46519370Spst break; 46619370Spst *bp++ = c; 46719370Spst csum += c; 46819370Spst } 46919370Spst *bp = 0; 47019370Spst 47119370Spst c1 = fromhex (readchar ()); 47219370Spst c2 = fromhex (readchar ()); 47398944Sobrien 47419370Spst if (csum == (c1 << 4) + c2) 47519370Spst break; 47619370Spst 47719370Spst fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n", 47819370Spst (c1 << 4) + c2, csum, buf); 47919370Spst write (remote_desc, "-", 1); 48019370Spst } 48119370Spst 48246283Sdfr if (remote_debug) 483130803Smarcel { 484130803Smarcel fprintf (stderr, "getpkt (\"%s\"); [sending ack] \n", buf); 485130803Smarcel fflush (stderr); 486130803Smarcel } 48746283Sdfr 48819370Spst write (remote_desc, "+", 1); 48946283Sdfr 49046283Sdfr if (remote_debug) 491130803Smarcel { 492130803Smarcel fprintf (stderr, "[sent ack]\n"); 493130803Smarcel fflush (stderr); 494130803Smarcel } 495130803Smarcel 49619370Spst return bp - buf; 49719370Spst} 49819370Spst 49919370Spstvoid 50098944Sobrienwrite_ok (char *buf) 50119370Spst{ 50219370Spst buf[0] = 'O'; 50319370Spst buf[1] = 'K'; 50419370Spst buf[2] = '\0'; 50519370Spst} 50619370Spst 50719370Spstvoid 50898944Sobrienwrite_enn (char *buf) 50919370Spst{ 510130803Smarcel /* Some day, we should define the meanings of the error codes... */ 51119370Spst buf[0] = 'E'; 512130803Smarcel buf[1] = '0'; 513130803Smarcel buf[2] = '1'; 51419370Spst buf[3] = '\0'; 51519370Spst} 51619370Spst 51719370Spstvoid 51898944Sobrienconvert_int_to_ascii (char *from, char *to, int n) 51919370Spst{ 52019370Spst int nib; 52119370Spst char ch; 52219370Spst while (n--) 52319370Spst { 52419370Spst ch = *from++; 52519370Spst nib = ((ch & 0xf0) >> 4) & 0x0f; 52619370Spst *to++ = tohex (nib); 52719370Spst nib = ch & 0x0f; 52819370Spst *to++ = tohex (nib); 52919370Spst } 53019370Spst *to++ = 0; 53119370Spst} 53219370Spst 53319370Spst 53419370Spstvoid 53598944Sobrienconvert_ascii_to_int (char *from, char *to, int n) 53619370Spst{ 53719370Spst int nib1, nib2; 53819370Spst while (n--) 53919370Spst { 54019370Spst nib1 = fromhex (*from++); 54119370Spst nib2 = fromhex (*from++); 54219370Spst *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f); 54319370Spst } 54419370Spst} 54519370Spst 54619370Spststatic char * 54798944Sobrienoutreg (int regno, char *buf) 54819370Spst{ 54998944Sobrien if ((regno >> 12) != 0) 55098944Sobrien *buf++ = tohex ((regno >> 12) & 0xf); 55198944Sobrien if ((regno >> 8) != 0) 55298944Sobrien *buf++ = tohex ((regno >> 8) & 0xf); 55398944Sobrien *buf++ = tohex ((regno >> 4) & 0xf); 55419370Spst *buf++ = tohex (regno & 0xf); 55519370Spst *buf++ = ':'; 556130803Smarcel collect_register_as_string (regno, buf); 557130803Smarcel buf += 2 * register_size (regno); 55819370Spst *buf++ = ';'; 55919370Spst 56019370Spst return buf; 56119370Spst} 56219370Spst 56319370Spstvoid 564130803Smarcelnew_thread_notify (int id) 565130803Smarcel{ 566130803Smarcel char own_buf[256]; 567130803Smarcel 568130803Smarcel /* The `n' response is not yet part of the remote protocol. Do nothing. */ 569130803Smarcel if (1) 570130803Smarcel return; 571130803Smarcel 572130803Smarcel if (server_waiting == 0) 573130803Smarcel return; 574130803Smarcel 575130803Smarcel sprintf (own_buf, "n%x", id); 576130803Smarcel disable_async_io (); 577130803Smarcel putpkt (own_buf); 578130803Smarcel enable_async_io (); 579130803Smarcel} 580130803Smarcel 581130803Smarcelvoid 582130803Smarceldead_thread_notify (int id) 583130803Smarcel{ 584130803Smarcel char own_buf[256]; 585130803Smarcel 586130803Smarcel /* The `x' response is not yet part of the remote protocol. Do nothing. */ 587130803Smarcel if (1) 588130803Smarcel return; 589130803Smarcel 590130803Smarcel sprintf (own_buf, "x%x", id); 591130803Smarcel disable_async_io (); 592130803Smarcel putpkt (own_buf); 593130803Smarcel enable_async_io (); 594130803Smarcel} 595130803Smarcel 596130803Smarcelvoid 59798944Sobrienprepare_resume_reply (char *buf, char status, unsigned char signo) 59819370Spst{ 59998944Sobrien int nib, sig; 60019370Spst 60119370Spst *buf++ = status; 60219370Spst 60398944Sobrien sig = (int)target_signal_from_host (signo); 60498944Sobrien 60598944Sobrien nib = ((sig & 0xf0) >> 4); 60619370Spst *buf++ = tohex (nib); 60798944Sobrien nib = sig & 0x0f; 60819370Spst *buf++ = tohex (nib); 60919370Spst 61019370Spst if (status == 'T') 61119370Spst { 61298944Sobrien const char **regp = gdbserver_expedite_regs; 61398944Sobrien while (*regp) 61498944Sobrien { 61598944Sobrien buf = outreg (find_regno (*regp), buf); 61698944Sobrien regp ++; 61798944Sobrien } 61819370Spst 619130803Smarcel /* Formerly, if the debugger had not used any thread features we would not 620130803Smarcel burden it with a thread status response. This was for the benefit of 621130803Smarcel GDB 4.13 and older. However, in recent GDB versions the check 622130803Smarcel (``if (cont_thread != 0)'') does not have the desired effect because of 623130803Smarcel sillyness in the way that the remote protocol handles specifying a thread. 624130803Smarcel Since thread support relies on qSymbol support anyway, assume GDB can handle 625130803Smarcel threads. */ 626130803Smarcel 627130803Smarcel if (using_threads) 62819370Spst { 629130803Smarcel /* FIXME right place to set this? */ 630130803Smarcel thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id; 631130803Smarcel if (debug_threads) 632130803Smarcel fprintf (stderr, "Writing resume reply for %d\n\n", thread_from_wait); 633130803Smarcel /* This if (1) ought to be unnecessary. But remote_wait in GDB 634130803Smarcel will claim this event belongs to inferior_ptid if we do not 635130803Smarcel specify a thread, and there's no way for gdbserver to know 636130803Smarcel what inferior_ptid is. */ 637130803Smarcel if (1 || old_thread_from_wait != thread_from_wait) 63819370Spst { 639130803Smarcel general_thread = thread_from_wait; 64019370Spst sprintf (buf, "thread:%x;", thread_from_wait); 64119370Spst buf += strlen (buf); 64219370Spst old_thread_from_wait = thread_from_wait; 64319370Spst } 64419370Spst } 64519370Spst } 64619370Spst /* For W and X, we're done. */ 64719370Spst *buf++ = 0; 64819370Spst} 64919370Spst 65019370Spstvoid 65198944Sobriendecode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr) 65219370Spst{ 65319370Spst int i = 0, j = 0; 65419370Spst char ch; 65519370Spst *mem_addr_ptr = *len_ptr = 0; 65619370Spst 65719370Spst while ((ch = from[i++]) != ',') 65819370Spst { 65919370Spst *mem_addr_ptr = *mem_addr_ptr << 4; 66019370Spst *mem_addr_ptr |= fromhex (ch) & 0x0f; 66119370Spst } 66219370Spst 66319370Spst for (j = 0; j < 4; j++) 66419370Spst { 66519370Spst if ((ch = from[i++]) == 0) 66619370Spst break; 66719370Spst *len_ptr = *len_ptr << 4; 66819370Spst *len_ptr |= fromhex (ch) & 0x0f; 66919370Spst } 67019370Spst} 67119370Spst 67219370Spstvoid 67398944Sobriendecode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr, 67498944Sobrien char *to) 67519370Spst{ 67646283Sdfr int i = 0; 67719370Spst char ch; 67819370Spst *mem_addr_ptr = *len_ptr = 0; 67919370Spst 68019370Spst while ((ch = from[i++]) != ',') 68119370Spst { 68219370Spst *mem_addr_ptr = *mem_addr_ptr << 4; 68319370Spst *mem_addr_ptr |= fromhex (ch) & 0x0f; 68419370Spst } 68519370Spst 68619370Spst while ((ch = from[i++]) != ':') 68719370Spst { 68819370Spst *len_ptr = *len_ptr << 4; 68919370Spst *len_ptr |= fromhex (ch) & 0x0f; 69019370Spst } 69119370Spst 69219370Spst convert_ascii_to_int (&from[i++], to, *len_ptr); 69319370Spst} 694130803Smarcel 695130803Smarcelint 696130803Smarcellook_up_one_symbol (const char *name, CORE_ADDR *addrp) 697130803Smarcel{ 698130803Smarcel char own_buf[266], *p, *q; 699130803Smarcel int len; 700130803Smarcel 701130803Smarcel /* Send the request. */ 702130803Smarcel strcpy (own_buf, "qSymbol:"); 703130803Smarcel hexify (own_buf + strlen ("qSymbol:"), name, strlen (name)); 704130803Smarcel if (putpkt (own_buf) < 0) 705130803Smarcel return -1; 706130803Smarcel 707130803Smarcel /* FIXME: Eventually add buffer overflow checking (to getpkt?) */ 708130803Smarcel len = getpkt (own_buf); 709130803Smarcel if (len < 0) 710130803Smarcel return -1; 711130803Smarcel 712130803Smarcel if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0) 713130803Smarcel { 714130803Smarcel /* Malformed response. */ 715130803Smarcel if (remote_debug) 716130803Smarcel { 717130803Smarcel fprintf (stderr, "Malformed response to qSymbol, ignoring.\n"); 718130803Smarcel fflush (stderr); 719130803Smarcel } 720130803Smarcel 721130803Smarcel return -1; 722130803Smarcel } 723130803Smarcel 724130803Smarcel p = own_buf + strlen ("qSymbol:"); 725130803Smarcel q = p; 726130803Smarcel while (*q && *q != ':') 727130803Smarcel q++; 728130803Smarcel 729130803Smarcel /* Make sure we found a value for the symbol. */ 730130803Smarcel if (p == q || *q == '\0') 731130803Smarcel return 0; 732130803Smarcel 733130803Smarcel decode_address (addrp, p, q - p); 734130803Smarcel return 1; 735130803Smarcel} 736130803Smarcel 737