gdb support for user mode (Paul Brook)

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1367 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2005-04-17 19:16:13 +00:00
parent 6e4255f6a6
commit 1fddef4b1b
14 changed files with 265 additions and 29 deletions

View File

@ -298,6 +298,9 @@ endif
ifeq ($(ARCH),ia64) ifeq ($(ARCH),ia64)
OBJS += ia64-syscall.o OBJS += ia64-syscall.o
endif endif
ifdef CONFIG_GDBSTUB
OBJS+=gdbstub.o
endif
all: $(PROGS) all: $(PROGS)

12
exec.c
View File

@ -1076,7 +1076,7 @@ static void tb_reset_jump_recursive(TranslationBlock *tb)
tb_reset_jump_recursive2(tb, 1); 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) static void breakpoint_invalidate(CPUState *env, target_ulong pc)
{ {
target_ulong phys_addr; target_ulong phys_addr;
@ -1090,7 +1090,7 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc)
breakpoint is reached */ breakpoint is reached */
int cpu_breakpoint_insert(CPUState *env, target_ulong pc) 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; int i;
for(i = 0; i < env->nb_breakpoints; i++) { for(i = 0; i < env->nb_breakpoints; i++) {
@ -1112,7 +1112,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
/* remove a breakpoint */ /* remove a breakpoint */
int cpu_breakpoint_remove(CPUState *env, target_ulong pc) 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; int i;
for(i = 0; i < env->nb_breakpoints; i++) { for(i = 0; i < env->nb_breakpoints; i++) {
if (env->breakpoints[i] == pc) if (env->breakpoints[i] == pc)
@ -1120,9 +1120,9 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
} }
return -1; return -1;
found: found:
memmove(&env->breakpoints[i], &env->breakpoints[i + 1],
(env->nb_breakpoints - (i + 1)) * sizeof(env->breakpoints[0]));
env->nb_breakpoints--; env->nb_breakpoints--;
if (i < env->nb_breakpoints)
env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
breakpoint_invalidate(env, pc); breakpoint_invalidate(env, pc);
return 0; return 0;
@ -1135,7 +1135,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
CPU loop after each instruction */ CPU loop after each instruction */
void cpu_single_step(CPUState *env, int enabled) 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) { if (env->singlestep_enabled != enabled) {
env->singlestep_enabled = enabled; env->singlestep_enabled = enabled;
/* must flush all the translated code to avoid inconsistancies */ /* must flush all the translated code to avoid inconsistancies */

152
gdbstub.c
View File

@ -17,7 +17,18 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "vl.h"
#endif
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -31,9 +42,10 @@ enum RSState {
RS_GETLINE, RS_GETLINE,
RS_CHKSUM1, RS_CHKSUM1,
RS_CHKSUM2, RS_CHKSUM2,
RS_CONTINUE
}; };
/* XXX: This is not thread safe. Do we care? */
static int gdbserver_fd; static int gdbserver_fd = -1;
typedef struct GDBState { typedef struct GDBState {
enum RSState state; enum RSState state;
@ -43,6 +55,11 @@ typedef struct GDBState {
int line_csum; int line_csum;
} GDBState; } GDBState;
#ifdef CONFIG_USER_ONLY
/* XXX: remove this hack. */
static GDBState gdbserver_state;
#endif
static int get_char(GDBState *s) static int get_char(GDBState *s)
{ {
uint8_t ch; uint8_t ch;
@ -330,8 +347,47 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
env->npc = tswapl(registers[69]); env->npc = tswapl(registers[69]);
env->fsr = tswapl(registers[70]); 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) static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
{ {
return 0; return 0;
@ -343,10 +399,8 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
#endif #endif
/* port = 0 means default port */ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
static int gdb_handle_packet(GDBState *s, const char *line_buf)
{ {
CPUState *env = cpu_single_env;
const char *p; const char *p;
int ch, reg_size, type; int ch, reg_size, type;
char buf[4096]; char buf[4096];
@ -361,6 +415,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
ch = *p++; ch = *p++;
switch(ch) { switch(ch) {
case '?': case '?':
/* TODO: Make this return the correct value for user-mode. */
snprintf(buf, sizeof(buf), "S%02x", SIGTRAP); snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
put_packet(s, buf); put_packet(s, buf);
break; break;
@ -376,8 +431,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
env->npc = addr + 4; env->npc = addr + 4;
#endif #endif
} }
vm_start(); return RS_CONTINUE;
break;
case 's': case 's':
if (*p != '\0') { if (*p != '\0') {
addr = strtoul(p, (char **)&p, 16); addr = strtoul(p, (char **)&p, 16);
@ -391,8 +445,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
#endif #endif
} }
cpu_single_step(env, 1); cpu_single_step(env, 1);
vm_start(); return RS_CONTINUE;
break;
case 'g': case 'g':
reg_size = cpu_gdb_read_registers(env, mem_buf); reg_size = cpu_gdb_read_registers(env, mem_buf);
memtohex(buf, mem_buf, reg_size); memtohex(buf, mem_buf, reg_size);
@ -472,6 +525,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
extern void tb_flush(CPUState *env); extern void tb_flush(CPUState *env);
#ifndef CONFIG_USER_ONLY
static void gdb_vm_stopped(void *opaque, int reason) static void gdb_vm_stopped(void *opaque, int reason)
{ {
GDBState *s = opaque; GDBState *s = opaque;
@ -490,17 +544,20 @@ static void gdb_vm_stopped(void *opaque, int reason)
snprintf(buf, sizeof(buf), "S%02x", ret); snprintf(buf, sizeof(buf), "S%02x", ret);
put_packet(s, buf); 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; int i, csum;
char reply[1]; char reply[1];
#ifndef CONFIG_USER_ONLY
if (vm_running) { if (vm_running) {
/* when the CPU is running, we cannot do anything except stop /* when the CPU is running, we cannot do anything except stop
it when receiving a char */ it when receiving a char */
vm_stop(EXCP_INTERRUPT); vm_stop(EXCP_INTERRUPT);
} else { } else {
#endif
switch(s->state) { switch(s->state) {
case RS_IDLE: case RS_IDLE:
if (ch == '$') { if (ch == '$') {
@ -535,13 +592,67 @@ static void gdb_read_byte(GDBState *s, int ch)
} else { } else {
reply[0] = '+'; reply[0] = '+';
put_buffer(s, reply, 1); 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; 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) static int gdb_can_read(void *opaque)
{ {
return 256; return 256;
@ -559,10 +670,12 @@ static void gdb_read(void *opaque, const uint8_t *buf, int size)
vm_start(); vm_start();
} else { } else {
for(i = 0; i < size; i++) 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) static void gdb_accept(void *opaque, const uint8_t *buf, int size)
{ {
GDBState *s; GDBState *s;
@ -585,15 +698,21 @@ static void gdb_accept(void *opaque, const uint8_t *buf, int size)
val = 1; val = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); 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)); s = qemu_mallocz(sizeof(GDBState));
if (!s) { if (!s) {
close(fd); close(fd);
return; return;
} }
#endif
s->fd = fd; s->fd = fd;
fcntl(fd, F_SETFL, O_NONBLOCK); fcntl(fd, F_SETFL, O_NONBLOCK);
#ifndef CONFIG_USER_ONLY
/* stop the VM */ /* stop the VM */
vm_stop(EXCP_INTERRUPT); vm_stop(EXCP_INTERRUPT);
@ -601,6 +720,7 @@ static void gdb_accept(void *opaque, const uint8_t *buf, int size)
qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s); qemu_add_fd_read_handler(s->fd, gdb_can_read, gdb_read, s);
/* when the VM is stopped, the following callback is called */ /* when the VM is stopped, the following callback is called */
qemu_add_vm_stop_handler(gdb_vm_stopped, s); qemu_add_vm_stop_handler(gdb_vm_stopped, s);
#endif
} }
static int gdbserver_open(int port) static int gdbserver_open(int port)
@ -631,7 +751,9 @@ static int gdbserver_open(int port)
perror("listen"); perror("listen");
return -1; return -1;
} }
#ifndef CONFIG_USER_ONLY
fcntl(fd, F_SETFL, O_NONBLOCK); fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
return fd; return fd;
} }
@ -641,6 +763,10 @@ int gdbserver_start(int port)
if (gdbserver_fd < 0) if (gdbserver_fd < 0)
return -1; return -1;
/* accept connections */ /* accept connections */
#ifdef CONFIG_USER_ONLY
gdb_accept (NULL, NULL, 0);
#else
qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL); qemu_add_fd_read_handler(gdbserver_fd, NULL, gdb_accept, NULL);
#endif
return 0; return 0;
} }

11
gdbstub.h Normal file
View File

@ -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

View File

@ -278,6 +278,20 @@ void cpu_loop(CPUX86State *env)
case EXCP_INTERRUPT: case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */ /* just indicate that signals should be handled asap */
break; 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: default:
pc = env->segs[R_CS].base + env->eip; pc = env->segs[R_CS].base + env->eip;
fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", 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); queue_signal(info.si_signo, &info);
} }
break; 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: default:
error: error:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
@ -529,6 +557,20 @@ void cpu_loop (CPUSPARCState *env)
break; break;
case 0x100: // XXX, why do we get these? case 0x100: // XXX, why do we get these?
break; 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: default:
printf ("Unhandled trap: 0x%x\n", trapnr); printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0); cpu_dump_state(env, stderr, fprintf, 0);
@ -912,6 +954,18 @@ void cpu_loop(CPUPPCState *env)
/* Don't know why this should ever happen... */ /* Don't know why this should ever happen... */
break; break;
case EXCP_DEBUG: 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; break;
default: default:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
@ -930,10 +984,11 @@ void cpu_loop(CPUPPCState *env)
void usage(void) void usage(void)
{ {
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n" 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" "Linux CPU emulator (compiled for %s emulation)\n"
"\n" "\n"
"-h print this help\n" "-h print this help\n"
"-g wait gdb connection to port %d\n"
"-L path set the elf interpreter prefix (default=%s)\n" "-L path set the elf interpreter prefix (default=%s)\n"
"-s size set the stack size in bytes (default=%ld)\n" "-s size set the stack size in bytes (default=%ld)\n"
"\n" "\n"
@ -944,6 +999,7 @@ void usage(void)
"-d options activate log (logfile=%s)\n" "-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n", "-p pagesize set the host page size to 'pagesize'\n",
TARGET_ARCH, TARGET_ARCH,
DEFAULT_GDBSTUB_PORT,
interp_prefix, interp_prefix,
x86_stack_size, x86_stack_size,
DEBUG_LOGFILE); DEBUG_LOGFILE);
@ -967,6 +1023,7 @@ int main(int argc, char **argv)
CPUState *env; CPUState *env;
int optind; int optind;
const char *r; const char *r;
int use_gdbstub = 0;
if (argc <= 1) if (argc <= 1)
usage(); usage();
@ -1020,6 +1077,8 @@ int main(int argc, char **argv)
fprintf(stderr, "page size must be a power of two\n"); fprintf(stderr, "page size must be a power of two\n");
exit(1); exit(1);
} }
} else if (!strcmp(r, "g")) {
use_gdbstub = 1;
} else } else
#ifdef USE_CODE_COPY #ifdef USE_CODE_COPY
if (!strcmp(r, "no-code-copy")) { if (!strcmp(r, "no-code-copy")) {
@ -1176,6 +1235,10 @@ int main(int argc, char **argv)
#error unsupported target CPU #error unsupported target CPU
#endif #endif
if (use_gdbstub) {
gdbserver_start (DEFAULT_GDBSTUB_PORT);
gdb_handlesig(env, 0);
}
cpu_loop(env); cpu_loop(env);
/* never exits */ /* never exits */
return 0; return 0;

View File

@ -9,6 +9,7 @@
#include "cpu.h" #include "cpu.h"
#include "syscall.h" #include "syscall.h"
#include "gdbstub.h"
/* This struct is used to hold certain information about the image. /* This struct is used to hold certain information about the image.
* Basically, it replicates in user space what would be certain * Basically, it replicates in user space what would be certain

View File

@ -1676,6 +1676,12 @@ void process_pending_signals(void *cpu_env)
if (!k->first) if (!k->first)
k->pending = 0; k->pending = 0;
sig = gdb_handlesig (cpu_env, sig);
if (!sig) {
fprintf (stderr, "Lost signal\n");
abort();
}
handler = k->sa._sa_handler; handler = k->sa._sa_handler;
if (handler == TARGET_SIG_DFL) { if (handler == TARGET_SIG_DFL) {
/* default handler : ignore some signal. The other are fatal */ /* default handler : ignore some signal. The other are fatal */

View File

@ -26,6 +26,8 @@
#include "softfloat.h" #include "softfloat.h"
#define TARGET_HAS_ICE 1
#define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */ #define EXCP_SWI 2 /* software interrupt */
#define EXCP_PREFETCH_ABORT 3 #define EXCP_PREFETCH_ABORT 3
@ -62,6 +64,11 @@ typedef struct CPUARMState {
int user_mode_only; int user_mode_only;
uint32_t address; 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 /* in order to avoid passing too many arguments to the memory
write helpers, we store some rarely used information in the CPU write helpers, we store some rarely used information in the CPU
context) */ context) */

View File

@ -858,6 +858,12 @@ void OPPROTO op_undef_insn(void)
cpu_loop_exit(); 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: /* VFP support. We follow the convention used for VFP instrunctions:
Single precition routines have a "s" suffix, double precision a Single precition routines have a "s" suffix, double precision a
"d" suffix. */ "d" suffix. */

View File

@ -2026,6 +2026,17 @@ static inline int gen_intermediate_code_internal(CPUState *env,
dc->pc = pc_start; dc->pc = pc_start;
lj = -1; lj = -1;
do { 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) { if (search_pc) {
j = gen_opc_ptr - gen_opc_buf; j = gen_opc_ptr - gen_opc_buf;
if (lj < j) { if (lj < j) {
@ -2041,6 +2052,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
else else
disas_arm_insn(env, dc); 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)); (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
switch(dc->is_jmp) { switch(dc->is_jmp) {
case DISAS_JUMP_NEXT: case DISAS_JUMP_NEXT:

View File

@ -34,6 +34,8 @@
close to the modifying instruction */ close to the modifying instruction */
#define TARGET_HAS_PRECISE_SMC #define TARGET_HAS_PRECISE_SMC
#define TARGET_HAS_ICE 1
#include "cpu-defs.h" #include "cpu-defs.h"
#include "softfloat.h" #include "softfloat.h"

View File

@ -29,6 +29,8 @@
#include "softfloat.h" #include "softfloat.h"
#define TARGET_HAS_ICE 1
/* Instruction types */ /* Instruction types */
enum { enum {
PPC_NONE = 0x0000, PPC_NONE = 0x0000,

View File

@ -17,6 +17,8 @@
#include "softfloat.h" #include "softfloat.h"
#define TARGET_HAS_ICE 1
/*#define EXCP_INTERRUPT 0x100*/ /*#define EXCP_INTERRUPT 0x100*/
/* trap definitions */ /* trap definitions */

7
vl.h
View File

@ -71,6 +71,7 @@ static inline char *realpath(const char *path, char *resolved_path)
#else #else
#include "cpu.h" #include "cpu.h"
#include "gdbstub.h"
#endif /* !defined(QEMU_TOOL) */ #endif /* !defined(QEMU_TOOL) */
@ -829,10 +830,4 @@ const char *readline_get_history(unsigned int index);
void readline_start(const char *prompt, int is_password, void readline_start(const char *prompt, int is_password,
ReadLineFunc *readline_func, void *opaque); ReadLineFunc *readline_func, void *opaque);
/* gdbstub.c */
#define DEFAULT_GDBSTUB_PORT 1234
int gdbserver_start(int port);
#endif /* VL_H */ #endif /* VL_H */