diff options
author | royger <royger@FreeBSD.org> | 2014-09-25 08:28:10 +0000 |
---|---|---|
committer | royger <royger@FreeBSD.org> | 2014-09-25 08:28:10 +0000 |
commit | 494dc32ba6c0d7c44aa6018743e2880806f0da3d (patch) | |
tree | 3abf237e04642b4e670e2e2b0e6e7072f1ee5524 /sys/ddb | |
parent | fe82580e96f90207d8231ebbe1c9f7fbf5f2e04b (diff) | |
download | FreeBSD-src-494dc32ba6c0d7c44aa6018743e2880806f0da3d.zip FreeBSD-src-494dc32ba6c0d7c44aa6018743e2880806f0da3d.tar.gz |
ddb: allow specifying the exact address of the symtab and strtab
When the FreeBSD kernel is loaded from Xen the symtab and strtab are
not loaded the same way as the native boot loader. This patch adds
three new global variables to ddb that can be used to specify the
exact position and size of those tables, so they can be directly used
as parameters to db_add_symbol_table. A new helper is introduced, so callers
that used to set ksym_start and ksym_end can use this helper to set the new
variables.
It also adds support for loading them from the Xen PVH port, that was
previously missing those tables.
Sponsored by: Citrix Systems R&D
Reviewed by: kib
ddb/db_main.c:
- Add three new global variables: ksymtab, kstrtab, ksymtab_size that
can be used to specify the position and size of the symtab and
strtab.
- Use those new variables in db_init in order to call db_add_symbol_table.
- Move the logic in db_init to db_fetch_symtab in order to set ksymtab,
kstrtab, ksymtab_size from ksym_start and ksym_end.
ddb/ddb.h:
- Add prototype for db_fetch_ksymtab.
- Declate the extern variables ksymtab, kstrtab and ksymtab_size.
x86/xen/pv.c:
- Add support for finding the symtab and strtab when booted as a Xen
PVH guest. Since Xen loads the symtab and strtab as NetBSD expects
to find them we have to adapt and use the same method.
amd64/amd64/machdep.c:
arm/arm/machdep.c:
i386/i386/machdep.c:
mips/mips/machdep.c:
pc98/pc98/machdep.c:
powerpc/aim/machdep.c:
powerpc/booke/machdep.c:
sparc64/sparc64/machdep.c:
- Use the newly introduced db_fetch_ksymtab in order to set ksymtab,
kstrtab and ksymtab_size.
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 6e9286c..bee321c 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 42fc902..5aa646b 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; |