aboutsummaryrefslogtreecommitdiff
path: root/sys/ddb
diff options
context:
space:
mode:
authorRoger Pau Monné <royger@FreeBSD.org>2014-09-25 08:28:10 +0000
committerRoger Pau Monné <royger@FreeBSD.org>2014-09-25 08:28:10 +0000
commitc98a2727cc0905d5b478b577668222e8d5d32e81 (patch)
tree3abf237e04642b4e670e2e2b0e6e7072f1ee5524 /sys/ddb
parent5af6947046740202e589436161d76190377f8f90 (diff)
Notes
Diffstat (limited to 'sys/ddb')
-rw-r--r--sys/ddb/db_main.c48
-rw-r--r--sys/ddb/ddb.h8
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;