Revision 1fddef4b
b/Makefile.target | ||
---|---|---|
298 | 298 |
ifeq ($(ARCH),ia64) |
299 | 299 |
OBJS += ia64-syscall.o |
300 | 300 |
endif |
301 |
ifdef CONFIG_GDBSTUB |
|
302 |
OBJS+=gdbstub.o |
|
303 |
endif |
|
301 | 304 |
|
302 | 305 |
all: $(PROGS) |
303 | 306 |
|
b/exec.c | ||
---|---|---|
1076 | 1076 |
tb_reset_jump_recursive2(tb, 1); |
1077 | 1077 |
} |
1078 | 1078 |
|
1079 |
#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
|
|
1079 |
#if defined(TARGET_HAS_ICE)
|
|
1080 | 1080 |
static void breakpoint_invalidate(CPUState *env, target_ulong pc) |
1081 | 1081 |
{ |
1082 | 1082 |
target_ulong phys_addr; |
... | ... | |
1090 | 1090 |
breakpoint is reached */ |
1091 | 1091 |
int cpu_breakpoint_insert(CPUState *env, target_ulong pc) |
1092 | 1092 |
{ |
1093 |
#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
|
|
1093 |
#if defined(TARGET_HAS_ICE)
|
|
1094 | 1094 |
int i; |
1095 | 1095 |
|
1096 | 1096 |
for(i = 0; i < env->nb_breakpoints; i++) { |
... | ... | |
1112 | 1112 |
/* remove a breakpoint */ |
1113 | 1113 |
int cpu_breakpoint_remove(CPUState *env, target_ulong pc) |
1114 | 1114 |
{ |
1115 |
#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
|
|
1115 |
#if defined(TARGET_HAS_ICE)
|
|
1116 | 1116 |
int i; |
1117 | 1117 |
for(i = 0; i < env->nb_breakpoints; i++) { |
1118 | 1118 |
if (env->breakpoints[i] == pc) |
... | ... | |
1120 | 1120 |
} |
1121 | 1121 |
return -1; |
1122 | 1122 |
found: |
1123 |
memmove(&env->breakpoints[i], &env->breakpoints[i + 1], |
|
1124 |
(env->nb_breakpoints - (i + 1)) * sizeof(env->breakpoints[0])); |
|
1125 | 1123 |
env->nb_breakpoints--; |
1124 |
if (i < env->nb_breakpoints) |
|
1125 |
env->breakpoints[i] = env->breakpoints[env->nb_breakpoints]; |
|
1126 | 1126 |
|
1127 | 1127 |
breakpoint_invalidate(env, pc); |
1128 | 1128 |
return 0; |
... | ... | |
1135 | 1135 |
CPU loop after each instruction */ |
1136 | 1136 |
void cpu_single_step(CPUState *env, int enabled) |
1137 | 1137 |
{ |
1138 |
#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
|
|
1138 |
#if defined(TARGET_HAS_ICE)
|
|
1139 | 1139 |
if (env->singlestep_enabled != enabled) { |
1140 | 1140 |
env->singlestep_enabled = enabled; |
1141 | 1141 |
/* must flush all the translated code to avoid inconsistancies */ |
b/gdbstub.c | ||
---|---|---|
17 | 17 |
* License along with this library; if not, write to the Free Software |
18 | 18 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | 19 |
*/ |
20 |
#ifdef CONFIG_USER_ONLY |
|
21 |
#include <stdlib.h> |
|
22 |
#include <stdio.h> |
|
23 |
#include <stdarg.h> |
|
24 |
#include <string.h> |
|
25 |
#include <errno.h> |
|
26 |
#include <unistd.h> |
|
27 |
|
|
28 |
#include "qemu.h" |
|
29 |
#else |
|
20 | 30 |
#include "vl.h" |
31 |
#endif |
|
21 | 32 |
|
22 | 33 |
#include <sys/socket.h> |
23 | 34 |
#include <netinet/in.h> |
... | ... | |
31 | 42 |
RS_GETLINE, |
32 | 43 |
RS_CHKSUM1, |
33 | 44 |
RS_CHKSUM2, |
45 |
RS_CONTINUE |
|
34 | 46 |
}; |
35 |
|
|
36 |
static int gdbserver_fd; |
|
47 |
/* XXX: This is not thread safe. Do we care? */ |
|
48 |
static int gdbserver_fd = -1;
|
|
37 | 49 |
|
38 | 50 |
typedef struct GDBState { |
39 | 51 |
enum RSState state; |
... | ... | |
43 | 55 |
int line_csum; |
44 | 56 |
} GDBState; |
45 | 57 |
|
58 |
#ifdef CONFIG_USER_ONLY |
|
59 |
/* XXX: remove this hack. */ |
|
60 |
static GDBState gdbserver_state; |
|
61 |
#endif |
|
62 |
|
|
46 | 63 |
static int get_char(GDBState *s) |
47 | 64 |
{ |
48 | 65 |
uint8_t ch; |
... | ... | |
330 | 347 |
env->npc = tswapl(registers[69]); |
331 | 348 |
env->fsr = tswapl(registers[70]); |
332 | 349 |
} |
333 |
#else |
|
350 |
#elif defined (TARGET_ARM) |
|
351 |
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) |
|
352 |
{ |
|
353 |
int i; |
|
354 |
uint8_t *ptr; |
|
355 |
|
|
356 |
ptr = mem_buf; |
|
357 |
/* 16 core integer registers (4 bytes each). */ |
|
358 |
for (i = 0; i < 16; i++) |
|
359 |
{ |
|
360 |
*(uint32_t *)ptr = tswapl(env->regs[i]); |
|
361 |
ptr += 4; |
|
362 |
} |
|
363 |
/* 8 FPA registers (12 bytes each), FPS (4 bytes). |
|
364 |
Not yet implemented. */ |
|
365 |
memset (ptr, 0, 8 * 12 + 4); |
|
366 |
ptr += 8 * 12 + 4; |
|
367 |
/* CPSR (4 bytes). */ |
|
368 |
*(uint32_t *)ptr = tswapl (env->cpsr); |
|
369 |
ptr += 4; |
|
370 |
|
|
371 |
return ptr - mem_buf; |
|
372 |
} |
|
334 | 373 |
|
374 |
static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) |
|
375 |
{ |
|
376 |
int i; |
|
377 |
uint8_t *ptr; |
|
378 |
|
|
379 |
ptr = mem_buf; |
|
380 |
/* Core integer registers. */ |
|
381 |
for (i = 0; i < 16; i++) |
|
382 |
{ |
|
383 |
env->regs[i] = tswapl(*(uint32_t *)ptr); |
|
384 |
ptr += 4; |
|
385 |
} |
|
386 |
/* Ignore FPA regs and scr. */ |
|
387 |
ptr += 8 * 12 + 4; |
|
388 |
env->cpsr = tswapl(*(uint32_t *)ptr); |
|
389 |
} |
|
390 |
#else |
|
335 | 391 |
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) |
336 | 392 |
{ |
337 | 393 |
return 0; |
... | ... | |
343 | 399 |
|
344 | 400 |
#endif |
345 | 401 |
|
346 |
/* port = 0 means default port */ |
|
347 |
static int gdb_handle_packet(GDBState *s, const char *line_buf) |
|
402 |
static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) |
|
348 | 403 |
{ |
349 |
CPUState *env = cpu_single_env; |
|
350 | 404 |
const char *p; |
351 | 405 |
int ch, reg_size, type; |
352 | 406 |
char buf[4096]; |
... | ... | |
361 | 415 |
ch = *p++; |
362 | 416 |
switch(ch) { |
363 | 417 |
case '?': |
418 |
/* TODO: Make this return the correct value for user-mode. */ |
|
364 | 419 |
snprintf(buf, sizeof(buf), "S%02x", SIGTRAP); |
365 | 420 |
put_packet(s, buf); |
366 | 421 |
break; |
... | ... | |
376 | 431 |
env->npc = addr + 4; |
377 | 432 |
#endif |
378 | 433 |
} |
379 |
vm_start(); |
|
380 |
break; |
|
434 |
return RS_CONTINUE; |
|
381 | 435 |
case 's': |
382 | 436 |
if (*p != '\0') { |
383 | 437 |
addr = strtoul(p, (char **)&p, 16); |
... | ... | |
391 | 445 |
#endif |
392 | 446 |
} |
393 | 447 |
cpu_single_step(env, 1); |
394 |
vm_start(); |
|
395 |
break; |
|
448 |
return RS_CONTINUE; |
|
396 | 449 |
case 'g': |
397 | 450 |
reg_size = cpu_gdb_read_registers(env, mem_buf); |
398 | 451 |
memtohex(buf, mem_buf, reg_size); |
... | ... | |
472 | 525 |
|
473 | 526 |
extern void tb_flush(CPUState *env); |
474 | 527 |
|
528 |
#ifndef CONFIG_USER_ONLY |
|
475 | 529 |
static void gdb_vm_stopped(void *opaque, int reason) |
476 | 530 |
{ |
477 | 531 |
GDBState *s = opaque; |
... | ... | |
490 | 544 |
snprintf(buf, sizeof(buf), "S%02x", ret); |
491 | 545 |
put_packet(s, buf); |
492 | 546 |
} |
547 |
#endif |
|
493 | 548 |
|
494 |
static void gdb_read_byte(GDBState *s, int ch) |
|
549 |
static void gdb_read_byte(GDBState *s, CPUState *env, int ch)
|
|
495 | 550 |
{ |
496 | 551 |
int i, csum; |
497 | 552 |
char reply[1]; |
498 | 553 |
|
554 |
#ifndef CONFIG_USER_ONLY |
|
499 | 555 |
if (vm_running) { |
500 | 556 |
/* when the CPU is running, we cannot do anything except stop |
501 | 557 |
it when receiving a char */ |
502 | 558 |
vm_stop(EXCP_INTERRUPT); |
503 | 559 |
} else { |
560 |
#endif |
|
504 | 561 |
switch(s->state) { |
505 | 562 |
case RS_IDLE: |
506 | 563 |
if (ch == '$') { |
... | ... | |
535 | 592 |
} else { |
536 | 593 |
reply[0] = '+'; |
537 | 594 |
put_buffer(s, reply, 1); |
538 |
s->state = gdb_handle_packet(s, s->line_buf); |
|
595 |
s->state = gdb_handle_packet(s, env, s->line_buf);
|
|
539 | 596 |
} |
540 | 597 |
break; |
598 |
case RS_CONTINUE: |
|
599 |
#ifndef CONFIG_USER_ONLY |
|
600 |
vm_start(); |
|
601 |
s->state = RS_IDLE; |
|
602 |
#endif |
|
603 |
break; |
|
541 | 604 |
} |
605 |
#ifndef CONFIG_USER_ONLY |
|
542 | 606 |
} |
607 |
#endif |
|
543 | 608 |
} |
544 | 609 |
|
610 |
#ifdef CONFIG_USER_ONLY |
|
611 |
int |
|
612 |
gdb_handlesig (CPUState *env, int sig) |
|
613 |
{ |
|
614 |
GDBState *s; |
|
615 |
char buf[256]; |
|
616 |
int n; |
|
617 |
|
|
618 |
if (gdbserver_fd < 0) |
|
619 |
return sig; |
|
620 |
|
|
621 |
s = &gdbserver_state; |
|
622 |
|
|
623 |
/* disable single step if it was enabled */ |
|
624 |
cpu_single_step(env, 0); |
|
625 |
tb_flush(env); |
|
626 |
|
|
627 |
if (sig != 0) |
|
628 |
{ |
|
629 |
snprintf(buf, sizeof(buf), "S%02x", sig); |
|
630 |
put_packet(s, buf); |
|
631 |
} |
|
632 |
|
|
633 |
/* TODO: How do we terminate this loop? */ |
|
634 |
sig = 0; |
|
635 |
s->state = RS_IDLE; |
|
636 |
while (s->state != RS_CONTINUE) |
|
637 |
{ |
|
638 |
n = read (s->fd, buf, 256); |
|
639 |
if (n > 0) |
|
640 |
{ |
|
641 |
int i; |
|
642 |
|
|
643 |
for (i = 0; i < n; i++) |
|
644 |
gdb_read_byte (s, env, buf[i]); |
|
645 |
} |
|
646 |
else if (n == 0 || errno != EAGAIN) |
|
647 |
{ |
|
648 |
/* XXX: Connection closed. Should probably wait for annother |
|
649 |
connection before continuing. */ |
|
650 |
return sig; |
|
651 |
} |
|
652 |
} |
|
653 |
return sig; |
|
654 |
} |
|
655 |
#else |
|
545 | 656 |
static int gdb_can_read(void *opaque) |
546 | 657 |
{ |
547 | 658 |
return 256; |
... | ... | |
559 | 670 |
vm_start(); |
560 | 671 |
} else { |
561 | 672 |
for(i = 0; i < size; i++) |
562 |
gdb_read_byte(s, buf[i]); |
|
673 |
gdb_read_byte(s, cpu_single_env, buf[i]);
|
|
563 | 674 |
} |
564 | 675 |
} |
565 | 676 |
|
677 |
#endif |
|
678 |
|
|
566 | 679 |
static void gdb_accept(void *opaque, const uint8_t *buf, int size) |
567 | 680 |
{ |
568 | 681 |
GDBState *s; |
... | ... | |
585 | 698 |
val = 1; |
586 | 699 |
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); |
587 | 700 |
|
701 |
#ifdef CONFIG_USER_ONLY |
|
702 |
s = &gdbserver_state; |
|
703 |
memset (s, 0, sizeof (GDBState)); |
|
704 |
#else |
|
588 | 705 |
s = qemu_mallocz(sizeof(GDBState)); |
589 | 706 |
if (!s) { |
590 | 707 |
close(fd); |
591 | 708 |
return; |
592 | 709 |
} |
710 |
#endif |
|
593 | 711 |
s->fd = fd; |
594 | 712 |
|
595 | 713 |
fcntl(fd, F_SETFL, O_NONBLOCK); |
596 | 714 |
|
715 |
#ifndef CONFIG_USER_ONLY |
|
597 | 716 |
/* stop the VM */ |
598 | 717 |
vm_stop(EXCP_INTERRUPT); |
599 | 718 |
|
... | ... | |
601 | 720 |
qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s); |
602 | 721 |
/* when the VM is stopped, the following callback is called */ |
603 | 722 |
qemu_add_vm_stop_handler(gdb_vm_stopped, s); |
723 |
#endif |
|
604 | 724 |
} |
605 | 725 |
|
606 | 726 |
static int gdbserver_open(int port) |
... | ... | |
631 | 751 |
perror("listen"); |
632 | 752 |
return -1; |
633 | 753 |
} |
754 |
#ifndef CONFIG_USER_ONLY |
|
634 | 755 |
fcntl(fd, F_SETFL, O_NONBLOCK); |
756 |
#endif |
|
635 | 757 |
return fd; |
636 | 758 |
} |
637 | 759 |
|
... | ... | |
641 | 763 |
if (gdbserver_fd < 0) |
642 | 764 |
return -1; |
643 | 765 |
/* accept connections */ |
766 |
#ifdef CONFIG_USER_ONLY |
|
767 |
gdb_accept (NULL, NULL, 0); |
|
768 |
#else |
|
644 | 769 |
qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL); |
770 |
#endif |
|
645 | 771 |
return 0; |
646 | 772 |
} |
b/gdbstub.h | ||
---|---|---|
1 |
#ifndef GDBSTUB_H |
|
2 |
#define GDBSTUB_H |
|
3 |
|
|
4 |
#define DEFAULT_GDBSTUB_PORT 1234 |
|
5 |
|
|
6 |
#ifdef CONFIG_USER_ONLY |
|
7 |
int gdb_handlesig (CPUState *, int); |
|
8 |
#endif |
|
9 |
int gdbserver_start(int); |
|
10 |
|
|
11 |
#endif |
b/linux-user/main.c | ||
---|---|---|
278 | 278 |
case EXCP_INTERRUPT: |
279 | 279 |
/* just indicate that signals should be handled asap */ |
280 | 280 |
break; |
281 |
case EXCP_DEBUG: |
|
282 |
{ |
|
283 |
int sig; |
|
284 |
|
|
285 |
sig = gdb_handlesig (env, TARGET_SIGTRAP); |
|
286 |
if (sig) |
|
287 |
{ |
|
288 |
info.si_signo = sig; |
|
289 |
info.si_errno = 0; |
|
290 |
info.si_code = TARGET_TRAP_BRKPT; |
|
291 |
queue_signal(info.si_signo, &info); |
|
292 |
} |
|
293 |
} |
|
294 |
break; |
|
281 | 295 |
default: |
282 | 296 |
pc = env->segs[R_CS].base + env->eip; |
283 | 297 |
fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", |
... | ... | |
379 | 393 |
queue_signal(info.si_signo, &info); |
380 | 394 |
} |
381 | 395 |
break; |
396 |
case EXCP_DEBUG: |
|
397 |
{ |
|
398 |
int sig; |
|
399 |
|
|
400 |
sig = gdb_handlesig (env, TARGET_SIGTRAP); |
|
401 |
if (sig) |
|
402 |
{ |
|
403 |
info.si_signo = sig; |
|
404 |
info.si_errno = 0; |
|
405 |
info.si_code = TARGET_TRAP_BRKPT; |
|
406 |
queue_signal(info.si_signo, &info); |
|
407 |
} |
|
408 |
} |
|
409 |
break; |
|
382 | 410 |
default: |
383 | 411 |
error: |
384 | 412 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
... | ... | |
529 | 557 |
break; |
530 | 558 |
case 0x100: // XXX, why do we get these? |
531 | 559 |
break; |
560 |
case EXCP_DEBUG: |
|
561 |
{ |
|
562 |
int sig; |
|
563 |
|
|
564 |
sig = gdb_handlesig (env, TARGET_SIGTRAP); |
|
565 |
if (sig) |
|
566 |
{ |
|
567 |
info.si_signo = sig; |
|
568 |
info.si_errno = 0; |
|
569 |
info.si_code = TARGET_TRAP_BRKPT; |
|
570 |
queue_signal(info.si_signo, &info); |
|
571 |
} |
|
572 |
} |
|
573 |
break; |
|
532 | 574 |
default: |
533 | 575 |
printf ("Unhandled trap: 0x%x\n", trapnr); |
534 | 576 |
cpu_dump_state(env, stderr, fprintf, 0); |
... | ... | |
911 | 953 |
case EXCP_INTERRUPT: |
912 | 954 |
/* Don't know why this should ever happen... */ |
913 | 955 |
break; |
914 |
case EXCP_DEBUG: |
|
915 |
break; |
|
956 |
case EXCP_DEBUG: |
|
957 |
{ |
|
958 |
int sig; |
|
959 |
|
|
960 |
sig = gdb_handlesig (env, TARGET_SIGTRAP); |
|
961 |
if (sig) |
|
962 |
{ |
|
963 |
info.si_signo = sig; |
|
964 |
info.si_errno = 0; |
|
965 |
info.si_code = TARGET_TRAP_BRKPT; |
|
966 |
queue_signal(info.si_signo, &info); |
|
967 |
} |
|
968 |
} |
|
969 |
break; |
|
916 | 970 |
default: |
917 | 971 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
918 | 972 |
trapnr); |
... | ... | |
930 | 984 |
void usage(void) |
931 | 985 |
{ |
932 | 986 |
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n" |
933 |
"usage: qemu-" TARGET_ARCH " [-h] [-d opts] [-L path] [-s size] program [arguments...]\n" |
|
987 |
"usage: qemu-" TARGET_ARCH " [-h] [-g] [-d opts] [-L path] [-s size] program [arguments...]\n"
|
|
934 | 988 |
"Linux CPU emulator (compiled for %s emulation)\n" |
935 | 989 |
"\n" |
936 | 990 |
"-h print this help\n" |
991 |
"-g wait gdb connection to port %d\n" |
|
937 | 992 |
"-L path set the elf interpreter prefix (default=%s)\n" |
938 | 993 |
"-s size set the stack size in bytes (default=%ld)\n" |
939 | 994 |
"\n" |
... | ... | |
944 | 999 |
"-d options activate log (logfile=%s)\n" |
945 | 1000 |
"-p pagesize set the host page size to 'pagesize'\n", |
946 | 1001 |
TARGET_ARCH, |
1002 |
DEFAULT_GDBSTUB_PORT, |
|
947 | 1003 |
interp_prefix, |
948 | 1004 |
x86_stack_size, |
949 | 1005 |
DEBUG_LOGFILE); |
... | ... | |
967 | 1023 |
CPUState *env; |
968 | 1024 |
int optind; |
969 | 1025 |
const char *r; |
1026 |
int use_gdbstub = 0; |
|
970 | 1027 |
|
971 | 1028 |
if (argc <= 1) |
972 | 1029 |
usage(); |
... | ... | |
1020 | 1077 |
fprintf(stderr, "page size must be a power of two\n"); |
1021 | 1078 |
exit(1); |
1022 | 1079 |
} |
1080 |
} else if (!strcmp(r, "g")) { |
|
1081 |
use_gdbstub = 1; |
|
1023 | 1082 |
} else |
1024 | 1083 |
#ifdef USE_CODE_COPY |
1025 | 1084 |
if (!strcmp(r, "no-code-copy")) { |
... | ... | |
1176 | 1235 |
#error unsupported target CPU |
1177 | 1236 |
#endif |
1178 | 1237 |
|
1238 |
if (use_gdbstub) { |
|
1239 |
gdbserver_start (DEFAULT_GDBSTUB_PORT); |
|
1240 |
gdb_handlesig(env, 0); |
|
1241 |
} |
|
1179 | 1242 |
cpu_loop(env); |
1180 | 1243 |
/* never exits */ |
1181 | 1244 |
return 0; |
b/linux-user/qemu.h | ||
---|---|---|
9 | 9 |
|
10 | 10 |
#include "cpu.h" |
11 | 11 |
#include "syscall.h" |
12 |
#include "gdbstub.h" |
|
12 | 13 |
|
13 | 14 |
/* This struct is used to hold certain information about the image. |
14 | 15 |
* Basically, it replicates in user space what would be certain |
b/linux-user/signal.c | ||
---|---|---|
1675 | 1675 |
k->first = q->next; |
1676 | 1676 |
if (!k->first) |
1677 | 1677 |
k->pending = 0; |
1678 |
|
|
1679 |
sig = gdb_handlesig (cpu_env, sig); |
|
1680 |
if (!sig) { |
|
1681 |
fprintf (stderr, "Lost signal\n"); |
|
1682 |
abort(); |
|
1683 |
} |
|
1678 | 1684 |
|
1679 | 1685 |
handler = k->sa._sa_handler; |
1680 | 1686 |
if (handler == TARGET_SIG_DFL) { |
b/target-arm/cpu.h | ||
---|---|---|
26 | 26 |
|
27 | 27 |
#include "softfloat.h" |
28 | 28 |
|
29 |
#define TARGET_HAS_ICE 1 |
|
30 |
|
|
29 | 31 |
#define EXCP_UDEF 1 /* undefined instruction */ |
30 | 32 |
#define EXCP_SWI 2 /* software interrupt */ |
31 | 33 |
#define EXCP_PREFETCH_ABORT 3 |
... | ... | |
62 | 64 |
int user_mode_only; |
63 | 65 |
uint32_t address; |
64 | 66 |
|
67 |
/* ICE debug support. */ |
|
68 |
target_ulong breakpoints[MAX_BREAKPOINTS]; |
|
69 |
int nb_breakpoints; |
|
70 |
int singlestep_enabled; |
|
71 |
|
|
65 | 72 |
/* in order to avoid passing too many arguments to the memory |
66 | 73 |
write helpers, we store some rarely used information in the CPU |
67 | 74 |
context) */ |
b/target-arm/op.c | ||
---|---|---|
858 | 858 |
cpu_loop_exit(); |
859 | 859 |
} |
860 | 860 |
|
861 |
void OPPROTO op_debug(void) |
|
862 |
{ |
|
863 |
env->exception_index = EXCP_DEBUG; |
|
864 |
cpu_loop_exit(); |
|
865 |
} |
|
866 |
|
|
861 | 867 |
/* VFP support. We follow the convention used for VFP instrunctions: |
862 | 868 |
Single precition routines have a "s" suffix, double precision a |
863 | 869 |
"d" suffix. */ |
b/target-arm/translate.c | ||
---|---|---|
2026 | 2026 |
dc->pc = pc_start; |
2027 | 2027 |
lj = -1; |
2028 | 2028 |
do { |
2029 |
if (env->nb_breakpoints > 0) { |
|
2030 |
for(j = 0; j < env->nb_breakpoints; j++) { |
|
2031 |
if (env->breakpoints[j] == dc->pc) { |
|
2032 |
gen_op_movl_T0_im((long)dc->pc); |
|
2033 |
gen_op_movl_reg_TN[0][15](); |
|
2034 |
gen_op_debug(); |
|
2035 |
dc->is_jmp = DISAS_JUMP; |
|
2036 |
break; |
|
2037 |
} |
|
2038 |
} |
|
2039 |
} |
|
2029 | 2040 |
if (search_pc) { |
2030 | 2041 |
j = gen_opc_ptr - gen_opc_buf; |
2031 | 2042 |
if (lj < j) { |
... | ... | |
2040 | 2051 |
disas_thumb_insn(dc); |
2041 | 2052 |
else |
2042 | 2053 |
disas_arm_insn(env, dc); |
2043 |
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && |
|
2054 |
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && |
|
2055 |
!env->singlestep_enabled && |
|
2044 | 2056 |
(dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); |
2045 | 2057 |
switch(dc->is_jmp) { |
2046 | 2058 |
case DISAS_JUMP_NEXT: |
b/target-i386/cpu.h | ||
---|---|---|
34 | 34 |
close to the modifying instruction */ |
35 | 35 |
#define TARGET_HAS_PRECISE_SMC |
36 | 36 |
|
37 |
#define TARGET_HAS_ICE 1 |
|
38 |
|
|
37 | 39 |
#include "cpu-defs.h" |
38 | 40 |
|
39 | 41 |
#include "softfloat.h" |
b/target-ppc/cpu.h | ||
---|---|---|
29 | 29 |
|
30 | 30 |
#include "softfloat.h" |
31 | 31 |
|
32 |
#define TARGET_HAS_ICE 1 |
|
33 |
|
|
32 | 34 |
/* Instruction types */ |
33 | 35 |
enum { |
34 | 36 |
PPC_NONE = 0x0000, |
b/target-sparc/cpu.h | ||
---|---|---|
17 | 17 |
|
18 | 18 |
#include "softfloat.h" |
19 | 19 |
|
20 |
#define TARGET_HAS_ICE 1 |
|
21 |
|
|
20 | 22 |
/*#define EXCP_INTERRUPT 0x100*/ |
21 | 23 |
|
22 | 24 |
/* trap definitions */ |
b/vl.h | ||
---|---|---|
71 | 71 |
#else |
72 | 72 |
|
73 | 73 |
#include "cpu.h" |
74 |
#include "gdbstub.h" |
|
74 | 75 |
|
75 | 76 |
#endif /* !defined(QEMU_TOOL) */ |
76 | 77 |
|
... | ... | |
829 | 830 |
void readline_start(const char *prompt, int is_password, |
830 | 831 |
ReadLineFunc *readline_func, void *opaque); |
831 | 832 |
|
832 |
/* gdbstub.c */ |
|
833 |
|
|
834 |
#define DEFAULT_GDBSTUB_PORT 1234 |
|
835 |
|
|
836 |
int gdbserver_start(int port); |
|
837 |
|
|
838 | 833 |
#endif /* VL_H */ |
Also available in: Unified diff