Version:
~
[ 2.3.5 ] ~
[ 2.3 ] ~
** Warning: Cannot open xref database.
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: gdbstub.cc,v 1.29 2007/02/07 17:53:06 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2002-2006 The Bochs Project Team
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //
12 // This library 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 GNU
15 // Lesser General Public License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this library; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/types.h>
24 #ifdef __MINGW32__
25 #include <winsock2.h>
26 #define SIGTRAP 5
27 #else
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
31 #include <arpa/inet.h>
32 #include <signal.h>
33 #include <netdb.h>
34 #endif
35
36 #define NEED_CPU_REG_SHORTCUTS 1
37
38 #include "bochs.h"
39 #include "cpu/cpu.h"
40 #include "iodev/iodev.h"
41
42 #define LOG_THIS gdbstublog->
43 #define IFDBG(x) x
44
45 static int last_stop_reason = GDBSTUB_STOP_NO_REASON;
46
47 #define GDBSTUB_EXECUTION_BREAKPOINT (0xac1)
48 #define GDBSTUB_TRACE (0xac2)
49 #define GDBSTUB_USER_BREAK (0xac3)
50
51 static bx_list_c *gdbstub_list;
52 static int listen_socket_fd;
53 static int socket_fd;
54 static logfunctions *gdbstublog;
55
56 static int hex(char ch)
57 {
58 if ((ch >= 'a') && (ch <= 'f')) return(ch - 'a' + 10);
59 if ((ch >= '') && (ch <= '9')) return(ch - '');
60 if ((ch >= 'A') && (ch <= 'F')) return(ch - 'A' + 10);
61 return(-1);
62 }
63
64 static char buf[4096], *bufptr = buf;
65
66 static void flush_debug_buffer()
67 {
68 char *p = buf;
69 while (p != bufptr) {
70 int n = send(socket_fd, p, bufptr-p, 0);
71 if (n == -1) {
72 BX_ERROR(("error on debug socket: %m"));
73 break;
74 }
75 p += n;
76 }
77 bufptr = buf;
78 }
79
80 static void put_debug_char(char ch)
81 {
82 if (bufptr == buf + sizeof buf)
83 flush_debug_buffer();
84 *bufptr++ = ch;
85 }
86
87 static char get_debug_char(void)
88 {
89 char ch;
90
91 recv(socket_fd, &ch, 1, 0);
92
93 return(ch);
94 }
95
96 static const char hexchars[]="0123456789abcdef";
97
98 static void put_reply(char* buffer)
99 {
100 unsigned char csum;
101 int i;
102
103 BX_DEBUG (("put_buffer %s", buffer));
104
105 do {
106 put_debug_char('$');
107
108 csum = 0;
109
110 i = 0;
111 while (buffer[i] != 0)
112 {
113 put_debug_char(buffer[i]);
114 csum = csum + buffer[i];
115 i++;
116 }
117
118 put_debug_char('#');
119 put_debug_char(hexchars[csum >> 4]);
120 put_debug_char(hexchars[csum % 16]);
121 flush_debug_buffer();
122 } while (get_debug_char() != '+');
123 }
124
125 static void get_command(char* buffer)
126 {
127 unsigned char checksum;
128 unsigned char xmitcsum;
129 char ch;
130 unsigned int count;
131 unsigned int i;
132
133 do {
134 while ((ch = get_debug_char()) != '$');
135
136 checksum = 0;
137 xmitcsum = 0;
138 count = 0;
139
140 while (1)
141 {
142 ch = get_debug_char();
143 if (ch == '#') break;
144 checksum = checksum + ch;
145 buffer[count] = ch;
146 count++;
147 }
148 buffer[count] = 0;
149
150 if (ch == '#')
151 {
152 xmitcsum = hex(get_debug_char()) << 4;
153 xmitcsum += hex(get_debug_char());
154 if (checksum != xmitcsum)
155 {
156 BX_INFO(("Bad checksum"));
157 }
158 }
159
160 if (checksum != xmitcsum)
161 {
162 put_debug_char('-');
163 flush_debug_buffer();
164 }
165 else
166 {
167 put_debug_char('+');
168 if (buffer[2] == ':')
169 {
170 put_debug_char(buffer[0]);
171 put_debug_char(buffer[1]);
172 count = strlen(buffer);
173 for (i = 3; i <= count; i++)
174 {
175 buffer[i - 3] = buffer[i];
176 }
177 }
178 flush_debug_buffer();
179 }
180 } while (checksum != xmitcsum);
181 }
182
183 void hex2mem(char* buf, unsigned char* mem, int count)
184 {
185 int i;
186 unsigned char ch;
187
188 for (i = 0; i<count; i++)
189 {
190 ch = hex(*buf++) << 4;
191 ch = ch + hex(*buf++);
192 *mem = ch;
193 mem++;
194 }
195 }
196
197 char* mem2hex(char* mem, char* buf, int count)
198 {
199 int i;
200 unsigned char ch;
201
202 for (i = 0; i<count; i++)
203 {
204 ch = *mem;
205 mem++;
206 *buf = hexchars[ch >> 4];
207 buf++;
208 *buf = hexchars[ch % 16];
209 buf++;
210 }
211 *buf = 0;
212 return(buf);
213 }
214
215 int hexdigit(char c)
216 {
217 if (isdigit(c))
218 return c - '';
219 else if (isupper(c))
220 return c - 'A' + 10;
221 else
222 return c - 'a' + 10;
223 }
224
225 Bit64u read_little_endian_hex(char *&buf)
226 {
227 int byte;
228 Bit64u ret = 0;
229 int n = 0;
230 while (isxdigit(*buf)) {
231 byte = hexdigit(*buf++);
232 if (isxdigit(*buf))
233 byte = (byte << 4) | hexdigit(*buf++);
234 ret |= (unsigned long long)byte << (n*8);
235 ++n;
236 }
237 return ret;
238 }
239
240 static int continue_thread = -1;
241 static int other_thread = 0;
242
243 #if !BX_SUPPORT_X86_64
244 #define NUMREGS (16)
245 #define NUMREGSBYTES (NUMREGS * 4)
246 static int registers[NUMREGS];
247 #endif
248
249 #define MAX_BREAKPOINTS (255)
250 static unsigned int breakpoints[MAX_BREAKPOINTS] = {0,};
251 static unsigned int nr_breakpoints = 0;
252
253 static int stub_trace_flag = 0;
254 static int instr_count = 0;
255 static int saved_eip = 0;
256 static int bx_enter_gdbstub = 0;
257
258 void bx_gdbstub_break(void)
259 {
260 bx_enter_gdbstub = 1;
261 }
262
263 int bx_gdbstub_check(unsigned int eip)
264 {
265 unsigned int i;
266 unsigned char ch;
267 long arg;
268 int r;
269 #if defined(__CYGWIN__) || defined(__MINGW32__)
270 fd_set fds;
271 struct timeval tv = {0, 0};
272 #endif
273
274 if (bx_enter_gdbstub)
275 {
276 bx_enter_gdbstub = 0;
277 last_stop_reason = GDBSTUB_EXECUTION_BREAKPOINT;
278 return GDBSTUB_EXECUTION_BREAKPOINT;
279 }
280
281 instr_count++;
282
283 if ((instr_count % 500) == 0)
284 {
285 #if !defined(__CYGWIN__) && !defined(__MINGW32__)
286 arg = fcntl(socket_fd, F_GETFL);
287 fcntl(socket_fd, F_SETFL, arg | O_NONBLOCK);
288 r = recv(socket_fd, &ch, 1, 0);
289 fcntl(socket_fd, F_SETFL, arg);
290 #else
291 FD_ZERO(&fds);
292 FD_SET(socket_fd, &fds);
293 r = select(socket_fd + 1, &fds, NULL, NULL, &tv);
294 if (r == 1)
295 {
296 r = recv(socket_fd, (char *)&ch, 1, 0);
297 }
298 #endif
299 if (r == 1)
300 {
301 BX_INFO(("Got byte %x", (unsigned int)ch));
302 last_stop_reason = GDBSTUB_USER_BREAK;
303 return GDBSTUB_USER_BREAK;
304 }
305 }
306
307 for (i = 0; i < nr_breakpoints; i++)
308 {
309 if (eip == breakpoints[i])
310 {
311 BX_INFO(("found breakpoint at %x", eip));
312 last_stop_reason = GDBSTUB_EXECUTION_BREAKPOINT;
313 return GDBSTUB_EXECUTION_BREAKPOINT;
314 }
315 }
316
317 if (stub_trace_flag == 1)
318 {
319 last_stop_reason = GDBSTUB_TRACE;
320 return GDBSTUB_TRACE;
321 }
322 last_stop_reason = GDBSTUB_STOP_NO_REASON;
323 return GDBSTUB_STOP_NO_REASON;
324 }
325
326 static int remove_breakpoint(unsigned int addr, int len)
327 {
328 unsigned int i;
329
330 if (len != 1)
331 {
332 return(0);
333 }
334
335 for (i = 0; i < MAX_BREAKPOINTS; i++)
336 {
337 if (breakpoints[i] == addr)
338 {
339 BX_INFO(("Removing breakpoint at %x", addr));
340 breakpoints[i] = 0;
341 return(1);
342 }
343 }
344 return(0);
345 }
346
347 static void insert_breakpoint(unsigned int addr)
348 {
349 unsigned int i;
350
351 BX_INFO(("setting breakpoint at %x", addr));
352
353 for (i = 0; i < (unsigned)MAX_BREAKPOINTS; i++)
354 {
355 if (breakpoints[i] == 0)
356 {
357 breakpoints[i] = addr;
358 if (i >= nr_breakpoints)
359 {
360 nr_breakpoints = i + 1;
361 }
362 return;
363 }
364 }
365 BX_INFO(("No slot for breakpoint"));
366 }
367
368 static void do_pc_breakpoint(int insert, unsigned long long addr, int len)
369 {
370 for (int i = 0; i < len; ++i)
371 if (insert)
372 insert_breakpoint(addr+i);
373 else
374 remove_breakpoint(addr+i, 1);
375 }
376
377 static void do_breakpoint(int insert, char* buffer)
378 {
379 char* ebuf;
380 unsigned long type = strtoul(buffer, &ebuf, 16);
381 unsigned long long addr = strtoull(ebuf+1, &ebuf, 16);
382 unsigned long len = strtoul(ebuf+1, &ebuf, 16);
383 switch (type) {
384 case 0:
385 case 1:
386 do_pc_breakpoint(insert, addr, len);
387 put_reply("OK");
388 break;
389 default:
390 put_reply("");
391 break;
392 }
393 }
394
395 static void write_signal(char* buf, int signal)
396 {
397 buf[0] = hexchars[signal >> 4];
398 buf[1] = hexchars[signal % 16];
399 buf[2] = 0;
400 }
401
402 static int access_linear(Bit64u laddress,
403 unsigned len,
404 unsigned int rw,
405 Bit8u* data)
406 {
407 bx_phy_address phys;
408 bx_bool valid;
409
410 if (((laddress & 0xfff) + len) > 4096)
411 {
412 valid = access_linear(laddress,
413 4096 - (laddress & 0xfff),
414 rw,
415 data);
416 if (!valid) return(0);
417
418 valid = access_linear(laddress,
419 len + (laddress & 0xfff) - 4096,
420 rw,
421 (Bit8u *)((unsigned long)data +
422 4096 - (laddress & 0xfff)));
423 return(valid);
424 }
425
426 valid = BX_CPU(0)->dbg_xlate_linear2phy(laddress, (bx_phy_address*)&phys);
427 if (!valid) return(0);
428
429 if (rw == BX_READ) {
430 valid = BX_MEM(0)->dbg_fetch_mem(BX_CPU(0), phys, len, data);
431 } else {
432 valid = BX_MEM(0)->dbg_set_mem(phys, len, data);
433 }
434
435 return(valid);
436 }
437
438 static void debug_loop(void)
439 {
440 char buffer[255];
441 char obuf[255];
442 int ne;
443 unsigned char mem[255];
444
445 ne = 0;
446
447 while (ne == 0)
448 {
449 get_command(buffer);
450 BX_DEBUG(("get_buffer %s", buffer));
451
452 switch (buffer[0])
453 {
454 case 'c':
455 {
456 char buf[255];
457 int new_eip;
458
459 if (buffer[1] != 0)
460 {
461 new_eip = atoi(buffer + 1);
462
463 BX_INFO(("continuing at %x", new_eip));
464
465 for (int i=0; i<BX_SMP_PROCESSORS; i++) {
466 BX_CPU(i)->invalidate_prefetch_q();
467 }
468
469 saved_eip = EIP;
470
471 BX_CPU(0)->dword.eip = new_eip;
472 }
473
474 stub_trace_flag = 0;
475 bx_cpu.cpu_loop(0);
476
477 DEV_vga_refresh();
478
479 if (buffer[1] != 0)
480 {
481 bx_cpu.invalidate_prefetch_q();
482 BX_CPU_THIS_PTR dword.eip = saved_eip;
483 }
484
485 BX_INFO(("stopped with %x", last_stop_reason));
486 buf[0] = 'S';
487 if (last_stop_reason == GDBSTUB_EXECUTION_BREAKPOINT ||
488 last_stop_reason == GDBSTUB_TRACE)
489 {
490 write_signal(&buf[1], SIGTRAP);
491 }
492 else
493 {
494 write_signal(&buf[1], 0);
495 }
496 put_reply(buf);
497 break;
498 }
499
500 case 's':
501 {
502 char buf[255];
503
504 BX_INFO(("stepping"));
505 stub_trace_flag = 1;
506 bx_cpu.cpu_loop(0);
507 DEV_vga_refresh();
508 stub_trace_flag = 0;
509 BX_INFO(("stopped with %x", last_stop_reason));
510 buf[0] = 'S';
511 if (last_stop_reason == GDBSTUB_EXECUTION_BREAKPOINT ||
512 last_stop_reason == GDBSTUB_TRACE)
513 {
514 write_signal(&buf[1], SIGTRAP);
515 }
516 else
517 {
518 write_signal(&buf[1], SIGTRAP);
519 }
520 put_reply(buf);
521 break;
522 }
523
524 case 'M':
525 {
526 Bit64u addr;
527 int len;
528 unsigned char mem[255];
529 char* ebuf;
530
531 addr = strtoull(&buffer[1], &ebuf, 16);
532 len = strtoul(ebuf + 1, &ebuf, 16);
533 hex2mem(ebuf + 1, mem, len);
534
535 if (len == 1 && mem[0] == 0xcc)
536 {
537 insert_breakpoint(addr);
538 put_reply("OK");
539 }
540 else if (remove_breakpoint(addr, len))
541 {
542 put_reply("OK");
543 }
544 else
545 {
546 if (access_linear(addr, len, BX_WRITE, mem))
547 {
548 put_reply("OK");
549 }
550 else
551 {
552 put_reply("Eff");
553 }
554 }
555 break;
556 }
557
558 case 'm':
559 {
560 Bit64u addr;
561 int len;
562 char* ebuf;
563
564 addr = strtoull(&buffer[1], &ebuf, 16);
565 len = strtoul(ebuf + 1, NULL, 16);
566 BX_INFO(("addr %Lx len %x", addr, len));
567
568 access_linear(addr, len, BX_READ, mem);
569 mem2hex((char *)mem, obuf, len);
570 put_reply(obuf);
571 break;
572 }
573
574 case 'P':
575 {
576 int reg;
577 unsigned long long value;
578 char* ebuf;
579
580 reg = strtoul(&buffer[1], &ebuf, 16);
581 ++ebuf;
582 value = read_little_endian_hex(ebuf);
583
584 BX_INFO(("reg %d set to %Lx", reg, value));
585 #if !BX_SUPPORT_X86_64
586 switch (reg)
587 {
588 case 1:
589 EAX = value;
590 break;
591
592 case 2:
593 ECX = value;
594 break;
595
596 case 3:
597 EBX = value;
598 break;
599
600 case 4:
601 ESP = value;
602 break;
603
604 case 5:
605 EBP = value;
606 break;
607
608 case 6:
609 ESI = value;
610 break;
611
612 case 7:
613 EDI = value;
614 break;
615
616 case 8:
617 EIP = value;
618 BX_CPU_THIS_PTR invalidate_prefetch_q();
619 break;
620
621 default:
622 break;
623 }
624 #else
625 switch (reg)
626 {
627 case 0:
628 RAX = value;
629 break;
630
631 case 1:
632 RBX = value;
633 break;
634
635 case 2:
636 RCX = value;
637 break;
638
639 case 3:
640 RDX = value;
641 break;
642
643 case 4:
644 RSI = value;
645 break;
646
647 case 5:
648 RDI = value;
649 break;
650
651 case 6:
652 ESP = value;
653 break;
654
655 case 7:
656 RBP = value;
657 break;
658
659 case 8:
660 R8 = value;
661 break;
662
663 case 9:
664 R9 = value;
665 break;
666
667 case 10:
668 R10 = value;
669 break;
670
671 case 11:
672 R11 = value;
673 break;
674
675 case 12:
676 R12 = value;
677 break;
678
679 case 13:
680 R13 = value;
681 break;
682
683 case 14:
684 R15 = value;
685 break;
686
687 case 15:
688 R15 = value;
689 break;
690
691 case 16:
692 RIP = value;
693 BX_CPU_THIS_PTR invalidate_prefetch_q();
694 break;
695
696 default:
697 break;
698 }
699 #endif
700 put_reply("OK");
701
702 break;
703 }
704
705 case 'g':
706 #if !BX_SUPPORT_X86_64
707 registers[0] = EAX;
708 registers[1] = ECX;
709 registers[2] = EDX;
710 registers[3] = EBX;
711 registers[4] = ESP;
712 registers[5] = EBP;
713 registers[6] = ESI;
714 registers[7] = EDI;
715 if (last_stop_reason == GDBSTUB_EXECUTION_BREAKPOINT)
716 {
717 registers[8] = EIP + 1;
718 }
719 else
720 {
721 registers[8] = EIP;
722 }
723 registers[9] = BX_CPU_THIS_PTR read_eflags();
724 registers[10] =
725 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
726 registers[11] =
727 BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
728 registers[12] =
729 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
730 registers[13] =
731 BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
732 registers[14] =
733 BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
734 registers[15] =
735 BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
736 mem2hex((char *)registers, obuf, NUMREGSBYTES);
737 #else
738 #define PUTREG(buf, val, len) do { \
739 Bit64u u = (val); \
740 (buf) = mem2hex((char*)&u, (buf), (len)); \
741 } while (0)
742 char* buf;
743 buf = obuf;
744 PUTREG(buf, RAX, 8);
745 PUTREG(buf, RBX, 8);
746 PUTREG(buf, RCX, 8);
747 PUTREG(buf, RDX, 8);
748 PUTREG(buf, RSI, 8);
749 PUTREG(buf, RDI, 8);
750 PUTREG(buf, RBP, 8);
751 PUTREG(buf, RSP, 8);
752 PUTREG(buf, R8, 8);
753 PUTREG(buf, R9, 8);
754 PUTREG(buf, R10, 8);
755 PUTREG(buf, R11, 8);
756 PUTREG(buf, R12, 8);
757 PUTREG(buf, R13, 8);
758 PUTREG(buf, R14, 8);
759 PUTREG(buf, R15, 8);
760 Bit64u rip;
761 rip = RIP;
762 if (last_stop_reason == GDBSTUB_EXECUTION_BREAKPOINT)
763 {
764 ++rip;
765 }
766 PUTREG(buf, rip, 8);
767 PUTREG(buf, BX_CPU_THIS_PTR read_eflags(), 4);
768 PUTREG(buf, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, 4);
769 PUTREG(buf, BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value, 4);
770 PUTREG(buf, BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value, 4);
771 PUTREG(buf, BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value, 4);
772 PUTREG(buf, BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value, 4);
773 PUTREG(buf, BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value, 4);
774 #endif
775 put_reply(obuf);
776 break;
777
778 case '?':
779 sprintf(obuf, "S%02x", SIGTRAP);
780 put_reply(obuf);
781 break;
782
783 case 'H':
784 if (buffer[1] == 'c')
785 {
786 continue_thread = strtol(&buffer[2], NULL, 16);
787 put_reply("OK");
788 }
789 else if (buffer[1] == 'g')
790 {
791 other_thread = strtol(&buffer[2], NULL, 16);
792 put_reply("OK");
793 }
794 else
795 {
796 put_reply("Eff");
797 }
798 break;
799
800 case 'q':
801 if (buffer[1] == 'C')
802 {
803 sprintf(obuf,"%Lx", (Bit64u)1);
804 put_reply(obuf);
805 }
806 else if (strncmp(&buffer[1], "Offsets", strlen("Offsets")) == 0)
807 {
808 sprintf(obuf, "Text=%x;Data=%x;Bss=%x",
809 SIM->get_param_num("text_base", gdbstub_list)->get(),
810 SIM->get_param_num("data_base", gdbstub_list)->get(),
811 SIM->get_param_num("bss_base", gdbstub_list)->get());
812 put_reply(obuf);
813 }
814 else
815 {
816 put_reply("Eff");
817 }
818 break;
819
820 case 'Z':
821 do_breakpoint(1, buffer+1);
822 break;
823 case 'z':
824 do_breakpoint(0, buffer+1);
825 break;
826 case 'k':
827 BX_PANIC(("Debugger asked us to quit"));
828 break;
829
830 default:
831 put_reply("");
832 break;
833 }
834 }
835 }
836
837 static void wait_for_connect(int portn)
838 {
839 struct sockaddr_in sockaddr;
840 socklen_t sockaddr_len;
841 struct protoent *protoent;
842 int r;
843 int opt;
844
845 listen_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
846 if (listen_socket_fd == -1)
847 {
848 BX_PANIC(("Failed to create socket"));
849 exit(1);
850 }
851
852 /* Allow rapid reuse of this port */
853 opt = 1;
854 #if __MINGW32__
855 r = setsockopt(listen_socket_fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt));
856 #else
857 r = setsockopt(listen_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
858 #endif
859 if (r == -1)
860 {
861 BX_INFO(("setsockopt(SO_REUSEADDR) failed"));
862 }
863
864 memset (&sockaddr, '\000', sizeof sockaddr);
865 #if BX_HAVE_SOCKADDR_IN_SIN_LEN
866 // if you don't have sin_len change that to #if 0. This is the subject of
867 // bug [ 626840 ] no 'sin_len' in 'struct sockaddr_in'.
868 sockaddr.sin_len = sizeof sockaddr;
869 #endif
870 sockaddr.sin_family = AF_INET;
871 sockaddr.sin_port = htons(portn);
872 sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
873
874 r = bind(listen_socket_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
875 if (r == -1)
876 {
877 BX_PANIC(("Failed to bind socket"));
878 }
879
880 r = listen(listen_socket_fd, 0);
881 if (r == -1)
882 {
883 BX_PANIC(("Failed to listen on socket"));
884 }
885
886 sockaddr_len = sizeof sockaddr;
887 socket_fd = accept(listen_socket_fd, (struct sockaddr *)&sockaddr, &sockaddr_len);
888 if (socket_fd == -1)
889 {
890 BX_PANIC(("Failed to accept on socket"));
891 }
892 close(listen_socket_fd);
893
894 protoent = getprotobyname ("tcp");
895 if (!protoent)
896 {
897 BX_INFO(("getprotobyname (\"tcp\") failed"));
898 return;
899 }
900
901 /* Disable Nagle - allow small packets to be sent without delay. */
902 opt = 1;
903 #ifdef __MINGW32__
904 r = setsockopt (socket_fd, protoent->p_proto, TCP_NODELAY, (const char *)&opt, sizeof(opt));
905 #else
906 r = setsockopt (socket_fd, protoent->p_proto, TCP_NODELAY, &opt, sizeof(opt));
907 #endif
908 if (r == -1)
909 {
910 BX_INFO(("setsockopt(TCP_NODELAY) failed"));
911 }
912 Bit32u ip = sockaddr.sin_addr.s_addr;
913 printf("Connected to %d.%d.%d.%d\n", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff);
914 }
915
916 void bx_gdbstub_init(void)
917 {
918 gdbstublog = new logfunctions();
919 gdbstublog->put("GDBST");
920 gdbstublog->setonoff(LOGLEV_PANIC, ACT_FATAL);
921
922 gdbstub_list = (bx_list_c*) SIM->get_param(BXPN_GDBSTUB);
923 int portn = SIM->get_param_num("port", gdbstub_list)->get();
924
925 #ifdef __MINGW32__
926 WSADATA wsaData;
927 WSAStartup(2, &wsaData);
928 #endif
929
930 /* Wait for connect */
931 printf("Waiting for gdb connection on port %d\n", portn);
932 wait_for_connect(portn);
933
934 /* Do debugger command loop */
935 debug_loop();
936
937 /* CPU loop */
938 bx_cpu.cpu_loop(0);
939 }
940
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.