gdbstub.c 44.9 KB
Newer Older
bellard's avatar
bellard committed
1 2
/*
 * gdb server stub
3
 *
bellard's avatar
bellard committed
4
 * Copyright (c) 2003-2005 Fabrice Bellard
bellard's avatar
bellard committed
5 6 7 8 9 10 11 12 13 14 15 16
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
bellard's avatar
bellard committed
18
 */
Peter Maydell's avatar
Peter Maydell committed
19
#include "qemu/osdep.h"
20
#include "qapi/error.h"
21
#include "qemu/cutils.h"
22
#include "cpu.h"
23
#ifdef CONFIG_USER_ONLY
24 25
#include "qemu.h"
#else
26
#include "monitor/monitor.h"
27
#include "sysemu/char.h"
28
#include "sysemu/sysemu.h"
29
#include "exec/gdbstub.h"
30
#endif
31

32 33
#define MAX_PACKET_LENGTH 4096

34
#include "cpu.h"
35
#include "qemu/sockets.h"
36
#include "sysemu/kvm.h"
37
#include "exec/semihost.h"
38
#include "exec/exec-all.h"
39

Jan Kiszka's avatar
Jan Kiszka committed
40 41 42 43 44 45
#ifdef CONFIG_USER_ONLY
#define GDB_ATTACHED "0"
#else
#define GDB_ATTACHED "1"
#endif

46 47
static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
                                         uint8_t *buf, int len, bool is_write)
48
{
49 50 51 52 53 54
    CPUClass *cc = CPU_GET_CLASS(cpu);

    if (cc->memory_rw_debug) {
        return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
    }
    return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
55
}
56 57 58 59

enum {
    GDB_SIGNAL_0 = 0,
    GDB_SIGNAL_INT = 2,
60
    GDB_SIGNAL_QUIT = 3,
61
    GDB_SIGNAL_TRAP = 5,
62 63 64 65
    GDB_SIGNAL_ABRT = 6,
    GDB_SIGNAL_ALRM = 14,
    GDB_SIGNAL_IO = 23,
    GDB_SIGNAL_XCPU = 24,
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
    GDB_SIGNAL_UNKNOWN = 143
};

#ifdef CONFIG_USER_ONLY

/* Map target signal numbers to GDB protocol signal numbers and vice
 * versa.  For user emulation's currently supported systems, we can
 * assume most signals are defined.
 */

static int gdb_signal_table[] = {
    0,
    TARGET_SIGHUP,
    TARGET_SIGINT,
    TARGET_SIGQUIT,
    TARGET_SIGILL,
    TARGET_SIGTRAP,
    TARGET_SIGABRT,
    -1, /* SIGEMT */
    TARGET_SIGFPE,
    TARGET_SIGKILL,
    TARGET_SIGBUS,
    TARGET_SIGSEGV,
    TARGET_SIGSYS,
    TARGET_SIGPIPE,
    TARGET_SIGALRM,
    TARGET_SIGTERM,
    TARGET_SIGURG,
    TARGET_SIGSTOP,
    TARGET_SIGTSTP,
    TARGET_SIGCONT,
    TARGET_SIGCHLD,
    TARGET_SIGTTIN,
    TARGET_SIGTTOU,
    TARGET_SIGIO,
    TARGET_SIGXCPU,
    TARGET_SIGXFSZ,
    TARGET_SIGVTALRM,
    TARGET_SIGPROF,
    TARGET_SIGWINCH,
    -1, /* SIGLOST */
    TARGET_SIGUSR1,
    TARGET_SIGUSR2,
blueswir1's avatar
blueswir1 committed
109
#ifdef TARGET_SIGPWR
110
    TARGET_SIGPWR,
blueswir1's avatar
blueswir1 committed
111 112 113
#else
    -1,
#endif
114 115 116 117 118 119 120 121 122 123 124 125
    -1, /* SIGPOLL */
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
blueswir1's avatar
blueswir1 committed
126
#ifdef __SIGRTMIN
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
    __SIGRTMIN + 1,
    __SIGRTMIN + 2,
    __SIGRTMIN + 3,
    __SIGRTMIN + 4,
    __SIGRTMIN + 5,
    __SIGRTMIN + 6,
    __SIGRTMIN + 7,
    __SIGRTMIN + 8,
    __SIGRTMIN + 9,
    __SIGRTMIN + 10,
    __SIGRTMIN + 11,
    __SIGRTMIN + 12,
    __SIGRTMIN + 13,
    __SIGRTMIN + 14,
    __SIGRTMIN + 15,
    __SIGRTMIN + 16,
    __SIGRTMIN + 17,
    __SIGRTMIN + 18,
    __SIGRTMIN + 19,
    __SIGRTMIN + 20,
    __SIGRTMIN + 21,
    __SIGRTMIN + 22,
    __SIGRTMIN + 23,
    __SIGRTMIN + 24,
    __SIGRTMIN + 25,
    __SIGRTMIN + 26,
    __SIGRTMIN + 27,
    __SIGRTMIN + 28,
    __SIGRTMIN + 29,
    __SIGRTMIN + 30,
    __SIGRTMIN + 31,
    -1, /* SIGCANCEL */
    __SIGRTMIN,
    __SIGRTMIN + 32,
    __SIGRTMIN + 33,
    __SIGRTMIN + 34,
    __SIGRTMIN + 35,
    __SIGRTMIN + 36,
    __SIGRTMIN + 37,
    __SIGRTMIN + 38,
    __SIGRTMIN + 39,
    __SIGRTMIN + 40,
    __SIGRTMIN + 41,
    __SIGRTMIN + 42,
    __SIGRTMIN + 43,
    __SIGRTMIN + 44,
    __SIGRTMIN + 45,
    __SIGRTMIN + 46,
    __SIGRTMIN + 47,
    __SIGRTMIN + 48,
    __SIGRTMIN + 49,
    __SIGRTMIN + 50,
    __SIGRTMIN + 51,
    __SIGRTMIN + 52,
    __SIGRTMIN + 53,
    __SIGRTMIN + 54,
    __SIGRTMIN + 55,
    __SIGRTMIN + 56,
    __SIGRTMIN + 57,
    __SIGRTMIN + 58,
    __SIGRTMIN + 59,
    __SIGRTMIN + 60,
    __SIGRTMIN + 61,
    __SIGRTMIN + 62,
    __SIGRTMIN + 63,
    __SIGRTMIN + 64,
    __SIGRTMIN + 65,
    __SIGRTMIN + 66,
    __SIGRTMIN + 67,
    __SIGRTMIN + 68,
    __SIGRTMIN + 69,
    __SIGRTMIN + 70,
    __SIGRTMIN + 71,
    __SIGRTMIN + 72,
    __SIGRTMIN + 73,
    __SIGRTMIN + 74,
    __SIGRTMIN + 75,
    __SIGRTMIN + 76,
    __SIGRTMIN + 77,
    __SIGRTMIN + 78,
    __SIGRTMIN + 79,
    __SIGRTMIN + 80,
    __SIGRTMIN + 81,
    __SIGRTMIN + 82,
    __SIGRTMIN + 83,
    __SIGRTMIN + 84,
    __SIGRTMIN + 85,
    __SIGRTMIN + 86,
    __SIGRTMIN + 87,
    __SIGRTMIN + 88,
    __SIGRTMIN + 89,
    __SIGRTMIN + 90,
    __SIGRTMIN + 91,
    __SIGRTMIN + 92,
    __SIGRTMIN + 93,
    __SIGRTMIN + 94,
    __SIGRTMIN + 95,
    -1, /* SIGINFO */
    -1, /* UNKNOWN */
    -1, /* DEFAULT */
    -1,
    -1,
    -1,
    -1,
    -1,
    -1
blueswir1's avatar
blueswir1 committed
233
#endif
234
};
bellard's avatar
bellard committed
235
#else
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
/* In system mode we only need SIGINT and SIGTRAP; other signals
   are not yet supported.  */

enum {
    TARGET_SIGINT = 2,
    TARGET_SIGTRAP = 5
};

static int gdb_signal_table[] = {
    -1,
    -1,
    TARGET_SIGINT,
    -1,
    -1,
    TARGET_SIGTRAP
};
#endif

#ifdef CONFIG_USER_ONLY
static int target_signal_to_gdb (int sig)
{
    int i;
    for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
        if (gdb_signal_table[i] == sig)
            return i;
    return GDB_SIGNAL_UNKNOWN;
}
bellard's avatar
bellard committed
263
#endif
bellard's avatar
bellard committed
264

265 266 267 268 269 270 271 272
static int gdb_signal_to_target (int sig)
{
    if (sig < ARRAY_SIZE (gdb_signal_table))
        return gdb_signal_table[sig];
    else
        return -1;
}

bellard's avatar
bellard committed
273
//#define DEBUG_GDB
bellard's avatar
bellard committed
274

275 276 277 278 279 280 281 282 283
typedef struct GDBRegisterState {
    int base_reg;
    int num_regs;
    gdb_reg_cb get_reg;
    gdb_reg_cb set_reg;
    const char *xml;
    struct GDBRegisterState *next;
} GDBRegisterState;

284
enum RSState {
285
    RS_INACTIVE,
286 287 288 289 290 291
    RS_IDLE,
    RS_GETLINE,
    RS_CHKSUM1,
    RS_CHKSUM2,
};
typedef struct GDBState {
292 293
    CPUState *c_cpu; /* current CPU for step/continue ops */
    CPUState *g_cpu; /* current CPU for other ops */
294
    CPUState *query_cpu; /* for q{f|s}ThreadInfo */
bellard's avatar
bellard committed
295
    enum RSState state; /* parsing state */
296
    char line_buf[MAX_PACKET_LENGTH];
297 298
    int line_buf_index;
    int line_csum;
299
    uint8_t last_packet[MAX_PACKET_LENGTH + 4];
300
    int last_packet_len;
301
    int signal;
bellard's avatar
bellard committed
302
#ifdef CONFIG_USER_ONLY
303
    int fd;
bellard's avatar
bellard committed
304
    int running_state;
305 306
#else
    CharDriverState *chr;
307
    CharDriverState *mon_chr;
bellard's avatar
bellard committed
308
#endif
309 310
    char syscall_buf[256];
    gdb_syscall_complete_cb current_syscall_cb;
311
} GDBState;
bellard's avatar
bellard committed
312

313 314 315 316 317
/* By default use no IRQs and no timers while single stepping so as to
 * make single stepping like an ICE HW step.
 */
static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;

318 319
static GDBState *gdbserver_state;

320
bool gdb_has_xml;
321

322
#ifdef CONFIG_USER_ONLY
323 324 325
/* XXX: This is not thread safe.  Do we care?  */
static int gdbserver_fd = -1;

326
static int get_char(GDBState *s)
bellard's avatar
bellard committed
327 328 329 330 331
{
    uint8_t ch;
    int ret;

    for(;;) {
Blue Swirl's avatar
Blue Swirl committed
332
        ret = qemu_recv(s->fd, &ch, 1, 0);
bellard's avatar
bellard committed
333
        if (ret < 0) {
334 335
            if (errno == ECONNRESET)
                s->fd = -1;
336
            if (errno != EINTR)
bellard's avatar
bellard committed
337 338
                return -1;
        } else if (ret == 0) {
339 340
            close(s->fd);
            s->fd = -1;
bellard's avatar
bellard committed
341 342 343 344 345 346 347
            return -1;
        } else {
            break;
        }
    }
    return ch;
}
348
#endif
bellard's avatar
bellard committed
349

350
static enum {
pbrook's avatar
pbrook committed
351 352 353 354 355
    GDB_SYS_UNKNOWN,
    GDB_SYS_ENABLED,
    GDB_SYS_DISABLED,
} gdb_syscall_mode;

356
/* Decide if either remote gdb syscalls or native file IO should be used. */
pbrook's avatar
pbrook committed
357 358
int use_gdb_syscalls(void)
{
359 360
    SemihostingTarget target = semihosting_get_target();
    if (target == SEMIHOSTING_TARGET_NATIVE) {
361 362
        /* -semihosting-config target=native */
        return false;
363
    } else if (target == SEMIHOSTING_TARGET_GDB) {
364 365 366 367 368 369
        /* -semihosting-config target=gdb */
        return true;
    }

    /* -semihosting-config target=auto */
    /* On the first call check if gdb is connected and remember. */
pbrook's avatar
pbrook committed
370
    if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
371 372
        gdb_syscall_mode = (gdbserver_state ? GDB_SYS_ENABLED
                                            : GDB_SYS_DISABLED);
pbrook's avatar
pbrook committed
373 374 375 376
    }
    return gdb_syscall_mode == GDB_SYS_ENABLED;
}

377 378 379 380 381 382
/* Resume execution.  */
static inline void gdb_continue(GDBState *s)
{
#ifdef CONFIG_USER_ONLY
    s->running_state = 1;
#else
383
    if (!runstate_needs_reset()) {
384 385
        vm_start();
    }
386 387 388
#endif
}

389
static void put_buffer(GDBState *s, const uint8_t *buf, int len)
bellard's avatar
bellard committed
390
{
391
#ifdef CONFIG_USER_ONLY
bellard's avatar
bellard committed
392 393 394
    int ret;

    while (len > 0) {
bellard's avatar
bellard committed
395
        ret = send(s->fd, buf, len, 0);
bellard's avatar
bellard committed
396
        if (ret < 0) {
397
            if (errno != EINTR)
bellard's avatar
bellard committed
398 399 400 401 402 403
                return;
        } else {
            buf += ret;
            len -= ret;
        }
    }
404
#else
405
    qemu_chr_fe_write(s->chr, buf, len);
406
#endif
bellard's avatar
bellard committed
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
}

static inline int fromhex(int v)
{
    if (v >= '0' && v <= '9')
        return v - '0';
    else if (v >= 'A' && v <= 'F')
        return v - 'A' + 10;
    else if (v >= 'a' && v <= 'f')
        return v - 'a' + 10;
    else
        return 0;
}

static inline int tohex(int v)
{
    if (v < 10)
        return v + '0';
    else
        return v - 10 + 'a';
}

static void memtohex(char *buf, const uint8_t *mem, int len)
{
    int i, c;
    char *q;
    q = buf;
    for(i = 0; i < len; i++) {
        c = mem[i];
        *q++ = tohex(c >> 4);
        *q++ = tohex(c & 0xf);
    }
    *q = '\0';
}

static void hextomem(uint8_t *mem, const char *buf, int len)
{
    int i;

    for(i = 0; i < len; i++) {
        mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
        buf += 2;
    }
}

/* return -1 if error, 0 if OK */
453
static int put_packet_binary(GDBState *s, const char *buf, int len)
bellard's avatar
bellard committed
454
{
455
    int csum, i;
456
    uint8_t *p;
bellard's avatar
bellard committed
457 458

    for(;;) {
459 460 461 462
        p = s->last_packet;
        *(p++) = '$';
        memcpy(p, buf, len);
        p += len;
bellard's avatar
bellard committed
463 464 465 466
        csum = 0;
        for(i = 0; i < len; i++) {
            csum += buf[i];
        }
467 468 469
        *(p++) = '#';
        *(p++) = tohex((csum >> 4) & 0xf);
        *(p++) = tohex((csum) & 0xf);
bellard's avatar
bellard committed
470

471
        s->last_packet_len = p - s->last_packet;
472
        put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
bellard's avatar
bellard committed
473

474 475 476
#ifdef CONFIG_USER_ONLY
        i = get_char(s);
        if (i < 0)
bellard's avatar
bellard committed
477
            return -1;
478
        if (i == '+')
bellard's avatar
bellard committed
479
            break;
480 481 482
#else
        break;
#endif
bellard's avatar
bellard committed
483 484 485 486
    }
    return 0;
}

487 488 489 490 491 492
/* return -1 if error, 0 if OK */
static int put_packet(GDBState *s, const char *buf)
{
#ifdef DEBUG_GDB
    printf("reply='%s'\n", buf);
#endif
bellard's avatar
bellard committed
493

494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
    return put_packet_binary(s, buf, strlen(buf));
}

/* Encode data using the encoding for 'x' packets.  */
static int memtox(char *buf, const char *mem, int len)
{
    char *p = buf;
    char c;

    while (len--) {
        c = *(mem++);
        switch (c) {
        case '#': case '$': case '*': case '}':
            *(p++) = '}';
            *(p++) = c ^ 0x20;
            break;
        default:
            *(p++) = c;
            break;
        }
    }
    return p - buf;
}
517

518 519
static const char *get_feature_xml(const char *p, const char **newp,
                                   CPUClass *cc)
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
{
    size_t len;
    int i;
    const char *name;
    static char target_xml[1024];

    len = 0;
    while (p[len] && p[len] != ':')
        len++;
    *newp = p + len;

    name = NULL;
    if (strncmp(p, "target.xml", len) == 0) {
        /* Generate the XML description for this CPU.  */
        if (!target_xml[0]) {
            GDBRegisterState *r;
536
            CPUState *cpu = first_cpu;
537

538 539 540 541 542 543 544 545 546 547 548 549 550 551
            pstrcat(target_xml, sizeof(target_xml),
                    "<?xml version=\"1.0\"?>"
                    "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
                    "<target>");
            if (cc->gdb_arch_name) {
                gchar *arch = cc->gdb_arch_name(cpu);
                pstrcat(target_xml, sizeof(target_xml), "<architecture>");
                pstrcat(target_xml, sizeof(target_xml), arch);
                pstrcat(target_xml, sizeof(target_xml), "</architecture>");
                g_free(arch);
            }
            pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
            pstrcat(target_xml, sizeof(target_xml), cc->gdb_core_xml_file);
            pstrcat(target_xml, sizeof(target_xml), "\"/>");
552
            for (r = cpu->gdb_regs; r; r = r->next) {
553 554 555
                pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
                pstrcat(target_xml, sizeof(target_xml), r->xml);
                pstrcat(target_xml, sizeof(target_xml), "\"/>");
556
            }
557
            pstrcat(target_xml, sizeof(target_xml), "</target>");
558 559 560 561 562 563 564 565 566 567
        }
        return target_xml;
    }
    for (i = 0; ; i++) {
        name = xml_builtin[i][0];
        if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
            break;
    }
    return name ? xml_builtin[i][1] : NULL;
}
568

569
static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
570
{
571
    CPUClass *cc = CPU_GET_CLASS(cpu);
572
    CPUArchState *env = cpu->env_ptr;
573
    GDBRegisterState *r;
574

575
    if (reg < cc->gdb_num_core_regs) {
576
        return cc->gdb_read_register(cpu, mem_buf, reg);
577
    }
578

579
    for (r = cpu->gdb_regs; r; r = r->next) {
580 581 582 583 584
        if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
            return r->get_reg(env, mem_buf, reg - r->base_reg);
        }
    }
    return 0;
585 586
}

587
static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
588
{
589
    CPUClass *cc = CPU_GET_CLASS(cpu);
590
    CPUArchState *env = cpu->env_ptr;
591
    GDBRegisterState *r;
592

593
    if (reg < cc->gdb_num_core_regs) {
594
        return cc->gdb_write_register(cpu, mem_buf, reg);
595
    }
596

597
    for (r = cpu->gdb_regs; r; r = r->next) {
598 599 600 601
        if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
            return r->set_reg(env, mem_buf, reg - r->base_reg);
        }
    }
bellard's avatar
bellard committed
602 603 604
    return 0;
}

605 606 607 608 609 610
/* Register a supplemental set of CPU registers.  If g_pos is nonzero it
   specifies the first register number and these registers are included in
   a standard "g" packet.  Direction is relative to gdb, i.e. get_reg is
   gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
 */

611 612 613
void gdb_register_coprocessor(CPUState *cpu,
                              gdb_reg_cb get_reg, gdb_reg_cb set_reg,
                              int num_regs, const char *xml, int g_pos)
bellard's avatar
bellard committed
614
{
615 616 617
    GDBRegisterState *s;
    GDBRegisterState **p;

618
    p = &cpu->gdb_regs;
619 620 621 622 623 624
    while (*p) {
        /* Check for duplicates.  */
        if (strcmp((*p)->xml, xml) == 0)
            return;
        p = &(*p)->next;
    }
Stefan Weil's avatar
Stefan Weil committed
625 626

    s = g_new0(GDBRegisterState, 1);
627
    s->base_reg = cpu->gdb_num_regs;
Stefan Weil's avatar
Stefan Weil committed
628 629 630 631 632
    s->num_regs = num_regs;
    s->get_reg = get_reg;
    s->set_reg = set_reg;
    s->xml = xml;

633
    /* Add to end of list.  */
634
    cpu->gdb_num_regs += num_regs;
635 636 637 638 639
    *p = s;
    if (g_pos) {
        if (g_pos != s->base_reg) {
            fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
                    "Expected %d got %d\n", xml, g_pos, s->base_reg);
640 641
        } else {
            cpu->gdb_num_g_regs = cpu->gdb_num_regs;
642 643
        }
    }
bellard's avatar
bellard committed
644 645
}

646
#ifndef CONFIG_USER_ONLY
647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
{
    static const int xlat[] = {
        [GDB_WATCHPOINT_WRITE]  = BP_GDB | BP_MEM_WRITE,
        [GDB_WATCHPOINT_READ]   = BP_GDB | BP_MEM_READ,
        [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
    };

    CPUClass *cc = CPU_GET_CLASS(cpu);
    int cputype = xlat[gdbtype];

    if (cc->gdb_stop_before_watchpoint) {
        cputype |= BP_STOP_BEFORE_ACCESS;
    }
    return cputype;
}
664 665
#endif

666
static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
667
{
668
    CPUState *cpu;
669 670
    int err = 0;

671
    if (kvm_enabled()) {
672
        return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
673
    }
674

675 676 677
    switch (type) {
    case GDB_BREAKPOINT_SW:
    case GDB_BREAKPOINT_HW:
678
        CPU_FOREACH(cpu) {
679 680
            err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
            if (err) {
681
                break;
682
            }
683 684
        }
        return err;
685 686 687 688
#ifndef CONFIG_USER_ONLY
    case GDB_WATCHPOINT_WRITE:
    case GDB_WATCHPOINT_READ:
    case GDB_WATCHPOINT_ACCESS:
689
        CPU_FOREACH(cpu) {
690 691 692
            err = cpu_watchpoint_insert(cpu, addr, len,
                                        xlat_gdb_type(cpu, type), NULL);
            if (err) {
693
                break;
694
            }
695 696
        }
        return err;
697 698 699 700 701 702
#endif
    default:
        return -ENOSYS;
    }
}

703
static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
704
{
705
    CPUState *cpu;
706 707
    int err = 0;

708
    if (kvm_enabled()) {
709
        return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
710
    }
711

712 713 714
    switch (type) {
    case GDB_BREAKPOINT_SW:
    case GDB_BREAKPOINT_HW:
715
        CPU_FOREACH(cpu) {
716 717
            err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
            if (err) {
718
                break;
719
            }
720 721
        }
        return err;
722 723 724 725
#ifndef CONFIG_USER_ONLY
    case GDB_WATCHPOINT_WRITE:
    case GDB_WATCHPOINT_READ:
    case GDB_WATCHPOINT_ACCESS:
726
        CPU_FOREACH(cpu) {
727 728
            err = cpu_watchpoint_remove(cpu, addr, len,
                                        xlat_gdb_type(cpu, type));
729 730 731 732
            if (err)
                break;
        }
        return err;
733 734 735 736 737 738
#endif
    default:
        return -ENOSYS;
    }
}

739
static void gdb_breakpoint_remove_all(void)
740
{
741
    CPUState *cpu;
742

743
    if (kvm_enabled()) {
744
        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
745 746 747
        return;
    }

748
    CPU_FOREACH(cpu) {
749
        cpu_breakpoint_remove_all(cpu, BP_GDB);
750
#ifndef CONFIG_USER_ONLY
751
        cpu_watchpoint_remove_all(cpu, BP_GDB);
752
#endif
753
    }
754 755
}

756 757
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
{
758
    CPUState *cpu = s->c_cpu;
759 760

    cpu_synchronize_state(cpu);
761
    cpu_set_pc(cpu, pc);
762 763
}

764
static CPUState *find_cpu(uint32_t thread_id)
765
{
766
    CPUState *cpu;
767

768
    CPU_FOREACH(cpu) {
769
        if (cpu_index(cpu) == thread_id) {
770
            return cpu;
771
        }
772
    }
773 774

    return NULL;
775 776
}

777 778 779 780 781 782 783 784
static int is_query_packet(const char *p, const char *query, char separator)
{
    unsigned int query_len = strlen(query);

    return strncmp(p, query, query_len) == 0 &&
        (p[query_len] == '\0' || p[query_len] == separator);
}

785
static int gdb_handle_packet(GDBState *s, const char *line_buf)
bellard's avatar
bellard committed
786
{
787
    CPUState *cpu;
788
    CPUClass *cc;
bellard's avatar
bellard committed
789
    const char *p;
790 791
    uint32_t thread;
    int ch, reg_size, type, res;
792 793 794
    char buf[MAX_PACKET_LENGTH];
    uint8_t mem_buf[MAX_PACKET_LENGTH];
    uint8_t *registers;
795
    target_ulong addr, len;
796

797 798 799 800 801 802 803
#ifdef DEBUG_GDB
    printf("command='%s'\n", line_buf);
#endif
    p = line_buf;
    ch = *p++;
    switch(ch) {
    case '?':
804
        /* TODO: Make this return the correct value for user-mode.  */
805
        snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
806
                 cpu_index(s->c_cpu));
807
        put_packet(s, buf);
808 809 810 811
        /* Remove all the breakpoints when this query is issued,
         * because gdb is doing and initial connect and the state
         * should be cleaned up.
         */
812
        gdb_breakpoint_remove_all();
813 814 815
        break;
    case 'c':
        if (*p != '\0') {
816
            addr = strtoull(p, (char **)&p, 16);
817
            gdb_set_cpu_pc(s, addr);
818
        }
819
        s->signal = 0;
820
        gdb_continue(s);
bellard's avatar
bellard committed
821
	return RS_IDLE;
822
    case 'C':
823 824 825
        s->signal = gdb_signal_to_target (strtoul(p, (char **)&p, 16));
        if (s->signal == -1)
            s->signal = 0;
826 827
        gdb_continue(s);
        return RS_IDLE;
Jan Kiszka's avatar
Jan Kiszka committed
828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
    case 'v':
        if (strncmp(p, "Cont", 4) == 0) {
            int res_signal, res_thread;

            p += 4;
            if (*p == '?') {
                put_packet(s, "vCont;c;C;s;S");
                break;
            }
            res = 0;
            res_signal = 0;
            res_thread = 0;
            while (*p) {
                int action, signal;

                if (*p++ != ';') {
                    res = 0;
                    break;
                }
                action = *p++;
                signal = 0;
                if (action == 'C' || action == 'S') {
850 851 852 853
                    signal = gdb_signal_to_target(strtoul(p, (char **)&p, 16));
                    if (signal == -1) {
                        signal = 0;
                    }
Jan Kiszka's avatar
Jan Kiszka committed
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
                } else if (action != 'c' && action != 's') {
                    res = 0;
                    break;
                }
                thread = 0;
                if (*p == ':') {
                    thread = strtoull(p+1, (char **)&p, 16);
                }
                action = tolower(action);
                if (res == 0 || (res == 'c' && action == 's')) {
                    res = action;
                    res_signal = signal;
                    res_thread = thread;
                }
            }
            if (res) {
                if (res_thread != -1 && res_thread != 0) {
871 872
                    cpu = find_cpu(res_thread);
                    if (cpu == NULL) {
Jan Kiszka's avatar
Jan Kiszka committed
873 874 875
                        put_packet(s, "E22");
                        break;
                    }
876
                    s->c_cpu = cpu;
Jan Kiszka's avatar
Jan Kiszka committed
877 878
                }
                if (res == 's') {
879
                    cpu_single_step(s->c_cpu, sstep_flags);
Jan Kiszka's avatar
Jan Kiszka committed
880 881 882 883 884 885 886 887 888
                }
                s->signal = res_signal;
                gdb_continue(s);
                return RS_IDLE;
            }
            break;
        } else {
            goto unknown_command;
        }
889 890 891 892 893 894
    case 'k':
        /* Kill the target */
        fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
        exit(0);
    case 'D':
        /* Detach packet */
895
        gdb_breakpoint_remove_all();
Daniel Gutson's avatar
Daniel Gutson committed
896
        gdb_syscall_mode = GDB_SYS_DISABLED;
897 898 899
        gdb_continue(s);
        put_packet(s, "OK");
        break;
900 901
    case 's':
        if (*p != '\0') {
902
            addr = strtoull(p, (char **)&p, 16);
903
            gdb_set_cpu_pc(s, addr);
904
        }
905
        cpu_single_step(s->c_cpu, sstep_flags);
906
        gdb_continue(s);
bellard's avatar
bellard committed
907
	return RS_IDLE;
pbrook's avatar
pbrook committed
908 909 910 911 912 913 914 915 916 917 918 919 920 921 922
    case 'F':
        {
            target_ulong ret;
            target_ulong err;

            ret = strtoull(p, (char **)&p, 16);
            if (*p == ',') {
                p++;
                err = strtoull(p, (char **)&p, 16);
            } else {
                err = 0;
            }
            if (*p == ',')
                p++;
            type = *p;
923
            if (s->current_syscall_cb) {
924
                s->current_syscall_cb(s->c_cpu, ret, err);
925 926
                s->current_syscall_cb = NULL;
            }
pbrook's avatar
pbrook committed
927 928 929
            if (type == 'C') {
                put_packet(s, "T02");
            } else {
930
                gdb_continue(s);
pbrook's avatar
pbrook committed
931 932 933
            }
        }
        break;
934
    case 'g':
935
        cpu_synchronize_state(s->g_cpu);
936
        len = 0;
937
        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs; addr++) {
938
            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
939 940 941
            len += reg_size;
        }
        memtohex(buf, mem_buf, len);
942 943 944
        put_packet(s, buf);
        break;
    case 'G':
945
        cpu_synchronize_state(s->g_cpu);
946
        registers = mem_buf;
947 948
        len = strlen(p) / 2;
        hextomem((uint8_t *)registers, p, len);
949
        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs && len > 0; addr++) {
950
            reg_size = gdb_write_register(s->g_cpu, registers, addr);
951 952 953
            len -= reg_size;
            registers += reg_size;
        }
954 955 956
        put_packet(s, "OK");
        break;
    case 'm':
957
        addr = strtoull(p, (char **)&p, 16);
958 959
        if (*p == ',')
            p++;
960
        len = strtoull(p, NULL, 16);
961 962 963 964 965 966 967

        /* memtohex() doubles the required space */
        if (len > MAX_PACKET_LENGTH / 2) {
            put_packet (s, "E22");
            break;
        }

968
        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) {
969 970 971 972 973
            put_packet (s, "E14");
        } else {
            memtohex(buf, mem_buf, len);
            put_packet(s, buf);
        }
974 975
        break;
    case 'M':
976
        addr = strtoull(p, (char **)&p, 16);
977 978
        if (*p == ',')
            p++;
979
        len = strtoull(p, (char **)&p, 16);
980
        if (*p == ':')
981
            p++;
982 983 984 985 986 987

        /* hextomem() reads 2*len bytes */
        if (len > strlen(p) / 2) {
            put_packet (s, "E22");
            break;
        }
988
        hextomem(mem_buf, p, len);
989
        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
990
                                   true) != 0) {
991
            put_packet(s, "E14");
992
        } else {
993
            put_packet(s, "OK");
994
        }
995
        break;
996 997 998 999 1000 1001 1002
    case 'p':
        /* Older gdb are really dumb, and don't use 'g' if 'p' is avaialable.
           This works, but can be very slow.  Anything new enough to
           understand XML also knows how to use this properly.  */
        if (!gdb_has_xml)
            goto unknown_command;
        addr = strtoull(p, (char **)&p, 16);
1003
        reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
        if (reg_size) {
            memtohex(buf, mem_buf, reg_size);
            put_packet(s, buf);
        } else {
            put_packet(s, "E14");
        }
        break;
    case 'P':
        if (!gdb_has_xml)
            goto unknown_command;
        addr = strtoull(p, (char **)&p, 16);
        if (*p == '=')
            p++;
        reg_size = strlen(p) / 2;
        hextomem(mem_buf, p, reg_size);
1019
        gdb_write_register(s->g_cpu, mem_buf, addr);
1020 1021
        put_packet(s, "OK");
        break;
1022 1023 1024 1025 1026
    case 'Z':
    case 'z':
        type = strtoul(p, (char **)&p, 16);
        if (*p == ',')
            p++;
1027
        addr = strtoull(p, (char **)&p, 16);
1028 1029
        if (*p == ',')
            p++;
1030
        len = strtoull(p, (char **)&p, 16);
1031
        if (ch == 'Z')
1032
            res = gdb_breakpoint_insert(addr, len, type);
1033
        else
1034
            res = gdb_breakpoint_remove(addr, len, type);
1035 1036 1037
        if (res >= 0)
             put_packet(s, "OK");
        else if (res == -ENOSYS)
pbrook's avatar
pbrook committed
1038
            put_packet(s, "");
1039 1040
        else
            put_packet(s, "E22");
1041
        break;
1042 1043 1044 1045 1046 1047 1048
    case 'H':
        type = *p++;
        thread = strtoull(p, (char **)&p, 16);
        if (thread == -1 || thread == 0) {
            put_packet(s, "OK");
            break;
        }
1049 1050
        cpu = find_cpu(thread);
        if (cpu == NULL) {
1051 1052 1053 1054 1055
            put_packet(s, "E22");
            break;
        }
        switch (type) {
        case 'c':
1056
            s->c_cpu = cpu;
1057 1058 1059
            put_packet(s, "OK");
            break;
        case 'g':
1060
            s->g_cpu = cpu;
1061 1062 1063 1064 1065 1066 1067 1068 1069
            put_packet(s, "OK");
            break;
        default:
             put_packet(s, "E22");
             break;
        }
        break;
    case 'T':
        thread = strtoull(p, (char **)&p, 16);
1070
        cpu = find_cpu(thread);
1071

1072
        if (cpu != NULL) {
1073 1074
            put_packet(s, "OK");
        } else {
1075
            put_packet(s, "E22");
1076
        }
1077
        break;
1078
    case 'q':
1079 1080 1081 1082
    case 'Q':
        /* parse any 'q' packets here */
        if (!strcmp(p,"qemu.sstepbits")) {
            /* Query Breakpoint bit definitions */
blueswir1's avatar
blueswir1 committed
1083 1084 1085 1086
            snprintf(buf, sizeof(buf), "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
                     SSTEP_ENABLE,
                     SSTEP_NOIRQ,
                     SSTEP_NOTIMER);
1087 1088
            put_packet(s, buf);
            break;
1089
        } else if (is_query_packet(p, "qemu.sstep", '=')) {
1090 1091 1092 1093
            /* Display or change the sstep_flags */
            p += 10;
            if (*p != '=') {
                /* Display current setting */
blueswir1's avatar
blueswir1 committed
1094
                snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
1095 1096 1097 1098 1099 1100 1101 1102
                put_packet(s, buf);
                break;
            }
            p++;
            type = strtoul(p, (char **)&p, 16);
            sstep_flags = type;
            put_packet(s, "OK");
            break;
1103 1104 1105 1106 1107 1108
        } else if (strcmp(p,"C") == 0) {
            /* "Current thread" remains vague in the spec, so always return
             *  the first CPU (gdb returns the first thread). */
            put_packet(s, "QC1");
            break;
        } else if (strcmp(p,"fThreadInfo") == 0) {
1109
            s->query_cpu = first_cpu;
1110 1111 1112 1113
            goto report_cpuinfo;
        } else if (strcmp(p,"sThreadInfo") == 0) {
        report_cpuinfo:
            if (s->query_cpu) {
1114
                snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
1115
                put_packet(s, buf);
1116
                s->query_cpu = CPU_NEXT(s->query_cpu);
1117 1118 1119 1120 1121
            } else
                put_packet(s, "l");
            break;
        } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
            thread = strtoull(p+16, (char **)&p, 16);
1122 1123
            cpu = find_cpu(thread);
            if (cpu != NULL) {
1124
                cpu_synchronize_state(cpu);
1125 1126
                /* memtohex() doubles the required space */
                len = snprintf((char *)mem_buf, sizeof(buf) / 2,
1127
                               "CPU#%d [%s]", cpu->cpu_index,
1128
                               cpu->halted ? "halted " : "running");
1129 1130 1131
                memtohex(buf, mem_buf, len);
                put_packet(s, buf);
            }
1132
            break;
1133
        }
blueswir1's avatar
blueswir1 committed
1134
#ifdef CONFIG_USER_ONLY
1135
        else if (strcmp(p, "Offsets") == 0) {
1136
            TaskState *ts = s->c_cpu->opaque;
1137

blueswir1's avatar
blueswir1 committed
1138 1139 1140 1141 1142 1143
            snprintf(buf, sizeof(buf),
                     "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
                     ";Bss=" TARGET_ABI_FMT_lx,
                     ts->info->code_offset,
                     ts->info->data_offset,
                     ts->info->data_offset);
1144 1145 1146
            put_packet(s, buf);
            break;
        }
blueswir1's avatar
blueswir1 committed
1147
#else /* !CONFIG_USER_ONLY */
1148 1149 1150 1151 1152 1153 1154 1155
        else if (strncmp(p, "Rcmd,", 5) == 0) {
            int len = strlen(p + 5);

            if ((len % 2) != 0) {
                put_packet(s, "E01");
                break;
            }
            len = len / 2;
1156
            hextomem(mem_buf, p + 5, len);
1157
            mem_buf[len++] = 0;
1158
            qemu_chr_be_write(s->mon_chr, mem_buf, len);
1159 1160 1161
            put_packet(s, "OK");
            break;
        }
blueswir1's avatar
blueswir1 committed
1162
#endif /* !CONFIG_USER_ONLY */
1163
        if (is_query_packet(p, "Supported", ':')) {
1164
            snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
1165 1166 1167 1168
            cc = CPU_GET_CLASS(first_cpu);
            if (cc->gdb_core_xml_file != NULL) {
                pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
            }
1169 1170 1171 1172 1173 1174 1175
            put_packet(s, buf);
            break;
        }
        if (strncmp(p, "Xfer:features:read:", 19) == 0) {
            const char *xml;
            target_ulong total_len;

1176 1177 1178 1179 1180
            cc = CPU_GET_CLASS(first_cpu);
            if (cc->gdb_core_xml_file == NULL) {
                goto unknown_command;
            }

1181
            gdb_has_xml = true;
1182
            p += 19;
1183
            xml = get_feature_xml(p, &p, cc);
1184
            if (!xml) {
1185
                snprintf(buf, sizeof(buf), "E00");
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
                put_packet(s, buf);
                break;
            }

            if (*p == ':')
                p++;
            addr = strtoul(p, (char **)&p, 16);
            if (*p == ',')
                p++;
            len = strtoul(p, (char **)&p, 16);

            total_len = strlen(xml);
            if (addr > total_len) {
1199
                snprintf(buf, sizeof(buf), "E00");
1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
                put_packet(s, buf);
                break;
            }
            if (len > (MAX_PACKET_LENGTH - 5) / 2)
                len = (MAX_PACKET_LENGTH - 5) / 2;
            if (len < total_len - addr) {
                buf[0] = 'm';
                len = memtox(buf + 1, xml + addr, len);
            } else {
                buf[0] = 'l';
                len = memtox(buf + 1, xml + addr, total_len - addr);
            }
            put_packet_binary(s, buf, len + 1);
            break;
        }
Jan Kiszka's avatar
Jan Kiszka committed
1215 1216 1217 1218
        if (is_query_packet(p, "Attached", ':')) {
            put_packet(s, GDB_ATTACHED);
            break;
        }
1219 1220 1221
        /* Unrecognised 'q' command.  */
        goto unknown_command;

1222
    default:
1223
    unknown_command:
1224 1225 1226 1227 1228 1229 1230 1231
        /* put empty packet */
        buf[0] = '\0';
        put_packet(s, buf);
        break;
    }
    return RS_IDLE;
}

1232
void gdb_set_stop_cpu(CPUState *cpu)
1233
{
1234 1235
    gdbserver_state->c_cpu = cpu;
    gdbserver_state->g_cpu = cpu;
1236 1237
}

1238
#ifndef CONFIG_USER_ONLY
1239
static void gdb_vm_state_change(void *opaque, int running, RunState state)
1240
{
1241
    GDBState *s = gdbserver_state;
1242
    CPUState *cpu = s->c_cpu;
1243
    char buf[256];
1244
    const char *type;
1245 1246
    int ret;

1247 1248 1249 1250 1251 1252
    if (running || s->state == RS_INACTIVE) {
        return;
    }
    /* Is there a GDB syscall waiting to be sent?  */
    if (s->current_syscall_cb) {
        put_packet(s, s->syscall_buf);
pbrook's avatar
pbrook committed
1253
        return;
1254
    }
1255
    switch (state) {
1256
    case RUN_STATE_DEBUG:
1257 1258
        if (cpu->watchpoint_hit) {
            switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
1259
            case BP_MEM_READ:
1260 1261
                type = "r";
                break;
1262
            case BP_MEM_ACCESS:
1263 1264 1265 1266 1267 1268
                type = "a";
                break;
            default:
                type = "";
                break;
            }
1269 1270
            snprintf(buf, sizeof(buf),
                     "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
1271
                     GDB_SIGNAL_TRAP, cpu_index(cpu), type,
1272 1273
                     (target_ulong)cpu->watchpoint_hit->vaddr);
            cpu->watchpoint_hit = NULL;
1274
            goto send_packet;
1275
        }
1276
        tb_flush(cpu);
1277
        ret = GDB_SIGNAL_TRAP;
1278
        break;
1279
    case RUN_STATE_PAUSED:
1280
        ret = GDB_SIGNAL_INT;
1281
        break;
1282
    case RUN_STATE_SHUTDOWN:
1283 1284
        ret = GDB_SIGNAL_QUIT;
        break;
1285
    case RUN_STATE_IO_ERROR:
1286 1287
        ret = GDB_SIGNAL_IO;
        break;
1288
    case RUN_STATE_WATCHDOG:
1289 1290
        ret = GDB_SIGNAL_ALRM;
        break;
1291
    case RUN_STATE_INTERNAL_ERROR:
1292 1293
        ret = GDB_SIGNAL_ABRT;
        break;
1294 1295
    case RUN_STATE_SAVE_VM:
    case RUN_STATE_RESTORE_VM:
1296
        return;
1297
    case RUN_STATE_FINISH_MIGRATE:
1298 1299 1300 1301 1302
        ret = GDB_SIGNAL_XCPU;
        break;
    default:
        ret = GDB_SIGNAL_UNKNOWN;
        break;
1303
    }
1304
    gdb_set_stop_cpu(cpu);
1305
    snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu));
1306 1307

send_packet:
1308
    put_packet(s, buf);
1309 1310

    /* disable single step if it was enabled */
1311
    cpu_single_step(cpu, 0);
1312
}
1313
#endif
1314

pbrook's avatar
pbrook committed
1315 1316
/* Send a gdb syscall request.
   This accepts limited printf-style format specifiers, specifically:
pbrook's avatar
pbrook committed
1317 1318 1319
    %x  - target_ulong argument printed in hex.
    %lx - 64-bit argument printed in hex.
    %s  - string pointer (target_ulong) and length (int) pair.  */
1320
void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
pbrook's avatar
pbrook committed
1321 1322
{
    char *p;
1323
    char *p_end;
pbrook's avatar
pbrook committed
1324
    target_ulong addr;
pbrook's avatar
pbrook committed
1325
    uint64_t i64;