diff options
| author | Roger Pau Monné <royger@FreeBSD.org> | 2014-09-25 08:28:10 +0000 |
|---|---|---|
| committer | Roger Pau Monné <royger@FreeBSD.org> | 2014-09-25 08:28:10 +0000 |
| commit | c98a2727cc0905d5b478b577668222e8d5d32e81 (patch) | |
| tree | 3abf237e04642b4e670e2e2b0e6e7072f1ee5524 /sys/ddb | |
| parent | 5af6947046740202e589436161d76190377f8f90 (diff) | |
Notes
Diffstat (limited to 'sys/ddb')
| -rw-r--r-- | sys/ddb/db_main.c | 48 | ||||
| -rw-r--r-- | sys/ddb/ddb.h | 8 |
2 files changed, 42 insertions, 14 deletions
diff --git a/sys/ddb/db_main.c b/sys/ddb/db_main.c index 6e9286cbc1c1..bee321cc34ed 100644 --- a/sys/ddb/db_main.c +++ b/sys/ddb/db_main.c @@ -56,7 +56,12 @@ static dbbe_trace_thread_f db_trace_thread_wrapper; KDB_BACKEND(ddb, db_init, db_trace_self_wrapper, db_trace_thread_wrapper, db_trap); -vm_offset_t ksym_start, ksym_end; +/* + * Symbols can be loaded by specifying the exact addresses of + * the symtab and strtab in memory. This is used when loaded from + * boot loaders different than the native one (like Xen). + */ +vm_offset_t ksymtab, kstrtab, ksymtab_size; boolean_t X_db_line_at_pc(db_symtab_t *symtab, c_db_sym_t sym, char **file, int *line, @@ -168,24 +173,39 @@ X_db_symbol_values(db_symtab_t *symtab, c_db_sym_t sym, const char **namep, } } +int +db_fetch_ksymtab(vm_offset_t ksym_start, vm_offset_t ksym_end) +{ + Elf_Size strsz; + + if (ksym_end > ksym_start && ksym_start != 0) { + ksymtab = ksym_start; + ksymtab_size = *(Elf_Size*)ksymtab; + ksymtab += sizeof(Elf_Size); + kstrtab = ksymtab + ksymtab_size; + strsz = *(Elf_Size*)kstrtab; + kstrtab += sizeof(Elf_Size); + if (kstrtab + strsz > ksym_end) { + /* Sizes doesn't match, unset everything. */ + ksymtab = ksymtab_size = kstrtab = 0; + } + } + + if (ksymtab == 0 || ksymtab_size == 0 || kstrtab == 0) + return (-1); + + return (0); +} + static int db_init(void) { - uintptr_t symtab, strtab; - Elf_Size tabsz, strsz; db_command_init(); - if (ksym_end > ksym_start && ksym_start != 0) { - symtab = ksym_start; - tabsz = *((Elf_Size*)symtab); - symtab += sizeof(Elf_Size); - strtab = symtab + tabsz; - strsz = *((Elf_Size*)strtab); - strtab += sizeof(Elf_Size); - if (strtab + strsz <= ksym_end) { - db_add_symbol_table((char *)symtab, - (char *)(symtab + tabsz), "elf", (char *)strtab); - } + + if (ksymtab != 0 && kstrtab != 0 && ksymtab_size != 0) { + db_add_symbol_table((char *)ksymtab, + (char *)(ksymtab + ksymtab_size), "elf", (char *)kstrtab); } db_add_symbol_table(NULL, NULL, "kld", NULL); return (1); /* We're the default debugger. */ diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h index 42fc9025954f..5aa646b3302a 100644 --- a/sys/ddb/ddb.h +++ b/sys/ddb/ddb.h @@ -77,6 +77,13 @@ int DB_CALL(db_expr_t, db_expr_t *, int, db_expr_t[]); #endif /* + * Extern variables to set the address and size of the symtab and strtab. + * Most users should use db_fetch_symtab in order to set them from the + * boot loader provided values. + */ +extern vm_offset_t ksymtab, kstrtab, ksymtab_size; + +/* * There are three "command tables": * - One for simple commands; a list of these is displayed * by typing 'help' at the debugger prompt. @@ -218,6 +225,7 @@ int db_value_of_name_vnet(const char *name, db_expr_t *valuep); int db_write_bytes(vm_offset_t addr, size_t size, char *data); void db_command_register(struct command_table *, struct command *); void db_command_unregister(struct command_table *, struct command *); +int db_fetch_ksymtab(vm_offset_t ksym_start, vm_offset_t ksym_end); db_cmdfcn_t db_breakpoint_cmd; db_cmdfcn_t db_capture_cmd; |
