Commit 4046d9130ebf3fb4dbb3fa49dfc7e23df7e59d87

Authored by pbrook
1 parent f7499989

Use standard character device interface for gdbstub.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2363 c046a42c-6fe2-441c-8c8c-71466251a162
gdbstub.c
@@ -53,25 +53,28 @@ enum RSState { @@ -53,25 +53,28 @@ enum RSState {
53 RS_CHKSUM1, 53 RS_CHKSUM1,
54 RS_CHKSUM2, 54 RS_CHKSUM2,
55 }; 55 };
56 -/* XXX: This is not thread safe. Do we care? */  
57 -static int gdbserver_fd = -1;  
58 -  
59 typedef struct GDBState { 56 typedef struct GDBState {
60 CPUState *env; /* current CPU */ 57 CPUState *env; /* current CPU */
61 enum RSState state; /* parsing state */ 58 enum RSState state; /* parsing state */
62 - int fd;  
63 char line_buf[4096]; 59 char line_buf[4096];
64 int line_buf_index; 60 int line_buf_index;
65 int line_csum; 61 int line_csum;
  62 + char last_packet[4100];
  63 + int last_packet_len;
66 #ifdef CONFIG_USER_ONLY 64 #ifdef CONFIG_USER_ONLY
  65 + int fd;
67 int running_state; 66 int running_state;
  67 +#else
  68 + CharDriverState *chr;
68 #endif 69 #endif
69 } GDBState; 70 } GDBState;
70 71
71 #ifdef CONFIG_USER_ONLY 72 #ifdef CONFIG_USER_ONLY
  73 +/* XXX: This is not thread safe. Do we care? */
  74 +static int gdbserver_fd = -1;
  75 +
72 /* XXX: remove this hack. */ 76 /* XXX: remove this hack. */
73 static GDBState gdbserver_state; 77 static GDBState gdbserver_state;
74 -#endif  
75 78
76 static int get_char(GDBState *s) 79 static int get_char(GDBState *s)
77 { 80 {
@@ -91,9 +94,11 @@ static int get_char(GDBState *s) @@ -91,9 +94,11 @@ static int get_char(GDBState *s)
91 } 94 }
92 return ch; 95 return ch;
93 } 96 }
  97 +#endif
94 98
95 static void put_buffer(GDBState *s, const uint8_t *buf, int len) 99 static void put_buffer(GDBState *s, const uint8_t *buf, int len)
96 { 100 {
  101 +#ifdef CONFIG_USER_ONLY
97 int ret; 102 int ret;
98 103
99 while (len > 0) { 104 while (len > 0) {
@@ -106,6 +111,9 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len) @@ -106,6 +111,9 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len)
106 len -= ret; 111 len -= ret;
107 } 112 }
108 } 113 }
  114 +#else
  115 + qemu_chr_write(s->chr, buf, len);
  116 +#endif
109 } 117 }
110 118
111 static inline int fromhex(int v) 119 static inline int fromhex(int v)
@@ -154,33 +162,39 @@ static void hextomem(uint8_t *mem, const char *buf, int len) @@ -154,33 +162,39 @@ static void hextomem(uint8_t *mem, const char *buf, int len)
154 /* return -1 if error, 0 if OK */ 162 /* return -1 if error, 0 if OK */
155 static int put_packet(GDBState *s, char *buf) 163 static int put_packet(GDBState *s, char *buf)
156 { 164 {
157 - char buf1[3];  
158 - int len, csum, ch, i; 165 + int len, csum, i;
  166 + char *p;
159 167
160 #ifdef DEBUG_GDB 168 #ifdef DEBUG_GDB
161 printf("reply='%s'\n", buf); 169 printf("reply='%s'\n", buf);
162 #endif 170 #endif
163 171
164 for(;;) { 172 for(;;) {
165 - buf1[0] = '$';  
166 - put_buffer(s, buf1, 1); 173 + p = s->last_packet;
  174 + *(p++) = '$';
167 len = strlen(buf); 175 len = strlen(buf);
168 - put_buffer(s, buf, len); 176 + memcpy(p, buf, len);
  177 + p += len;
169 csum = 0; 178 csum = 0;
170 for(i = 0; i < len; i++) { 179 for(i = 0; i < len; i++) {
171 csum += buf[i]; 180 csum += buf[i];
172 } 181 }
173 - buf1[0] = '#';  
174 - buf1[1] = tohex((csum >> 4) & 0xf);  
175 - buf1[2] = tohex((csum) & 0xf); 182 + *(p++) = '#';
  183 + *(p++) = tohex((csum >> 4) & 0xf);
  184 + *(p++) = tohex((csum) & 0xf);
176 185
177 - put_buffer(s, buf1, 3); 186 + s->last_packet_len = p - s->last_packet;
  187 + put_buffer(s, s->last_packet, s->last_packet_len);
178 188
179 - ch = get_char(s);  
180 - if (ch < 0) 189 +#ifdef CONFIG_USER_ONLY
  190 + i = get_char(s);
  191 + if (i < 0)
181 return -1; 192 return -1;
182 - if (ch == '+') 193 + if (i == '+')
183 break; 194 break;
  195 +#else
  196 + break;
  197 +#endif
184 } 198 }
185 return 0; 199 return 0;
186 } 200 }
@@ -864,6 +878,26 @@ static void gdb_read_byte(GDBState *s, int ch) @@ -864,6 +878,26 @@ static void gdb_read_byte(GDBState *s, int ch)
864 char reply[1]; 878 char reply[1];
865 879
866 #ifndef CONFIG_USER_ONLY 880 #ifndef CONFIG_USER_ONLY
  881 + if (s->last_packet_len) {
  882 + /* Waiting for a response to the last packet. If we see the start
  883 + of a new command then abandon the previous response. */
  884 + if (ch == '-') {
  885 +#ifdef DEBUG_GDB
  886 + printf("Got NACK, retransmitting\n");
  887 +#endif
  888 + put_buffer(s, s->last_packet, s->last_packet_len);
  889 + }
  890 +#ifdef DEBUG_GDB
  891 + else if (ch == '+')
  892 + printf("Got ACK\n");
  893 + else
  894 + printf("Got '%c' when expecting ACK/NACK\n", ch);
  895 +#endif
  896 + if (ch == '+' || ch == '$')
  897 + s->last_packet_len = 0;
  898 + if (ch != '$')
  899 + return;
  900 + }
867 if (vm_running) { 901 if (vm_running) {
868 /* when the CPU is running, we cannot do anything except stop 902 /* when the CPU is running, we cannot do anything except stop
869 it when receiving a char */ 903 it when receiving a char */
@@ -972,30 +1006,6 @@ void gdb_exit(CPUState *env, int code) @@ -972,30 +1006,6 @@ void gdb_exit(CPUState *env, int code)
972 put_packet(s, buf); 1006 put_packet(s, buf);
973 } 1007 }
974 1008
975 -#else  
976 -static void gdb_read(void *opaque)  
977 -{  
978 - GDBState *s = opaque;  
979 - int i, size;  
980 - uint8_t buf[4096];  
981 -  
982 - size = recv(s->fd, buf, sizeof(buf), 0);  
983 - if (size < 0)  
984 - return;  
985 - if (size == 0) {  
986 - /* end of connection */  
987 - qemu_del_vm_stop_handler(gdb_vm_stopped, s);  
988 - qemu_set_fd_handler(s->fd, NULL, NULL, NULL);  
989 - qemu_free(s);  
990 - if (autostart)  
991 - vm_start();  
992 - } else {  
993 - for(i = 0; i < size; i++)  
994 - gdb_read_byte(s, buf[i]);  
995 - }  
996 -}  
997 -  
998 -#endif  
999 1009
1000 static void gdb_accept(void *opaque) 1010 static void gdb_accept(void *opaque)
1001 { 1011 {
@@ -1019,32 +1029,12 @@ static void gdb_accept(void *opaque) @@ -1019,32 +1029,12 @@ static void gdb_accept(void *opaque)
1019 val = 1; 1029 val = 1;
1020 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); 1030 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
1021 1031
1022 -#ifdef CONFIG_USER_ONLY  
1023 s = &gdbserver_state; 1032 s = &gdbserver_state;
1024 memset (s, 0, sizeof (GDBState)); 1033 memset (s, 0, sizeof (GDBState));
1025 -#else  
1026 - s = qemu_mallocz(sizeof(GDBState));  
1027 - if (!s) {  
1028 - close(fd);  
1029 - return;  
1030 - }  
1031 -#endif  
1032 s->env = first_cpu; /* XXX: allow to change CPU */ 1034 s->env = first_cpu; /* XXX: allow to change CPU */
1033 s->fd = fd; 1035 s->fd = fd;
1034 1036
1035 -#ifdef CONFIG_USER_ONLY  
1036 fcntl(fd, F_SETFL, O_NONBLOCK); 1037 fcntl(fd, F_SETFL, O_NONBLOCK);
1037 -#else  
1038 - socket_set_nonblock(fd);  
1039 -  
1040 - /* stop the VM */  
1041 - vm_stop(EXCP_INTERRUPT);  
1042 -  
1043 - /* start handling I/O */  
1044 - qemu_set_fd_handler(s->fd, gdb_read, NULL, s);  
1045 - /* when the VM is stopped, the following callback is called */  
1046 - qemu_add_vm_stop_handler(gdb_vm_stopped, s);  
1047 -#endif  
1048 } 1038 }
1049 1039
1050 static int gdbserver_open(int port) 1040 static int gdbserver_open(int port)
@@ -1075,9 +1065,6 @@ static int gdbserver_open(int port) @@ -1075,9 +1065,6 @@ static int gdbserver_open(int port)
1075 perror("listen"); 1065 perror("listen");
1076 return -1; 1066 return -1;
1077 } 1067 }
1078 -#ifndef CONFIG_USER_ONLY  
1079 - socket_set_nonblock(fd);  
1080 -#endif  
1081 return fd; 1068 return fd;
1082 } 1069 }
1083 1070
@@ -1087,10 +1074,52 @@ int gdbserver_start(int port) @@ -1087,10 +1074,52 @@ int gdbserver_start(int port)
1087 if (gdbserver_fd < 0) 1074 if (gdbserver_fd < 0)
1088 return -1; 1075 return -1;
1089 /* accept connections */ 1076 /* accept connections */
1090 -#ifdef CONFIG_USER_ONLY  
1091 gdb_accept (NULL); 1077 gdb_accept (NULL);
  1078 + return 0;
  1079 +}
1092 #else 1080 #else
1093 - qemu_set_fd_handler(gdbserver_fd, gdb_accept, NULL, NULL);  
1094 -#endif 1081 +static int gdb_chr_can_recieve(void *opaque)
  1082 +{
  1083 + return 1;
  1084 +}
  1085 +
  1086 +static void gdb_chr_recieve(void *opaque, const uint8_t *buf, int size)
  1087 +{
  1088 + GDBState *s = opaque;
  1089 + int i;
  1090 +
  1091 + for (i = 0; i < size; i++) {
  1092 + gdb_read_byte(s, buf[i]);
  1093 + }
  1094 +}
  1095 +
  1096 +static void gdb_chr_event(void *opaque, int event)
  1097 +{
  1098 + switch (event) {
  1099 + case CHR_EVENT_RESET:
  1100 + vm_stop(EXCP_INTERRUPT);
  1101 + break;
  1102 + default:
  1103 + break;
  1104 + }
  1105 +}
  1106 +
  1107 +int gdbserver_start(CharDriverState *chr)
  1108 +{
  1109 + GDBState *s;
  1110 +
  1111 + if (!chr)
  1112 + return -1;
  1113 +
  1114 + s = qemu_mallocz(sizeof(GDBState));
  1115 + if (!s) {
  1116 + return -1;
  1117 + }
  1118 + s->env = first_cpu; /* XXX: allow to change CPU */
  1119 + s->chr = chr;
  1120 + qemu_chr_add_handlers(chr, gdb_chr_can_recieve, gdb_chr_recieve,
  1121 + gdb_chr_event, s);
  1122 + qemu_add_vm_stop_handler(gdb_vm_stopped, s);
1095 return 0; 1123 return 0;
1096 } 1124 }
  1125 +#endif
gdbstub.h
@@ -6,7 +6,9 @@ @@ -6,7 +6,9 @@
6 #ifdef CONFIG_USER_ONLY 6 #ifdef CONFIG_USER_ONLY
7 int gdb_handlesig (CPUState *, int); 7 int gdb_handlesig (CPUState *, int);
8 void gdb_exit(CPUState *, int); 8 void gdb_exit(CPUState *, int);
9 -#endif  
10 int gdbserver_start(int); 9 int gdbserver_start(int);
  10 +#else
  11 +int gdbserver_start(CharDriverState *chr);
  12 +#endif
11 13
12 #endif 14 #endif
qemu-doc.texi
@@ -631,7 +631,8 @@ non graphical mode. @@ -631,7 +631,8 @@ non graphical mode.
631 @item -s 631 @item -s
632 Wait gdb connection to port 1234 (@pxref{gdb_usage}). 632 Wait gdb connection to port 1234 (@pxref{gdb_usage}).
633 @item -p port 633 @item -p port
634 -Change gdb connection port. 634 +Change gdb connection port. @var{port} can be either a decimal number
  635 +to specify a TCP port, or a host device (same devices as the serial port).
635 @item -S 636 @item -S
636 Do not start CPU at startup (you must type 'c' in the monitor). 637 Do not start CPU at startup (you must type 'c' in the monitor).
637 @item -d 638 @item -d
@@ -6496,7 +6496,8 @@ static BOOL WINAPI qemu_ctrl_handler(DWORD type) @@ -6496,7 +6496,8 @@ static BOOL WINAPI qemu_ctrl_handler(DWORD type)
6496 int main(int argc, char **argv) 6496 int main(int argc, char **argv)
6497 { 6497 {
6498 #ifdef CONFIG_GDBSTUB 6498 #ifdef CONFIG_GDBSTUB
6499 - int use_gdbstub, gdbstub_port; 6499 + int use_gdbstub;
  6500 + char gdbstub_port_name[128];
6500 #endif 6501 #endif
6501 int i, cdrom_index; 6502 int i, cdrom_index;
6502 int snapshot, linux_boot; 6503 int snapshot, linux_boot;
@@ -6564,7 +6565,7 @@ int main(int argc, char **argv) @@ -6564,7 +6565,7 @@ int main(int argc, char **argv)
6564 bios_size = BIOS_SIZE; 6565 bios_size = BIOS_SIZE;
6565 #ifdef CONFIG_GDBSTUB 6566 #ifdef CONFIG_GDBSTUB
6566 use_gdbstub = 0; 6567 use_gdbstub = 0;
6567 - gdbstub_port = DEFAULT_GDBSTUB_PORT; 6568 + sprintf(gdbstub_port_name, "%d", DEFAULT_GDBSTUB_PORT);
6568 #endif 6569 #endif
6569 snapshot = 0; 6570 snapshot = 0;
6570 nographic = 0; 6571 nographic = 0;
@@ -6808,7 +6809,7 @@ int main(int argc, char **argv) @@ -6808,7 +6809,7 @@ int main(int argc, char **argv)
6808 use_gdbstub = 1; 6809 use_gdbstub = 1;
6809 break; 6810 break;
6810 case QEMU_OPTION_p: 6811 case QEMU_OPTION_p:
6811 - gdbstub_port = atoi(optarg); 6812 + pstrcpy(gdbstub_port_name, sizeof(gdbstub_port_name), optarg);
6812 break; 6813 break;
6813 #endif 6814 #endif
6814 case QEMU_OPTION_L: 6815 case QEMU_OPTION_L:
@@ -7216,13 +7217,19 @@ int main(int argc, char **argv) @@ -7216,13 +7217,19 @@ int main(int argc, char **argv)
7216 7217
7217 #ifdef CONFIG_GDBSTUB 7218 #ifdef CONFIG_GDBSTUB
7218 if (use_gdbstub) { 7219 if (use_gdbstub) {
7219 - if (gdbserver_start(gdbstub_port) < 0) {  
7220 - fprintf(stderr, "Could not open gdbserver socket on port %d\n",  
7221 - gdbstub_port); 7220 + CharDriverState *chr;
  7221 + int port;
  7222 +
  7223 + port = atoi(gdbstub_port_name);
  7224 + if (port != 0)
  7225 + sprintf(gdbstub_port_name, "tcp::%d,nowait,nodelay,server", port);
  7226 + chr = qemu_chr_open(gdbstub_port_name);
  7227 + if (!chr) {
  7228 + fprintf(stderr, "qemu: could not open gdbstub device '%s'\n",
  7229 + gdbstub_port_name);
7222 exit(1); 7230 exit(1);
7223 - } else {  
7224 - printf("Waiting gdb connection on port %d\n", gdbstub_port);  
7225 } 7231 }
  7232 + gdbserver_start(chr);
7226 } else 7233 } else
7227 #endif 7234 #endif
7228 if (loadvm) 7235 if (loadvm)
@@ -84,7 +84,6 @@ static inline char *realpath(const char *path, char *resolved_path) @@ -84,7 +84,6 @@ static inline char *realpath(const char *path, char *resolved_path)
84 84
85 #include "audio/audio.h" 85 #include "audio/audio.h"
86 #include "cpu.h" 86 #include "cpu.h"
87 -#include "gdbstub.h"  
88 87
89 #endif /* !defined(QEMU_TOOL) */ 88 #endif /* !defined(QEMU_TOOL) */
90 89
@@ -1364,6 +1363,8 @@ pflash_t *pflash_register (target_ulong base, ram_addr_t off, @@ -1364,6 +1363,8 @@ pflash_t *pflash_register (target_ulong base, ram_addr_t off,
1364 uint16_t id0, uint16_t id1, 1363 uint16_t id0, uint16_t id1,
1365 uint16_t id2, uint16_t id3); 1364 uint16_t id2, uint16_t id3);
1366 1365
  1366 +#include "gdbstub.h"
  1367 +
1367 #endif /* defined(QEMU_TOOL) */ 1368 #endif /* defined(QEMU_TOOL) */
1368 1369
1369 /* monitor.c */ 1370 /* monitor.c */