1
/* Remote utility routines for the remote server for GDB.
3
Free Software Foundation, Inc.
5
This file is part of GDB.
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
Boston, MA 02110-1301, USA. */
22
* Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved.
24
* This program is free software; you can redistribute it and/or
25
* modify it under the terms of the GNU General Public
26
* License v2 as published by the Free Software Foundation.
28
* This program is distributed in the hope that it will be useful,
29
* but WITHOUT ANY WARRANTY; without even the implied warranty of
30
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
31
* General Public License for more details.
33
* You should have received a copy of the GNU General Public
34
* License along with this program; if not, write to the
35
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
36
* Boston, MA 021110-1307, USA.
39
/* This module handles communication with remote gdb. courtesy
40
* of gdbserver remote-utils.c */
46
#include <sys/ioctl.h>
48
#include <netinet/in.h>
49
#include <sys/socket.h>
51
#include <netinet/tcp.h>
52
#include <arpa/inet.h>
61
extern int gx_remote_dbg;
66
/* Returns: 0 success. -1 failure */
68
do_tcp(char *port_str)
71
struct sockaddr_in sockaddr;
75
port = atoi(port_str);
77
sock_fd = socket(PF_INET, SOCK_STREAM, 0);
79
gxprt("ERROR: failed socket open. errno:%d\n", errno);
83
/* Allow rapid reuse of this port. */
85
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp,sizeof(tmp));
87
sockaddr.sin_family = PF_INET;
88
sockaddr.sin_port = htons (port);
89
sockaddr.sin_addr.s_addr = INADDR_ANY;
91
if (bind(sock_fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
92
|| listen (sock_fd, 1)) {
93
gxprt("ERROR: can't bind address. errno:%d\n", errno);
97
printf("Listening on port %d\n", port);
99
tmp = sizeof(sockaddr);
100
remote_fd = accept(sock_fd, (struct sockaddr *) &sockaddr, &tmp);
101
if (remote_fd == -1) {
102
gxprt("ERROR: accept failed. errno:%d\n", errno);
107
/* Enable TCP keep alive process. */
109
setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp,sizeof(tmp));
111
/* Tell TCP not to delay small packets. This greatly speeds up
112
* interactive response. */
114
setsockopt(remote_fd, IPPROTO_TCP, TCP_NODELAY,
115
(char *)&tmp, sizeof(tmp));
117
close(sock_fd); /* No longer need this */
119
signal(SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
120
* exits when the remote side dies. */
122
/* Convert IP address to string */
123
printf("Remote debugging from host %s\n", inet_ntoa(sockaddr.sin_addr));
129
* Open a connection for remote gdb on the given port number
130
* Returns: 0 for success. -1 for failure
133
gx_remote_open(char *portnum_str)
135
int save_fcntl_flags;
137
if (do_tcp(portnum_str) == -1) {
142
#if defined(F_SETFL) && defined (FASYNC)
143
save_fcntl_flags = fcntl(remote_fd, F_GETFL, 0);
144
fcntl(remote_fd, F_SETFL, save_fcntl_flags | FASYNC);
145
#if defined (F_SETOWN)
146
fcntl (remote_fd, F_SETOWN, getpid ());
153
gx_remote_close(void)
159
/* Returns next char from remote gdb. -1 if error. */
163
static char buf[BUFSIZ];
164
static int bufcnt = 0;
169
return *bufp++ & 0x7f;
171
bufcnt = read(remote_fd, buf, sizeof (buf));
172
ll = *(uint64_t *)buf;
175
gxprt("readchar: Got EOF\n");
182
return *bufp++ & 0x7f;
185
/* Read a packet from the remote machine, with error checking,
186
* and store it in buf.
187
* Returns: length of packet, or negative int if error.
190
gx_getpkt (char *buf)
193
unsigned char csum, c1, c2;
205
gxprt("[getpkt: discarding char '%c']\n", c);
222
c1 = gx_fromhex(readchar());
223
c2 = gx_fromhex(readchar());
225
if (csum == (c1 << 4) + c2)
228
gxprt("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
229
(c1 << 4) + c2, csum, buf);
230
write(remote_fd, "-", 1);
233
gxprt("getpkt (\"%s\"); [sending ack] \n", buf);
236
write(remote_fd, "+", 1);
239
gxprt("[sent ack]\n");
245
gx_reply_ok(char *buf)
254
gx_reply_error(char *buf)
263
* Send a packet to the remote machine, with error checking.
264
* The data of the packet is in buf.
265
* Returns: >= 0 on success, -1 otherwise.
268
gx_putpkt (char *buf)
271
unsigned char csum = 0;
274
int cnt = strlen (buf);
279
/* Copy the packet into buffer buf2, encapsulating it
280
* and giving it a checksum. */
285
for (i = 0; i < cnt; i++) {
290
*p++ = gx_tohex((csum >> 4) & 0xf);
291
*p++ = gx_tohex(csum & 0xf);
295
/* Send it over and over until we get a positive ack. */
300
if (write(remote_fd, buf2, p - buf2) != p - buf2) {
301
perror("putpkt(write)");
306
gxprt("putpkt (\"%s\"); [looking for ack]\n", buf2);
308
cc = read(remote_fd, buf3, 1);
310
gxprt("[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
314
gxprt("putpkt(read): Got EOF\n");
316
gxprt("putpkt(read)");
320
/* Check for an input interrupt while we're here. */
321
if (buf3[0] == '\003')
322
gxprt("WARN: need to send SIGINT in putpkt\n");
324
} while (buf3[0] != '+');
327
return 1; /* Success! */