[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Win32 support for the GDB stub (take 2)
From: |
Filip Navara |
Subject: |
[Qemu-devel] [PATCH] Win32 support for the GDB stub (take 2) |
Date: |
Sun, 23 Jan 2005 11:33:10 +0100 |
User-agent: |
Mozilla Thunderbird 0.9 (Windows/20041103) |
Now with corrections suggested by malc...
Filip Navara
address@hidden
Index: configure
===================================================================
RCS file: /cvsroot/qemu/qemu/configure,v
retrieving revision 1.51
diff -u -r1.51 configure
--- configure 10 Jan 2005 23:18:50 -0000 1.51
+++ configure 22 Jan 2005 14:11:11 -0000
@@ -184,7 +184,6 @@
if test "$mingw32" = "yes" ; then
linux="no"
EXESUF=".exe"
- gdbstub="no"
oss="no"
fi
Index: gdbstub.c
===================================================================
RCS file: /cvsroot/qemu/qemu/gdbstub.c,v
retrieving revision 1.23
diff -u -r1.23 gdbstub.c
--- gdbstub.c 17 Jan 2005 22:03:16 -0000 1.23
+++ gdbstub.c 22 Jan 2005 17:59:07 -0000
@@ -19,11 +19,21 @@
*/
#include "vl.h"
+#ifdef _WIN32
+#include <winsock2.h>
+#define SIGTRAP 24
+typedef int socklen_t;
+#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
+#endif
#include <signal.h>
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
//#define DEBUG_GDB
enum RSState {
@@ -49,9 +59,13 @@
int ret;
for(;;) {
- ret = read(s->fd, &ch, 1);
+ ret = recv(s->fd, &ch, 1, MSG_NOSIGNAL);
if (ret < 0) {
+#ifdef _WIN32
+ if (WSAGetLastError() != EINTR && WSAGetLastError() != EAGAIN)
+#else
if (errno != EINTR && errno != EAGAIN)
+#endif
return -1;
} else if (ret == 0) {
return -1;
@@ -67,9 +81,13 @@
int ret;
while (len > 0) {
- ret = write(s->fd, buf, len);
+ ret = send(s->fd, buf, len, MSG_NOSIGNAL);
if (ret < 0) {
+#ifdef _WIN32
+ if (WSAGetLastError() != EINTR && WSAGetLastError() != EAGAIN)
+#else
if (errno != EINTR && errno != EAGAIN)
+#endif
return;
} else {
buf += ret;
@@ -551,7 +569,7 @@
{
GDBState *s = opaque;
int i;
- if (size == 0) {
+ if (size <= 0) {
/* end of connection */
qemu_del_vm_stop_handler(gdb_vm_stopped, s);
qemu_del_fd_read_handler(s->fd);
@@ -569,6 +587,9 @@
struct sockaddr_in sockaddr;
socklen_t len;
int val, fd;
+#ifdef _WIN32
+ u_long nbio = 1;
+#endif
for(;;) {
len = sizeof(sockaddr);
@@ -583,7 +604,11 @@
/* set short latency */
val = 1;
+#ifdef _WIN32
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&val, sizeof(val));
+#else
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+#endif
s = qemu_mallocz(sizeof(GDBState));
if (!s) {
@@ -592,7 +617,11 @@
}
s->fd = fd;
+#ifdef _WIN32
+ ioctlsocket(fd, FIONBIO, &nbio);
+#else
fcntl(fd, F_SETFL, O_NONBLOCK);
+#endif
/* stop the VM */
vm_stop(EXCP_INTERRUPT);
@@ -607,6 +636,9 @@
{
struct sockaddr_in sockaddr;
int fd, val, ret;
+#ifdef _WIN32
+ u_long nbio = 1;
+#endif
fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0) {
@@ -616,7 +648,11 @@
/* allow fast reuse */
val = 1;
+#ifdef _WIN32
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&val, sizeof(val));
+#else
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+#endif
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(port);
@@ -631,12 +667,21 @@
perror("listen");
return -1;
}
+#ifdef _WIN32
+ ioctlsocket(fd, FIONBIO, &nbio);
+#else
fcntl(fd, F_SETFL, O_NONBLOCK);
+#endif
return fd;
}
int gdbserver_start(int port)
{
+#ifdef _WIN32
+ WSADATA wsaData;
+ if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
+ return -1;
+#endif
gdbserver_fd = gdbserver_open(port);
if (gdbserver_fd < 0)
return -1;
Index: vl.c
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.c,v
retrieving revision 1.117
diff -u -r1.117 vl.c
--- vl.c 15 Jan 2005 21:50:11 -0000 1.117
+++ vl.c 22 Jan 2005 17:59:20 -0000
@@ -2572,97 +2572,159 @@
{
#ifndef _WIN32
struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
+#endif
IOHandlerRecord *ioh, *ioh_next;
uint8_t buf[4096];
int n, max_size;
-#endif
int ret;
+ /* poll any events */
#ifdef _WIN32
- if (timeout > 0)
- Sleep(timeout);
+ /* XXX: better handling of removal */
+ for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
+ ioh_next = ioh->next;
+
+ if (!ioh->fd_can_read) {
+ max_size = 0;
+ } else {
+ max_size = ioh->fd_can_read(ioh->opaque);
+ if (max_size > 0) {
+ if (max_size > sizeof(buf))
+ max_size = sizeof(buf);
+ }
+ }
+ ioh->max_size = max_size;
+
+ if (!ioh->fd_can_read || max_size) {
+ int optval, optlen;
+ int signalled = 0;
+ int is_socket = 0;
+
+ optlen = sizeof(optval);
+ if (getsockopt(ioh->fd, SOL_SOCKET, SO_TYPE,
+ (char *)&optval, &optlen) != SOCKET_ERROR) {
+ fd_set rfds;
+ struct timeval tv;
+ FD_ZERO(&rfds);
+ FD_SET(ioh->fd, &rfds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ is_socket = 1;
+ signalled = select(1, &rfds, NULL, NULL, &tv);
+ if (signalled == SOCKET_ERROR)
+ ioh->fd_read(ioh->opaque, NULL, -WSAGetLastError());
+ } else {
+ if (WaitForSingleObject((HANDLE)_get_osfhandle(ioh->fd), 0) ==
+ WAIT_OBJECT_0)
+ signalled = 1;
+ }
+
+ if (signalled)
+ {
+ if (ioh->max_size == 0) {
+ /* just a read event */
+ ioh->fd_read(ioh->opaque, NULL, 0);
+ } else {
+ if (is_socket) {
+ n = recv(ioh->fd, buf, ioh->max_size, 0);
+ if (n == SOCKET_ERROR)
+ ioh->fd_read(ioh->opaque, NULL,
-WSAGetLastError());
+ else
+ ioh->fd_read(ioh->opaque, buf, n);
+ } else {
+ n = read(ioh->fd, buf, ioh->max_size);
+ if (n >= 0) {
+ ioh->fd_read(ioh->opaque, buf, n);
+ } else if (errno != EAGAIN) {
+ ioh->fd_read(ioh->opaque, NULL, -errno);
+ }
+ }
+ }
+ }
+ }
+ }
#else
- /* poll any events */
- /* XXX: separate device handlers from system ones */
- pf = ufds;
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
- if (!ioh->fd_can_read) {
- max_size = 0;
+ /* XXX: separate device handlers from system ones */
+ pf = ufds;
+ for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
+ if (!ioh->fd_can_read) {
+ max_size = 0;
+ pf->fd = ioh->fd;
+ pf->events = POLLIN;
+ ioh->ufd = pf;
+ pf++;
+ } else {
+ max_size = ioh->fd_can_read(ioh->opaque);
+ if (max_size > 0) {
+ if (max_size > sizeof(buf))
+ max_size = sizeof(buf);
pf->fd = ioh->fd;
pf->events = POLLIN;
ioh->ufd = pf;
pf++;
} else {
- max_size = ioh->fd_can_read(ioh->opaque);
- if (max_size > 0) {
- if (max_size > sizeof(buf))
- max_size = sizeof(buf);
- pf->fd = ioh->fd;
- pf->events = POLLIN;
- ioh->ufd = pf;
- pf++;
- } else {
- ioh->ufd = NULL;
- }
+ ioh->ufd = NULL;
}
- ioh->max_size = max_size;
}
-
- ret = poll(ufds, pf - ufds, timeout);
- if (ret > 0) {
- /* XXX: better handling of removal */
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
- ioh_next = ioh->next;
- pf = ioh->ufd;
- if (pf) {
- if (pf->revents & POLLIN) {
- if (ioh->max_size == 0) {
- /* just a read event */
- ioh->fd_read(ioh->opaque, NULL, 0);
- } else {
- n = read(ioh->fd, buf, ioh->max_size);
- if (n >= 0) {
- ioh->fd_read(ioh->opaque, buf, n);
- } else if (errno != EAGAIN) {
- ioh->fd_read(ioh->opaque, NULL, -errno);
- }
+ ioh->max_size = max_size;
+ }
+
+ ret = poll(ufds, pf - ufds, timeout);
+ if (ret > 0)
+ {
+ /* XXX: better handling of removal */
+ for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
+ ioh_next = ioh->next;
+ pf = ioh->ufd;
+ if (pf) {
+ if (pf->revents & POLLIN) {
+ if (ioh->max_size == 0) {
+ /* just a read event */
+ ioh->fd_read(ioh->opaque, NULL, 0);
+ } else {
+ n = read(ioh->fd, buf, ioh->max_size);
+ if (n >= 0) {
+ ioh->fd_read(ioh->opaque, buf, n);
+ } else if (errno != EAGAIN) {
+ ioh->fd_read(ioh->opaque, NULL, -errno);
}
}
}
}
}
-#endif /* !defined(_WIN32) */
+ }
+#endif
#if defined(CONFIG_SLIRP)
- /* XXX: merge with poll() */
- if (slirp_inited) {
- fd_set rfds, wfds, xfds;
- int nfds;
- struct timeval tv;
-
- nfds = -1;
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&xfds);
- slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
- if (ret >= 0) {
- slirp_select_poll(&rfds, &wfds, &xfds);
- }
+ /* XXX: merge with poll() */
+ if (slirp_inited) {
+ fd_set rfds, wfds, xfds;
+ int nfds;
+ struct timeval tv;
+
+ nfds = -1;
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_ZERO(&xfds);
+ slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+ if (ret >= 0) {
+ slirp_select_poll(&rfds, &wfds, &xfds);
}
+ }
#endif
- if (vm_running) {
- qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
- qemu_get_clock(vm_clock));
- /* run dma transfers, if any */
- DMA_run();
- }
+ if (vm_running) {
+ qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
+ qemu_get_clock(vm_clock));
+ /* run dma transfers, if any */
+ DMA_run();
+ }
- /* real time timers */
- qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
- qemu_get_clock(rt_clock));
+ /* real time timers */
+ qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
+ qemu_get_clock(rt_clock));
}
int main_loop(void)
- [Qemu-devel] [PATCH] Win32 support for the GDB stub (take 2),
Filip Navara <=