From: Paul Brook <paul@codesourcery.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [patch] Usermode support for GDB Stub
Date: Mon, 21 Mar 2005 02:20:37 +0000 [thread overview]
Message-ID: <200503210220.37853.paul@codesourcery.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 785 bytes --]
The attached patch adds gdb stub support to the qemu linux user mode emulator.
I added a bit of code to automatically generate an EXCP_DEBUG exception if we
get to the end of a translation block in single step mode, and no exception
has been raised. The arm target conditional execution capabilities mean
inserting explicit debug exception everywhere would be a pain.
Signal handling is still a somewhat incomplete (continuing/stepping after a
signal basically doesn't work), and it doesn't support multithreaded
applications. All the important stuff seems to work though (breakpoints,
stepping, reading/writing regs/memory).
I tested i386-user and arm-user emulation, and they both seem to work.
The other targets I can't conveniently test, but they at least build ok.
Paul
[-- Attachment #2: patch.qemu_user_gdb --]
[-- Type: text/x-diff, Size: 22296 bytes --]
Index: Makefile.target
===================================================================
RCS file: /cvsroot/qemu/qemu/Makefile.target,v
retrieving revision 1.62
diff -u -p -r1.62 Makefile.target
--- Makefile.target 13 Mar 2005 16:52:10 -0000 1.62
+++ Makefile.target 21 Mar 2005 02:02:57 -0000
@@ -296,6 +296,9 @@ endif
ifeq ($(ARCH),ia64)
OBJS += ia64-syscall.o
endif
+ifdef CONFIG_GDBSTUB
+OBJS+=gdbstub.o
+endif
all: $(PROGS)
Index: cpu-exec.c
===================================================================
RCS file: /cvsroot/qemu/qemu/cpu-exec.c,v
retrieving revision 1.51
diff -u -p -r1.51 cpu-exec.c
--- cpu-exec.c 22 Feb 2005 19:27:14 -0000 1.51
+++ cpu-exec.c 21 Mar 2005 02:02:57 -0000
@@ -568,6 +568,10 @@ int cpu_exec(CPUState *env1)
gen_func();
#endif
env->current_tb = NULL;
+ if (env->singlestep_enabled && env->exception_index == -1) {
+ env->exception_index = EXCP_DEBUG;
+ cpu_loop_exit ();
+ }
/* reset soft MMU for next block (it can currently
only be set by a memory fault) */
#if defined(TARGET_I386) && !defined(CONFIG_SOFTMMU)
Index: exec.c
===================================================================
RCS file: /cvsroot/qemu/qemu/exec.c,v
retrieving revision 1.57
diff -u -p -r1.57 exec.c
--- exec.c 10 Feb 2005 21:56:58 -0000 1.57
+++ exec.c 21 Mar 2005 02:02:58 -0000
@@ -1076,7 +1076,7 @@ static void tb_reset_jump_recursive(Tran
tb_reset_jump_recursive2(tb, 1);
}
-#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
+#if defined(TARGET_HAS_ICE)
static void breakpoint_invalidate(CPUState *env, target_ulong pc)
{
target_ulong phys_addr;
@@ -1090,7 +1090,7 @@ static void breakpoint_invalidate(CPUSta
breakpoint is reached */
int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
{
-#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
+#if defined(TARGET_HAS_ICE)
int i;
for(i = 0; i < env->nb_breakpoints; i++) {
@@ -1112,7 +1112,7 @@ int cpu_breakpoint_insert(CPUState *env,
/* remove a breakpoint */
int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
{
-#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
+#if defined(TARGET_HAS_ICE)
int i;
for(i = 0; i < env->nb_breakpoints; i++) {
if (env->breakpoints[i] == pc)
@@ -1120,9 +1120,9 @@ int cpu_breakpoint_remove(CPUState *env,
}
return -1;
found:
- memmove(&env->breakpoints[i], &env->breakpoints[i + 1],
- (env->nb_breakpoints - (i + 1)) * sizeof(env->breakpoints[0]));
env->nb_breakpoints--;
+ if (i < env->nb_breakpoints)
+ env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
breakpoint_invalidate(env, pc);
return 0;
@@ -1135,7 +1135,7 @@ int cpu_breakpoint_remove(CPUState *env,
CPU loop after each instruction */
void cpu_single_step(CPUState *env, int enabled)
{
-#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
+#if defined(TARGET_HAS_ICE)
if (env->singlestep_enabled != enabled) {
env->singlestep_enabled = enabled;
/* must flush all the translated code to avoid inconsistancies */
Index: gdbstub.c
===================================================================
RCS file: /cvsroot/qemu/qemu/gdbstub.c,v
retrieving revision 1.23
diff -u -p -r1.23 gdbstub.c
--- gdbstub.c 17 Jan 2005 22:03:16 -0000 1.23
+++ gdbstub.c 21 Mar 2005 02:02:58 -0000
@@ -17,7 +17,18 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef CONFIG_USER_ONLY
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "qemu.h"
+#else
#include "vl.h"
+#endif
#include <sys/socket.h>
#include <netinet/in.h>
@@ -31,9 +42,10 @@ enum RSState {
RS_GETLINE,
RS_CHKSUM1,
RS_CHKSUM2,
+ RS_CONTINUE
};
-
-static int gdbserver_fd;
+/* XXX: This is not thread safe. Do we care? */
+static int gdbserver_fd = -1;
typedef struct GDBState {
enum RSState state;
@@ -43,6 +55,11 @@ typedef struct GDBState {
int line_csum;
} GDBState;
+#ifdef CONFIG_USER_ONLY
+/* XXX: remove this hack. */
+static GDBState gdbserver_state;
+#endif
+
static int get_char(GDBState *s)
{
uint8_t ch;
@@ -330,8 +347,47 @@ static void cpu_gdb_write_registers(CPUS
env->npc = tswapl(registers[69]);
env->fsr = tswapl(registers[70]);
}
-#else
+#elif defined (TARGET_ARM)
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ int i;
+ uint8_t *ptr;
+
+ ptr = mem_buf;
+ /* 16 core integer registers (4 bytes each). */
+ for (i = 0; i < 16; i++)
+ {
+ *(uint32_t *)ptr = tswapl(env->regs[i]);
+ ptr += 4;
+ }
+ /* 8 FPA registers (12 bytes each), FPS (4 bytes).
+ Not yet implemented. */
+ memset (ptr, 0, 8 * 12 + 4);
+ ptr += 8 * 12 + 4;
+ /* CPSR (4 bytes). */
+ *(uint32_t *)ptr = tswapl (env->cpsr);
+ ptr += 4;
+ return ptr - mem_buf;
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+ int i;
+ uint8_t *ptr;
+
+ ptr = mem_buf;
+ /* Core integer registers. */
+ for (i = 0; i < 16; i++)
+ {
+ env->regs[i] = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ }
+ /* Ignore FPA regs and scr. */
+ ptr += 8 * 12 + 4;
+ env->cpsr = tswapl(*(uint32_t *)ptr);
+}
+#else
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
{
return 0;
@@ -343,10 +399,8 @@ static void cpu_gdb_write_registers(CPUS
#endif
-/* port = 0 means default port */
-static int gdb_handle_packet(GDBState *s, const char *line_buf)
+static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
{
- CPUState *env = cpu_single_env;
const char *p;
int ch, reg_size, type;
char buf[4096];
@@ -361,6 +415,7 @@ static int gdb_handle_packet(GDBState *s
ch = *p++;
switch(ch) {
case '?':
+ /* TODO: Make this return the correct value for user-mode. */
snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
put_packet(s, buf);
break;
@@ -376,8 +431,7 @@ static int gdb_handle_packet(GDBState *s
env->npc = addr + 4;
#endif
}
- vm_start();
- break;
+ return RS_CONTINUE;
case 's':
if (*p != '\0') {
addr = strtoul(p, (char **)&p, 16);
@@ -391,8 +445,7 @@ static int gdb_handle_packet(GDBState *s
#endif
}
cpu_single_step(env, 1);
- vm_start();
- break;
+ return RS_CONTINUE;
case 'g':
reg_size = cpu_gdb_read_registers(env, mem_buf);
memtohex(buf, mem_buf, reg_size);
@@ -472,6 +525,7 @@ static int gdb_handle_packet(GDBState *s
extern void tb_flush(CPUState *env);
+#ifndef CONFIG_USER_ONLY
static void gdb_vm_stopped(void *opaque, int reason)
{
GDBState *s = opaque;
@@ -490,17 +544,20 @@ static void gdb_vm_stopped(void *opaque,
snprintf(buf, sizeof(buf), "S%02x", ret);
put_packet(s, buf);
}
+#endif
-static void gdb_read_byte(GDBState *s, int ch)
+static void gdb_read_byte(GDBState *s, CPUState *env, int ch)
{
int i, csum;
char reply[1];
+#ifndef CONFIG_USER_ONLY
if (vm_running) {
/* when the CPU is running, we cannot do anything except stop
it when receiving a char */
vm_stop(EXCP_INTERRUPT);
} else {
+#endif
switch(s->state) {
case RS_IDLE:
if (ch == '$') {
@@ -535,13 +592,67 @@ static void gdb_read_byte(GDBState *s, i
} else {
reply[0] = '+';
put_buffer(s, reply, 1);
- s->state = gdb_handle_packet(s, s->line_buf);
+ s->state = gdb_handle_packet(s, env, s->line_buf);
}
break;
+ case RS_CONTINUE:
+#ifndef CONFIG_USER_ONLY
+ vm_start();
+ s->state = RS_IDLE;
+#endif
+ break;
}
+#ifndef CONFIG_USER_ONLY
}
+#endif
}
+#ifdef CONFIG_USER_ONLY
+int
+gdb_handlesig (CPUState *env, int sig)
+{
+ GDBState *s;
+ char buf[256];
+ int n;
+
+ if (gdbserver_fd < 0)
+ return sig;
+
+ s = &gdbserver_state;
+
+ /* disable single step if it was enabled */
+ cpu_single_step(env, 0);
+ tb_flush(env);
+
+ if (sig != 0)
+ {
+ snprintf(buf, sizeof(buf), "S%02x", sig);
+ put_packet(s, buf);
+ }
+
+ /* TODO: How do we terminate this loop? */
+ sig = 0;
+ s->state = RS_IDLE;
+ while (s->state != RS_CONTINUE)
+ {
+ n = read (s->fd, buf, 256);
+ if (n > 0)
+ {
+ int i;
+
+ for (i = 0; i < n; i++)
+ gdb_read_byte (s, env, buf[i]);
+ }
+ else if (n == 0 || errno != EAGAIN)
+ {
+ /* XXX: Connection closed. Should probably wait for annother
+ connection before continuing. */
+ return sig;
+ }
+ }
+ return sig;
+}
+#else
static int gdb_can_read(void *opaque)
{
return 256;
@@ -559,10 +670,12 @@ static void gdb_read(void *opaque, const
vm_start();
} else {
for(i = 0; i < size; i++)
- gdb_read_byte(s, buf[i]);
+ gdb_read_byte(s, cpu_single_env, buf[i]);
}
}
+#endif
+
static void gdb_accept(void *opaque, const uint8_t *buf, int size)
{
GDBState *s;
@@ -585,15 +698,21 @@ static void gdb_accept(void *opaque, con
val = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+#ifdef CONFIG_USER_ONLY
+ s = &gdbserver_state;
+ memset (s, 0, sizeof (GDBState));
+#else
s = qemu_mallocz(sizeof(GDBState));
if (!s) {
close(fd);
return;
}
+#endif
s->fd = fd;
fcntl(fd, F_SETFL, O_NONBLOCK);
+#ifndef CONFIG_USER_ONLY
/* stop the VM */
vm_stop(EXCP_INTERRUPT);
@@ -601,6 +720,7 @@ static void gdb_accept(void *opaque, con
qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s);
/* when the VM is stopped, the following callback is called */
qemu_add_vm_stop_handler(gdb_vm_stopped, s);
+#endif
}
static int gdbserver_open(int port)
@@ -631,7 +751,9 @@ static int gdbserver_open(int port)
perror("listen");
return -1;
}
+#ifndef CONFIG_USER_ONLY
fcntl(fd, F_SETFL, O_NONBLOCK);
+#endif
return fd;
}
@@ -641,6 +763,10 @@ int gdbserver_start(int port)
if (gdbserver_fd < 0)
return -1;
/* accept connections */
+#ifdef CONFIG_USER_ONLY
+ gdb_accept (NULL, NULL, 0);
+#else
qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL);
+#endif
return 0;
}
Index: gdbstub.h
===================================================================
RCS file: gdbstub.h
diff -N gdbstub.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdbstub.h 21 Mar 2005 02:02:58 -0000
@@ -0,0 +1,11 @@
+#ifndef GDBSTUB_H
+#define GDBSTUB_H
+
+#define DEFAULT_GDBSTUB_PORT 1234
+
+#ifdef CONFIG_USER_ONLY
+int gdb_handlesig (CPUState *, int);
+#endif
+int gdbserver_start(int);
+
+#endif
Index: vl.h
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.h,v
retrieving revision 1.69
diff -u -p -r1.69 vl.h
--- vl.h 13 Mar 2005 09:43:36 -0000 1.69
+++ vl.h 21 Mar 2005 02:03:00 -0000
@@ -71,6 +71,7 @@ static inline char *realpath(const char
#else
#include "cpu.h"
+#include "gdbstub.h"
#endif /* !defined(QEMU_TOOL) */
@@ -829,10 +830,4 @@ const char *readline_get_history(unsigne
void readline_start(const char *prompt, int is_password,
ReadLineFunc *readline_func, void *opaque);
-/* gdbstub.c */
-
-#define DEFAULT_GDBSTUB_PORT 1234
-
-int gdbserver_start(int port);
-
#endif /* VL_H */
Index: linux-user/main.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v
retrieving revision 1.62
diff -u -p -r1.62 main.c
--- linux-user/main.c 13 Mar 2005 16:56:51 -0000 1.62
+++ linux-user/main.c 21 Mar 2005 02:03:00 -0000
@@ -278,6 +278,20 @@ void cpu_loop(CPUX86State *env)
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
break;
+ case EXCP_DEBUG:
+ {
+ int sig;
+
+ sig = gdb_handlesig (env, TARGET_SIGTRAP);
+ if (sig)
+ {
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = TARGET_TRAP_BRKPT;
+ queue_signal(info.si_signo, &info);
+ }
+ }
+ break;
default:
pc = env->segs[R_CS].base + env->eip;
fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
@@ -379,6 +393,20 @@ void cpu_loop(CPUARMState *env)
queue_signal(info.si_signo, &info);
}
break;
+ case EXCP_DEBUG:
+ {
+ int sig;
+
+ sig = gdb_handlesig (env, TARGET_SIGTRAP);
+ if (sig)
+ {
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = TARGET_TRAP_BRKPT;
+ queue_signal(info.si_signo, &info);
+ }
+ }
+ break;
default:
error:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
@@ -529,6 +557,20 @@ void cpu_loop (CPUSPARCState *env)
break;
case 0x100: // XXX, why do we get these?
break;
+ case EXCP_DEBUG:
+ {
+ int sig;
+
+ sig = gdb_handlesig (env, TARGET_SIGTRAP);
+ if (sig)
+ {
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = TARGET_TRAP_BRKPT;
+ queue_signal(info.si_signo, &info);
+ }
+ }
+ break;
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
@@ -911,8 +953,20 @@ void cpu_loop(CPUPPCState *env)
case EXCP_INTERRUPT:
/* Don't know why this should ever happen... */
break;
- case EXCP_DEBUG:
- break;
+ case EXCP_DEBUG:
+ {
+ int sig;
+
+ sig = gdb_handlesig (env, TARGET_SIGTRAP);
+ if (sig)
+ {
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = TARGET_TRAP_BRKPT;
+ queue_signal(info.si_signo, &info);
+ }
+ }
+ break;
default:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
@@ -930,10 +984,11 @@ void cpu_loop(CPUPPCState *env)
void usage(void)
{
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
- "usage: qemu-" TARGET_ARCH " [-h] [-d opts] [-L path] [-s size] program [arguments...]\n"
+ "usage: qemu-" TARGET_ARCH " [-h] [-g] [-d opts] [-L path] [-s size] program [arguments...]\n"
"Linux CPU emulator (compiled for %s emulation)\n"
"\n"
"-h print this help\n"
+ "-g wait gdb connection to port %d\n"
"-L path set the elf interpreter prefix (default=%s)\n"
"-s size set the stack size in bytes (default=%ld)\n"
"\n"
@@ -944,6 +999,7 @@ void usage(void)
"-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n",
TARGET_ARCH,
+ DEFAULT_GDBSTUB_PORT,
interp_prefix,
x86_stack_size,
DEBUG_LOGFILE);
@@ -967,6 +1023,7 @@ int main(int argc, char **argv)
CPUState *env;
int optind;
const char *r;
+ int use_gdbstub = 0;
if (argc <= 1)
usage();
@@ -1020,6 +1077,8 @@ int main(int argc, char **argv)
fprintf(stderr, "page size must be a power of two\n");
exit(1);
}
+ } else if (!strcmp(r, "g")) {
+ use_gdbstub = 1;
} else
#ifdef USE_CODE_COPY
if (!strcmp(r, "no-code-copy")) {
@@ -1176,6 +1235,10 @@ int main(int argc, char **argv)
#error unsupported target CPU
#endif
+ if (use_gdbstub) {
+ gdbserver_start (DEFAULT_GDBSTUB_PORT);
+ gdb_handlesig(env, 0);
+ }
cpu_loop(env);
/* never exits */
return 0;
Index: linux-user/qemu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/qemu.h,v
retrieving revision 1.22
diff -u -p -r1.22 qemu.h
--- linux-user/qemu.h 7 Feb 2005 12:35:39 -0000 1.22
+++ linux-user/qemu.h 21 Mar 2005 02:03:00 -0000
@@ -9,6 +9,7 @@
#include "cpu.h"
#include "syscall.h"
+#include "gdbstub.h"
/* This struct is used to hold certain information about the image.
* Basically, it replicates in user space what would be certain
Index: linux-user/signal.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/signal.c,v
retrieving revision 1.27
diff -u -p -r1.27 signal.c
--- linux-user/signal.c 30 Jan 2005 22:59:18 -0000 1.27
+++ linux-user/signal.c 21 Mar 2005 02:03:01 -0000
@@ -1680,6 +1680,12 @@ void process_pending_signals(void *cpu_e
k->first = q->next;
if (!k->first)
k->pending = 0;
+
+ sig = gdb_handlesig (cpu_env, sig);
+ if (!sig) {
+ fprintf (stderr, "Lost signal\n");
+ abort();
+ }
handler = k->sa._sa_handler;
if (handler == TARGET_SIG_DFL) {
Index: target-arm/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.8
diff -u -p -r1.8 cpu.h
--- target-arm/cpu.h 13 Mar 2005 18:50:12 -0000 1.8
+++ target-arm/cpu.h 21 Mar 2005 02:03:01 -0000
@@ -26,6 +26,8 @@
#include "softfloat.h"
+#define TARGET_HAS_ICE 1
+
#define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */
#define EXCP_PREFETCH_ABORT 3
@@ -62,6 +64,11 @@ typedef struct CPUARMState {
int user_mode_only;
uint32_t address;
+ /* ICE debug support. */
+ target_ulong breakpoints[MAX_BREAKPOINTS];
+ int nb_breakpoints;
+ int singlestep_enabled;
+
/* in order to avoid passing too many arguments to the memory
write helpers, we store some rarely used information in the CPU
context) */
Index: target-arm/op.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/op.c,v
retrieving revision 1.10
diff -u -p -r1.10 op.c
--- target-arm/op.c 13 Mar 2005 18:50:12 -0000 1.10
+++ target-arm/op.c 21 Mar 2005 02:03:01 -0000
@@ -858,6 +858,12 @@ void OPPROTO op_undef_insn(void)
cpu_loop_exit();
}
+void OPPROTO op_debug(void)
+{
+ env->exception_index = EXCP_DEBUG;
+ cpu_loop_exit();
+}
+
/* VFP support. We follow the convention used for VFP instrunctions:
Single precition routines have a "s" suffix, double precision a
"d" suffix. */
Index: target-arm/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/translate.c,v
retrieving revision 1.18
diff -u -p -r1.18 translate.c
--- target-arm/translate.c 22 Feb 2005 19:27:29 -0000 1.18
+++ target-arm/translate.c 21 Mar 2005 02:03:01 -0000
@@ -2013,6 +2013,17 @@ static inline int gen_intermediate_code_
dc->pc = pc_start;
lj = -1;
do {
+ if (env->nb_breakpoints > 0) {
+ for(j = 0; j < env->nb_breakpoints; j++) {
+ if (env->breakpoints[j] == dc->pc) {
+ gen_op_movl_T0_im((long)dc->pc);
+ gen_op_movl_reg_TN[0][15]();
+ gen_op_debug();
+ dc->is_jmp = DISAS_JUMP;
+ break;
+ }
+ }
+ }
if (search_pc) {
j = gen_opc_ptr - gen_opc_buf;
if (lj < j) {
@@ -2027,7 +2038,8 @@ static inline int gen_intermediate_code_
disas_thumb_insn(dc);
else
disas_arm_insn(env, dc);
- } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+ } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+ !env->singlestep_enabled &&
(dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
switch(dc->is_jmp) {
case DISAS_JUMP_NEXT:
Index: target-i386/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.28
diff -u -p -r1.28 cpu.h
--- target-i386/cpu.h 13 Mar 2005 16:59:52 -0000 1.28
+++ target-i386/cpu.h 21 Mar 2005 02:03:02 -0000
@@ -34,6 +34,8 @@
close to the modifying instruction */
#define TARGET_HAS_PRECISE_SMC
+#define TARGET_HAS_ICE 1
+
#include "cpu-defs.h"
#include "softfloat.h"
Index: target-ppc/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-ppc/cpu.h,v
retrieving revision 1.16
diff -u -p -r1.16 cpu.h
--- target-ppc/cpu.h 13 Mar 2005 17:01:22 -0000 1.16
+++ target-ppc/cpu.h 21 Mar 2005 02:03:02 -0000
@@ -29,6 +29,8 @@
#include "softfloat.h"
+#define TARGET_HAS_ICE 1
+
/* Instruction types */
enum {
PPC_NONE = 0x0000,
Index: target-sparc/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.16
diff -u -p -r1.16 cpu.h
--- target-sparc/cpu.h 13 Mar 2005 17:01:47 -0000 1.16
+++ target-sparc/cpu.h 21 Mar 2005 02:03:02 -0000
@@ -17,6 +17,8 @@
#include "softfloat.h"
+#define TARGET_HAS_ICE 1
+
/*#define EXCP_INTERRUPT 0x100*/
/* trap definitions */
reply other threads:[~2005-03-21 2:49 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200503210220.37853.paul@codesourcery.com \
--to=paul@codesourcery.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.