Subversion Repositories HelenOS

Rev

Rev 3386 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3386 Rev 4153
Line 33... Line 33...
33
 */
33
 */
34
 
34
 
35
#include <arch/debugger.h>
35
#include <arch/debugger.h>
36
#include <console/kconsole.h>
36
#include <console/kconsole.h>
37
#include <console/cmd.h>
37
#include <console/cmd.h>
38
#include <symtab.h>
-
 
39
#include <print.h>
38
#include <print.h>
40
#include <panic.h>
39
#include <panic.h>
41
#include <interrupt.h>
40
#include <interrupt.h>
42
#include <arch/asm.h>
41
#include <arch/asm.h>
43
#include <arch/cpu.h>
42
#include <arch/cpu.h>
44
#include <debug.h>
43
#include <debug.h>
45
#include <func.h>
44
#include <func.h>
46
#include <smp/ipi.h>
45
#include <smp/ipi.h>
-
 
46
#include <symtab.h>
47
 
47
 
48
typedef struct  {
48
typedef struct  {
49
    uintptr_t address;      /**< Breakpoint address */
49
    uintptr_t address;      /**< Breakpoint address */
50
    int flags;              /**< Flags regarding breakpoint */
50
    int flags;              /**< Flags regarding breakpoint */
51
    int counter;            /**< How many times the exception occured */
51
    int counter;            /**< How many times the exception occured */
52
} bpinfo_t;
52
} bpinfo_t;
53
 
53
 
54
static bpinfo_t breakpoints[BKPOINTS_MAX];
54
static bpinfo_t breakpoints[BKPOINTS_MAX];
55
SPINLOCK_INITIALIZE(bkpoint_lock);
55
SPINLOCK_INITIALIZE(bkpoint_lock);
56
 
56
 
-
 
57
#ifdef CONFIG_KCONSOLE
-
 
58
 
57
static int cmd_print_breakpoints(cmd_arg_t *argv);
59
static int cmd_print_breakpoints(cmd_arg_t *argv);
58
static cmd_info_t bkpts_info = {
60
static cmd_info_t bkpts_info = {
59
    .name = "bkpts",
61
    .name = "bkpts",
60
    .description = "Print breakpoint table.",
62
    .description = "Print breakpoint table.",
61
    .func = cmd_print_breakpoints,
63
    .func = cmd_print_breakpoints,
62
    .argc = 0,
64
    .argc = 0,
63
};
65
};
64
 
66
 
65
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
-
 
66
 
-
 
67
static int cmd_del_breakpoint(cmd_arg_t *argv);
67
static int cmd_del_breakpoint(cmd_arg_t *argv);
68
static cmd_arg_t del_argv = {
68
static cmd_arg_t del_argv = {
69
    .type = ARG_TYPE_INT
69
    .type = ARG_TYPE_INT
70
};
70
};
71
static cmd_info_t delbkpt_info = {
71
static cmd_info_t delbkpt_info = {
Line 97... Line 97...
97
    .func = cmd_add_breakpoint,
97
    .func = cmd_add_breakpoint,
98
    .argc = 1,
98
    .argc = 1,
99
    .argv = &addw_argv
99
    .argv = &addw_argv
100
};
100
};
101
 
101
 
102
#endif
-
 
103
 
-
 
104
/** Print table of active breakpoints */
-
 
105
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
-
 
106
{
-
 
107
    unsigned int i;
-
 
108
    char *symbol;
-
 
109
 
-
 
110
#ifdef __32_BITS__  
102
#endif /* CONFIG_KCONSOLE */
111
    printf("#  Count Address    In symbol\n");
-
 
112
    printf("-- ----- ---------- ---------\n");
-
 
113
#endif
-
 
114
 
-
 
115
#ifdef __64_BITS__
-
 
116
    printf("#  Count Address            In symbol\n");
-
 
117
    printf("-- ----- ------------------ ---------\n");
-
 
118
#endif
-
 
119
   
-
 
120
    for (i = 0; i < BKPOINTS_MAX; i++)
-
 
121
        if (breakpoints[i].address) {
-
 
122
            symbol = get_symtab_entry(breakpoints[i].address);
-
 
123
 
-
 
124
#ifdef __32_BITS__
-
 
125
            printf("%-2u %-5d %#10zx %s\n", i,
-
 
126
                breakpoints[i].counter, breakpoints[i].address,
-
 
127
                symbol);
-
 
128
#endif
-
 
129
 
-
 
130
#ifdef __64_BITS__
-
 
131
            printf("%-2u %-5d %#18zx %s\n", i,
-
 
132
                breakpoints[i].counter, breakpoints[i].address,
-
 
133
                symbol);
-
 
134
#endif
-
 
135
 
-
 
136
        }
-
 
137
    return 1;
-
 
138
}
-
 
139
 
103
 
140
/* Setup DR register according to table */
104
/* Setup DR register according to table */
141
static void setup_dr(int curidx)
105
static void setup_dr(int curidx)
142
{
106
{
143
    unative_t dr7;
107
    unative_t dr7;
Line 235... Line 199...
235
    spinlock_unlock(&bkpoint_lock);
199
    spinlock_unlock(&bkpoint_lock);
236
    interrupts_restore(ipl);
200
    interrupts_restore(ipl);
237
 
201
 
238
    /* Send IPI */
202
    /* Send IPI */
239
#ifdef CONFIG_SMP
203
#ifdef CONFIG_SMP
240
//  ipi_broadcast(VECTOR_DEBUG_IPI);    
204
//  ipi_broadcast(VECTOR_DEBUG_IPI);
241
#endif  
205
#endif  
242
 
206
 
243
    return curidx;
207
    return curidx;
244
}
208
}
245
 
209
 
246
#ifdef amd64
210
#ifdef __64_BITS__
247
#   define getip(x) ((x)->rip)
211
    #define getip(x)  ((x)->rip)
248
#else
212
#else
249
#   define getip(x) ((x)->eip)
213
    #define getip(x)  ((x)->eip)
250
#endif
214
#endif
251
 
215
 
252
static void handle_exception(int slot, istate_t *istate)
216
static void handle_exception(int slot, istate_t *istate)
253
{
217
{
254
    ASSERT(breakpoints[slot].address);
218
    ASSERT(breakpoints[slot].address);
Line 263... Line 227...
263
        } else {
227
        } else {
264
            printf("Data watchpoint - new data: %lx\n",
228
            printf("Data watchpoint - new data: %lx\n",
265
                *((unative_t *) breakpoints[slot].address));
229
                *((unative_t *) breakpoints[slot].address));
266
        }
230
        }
267
    }
231
    }
-
 
232
 
268
    printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate),
233
    printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
269
        get_symtab_entry(getip(istate)));
234
        symtab_fmt_name_lookup(getip(istate)));
-
 
235
 
270
    printf("***Type 'exit' to exit kconsole.\n");
236
#ifdef CONFIG_KCONSOLE
271
    atomic_set(&haltstate,1);
237
    atomic_set(&haltstate, 1);
272
    kconsole((void *) "debug");
238
    kconsole("debug", "Debug console ready.\n", false);
273
    atomic_set(&haltstate,0);
239
    atomic_set(&haltstate, 0);
-
 
240
#endif
274
}
241
}
275
 
242
 
276
void breakpoint_del(int slot)
243
void breakpoint_del(int slot)
277
{
244
{
278
    bpinfo_t *cur;
245
    bpinfo_t *cur;
Line 297... Line 264...
297
#ifdef CONFIG_SMP
264
#ifdef CONFIG_SMP
298
//  ipi_broadcast(VECTOR_DEBUG_IPI);    
265
//  ipi_broadcast(VECTOR_DEBUG_IPI);    
299
#endif
266
#endif
300
}
267
}
301
 
268
 
302
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
-
 
303
 
269
 
304
/** Remove breakpoint from table */
-
 
305
int cmd_del_breakpoint(cmd_arg_t *argv)
-
 
306
{
-
 
307
    unative_t bpno = argv->intval;
-
 
308
    if (bpno > BKPOINTS_MAX) {
-
 
309
        printf("Invalid breakpoint number.\n");
-
 
310
        return 0;
-
 
311
    }
-
 
312
    breakpoint_del(argv->intval);
-
 
313
    return 1;
-
 
314
}
-
 
315
 
-
 
316
/** Add new breakpoint to table */
-
 
317
static int cmd_add_breakpoint(cmd_arg_t *argv)
-
 
318
{
-
 
319
    int flags;
-
 
320
    int id;
-
 
321
 
-
 
322
    if (argv == &add_argv) {
-
 
323
        flags = BKPOINT_INSTR;
-
 
324
    } else { /* addwatchp */
-
 
325
        flags = BKPOINT_WRITE;
-
 
326
    }
-
 
327
    printf("Adding breakpoint on address: %p\n", argv->intval);
-
 
328
    id = breakpoint_add((void *)argv->intval, flags, -1);
-
 
329
    if (id < 0)
-
 
330
        printf("Add breakpoint failed.\n");
-
 
331
    else
-
 
332
        printf("Added breakpoint %d.\n", id);
-
 
333
   
-
 
334
    return 1;
-
 
335
}
-
 
336
#endif
-
 
337
 
270
 
338
static void debug_exception(int n __attribute__((unused)), istate_t *istate)
271
static void debug_exception(int n __attribute__((unused)), istate_t *istate)
339
{
272
{
340
    unative_t dr6;
273
    unative_t dr6;
341
    int i;
274
    int i;
342
   
275
   
343
    /* Set RF to restart the instruction  */
276
    /* Set RF to restart the instruction  */
344
#ifdef amd64       
277
#ifdef __64_BITS__
345
    istate->rflags |= RFLAGS_RF;
278
    istate->rflags |= RFLAGS_RF;
346
#else
279
#else
347
    istate->eflags |= EFLAGS_RF;
280
    istate->eflags |= EFLAGS_RF;
348
#endif
281
#endif
349
 
282
 
Line 377... Line 310...
377
{
310
{
378
    int i;
311
    int i;
379
 
312
 
380
    for (i = 0; i < BKPOINTS_MAX; i++)
313
    for (i = 0; i < BKPOINTS_MAX; i++)
381
        breakpoints[i].address = NULL;
314
        breakpoints[i].address = NULL;
382
   
315
 
-
 
316
#ifdef CONFIG_KCONSOLE
383
    cmd_initialize(&bkpts_info);
317
    cmd_initialize(&bkpts_info);
384
    if (!cmd_register(&bkpts_info))
318
    if (!cmd_register(&bkpts_info))
385
        panic("could not register command %s\n", bkpts_info.name);
319
        printf("Cannot register command %s\n", bkpts_info.name);
386
 
320
 
387
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
-
 
388
    cmd_initialize(&delbkpt_info);
321
    cmd_initialize(&delbkpt_info);
389
    if (!cmd_register(&delbkpt_info))
322
    if (!cmd_register(&delbkpt_info))
390
        panic("could not register command %s\n", delbkpt_info.name);
323
        printf("Cannot register command %s\n", delbkpt_info.name);
391
 
324
 
392
    cmd_initialize(&addbkpt_info);
325
    cmd_initialize(&addbkpt_info);
393
    if (!cmd_register(&addbkpt_info))
326
    if (!cmd_register(&addbkpt_info))
394
        panic("could not register command %s\n", addbkpt_info.name);
327
        printf("Cannot register command %s\n", addbkpt_info.name);
395
 
328
 
396
    cmd_initialize(&addwatchp_info);
329
    cmd_initialize(&addwatchp_info);
397
    if (!cmd_register(&addwatchp_info))
330
    if (!cmd_register(&addwatchp_info))
398
        panic("could not register command %s\n", addwatchp_info.name);
331
        printf("Cannot register command %s\n", addwatchp_info.name);
399
#endif
332
#endif /* CONFIG_KCONSOLE */
400
   
333
   
401
    exc_register(VECTOR_DEBUG, "debugger", debug_exception);
334
    exc_register(VECTOR_DEBUG, "debugger", debug_exception);
402
#ifdef CONFIG_SMP
335
#ifdef CONFIG_SMP
403
    exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi);
336
    exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi);
404
#endif
337
#endif
405
}
338
}
406
 
339
 
-
 
340
#ifdef CONFIG_KCONSOLE
-
 
341
/** Print table of active breakpoints */
-
 
342
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
-
 
343
{
-
 
344
    unsigned int i;
-
 
345
    char *symbol;
-
 
346
 
-
 
347
#ifdef __32_BITS__
-
 
348
    printf("#  Count Address    In symbol\n");
-
 
349
    printf("-- ----- ---------- ---------\n");
-
 
350
#endif
-
 
351
 
-
 
352
#ifdef __64_BITS__
-
 
353
    printf("#  Count Address            In symbol\n");
-
 
354
    printf("-- ----- ------------------ ---------\n");
-
 
355
#endif
-
 
356
   
-
 
357
    for (i = 0; i < BKPOINTS_MAX; i++)
-
 
358
        if (breakpoints[i].address) {
-
 
359
            symbol = symtab_fmt_name_lookup(
-
 
360
                breakpoints[i].address);
-
 
361
 
-
 
362
#ifdef __32_BITS__
-
 
363
            printf("%-2u %-5d %#10zx %s\n", i,
-
 
364
                breakpoints[i].counter, breakpoints[i].address,
-
 
365
                symbol);
-
 
366
#endif
-
 
367
 
-
 
368
#ifdef __64_BITS__
-
 
369
            printf("%-2u %-5d %#18zx %s\n", i,
-
 
370
                breakpoints[i].counter, breakpoints[i].address,
-
 
371
                symbol);
-
 
372
#endif
-
 
373
 
-
 
374
        }
-
 
375
    return 1;
-
 
376
}
-
 
377
 
-
 
378
/** Remove breakpoint from table */
-
 
379
int cmd_del_breakpoint(cmd_arg_t *argv)
-
 
380
{
-
 
381
    unative_t bpno = argv->intval;
-
 
382
    if (bpno > BKPOINTS_MAX) {
-
 
383
        printf("Invalid breakpoint number.\n");
-
 
384
        return 0;
-
 
385
    }
-
 
386
    breakpoint_del(argv->intval);
-
 
387
    return 1;
-
 
388
}
-
 
389
 
-
 
390
/** Add new breakpoint to table */
-
 
391
static int cmd_add_breakpoint(cmd_arg_t *argv)
-
 
392
{
-
 
393
    int flags;
-
 
394
    int id;
-
 
395
 
-
 
396
    if (argv == &add_argv) {
-
 
397
        flags = BKPOINT_INSTR;
-
 
398
    } else { /* addwatchp */
-
 
399
        flags = BKPOINT_WRITE;
-
 
400
    }
-
 
401
    printf("Adding breakpoint on address: %p\n", argv->intval);
-
 
402
    id = breakpoint_add((void *)argv->intval, flags, -1);
-
 
403
    if (id < 0)
-
 
404
        printf("Add breakpoint failed.\n");
-
 
405
    else
-
 
406
        printf("Added breakpoint %d.\n", id);
-
 
407
   
-
 
408
    return 1;
-
 
409
}
-
 
410
#endif /* CONFIG_KCONSOLE */
-
 
411
 
407
/** @}
412
/** @}
408
 */
413
 */