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 53 RS_CHKSUM1,
54 54 RS_CHKSUM2,
55 55 };
56   -/* XXX: This is not thread safe. Do we care? */
57   -static int gdbserver_fd = -1;
58   -
59 56 typedef struct GDBState {
60 57 CPUState *env; /* current CPU */
61 58 enum RSState state; /* parsing state */
62   - int fd;
63 59 char line_buf[4096];
64 60 int line_buf_index;
65 61 int line_csum;
  62 + char last_packet[4100];
  63 + int last_packet_len;
66 64 #ifdef CONFIG_USER_ONLY
  65 + int fd;
67 66 int running_state;
  67 +#else
  68 + CharDriverState *chr;
68 69 #endif
69 70 } GDBState;
70 71  
71 72 #ifdef CONFIG_USER_ONLY
  73 +/* XXX: This is not thread safe. Do we care? */
  74 +static int gdbserver_fd = -1;
  75 +
72 76 /* XXX: remove this hack. */
73 77 static GDBState gdbserver_state;
74   -#endif
75 78  
76 79 static int get_char(GDBState *s)
77 80 {
... ... @@ -91,9 +94,11 @@ static int get_char(GDBState *s)
91 94 }
92 95 return ch;
93 96 }
  97 +#endif
94 98  
95 99 static void put_buffer(GDBState *s, const uint8_t *buf, int len)
96 100 {
  101 +#ifdef CONFIG_USER_ONLY
97 102 int ret;
98 103  
99 104 while (len > 0) {
... ... @@ -106,6 +111,9 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len)
106 111 len -= ret;
107 112 }
108 113 }
  114 +#else
  115 + qemu_chr_write(s->chr, buf, len);
  116 +#endif
109 117 }
110 118  
111 119 static inline int fromhex(int v)
... ... @@ -154,33 +162,39 @@ static void hextomem(uint8_t *mem, const char *buf, int len)
154 162 /* return -1 if error, 0 if OK */
155 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 168 #ifdef DEBUG_GDB
161 169 printf("reply='%s'\n", buf);
162 170 #endif
163 171  
164 172 for(;;) {
165   - buf1[0] = '$';
166   - put_buffer(s, buf1, 1);
  173 + p = s->last_packet;
  174 + *(p++) = '$';
167 175 len = strlen(buf);
168   - put_buffer(s, buf, len);
  176 + memcpy(p, buf, len);
  177 + p += len;
169 178 csum = 0;
170 179 for(i = 0; i < len; i++) {
171 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 192 return -1;
182   - if (ch == '+')
  193 + if (i == '+')
183 194 break;
  195 +#else
  196 + break;
  197 +#endif
184 198 }
185 199 return 0;
186 200 }
... ... @@ -864,6 +878,26 @@ static void gdb_read_byte(GDBState *s, int ch)
864 878 char reply[1];
865 879  
866 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 901 if (vm_running) {
868 902 /* when the CPU is running, we cannot do anything except stop
869 903 it when receiving a char */
... ... @@ -972,30 +1006,6 @@ void gdb_exit(CPUState *env, int code)
972 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 1010 static void gdb_accept(void *opaque)
1001 1011 {
... ... @@ -1019,32 +1029,12 @@ static void gdb_accept(void *opaque)
1019 1029 val = 1;
1020 1030 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
1021 1031  
1022   -#ifdef CONFIG_USER_ONLY
1023 1032 s = &gdbserver_state;
1024 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 1034 s->env = first_cpu; /* XXX: allow to change CPU */
1033 1035 s->fd = fd;
1034 1036  
1035   -#ifdef CONFIG_USER_ONLY
1036 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 1040 static int gdbserver_open(int port)
... ... @@ -1075,9 +1065,6 @@ static int gdbserver_open(int port)
1075 1065 perror("listen");
1076 1066 return -1;
1077 1067 }
1078   -#ifndef CONFIG_USER_ONLY
1079   - socket_set_nonblock(fd);
1080   -#endif
1081 1068 return fd;
1082 1069 }
1083 1070  
... ... @@ -1087,10 +1074,52 @@ int gdbserver_start(int port)
1087 1074 if (gdbserver_fd < 0)
1088 1075 return -1;
1089 1076 /* accept connections */
1090   -#ifdef CONFIG_USER_ONLY
1091 1077 gdb_accept (NULL);
  1078 + return 0;
  1079 +}
1092 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 1123 return 0;
1096 1124 }
  1125 +#endif
... ...
gdbstub.h
... ... @@ -6,7 +6,9 @@
6 6 #ifdef CONFIG_USER_ONLY
7 7 int gdb_handlesig (CPUState *, int);
8 8 void gdb_exit(CPUState *, int);
9   -#endif
10 9 int gdbserver_start(int);
  10 +#else
  11 +int gdbserver_start(CharDriverState *chr);
  12 +#endif
11 13  
12 14 #endif
... ...
qemu-doc.texi
... ... @@ -631,7 +631,8 @@ non graphical mode.
631 631 @item -s
632 632 Wait gdb connection to port 1234 (@pxref{gdb_usage}).
633 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 636 @item -S
636 637 Do not start CPU at startup (you must type 'c' in the monitor).
637 638 @item -d
... ...
... ... @@ -6496,7 +6496,8 @@ static BOOL WINAPI qemu_ctrl_handler(DWORD type)
6496 6496 int main(int argc, char **argv)
6497 6497 {
6498 6498 #ifdef CONFIG_GDBSTUB
6499   - int use_gdbstub, gdbstub_port;
  6499 + int use_gdbstub;
  6500 + char gdbstub_port_name[128];
6500 6501 #endif
6501 6502 int i, cdrom_index;
6502 6503 int snapshot, linux_boot;
... ... @@ -6564,7 +6565,7 @@ int main(int argc, char **argv)
6564 6565 bios_size = BIOS_SIZE;
6565 6566 #ifdef CONFIG_GDBSTUB
6566 6567 use_gdbstub = 0;
6567   - gdbstub_port = DEFAULT_GDBSTUB_PORT;
  6568 + sprintf(gdbstub_port_name, "%d", DEFAULT_GDBSTUB_PORT);
6568 6569 #endif
6569 6570 snapshot = 0;
6570 6571 nographic = 0;
... ... @@ -6808,7 +6809,7 @@ int main(int argc, char **argv)
6808 6809 use_gdbstub = 1;
6809 6810 break;
6810 6811 case QEMU_OPTION_p:
6811   - gdbstub_port = atoi(optarg);
  6812 + pstrcpy(gdbstub_port_name, sizeof(gdbstub_port_name), optarg);
6812 6813 break;
6813 6814 #endif
6814 6815 case QEMU_OPTION_L:
... ... @@ -7216,13 +7217,19 @@ int main(int argc, char **argv)
7216 7217  
7217 7218 #ifdef CONFIG_GDBSTUB
7218 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 7230 exit(1);
7223   - } else {
7224   - printf("Waiting gdb connection on port %d\n", gdbstub_port);
7225 7231 }
  7232 + gdbserver_start(chr);
7226 7233 } else
7227 7234 #endif
7228 7235 if (loadvm)
... ...
... ... @@ -84,7 +84,6 @@ static inline char *realpath(const char *path, char *resolved_path)
84 84  
85 85 #include "audio/audio.h"
86 86 #include "cpu.h"
87   -#include "gdbstub.h"
88 87  
89 88 #endif /* !defined(QEMU_TOOL) */
90 89  
... ... @@ -1364,6 +1363,8 @@ pflash_t *pflash_register (target_ulong base, ram_addr_t off,
1364 1363 uint16_t id0, uint16_t id1,
1365 1364 uint16_t id2, uint16_t id3);
1366 1365  
  1366 +#include "gdbstub.h"
  1367 +
1367 1368 #endif /* defined(QEMU_TOOL) */
1368 1369  
1369 1370 /* monitor.c */
... ...