Statistics
| Branch: | Revision:

root / gdbstub.c @ 6c9bf893

History | View | Annotate | Download (15.4 kB)

1
/*
2
 * gdb server stub
3
 * 
4
 * Copyright (c) 2003 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <string.h>
23
#include <unistd.h>
24
#include <errno.h>
25
#include <sys/socket.h>
26
#include <netinet/in.h>
27
#include <netinet/tcp.h>
28
#include <signal.h>
29

    
30
#include "config.h"
31
#include "cpu.h"
32
#include "thunk.h"
33
#include "exec-all.h"
34

    
35
//#define DEBUG_GDB
36

    
37
int gdbstub_fd = -1;
38

    
39
/* return 0 if OK */
40
static int gdbstub_open(int port)
41
{
42
    struct sockaddr_in sockaddr;
43
    socklen_t len;
44
    int fd, val, ret;
45

    
46
    fd = socket(PF_INET, SOCK_STREAM, 0);
47
    if (fd < 0) {
48
        perror("socket");
49
        return -1;
50
    }
51

    
52
    /* allow fast reuse */
53
    val = 1;
54
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
55

    
56
    sockaddr.sin_family = AF_INET;
57
    sockaddr.sin_port = htons(port);
58
    sockaddr.sin_addr.s_addr = 0;
59
    ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
60
    if (ret < 0) {
61
        perror("bind");
62
        return -1;
63
    }
64
    ret = listen(fd, 0);
65
    if (ret < 0) {
66
        perror("listen");
67
        return -1;
68
    }
69
    
70
    /* now wait for one connection */
71
    for(;;) {
72
        len = sizeof(sockaddr);
73
        gdbstub_fd = accept(fd, (struct sockaddr *)&sockaddr, &len);
74
        if (gdbstub_fd < 0 && errno != EINTR) {
75
            perror("accept");
76
            return -1;
77
        } else if (gdbstub_fd >= 0) {
78
            break;
79
        }
80
    }
81
    
82
    /* set short latency */
83
    val = 1;
84
    setsockopt(gdbstub_fd, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
85
    return 0;
86
}
87

    
88
static int get_char(void)
89
{
90
    uint8_t ch;
91
    int ret;
92

    
93
    for(;;) {
94
        ret = read(gdbstub_fd, &ch, 1);
95
        if (ret < 0) {
96
            if (errno != EINTR && errno != EAGAIN)
97
                return -1;
98
        } else if (ret == 0) {
99
            return -1;
100
        } else {
101
            break;
102
        }
103
    }
104
    return ch;
105
}
106

    
107
static void put_buffer(const uint8_t *buf, int len)
108
{
109
    int ret;
110

    
111
    while (len > 0) {
112
        ret = write(gdbstub_fd, buf, len);
113
        if (ret < 0) {
114
            if (errno != EINTR && errno != EAGAIN)
115
                return;
116
        } else {
117
            buf += ret;
118
            len -= ret;
119
        }
120
    }
121
}
122

    
123
static inline int fromhex(int v)
124
{
125
    if (v >= '0' && v <= '9')
126
        return v - '0';
127
    else if (v >= 'A' && v <= 'F')
128
        return v - 'A' + 10;
129
    else if (v >= 'a' && v <= 'f')
130
        return v - 'a' + 10;
131
    else
132
        return 0;
133
}
134

    
135
static inline int tohex(int v)
136
{
137
    if (v < 10)
138
        return v + '0';
139
    else
140
        return v - 10 + 'a';
141
}
142

    
143
static void memtohex(char *buf, const uint8_t *mem, int len)
144
{
145
    int i, c;
146
    char *q;
147
    q = buf;
148
    for(i = 0; i < len; i++) {
149
        c = mem[i];
150
        *q++ = tohex(c >> 4);
151
        *q++ = tohex(c & 0xf);
152
    }
153
    *q = '\0';
154
}
155

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

    
160
    for(i = 0; i < len; i++) {
161
        mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
162
        buf += 2;
163
    }
164
}
165

    
166
/* return -1 if error or EOF */
167
static int get_packet(char *buf, int buf_size)
168
{
169
    int ch, len, csum, csum1;
170
    char reply[1];
171
    
172
    for(;;) {
173
        for(;;) {
174
            ch = get_char();
175
            if (ch < 0)
176
                return -1;
177
            if (ch == '$')
178
                break;
179
        }
180
        len = 0;
181
        csum = 0;
182
        for(;;) {
183
            ch = get_char();
184
            if (ch < 0)
185
                return -1;
186
            if (ch == '#')
187
                break;
188
            if (len > buf_size - 1)
189
                return -1;
190
            buf[len++] = ch;
191
            csum += ch;
192
        }
193
        buf[len] = '\0';
194
        ch = get_char();
195
        if (ch < 0)
196
            return -1;
197
        csum1 = fromhex(ch) << 4;
198
        ch = get_char();
199
        if (ch < 0)
200
            return -1;
201
        csum1 |= fromhex(ch);
202
        if ((csum & 0xff) != csum1) {
203
            reply[0] = '-';
204
            put_buffer(reply, 1);
205
        } else {
206
            reply[0] = '+';
207
            put_buffer(reply, 1);
208
            break;
209
        }
210
    }
211
#ifdef DEBUG_GDB
212
    printf("command='%s'\n", buf);
213
#endif
214
    return len;
215
}
216

    
217
/* return -1 if error, 0 if OK */
218
static int put_packet(char *buf)
219
{
220
    char buf1[3];
221
    int len, csum, ch, i;
222

    
223
#ifdef DEBUG_GDB
224
    printf("reply='%s'\n", buf);
225
#endif
226

    
227
    for(;;) {
228
        buf1[0] = '$';
229
        put_buffer(buf1, 1);
230
        len = strlen(buf);
231
        put_buffer(buf, len);
232
        csum = 0;
233
        for(i = 0; i < len; i++) {
234
            csum += buf[i];
235
        }
236
        buf1[0] = '#';
237
        buf1[1] = tohex((csum >> 4) & 0xf);
238
        buf1[2] = tohex((csum) & 0xf);
239

    
240
        put_buffer(buf1, 3);
241

    
242
        ch = get_char();
243
        if (ch < 0)
244
            return -1;
245
        if (ch == '+')
246
            break;
247
    }
248
    return 0;
249
}
250

    
251
/* better than nothing for SOFTMMU : we use physical addresses */
252
#if !defined(CONFIG_USER_ONLY)
253
static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write)
254
{
255
    uint8_t *ptr;
256

    
257
    if (addr >= phys_ram_size ||
258
        ((int64_t)addr + len > phys_ram_size))
259
        return -1;
260
    ptr = phys_ram_base + addr;
261
    if (is_write)
262
        memcpy(ptr, buf, len);
263
    else
264
        memcpy(buf, ptr, len);
265
    return 0;
266
}
267
#else
268
static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write)
269
{
270
    int l, flags;
271
    uint32_t page;
272

    
273
    while (len > 0) {
274
        page = addr & TARGET_PAGE_MASK;
275
        l = (page + TARGET_PAGE_SIZE) - addr;
276
        if (l > len)
277
            l = len;
278
        flags = page_get_flags(page);
279
        if (!(flags & PAGE_VALID))
280
            return -1;
281
        if (is_write) {
282
            if (!(flags & PAGE_WRITE))
283
                return -1;
284
            memcpy((uint8_t *)addr, buf, l);
285
        } else {
286
            if (!(flags & PAGE_READ))
287
                return -1;
288
            memcpy(buf, (uint8_t *)addr, l);
289
        }
290
        len -= l;
291
        buf += l;
292
        addr += l;
293
    }
294
    return 0;
295
}
296
#endif
297

    
298
#if defined(TARGET_I386)
299

    
300
static void to_le32(uint8_t *p, int v)
301
{
302
    p[0] = v;
303
    p[1] = v >> 8;
304
    p[2] = v >> 16;
305
    p[3] = v >> 24;
306
}
307

    
308
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
309
{
310
    int i, fpus;
311

    
312
    for(i = 0; i < 8; i++) {
313
        to_le32(mem_buf + i * 4, env->regs[i]);
314
    }
315
    to_le32(mem_buf + 8 * 4, env->eip);
316
    to_le32(mem_buf + 9 * 4, env->eflags);
317
    to_le32(mem_buf + 10 * 4, env->segs[R_CS].selector);
318
    to_le32(mem_buf + 11 * 4, env->segs[R_SS].selector);
319
    to_le32(mem_buf + 12 * 4, env->segs[R_DS].selector);
320
    to_le32(mem_buf + 13 * 4, env->segs[R_ES].selector);
321
    to_le32(mem_buf + 14 * 4, env->segs[R_FS].selector);
322
    to_le32(mem_buf + 15 * 4, env->segs[R_GS].selector);
323
    /* XXX: convert floats */
324
    for(i = 0; i < 8; i++) {
325
        memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
326
    }
327
    to_le32(mem_buf + 36 * 4, env->fpuc);
328
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
329
    to_le32(mem_buf + 37 * 4, fpus);
330
    to_le32(mem_buf + 38 * 4, 0); /* XXX: convert tags */
331
    to_le32(mem_buf + 39 * 4, 0); /* fiseg */
332
    to_le32(mem_buf + 40 * 4, 0); /* fioff */
333
    to_le32(mem_buf + 41 * 4, 0); /* foseg */
334
    to_le32(mem_buf + 42 * 4, 0); /* fooff */
335
    to_le32(mem_buf + 43 * 4, 0); /* fop */
336
    return 44 * 4;
337
}
338

    
339
static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
340
{
341
    uint32_t *registers = (uint32_t *)mem_buf;
342
    int i;
343

    
344
    for(i = 0; i < 8; i++) {
345
        env->regs[i] = tswapl(registers[i]);
346
    }
347
    env->eip = registers[8];
348
    env->eflags = registers[9];
349
#if defined(CONFIG_USER_ONLY)
350
#define LOAD_SEG(index, sreg)\
351
            if (tswapl(registers[index]) != env->segs[sreg].selector)\
352
                cpu_x86_load_seg(env, sreg, tswapl(registers[index]));
353
            LOAD_SEG(10, R_CS);
354
            LOAD_SEG(11, R_SS);
355
            LOAD_SEG(12, R_DS);
356
            LOAD_SEG(13, R_ES);
357
            LOAD_SEG(14, R_FS);
358
            LOAD_SEG(15, R_GS);
359
#endif
360
}
361

    
362
#elif defined (TARGET_PPC)
363
static void to_le32(uint8_t *p, int v)
364
{
365
    p[3] = v;
366
    p[2] = v >> 8;
367
    p[1] = v >> 16;
368
    p[0] = v >> 24;
369
}
370

    
371
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
372
{
373
    uint32_t tmp;
374
    int i;
375

    
376
    /* fill in gprs */
377
    for(i = 0; i < 8; i++) {
378
        to_le32(mem_buf + i * 4, env->gpr[i]);
379
    }
380
    /* fill in fprs */
381
    for (i = 0; i < 32; i++) {
382
        to_le32(mem_buf + (i * 2) + 32, *((uint32_t *)&env->fpr[i]));
383
        to_le32(mem_buf + (i * 2) + 33, *((uint32_t *)&env->fpr[i] + 1));
384
    }
385
    /* nip, msr, ccr, lnk, ctr, xer, mq */
386
    to_le32(mem_buf + 96, tswapl(env->nip));
387
    to_le32(mem_buf + 97, tswapl(_load_msr()));
388
    to_le32(mem_buf + 98, 0);
389
    tmp = 0;
390
    for (i = 0; i < 8; i++)
391
        tmp |= env->crf[i] << (32 - (i * 4));
392
    to_le32(mem_buf + 98, tmp);
393
    to_le32(mem_buf + 99, tswapl(env->lr));
394
    to_le32(mem_buf + 100, tswapl(env->ctr));
395
    to_le32(mem_buf + 101, tswapl(_load_xer()));
396
    to_le32(mem_buf + 102, 0);
397

    
398
    return 102;
399
}
400

    
401
static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
402
{
403
    uint32_t *registers = (uint32_t *)mem_buf;
404
    int i;
405

    
406
    /* fill in gprs */
407
    for (i = 0; i < 32; i++) {
408
        env->gpr[i] = tswapl(registers[i]);
409
    }
410
    /* fill in fprs */
411
    for (i = 0; i < 32; i++) {
412
        *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
413
        *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
414
    }
415
    /* nip, msr, ccr, lnk, ctr, xer, mq */
416
    env->nip = tswapl(registers[96]);
417
    _store_msr(tswapl(registers[97]));
418
    registers[98] = tswapl(registers[98]);
419
    for (i = 0; i < 8; i++)
420
        env->crf[i] = (registers[98] >> (32 - (i * 4))) & 0xF;
421
    env->lr = tswapl(registers[99]);
422
    env->ctr = tswapl(registers[100]);
423
    _store_xer(tswapl(registers[101]));
424
}
425
#else
426

    
427
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
428
{
429
    return 0;
430
}
431

    
432
static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
433
{
434
}
435

    
436
#endif
437

    
438
/* port = 0 means default port */
439
int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
440
{
441
    CPUState *env;
442
    const char *p;
443
    int ret, ch, reg_size, type;
444
    char buf[4096];
445
    uint8_t mem_buf[2000];
446
    uint32_t *registers;
447
    uint32_t addr, len;
448
    
449
    printf("Waiting gdb connection on port %d\n", port);
450
    if (gdbstub_open(port) < 0)
451
        return -1;
452
    printf("Connected\n");
453
    for(;;) {
454
        ret = get_packet(buf, sizeof(buf));
455
        if (ret < 0)
456
            break;
457
        p = buf;
458
        ch = *p++;
459
        switch(ch) {
460
        case '?':
461
            snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
462
            put_packet(buf);
463
            break;
464
        case 'c':
465
            if (*p != '\0') {
466
                addr = strtoul(p, (char **)&p, 16);
467
                env = cpu_gdbstub_get_env(opaque);
468
#if defined(TARGET_I386)
469
                env->eip = addr;
470
#elif defined (TARGET_PPC)
471
                env->nip = addr;
472
#endif
473
            }
474
            ret = main_loop(opaque);
475
            if (ret == EXCP_DEBUG)
476
                ret = SIGTRAP;
477
            else
478
                ret = 0;
479
            snprintf(buf, sizeof(buf), "S%02x", ret);
480
            put_packet(buf);
481
            break;
482
        case 's':
483
            env = cpu_gdbstub_get_env(opaque);
484
            if (*p != '\0') {
485
                addr = strtoul(p, (char **)&p, 16);
486
#if defined(TARGET_I386)
487
                env->eip = addr;
488
#elif defined (TARGET_PPC)
489
                env->nip = addr;
490
#endif
491
            }
492
            cpu_single_step(env, 1);
493
            ret = main_loop(opaque);
494
            cpu_single_step(env, 0);
495
            if (ret == EXCP_DEBUG)
496
                ret = SIGTRAP;
497
            else
498
                ret = 0;
499
            snprintf(buf, sizeof(buf), "S%02x", ret);
500
            put_packet(buf);
501
            break;
502
        case 'g':
503
            env = cpu_gdbstub_get_env(opaque);
504
            reg_size = cpu_gdb_read_registers(env, mem_buf);
505
            memtohex(buf, mem_buf, reg_size);
506
            put_packet(buf);
507
            break;
508
        case 'G':
509
            env = cpu_gdbstub_get_env(opaque);
510
            registers = (void *)mem_buf;
511
            len = strlen(p) / 2;
512
            hextomem((uint8_t *)registers, p, len);
513
            cpu_gdb_write_registers(env, mem_buf, len);
514
            put_packet("OK");
515
            break;
516
        case 'm':
517
            addr = strtoul(p, (char **)&p, 16);
518
            if (*p == ',')
519
                p++;
520
            len = strtoul(p, NULL, 16);
521
            if (memory_rw(mem_buf, addr, len, 0) != 0)
522
                memset(mem_buf, 0, len);
523
            memtohex(buf, mem_buf, len);
524
            put_packet(buf);
525
            break;
526
        case 'M':
527
            addr = strtoul(p, (char **)&p, 16);
528
            if (*p == ',')
529
                p++;
530
            len = strtoul(p, (char **)&p, 16);
531
            if (*p == ',')
532
                p++;
533
            hextomem(mem_buf, p, len);
534
            if (memory_rw(mem_buf, addr, len, 1) != 0)
535
                put_packet("ENN");
536
            else
537
                put_packet("OK");
538
            break;
539
        case 'Z':
540
            type = strtoul(p, (char **)&p, 16);
541
            if (*p == ',')
542
                p++;
543
            addr = strtoul(p, (char **)&p, 16);
544
            if (*p == ',')
545
                p++;
546
            len = strtoul(p, (char **)&p, 16);
547
            if (type == 0 || type == 1) {
548
                env = cpu_gdbstub_get_env(opaque);
549
                if (cpu_breakpoint_insert(env, addr) < 0)
550
                    goto breakpoint_error;
551
                put_packet("OK");
552
            } else {
553
            breakpoint_error:
554
                put_packet("ENN");
555
            }
556
            break;
557
        case 'z':
558
            type = strtoul(p, (char **)&p, 16);
559
            if (*p == ',')
560
                p++;
561
            addr = strtoul(p, (char **)&p, 16);
562
            if (*p == ',')
563
                p++;
564
            len = strtoul(p, (char **)&p, 16);
565
            if (type == 0 || type == 1) {
566
                env = cpu_gdbstub_get_env(opaque);
567
                cpu_breakpoint_remove(env, addr);
568
                put_packet("OK");
569
            } else {
570
                goto breakpoint_error;
571
            }
572
            break;
573
        case 'Q':
574
            if (!strncmp(p, "Tinit", 5)) {
575
                /* init traces */
576
                put_packet("OK");
577
            } else if (!strncmp(p, "TStart", 6)) {
578
                /* start log (gdb 'tstart' command) */
579
                env = cpu_gdbstub_get_env(opaque);
580
                tb_flush(env);
581
                cpu_set_log(CPU_LOG_ALL);
582
                put_packet("OK");
583
            } else if (!strncmp(p, "TStop", 5)) {
584
                /* stop log (gdb 'tstop' command) */
585
                cpu_set_log(0);
586
                put_packet("OK");
587
            } else {
588
                goto unknown_command;
589
            }
590
            break;
591
        default:
592
        unknown_command:
593
            /* put empty packet */
594
            buf[0] = '\0';
595
            put_packet(buf);
596
            break;
597
        }
598
    }
599
    return 0;
600
}