- Fix several bugs with uninitialized fields in sockaddr_in. Now this code
works under FreeBSD. - Fix some formatting problems with long lines. - Cleanup wait_for_connect(). Only set SO_REUSEADDR once. Reuse sockaddr for bind() and accept(). - Turn on TCP_NODELAY to speed up GDB remote protocol transactions. - In bx_gdbstub_init(), remove `Communicating...' message. Add a `Waiting...' message just before calling wait_for_connect() to give the user some idea that the emulator is waiting for something.
This commit is contained in:
parent
3c769207e2
commit
81f089da2e
164
bochs/gdbstub.cc
164
bochs/gdbstub.cc
@ -3,11 +3,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#define NEED_CPU_REG_SHORTCUTS 1
|
||||
|
||||
@ -25,111 +24,6 @@ static int last_stop_reason = GDBSTUB_STOP_NO_REASON;
|
||||
static int listen_socket_fd;
|
||||
static int socket_fd;
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
/*
|
||||
* Check whether "cp" is a valid ascii representation
|
||||
* of an Internet address and convert to a binary address.
|
||||
* Returns 1 if the address is valid, 0 if not.
|
||||
* This replaces inet_addr, the return value from which
|
||||
* cannot distinguish between failure and a local broadcast address.
|
||||
*/
|
||||
int inet_aton(const char *cp, struct in_addr * addr)
|
||||
{
|
||||
unsigned int val;
|
||||
int base,n;
|
||||
char c;
|
||||
u_int parts[4];
|
||||
u_int *pp = parts;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
||||
/*
|
||||
* Collect number up to `.''. Values are specified as for C:
|
||||
* 0x=hex, 0=octal, other=decimal.
|
||||
*/
|
||||
val = 0;
|
||||
base = 10;
|
||||
if (*cp == '0')
|
||||
{
|
||||
if (*++cp == 'x' || *cp == 'X')
|
||||
base = 16, cp++;
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
while ((c = *cp) != '\0')
|
||||
{
|
||||
if (isascii(c) && isdigit(c))
|
||||
{
|
||||
val = (val * base) + (c - '0');
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (base == 16 && isascii(c) && isxdigit(c))
|
||||
{
|
||||
val = (val << 4) +
|
||||
(c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (*cp == '.')
|
||||
{
|
||||
|
||||
/*
|
||||
* Internet format: a.b.c.d a.b.c (with c treated as
|
||||
* 16-bits) a.b (with b treated as 24 bits)
|
||||
*/
|
||||
if (pp >= parts + 3 || val > 0xff)
|
||||
return (0);
|
||||
*pp++ = val, cp++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if (*cp && (!isascii(*cp) || !isspace(*cp)))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Concoct the address according to the number of parts specified.
|
||||
*/
|
||||
n = pp - parts + 1;
|
||||
switch (n)
|
||||
{
|
||||
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffff)
|
||||
return (0);
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
}
|
||||
if (addr)
|
||||
addr->s_addr = htonl(val);
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int hex(char ch)
|
||||
{
|
||||
if ((ch >= 'a') && (ch <= 'f')) return(ch - 'a' + 10);
|
||||
@ -692,8 +586,7 @@ static void debug_loop(void)
|
||||
sprintf(obuf,"%Lx", 1);
|
||||
put_reply(obuf);
|
||||
}
|
||||
else if (strncmp(&buffer[1], "Offsets", strlen("Offsets")) ==
|
||||
0)
|
||||
else if (strncmp(&buffer[1], "Offsets", strlen("Offsets")) == 0)
|
||||
{
|
||||
sprintf(obuf,
|
||||
"Text=%x;Data=%x;Bss=%x",
|
||||
@ -722,8 +615,8 @@ static void debug_loop(void)
|
||||
static void wait_for_connect(int portn)
|
||||
{
|
||||
struct sockaddr_in sockaddr;
|
||||
struct sockaddr csockaddr;
|
||||
signed int csockaddr_len;
|
||||
socklen_t sockaddr_len;
|
||||
struct protoent *protoent;
|
||||
int r;
|
||||
int opt;
|
||||
|
||||
@ -734,37 +627,54 @@ static void wait_for_connect(int portn)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Allow rapid reuse of this port */
|
||||
opt = 1;
|
||||
r = setsockopt(listen_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
if (r == -1)
|
||||
{
|
||||
BX_INFO (("setsockopt(SO_REUSEADDR) failed\n"));
|
||||
}
|
||||
|
||||
memset (&sockaddr, '\000', sizeof sockaddr);
|
||||
sockaddr.sin_len = sizeof sockaddr;
|
||||
sockaddr.sin_family = AF_INET;
|
||||
sockaddr.sin_port = htons(portn);
|
||||
inet_aton("127.0.0.1", &sockaddr.sin_addr);
|
||||
|
||||
r = bind(listen_socket_fd, (struct sockaddr *)&sockaddr,
|
||||
sizeof(sockaddr));
|
||||
sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
r = bind(listen_socket_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
|
||||
if (r == -1)
|
||||
{
|
||||
BX_PANIC (("Failed to bind socket\n"));
|
||||
}
|
||||
|
||||
opt = 1;
|
||||
setsockopt(listen_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt,
|
||||
sizeof(opt));
|
||||
|
||||
|
||||
r = listen(listen_socket_fd, 0);
|
||||
if (r == -1)
|
||||
{
|
||||
BX_PANIC (("Failed to listen on socket\n"));
|
||||
}
|
||||
|
||||
csockaddr_len = sizeof csockaddr;
|
||||
socket_fd = accept(listen_socket_fd, &csockaddr, (socklen_t *) &csockaddr_len);
|
||||
sockaddr_len = sizeof sockaddr;
|
||||
socket_fd = accept(listen_socket_fd, (struct sockaddr *)&sockaddr, &sockaddr_len);
|
||||
if (socket_fd == -1)
|
||||
{
|
||||
BX_PANIC (("Failed to accept on socket\n"));
|
||||
}
|
||||
close(listen_socket_fd);
|
||||
|
||||
protoent = getprotobyname ("tcp");
|
||||
if (!protoent)
|
||||
{
|
||||
BX_INFO (("getprotobyname (\"tcp\") failed\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable Nagle - allow small packets to be sent without delay. */
|
||||
opt = 1;
|
||||
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
r = setsockopt (socket_fd, protoent->p_proto, TCP_NODELAY, &opt, sizeof(opt));
|
||||
if (r == -1)
|
||||
{
|
||||
BX_INFO (("setsockopt(TCP_NODELAY) failed\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void bx_gdbstub_init(int argc, char* argv[])
|
||||
@ -776,16 +686,16 @@ void bx_gdbstub_init(int argc, char* argv[])
|
||||
bx_parse_cmdline (1, argc, argv);
|
||||
|
||||
portn = bx_options.gdbstub.port;
|
||||
printf("Communicating with gdb on port %d\n", portn);
|
||||
|
||||
bx_init_hardware();
|
||||
#if 1
|
||||
|
||||
/* Wait for connect */
|
||||
|
||||
printf("Waiting for gdb connection on localhost:%d\n", portn);
|
||||
wait_for_connect(portn);
|
||||
|
||||
/* Do debugger command loop */
|
||||
debug_loop();
|
||||
#endif
|
||||
|
||||
/* CPU loop */
|
||||
bx_cpu.cpu_loop(-1);
|
||||
|
Loading…
Reference in New Issue
Block a user