source: trunk/packages/xen-common/xen-common/xen/common/gdbstub.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 14.3 KB
Line 
1/*
2 * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
3 * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
4 *                    VA Linux Systems Japan. K.K.
5 *
6 * gdbstub arch neutral part
7 * Based on x86 cdb (xen/arch/x86/cdb.c) and ppc gdbstub(xen/common/gdbstub.c)
8 * But extensively modified.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23 */
24
25/*
26 * gdbstub: implements the architecture independant parts of the
27 * gdb remote protocol.
28 */
29
30/* We try to avoid assuming much about what the rest of the system is
31   doing.  In particular, dynamic memory allocation is out of the
32   question. */
33
34/* Resuming after we've stopped used to work, but more through luck
35   than any actual intention.  It doesn't at the moment. */
36
37#include <xen/lib.h>
38#include <xen/spinlock.h>
39#include <xen/serial.h>
40#include <xen/irq.h>
41#include <asm/debugger.h>
42#include <xen/init.h>
43#include <xen/smp.h>
44#include <xen/console.h>
45#include <xen/errno.h>
46
47/* Printk isn't particularly safe just after we've trapped to the
48   debugger. so avoid it. */
49#define dbg_printk(...)
50/*#define dbg_printk(...)   printk(__VA_ARGS__)*/
51
52#define GDB_RETRY_MAX   10
53
54static char opt_gdb[30] = "none";
55string_param("gdb", opt_gdb);
56
57static void gdbstub_console_puts(const char *str);
58
59/* value <-> char (de)serialzers */
60char
61hex2char(unsigned long x)
62{
63    const char array[] = "0123456789abcdef";
64
65    return array[x & 15];
66}
67
68int
69char2hex(unsigned char c)
70{
71    if ( (c >= '0') && (c <= '9') )
72        return c - '0';
73    else if ( (c >= 'a') && (c <= 'f') )
74        return c - 'a' + 10;
75    else if ( (c >= 'A') && (c <= 'F') )
76        return c - 'A' + 10;
77    else
78        BUG();
79    return -1;
80}
81
82char
83str2hex(const char *str)
84{
85    return (char2hex(str[0]) << 4) | char2hex(str[1]);
86}
87
88unsigned long
89str2ulong(const char *str, unsigned long bytes)
90{
91    unsigned long x = 0;
92    unsigned long i = 0;
93
94    while ( *str && (i < (bytes * 2)) )
95    {
96        x <<= 4;
97        x += char2hex(*str);
98        ++str;
99        ++i;
100    }
101
102    return x;
103}
104
105/* gdb io wrappers */
106static signed long
107gdb_io_write(const char *buf, unsigned long len, struct gdb_context *ctx)
108{
109    int i;
110    for ( i = 0; i < len; i++ )
111        serial_putc(ctx->serhnd, buf[i]);
112    return i;
113}
114
115static int
116gdb_io_write_char(u8 data, struct gdb_context *ctx)
117{
118    return gdb_io_write((char*)&data, 1, ctx);
119}
120
121static unsigned char
122gdb_io_read(struct gdb_context *ctx)
123{
124    return serial_getc(ctx->serhnd);
125}
126
127/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
128/* Does not acknowledge. */
129static int 
130attempt_receive_packet(struct gdb_context *ctx)
131{
132    u8 csum;
133    u8 received_csum;
134    u8 ch;
135
136    /* Skip over everything up to the first '$' */
137    while ( (ch = gdb_io_read(ctx)) != '$' )
138        continue;
139
140    csum = 0;
141    for ( ctx->in_bytes = 0;
142          ctx->in_bytes < sizeof(ctx->in_buf);
143          ctx->in_bytes++ )
144    {
145        ch = gdb_io_read(ctx);
146        if ( ch == '#' )
147            break;
148        ctx->in_buf[ctx->in_bytes] = ch;
149        csum += ch;
150    }
151
152    if ( ctx->in_bytes == sizeof(ctx->in_buf) )
153    {
154        dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
155        return -1;
156    }
157
158    ctx->in_buf[ctx->in_bytes] = '\0';
159    received_csum = char2hex(gdb_io_read(ctx)) * 16 +
160        char2hex(gdb_io_read(ctx));
161
162    return (received_csum == csum) ? 0 : -1;
163}
164
165/* Receive a command, discarding up to ten packets with csum
166 * errors.  Acknowledges all received packets. */
167static int 
168receive_command(struct gdb_context *ctx)
169{
170    int r, count = 0;
171
172    count = 0;
173    do {
174        r = attempt_receive_packet(ctx);
175        gdb_io_write_char((r < 0) ? '-' : '+', ctx);
176        count++;
177    } while ( (r < 0) && (count < GDB_RETRY_MAX) );
178
179    return r;
180}
181
182/* routines to send reply packets */
183
184static void 
185gdb_start_packet(struct gdb_context *ctx)
186{
187    ctx->out_buf[0] = '$';
188    ctx->out_offset = 1;
189    ctx->out_csum = 0;
190}
191
192static void 
193gdb_write_to_packet_char(u8 data, struct gdb_context *ctx)
194{
195    ctx->out_csum += data;
196    ctx->out_buf[ctx->out_offset] = data;
197    ctx->out_offset++;
198}
199
200void 
201gdb_write_to_packet(const char *buf, int count, struct gdb_context *ctx)
202{
203    int x;
204    for ( x = 0; x < count; x++ )
205        gdb_write_to_packet_char(buf[x], ctx);
206}
207
208void 
209gdb_write_to_packet_str(const char *buf, struct gdb_context *ctx)
210{
211    gdb_write_to_packet(buf, strlen(buf), ctx);
212}
213
214void
215gdb_write_to_packet_hex(unsigned long x, int int_size, struct gdb_context *ctx)
216{
217    char buf[sizeof(unsigned long) * 2 + 1];
218    int i = sizeof(unsigned long) * 2;
219    int width = int_size * 2;
220
221    buf[sizeof(unsigned long) * 2] = 0;
222
223    switch ( int_size )
224    {
225    case sizeof(u8):
226    case sizeof(u16):
227    case sizeof(u32):
228    case sizeof(u64):
229        break;
230    default:
231        dbg_printk("WARNING: %s x: 0x%lx int_size: %d\n",
232                   __func__, x, int_size);
233        break;
234    }
235
236    do {
237        buf[--i] = hex2char(x & 15);
238        x >>= 4;
239    } while ( x );
240
241    while ( (i + width) > (sizeof(unsigned long) * 2) )
242        buf[--i] = '0';
243
244    gdb_write_to_packet(&buf[i], width, ctx);
245}
246
247static int
248gdb_check_ack(struct gdb_context *ctx)
249{
250    u8 c = gdb_io_read(ctx);
251
252    switch ( c )
253    {
254    case '+':
255        return 1;
256    case '-':
257        return 0;
258    default:
259        printk("Bad ack: %c\n", c);
260        return 0;
261    }
262}
263
264/* Return 0 if the reply was successfully received, !0 otherwise. */
265void 
266gdb_send_packet(struct gdb_context *ctx)
267{
268    char buf[3];
269    int count;
270
271    snprintf(buf, sizeof(buf), "%.02x\n", ctx->out_csum);
272
273    gdb_write_to_packet_char('#', ctx);
274    gdb_write_to_packet(buf, 2, ctx);
275
276    count = 0;
277    do {
278        gdb_io_write(ctx->out_buf, ctx->out_offset, ctx);
279    } while ( !gdb_check_ack(ctx) && (count++ < GDB_RETRY_MAX) );
280
281    if ( count == GDB_RETRY_MAX )
282        dbg_printk("WARNING: %s reached max retry %d\n",
283                   __func__, GDB_RETRY_MAX);
284}
285
286void 
287gdb_send_reply(const char *buf, struct gdb_context *ctx)
288{
289    gdb_start_packet(ctx);
290    gdb_write_to_packet_str(buf, ctx);
291    gdb_send_packet(ctx);
292}
293
294/* arch neutral command handlers */
295
296static void 
297gdb_cmd_signum(struct gdb_context *ctx)
298{
299    gdb_write_to_packet_char('S', ctx);
300    gdb_write_to_packet_hex(ctx->signum, sizeof(ctx->signum), ctx);
301    gdb_send_packet(ctx);
302}
303
304static void 
305gdb_cmd_read_mem(unsigned long addr, unsigned long length,
306                 struct gdb_context *ctx)
307{
308    int x, r;
309    unsigned char val;
310
311    dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
312               length);
313
314    for ( x = 0; x < length; x++ )
315    {
316        r = gdb_arch_copy_from_user(&val, (void *)(addr + x), 1);
317        if ( r != 0 )
318        {
319            dbg_printk("Error reading from %lx.\n", addr + x);
320            break;
321        }
322        gdb_write_to_packet_hex(val, sizeof(val), ctx);
323    }
324
325    if ( x == 0 )
326        gdb_write_to_packet_str("E05", ctx);
327
328    dbg_printk("Read done.\n");
329
330    gdb_send_packet(ctx);
331}
332
333static void 
334gdb_cmd_write_mem(unsigned long addr, unsigned long length,
335                  const char *buf, struct gdb_context *ctx)
336{
337    int x, r;
338    unsigned char val;
339
340    dbg_printk("Memory write starting at %lx, length %lx.\n", addr, length);
341
342    for ( x = 0; x < length; x++, addr++, buf += 2 )
343    {
344        val = str2ulong(buf, sizeof(val));
345        r = gdb_arch_copy_to_user((void*)addr, (void*)&val, 1);
346        if ( r != 0 )
347        {
348            dbg_printk("Error writing to %lx.\n", addr);
349            break;
350        }
351    }
352
353    if (x == length)
354        gdb_write_to_packet_str("OK", ctx);
355    else
356        gdb_write_to_packet_str("E11", ctx);
357
358    dbg_printk("Write done.\n");
359
360    gdb_send_packet(ctx);
361}
362
363static void
364gdbstub_attach(struct gdb_context *ctx)
365{
366    if ( ctx->currently_attached )
367        return;   
368    ctx->currently_attached = 1;
369    ctx->console_steal_id = console_steal(ctx->serhnd, gdbstub_console_puts);
370}
371
372static void
373gdbstub_detach(struct gdb_context *ctx)
374{
375    if ( !ctx->currently_attached )
376        return;
377    ctx->currently_attached = 0;
378    console_giveback(ctx->console_steal_id);
379}
380
381/* command dispatcher */
382static int 
383process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
384{
385    const char *ptr;
386    unsigned long addr, length;
387    int resume = 0;
388
389    /* XXX check ctx->in_bytes >= 2 or similar. */
390
391    gdb_start_packet(ctx);
392    switch ( ctx->in_buf[0] )
393    {
394    case '?':    /* query signal number */
395        gdb_cmd_signum(ctx);
396        break;
397    case 'H':    /* thread operations */
398        gdb_send_reply("OK", ctx);
399        break;
400    case 'g': /* Read registers */
401        gdb_arch_read_reg_array(regs, ctx);
402        break;
403    case 'G': /* Write registers */
404        gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
405        break;
406    case 'm': /* Read memory */
407        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
408        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
409        {
410            gdb_send_reply("E03", ctx);
411            return 0;
412        }
413        length = simple_strtoul(ptr + 1, &ptr, 16);
414        if ( ptr[0] != 0 )
415        {
416            gdb_send_reply("E04", ctx);
417            return 0;
418        }
419        gdb_cmd_read_mem(addr, length, ctx);
420        break;
421    case 'M': /* Write memory */
422        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
423        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
424        {
425            gdb_send_reply("E03", ctx);
426            return 0;
427        }
428        length = simple_strtoul(ptr + 1, &ptr, 16);
429        if ( ptr[0] != ':')
430        {
431            gdb_send_reply("E04", ctx);
432            return 0;
433        }
434        gdb_cmd_write_mem(addr, length, ptr + 1, ctx);
435        break;
436    case 'p': /* read register */
437        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
438        if ( ptr == (ctx->in_buf + 1) )
439        {
440            gdb_send_reply("E03", ctx);
441            return 0;
442        }
443        if ( ptr[0] != 0 )
444        {
445            gdb_send_reply("E04", ctx);
446            return 0;
447        }
448        gdb_arch_read_reg(addr, regs, ctx);
449        break;
450    case 'D':
451        gdbstub_detach(ctx);
452        gdb_send_reply("OK", ctx);
453        /* fall through */
454    case 'k':
455        ctx->connected = 0;
456        /* fall through */
457    case 's': /* Single step */
458    case 'c': /* Resume at current address */
459    {
460        unsigned long addr = ~((unsigned long)0);
461        unsigned long type = GDB_CONTINUE;
462        if ( ctx->in_buf[0] == 's' )
463            type = GDB_STEP;
464        if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
465             ctx->in_buf[1] )
466            addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
467        if ( ctx->in_buf[0] != 'D' )
468            gdbstub_attach(ctx);
469        resume = 1;
470        gdb_arch_resume(regs, addr, type, ctx);
471        break;
472    }
473
474    default:
475        gdb_send_reply("", ctx);
476        break;
477    }
478    return resume;
479}
480
481static struct gdb_context
482__gdb_ctx = {
483    .serhnd  = -1,
484    .running = ATOMIC_INIT(1),
485    .signum  = 1
486};
487static struct gdb_context *gdb_ctx = &__gdb_ctx;
488
489static void
490gdbstub_console_puts(const char *str)
491{
492    const char *p;
493
494    gdb_start_packet(gdb_ctx);
495    gdb_write_to_packet_char('O', gdb_ctx);
496
497    for ( p = str; *p != '\0'; p++ )
498    {
499        gdb_write_to_packet_char(hex2char((*p>>4) & 0x0f), gdb_ctx );
500        gdb_write_to_packet_char(hex2char((*p) & 0x0f), gdb_ctx );
501    }
502
503    gdb_send_packet(gdb_ctx);
504}
505
506/* trap handler: main entry point */
507int 
508__trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
509{
510    int rc = 0;
511    unsigned long flags;
512
513    if ( gdb_ctx->serhnd < 0 )
514    {
515        dbg_printk("Debugger not ready yet.\n");
516        return -EBUSY;
517    }
518
519    /* We rely on our caller to ensure we're only on one processor
520     * at a time... We should probably panic here, but given that
521     * we're a debugger we should probably be a little tolerant of
522     * things going wrong. */
523    /* We don't want to use a spin lock here, because we're doing
524       two distinct things:
525
526       1 -- we don't want to run on more than one processor at a time,
527            and
528       2 -- we want to do something sensible if we re-enter ourselves.
529
530       Spin locks are good for 1, but useless for 2. */
531    if ( !atomic_dec_and_test(&gdb_ctx->running) )
532    {
533        printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
534        atomic_inc(&gdb_ctx->running);
535        return -EBUSY;
536    }
537
538    if ( !gdb_ctx->connected )
539    {
540        printk("GDB connection activated.\n");
541        gdb_arch_print_state(regs);
542        gdb_ctx->connected = 1;
543    }
544
545    smp_send_stop();
546
547    /* Try to make things a little more stable by disabling
548       interrupts while we're here. */
549    local_irq_save(flags);
550
551    watchdog_disable();
552    console_start_sync();
553
554    /* Shouldn't really do this, but otherwise we stop for no
555       obvious reason, which is Bad */
556    printk("Waiting for GDB to attach...\n");
557
558    gdb_arch_enter(regs);
559    gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
560
561    /* If gdb is already attached, tell it we've stopped again. */
562    if ( gdb_ctx->currently_attached )
563    {
564        gdb_start_packet(gdb_ctx);
565        gdb_cmd_signum(gdb_ctx);
566    }
567
568    do {
569        if ( receive_command(gdb_ctx) < 0 )
570        {
571            dbg_printk("Error in GDB session...\n");
572            rc = -EIO;
573            break;
574        }
575    } while ( process_command(regs, gdb_ctx) == 0 );
576
577    gdb_arch_exit(regs);
578    console_end_sync();
579    watchdog_enable();
580    atomic_inc(&gdb_ctx->running);
581
582    local_irq_restore(flags);
583
584    return rc;
585}
586
587void
588initialise_gdb(void)
589{
590    gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
591    if ( gdb_ctx->serhnd != -1 )
592        printk("GDB stub initialised.\n");
593    serial_start_sync(gdb_ctx->serhnd);
594}
595
596/*
597 * Local variables:
598 * mode: C
599 * c-set-style: "BSD"
600 * c-basic-offset: 4
601 * tab-width: 4
602 * End:
603 */
Note: See TracBrowser for help on using the repository browser.