summaryrefslogtreecommitdiff
path: root/sys/ddb/db_sym.c
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>2001-02-10 10:43:19 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>2001-02-10 10:43:19 +0000
commit5bfde2c9bd95671842fedd8d95bf23e072278fb3 (patch)
tree1abbcb3d3f121b6be953ef37a37676a20a6446cc /sys/ddb/db_sym.c
parent5e833b12704c89c1fad72b7b6f3706cfd15ab035 (diff)
new symbol handling in ddb for ELF, there is still a problem with hangman on alpha though..
Diffstat (limited to 'sys/ddb/db_sym.c')
-rw-r--r--sys/ddb/db_sym.c484
1 files changed, 364 insertions, 120 deletions
diff --git a/sys/ddb/db_sym.c b/sys/ddb/db_sym.c
index 0cf3ed052e6..0b4840c5304 100644
--- a/sys/ddb/db_sym.c
+++ b/sys/ddb/db_sym.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: db_sym.c,v 1.21 1997/07/19 22:31:20 niklas Exp $ */
-/* $NetBSD: db_sym.c,v 1.12 1996/02/05 01:57:15 christos Exp $ */
+/* $OpenBSD: db_sym.c,v 1.22 2001/02/10 10:42:35 niklas Exp $ */
+/* $NetBSD: db_sym.c,v 1.24 2000/08/11 22:50:47 tv Exp $ */
/*
* Mach Operating System
@@ -29,13 +29,11 @@
#include <sys/param.h>
#include <sys/proc.h>
-#include <sys/malloc.h>
#include <sys/systm.h>
-#include <vm/vm.h>
-
#include <machine/db_machdep.h>
+#include <ddb/db_lex.h>
#include <ddb/db_sym.h>
#include <ddb/db_output.h>
#include <ddb/db_extern.h>
@@ -44,47 +42,141 @@
/*
* Multiple symbol tables
*/
-static TAILQ_HEAD(, db_symtab) db_symtabs;
-static struct db_symtab db_sym_kernel;
-size_t db_nsymtabs = 0;
+#ifndef MAXLKMS
+#define MAXLKMS 20
+#endif
+
+#ifndef MAXNOSYMTABS
+#define MAXNOSYMTABS MAXLKMS+1 /* Room for kernel + LKM's */
+#endif
+
+db_symtab_t db_symtabs[MAXNOSYMTABS] = {{0,},};
-db_symtab_t db_last_symtab;
+db_symtab_t *db_last_symtab;
+
+static db_forall_func_t db_sift;
/*
- * Init sym module
+ * Put the most picky symbol table formats at the top!
*/
+const db_symformat_t *db_symformats[] = {
+#ifdef DB_ELF_SYMBOLS
+ &db_symformat_elf,
+#endif
+#ifdef DB_AOUT_SYMBOLS
+ &db_symformat_aout,
+#endif
+ NULL,
+};
+
+const db_symformat_t *db_symformat;
+
+boolean_t X_db_sym_init __P((int, void *, void *, const char *));
+db_sym_t X_db_lookup __P((db_symtab_t *, char *));
+db_sym_t X_db_search_symbol __P((db_symtab_t *, db_addr_t,
+ db_strategy_t, db_expr_t *));
+void X_db_symbol_values __P((db_symtab_t *, db_sym_t, char **,
+ db_expr_t *));
+boolean_t X_db_line_at_pc __P((db_symtab_t *, db_sym_t, char **,
+ int *, db_expr_t));
+int X_db_sym_numargs __P((db_symtab_t *, db_sym_t, int *,
+ char **));
+
+/*
+ * Initialize the kernel debugger by initializing the master symbol
+ * table. Note that if initializing the master symbol table fails,
+ * no other symbol tables can be loaded.
+ */
+#if 0
void
-db_sym_init(void)
+ddb_init(symsize, vss, vse)
+ int symsize;
+ void *vss, *vse;
{
- TAILQ_INIT(&db_symtabs);
+ const db_symformat_t **symf;
+ const char *name = "bsd";
+
+ if (symsize <= 0) {
+ printf(" [ no symbols available ]\n");
+ return;
+ }
+
+ /*
+ * Do this check now for the master symbol table to avoid printing
+ * the message N times.
+ */
+ if (ALIGNED_POINTER(vss, long) == 0) {
+ printf("[ %s symbol table has bad start address %p ]\n",
+ name, vss);
+ return;
+ }
+
+ for (symf = db_symformats; *symf != NULL; symf++) {
+ db_symformat = *symf;
+ if (X_db_sym_init(symsize, vss, vse, name) == TRUE)
+ return;
+ }
+
+ db_symformat = NULL;
+ printf("[ no symbol table formats found ]\n");
+}
+#else
+void
+ddb_init()
+{
+ const db_symformat_t **symf;
+ const char *name = "bsd";
+ extern char *esym;
+ extern long end;
+
+ /*
+ * Do this check now for the master symbol table to avoid printing
+ * the message N times.
+ */
+ if ((((vaddr_t)&end) & (sizeof(long) - 1)) != 0) {
+ printf("[ %s symbol table has bad start address %p ]\n",
+ name, &end);
+ return;
+ }
+
+ for (symf = db_symformats; *symf != NULL; symf++) {
+ db_symformat = *symf;
+ if (X_db_sym_init((long)esym - (long)&end, &end, esym, name) == TRUE)
+ return;
+ }
+
+ db_symformat = NULL;
+ printf("[ no symbol table formats found ]\n");
}
+#endif
/*
* Add symbol table, with given name, to list of symbol tables.
*/
int
-db_add_symbol_table(start, end, name, ref, rend)
+db_add_symbol_table(start, end, name, ref)
char *start;
char *end;
- char *name;
+ const char *name;
char *ref;
- char *rend;
{
- db_symtab_t new = db_nsymtabs? NULL : &db_sym_kernel;
+ int slot;
- if (new == NULL &&
- (new = malloc(sizeof(*new), M_DEVBUF, M_WAITOK)) == NULL)
- return -1;
+ for (slot = 0; slot < MAXNOSYMTABS; slot++) {
+ if (db_symtabs[slot].name == NULL)
+ break;
+ }
+ if (slot >= MAXNOSYMTABS) {
+ db_printf("No slots left for %s symbol table", name);
+ return(-1);
+ }
- new->start = start;
- new->end = end;
- new->name = name;
- new->private = ref;
- new->rend = rend;
- new->id = db_nsymtabs;
- TAILQ_INSERT_TAIL(&db_symtabs, new, list);
+ db_symtabs[slot].start = start;
+ db_symtabs[slot].end = end;
+ db_symtabs[slot].name = name;
+ db_symtabs[slot].private = ref;
- return db_nsymtabs++;
+ return(slot);
}
/*
@@ -94,43 +186,22 @@ void
db_del_symbol_table(name)
char *name;
{
- register db_symtab_t p;
+ int slot;
- for (p = db_symiter(NULL); p != NULL; p = db_symiter(p))
- if (!strcmp(name, p->name))
+ for (slot = 0; slot < MAXNOSYMTABS; slot++) {
+ if (db_symtabs[slot].name &&
+ ! strcmp(db_symtabs[slot].name, name))
break;
+ }
+ if (slot >= MAXNOSYMTABS) {
+ db_printf("Unable to find symbol table slot for %s.", name);
+ return;
+ }
- if (p == NULL)
- db_printf("ddb: %s symbol table was not allocated", name);
-
- if (--db_nsymtabs == 0)
- panic("ddb: kernel symtab delete");
-
- TAILQ_REMOVE(&db_symtabs, p, list);
- free(p, M_DEVBUF);
-}
-
-db_symtab_t
-db_istab(i)
- size_t i;
-{
- register db_symtab_t p;
-
- for (p = db_symiter(NULL); i && p != NULL ; p = db_symiter(p))
- i--;
-
- return i? NULL : p;
-}
-
-db_symtab_t
-db_symiter(st)
- db_symtab_t st;
-{
- if (st == NULL)
- st = db_symtabs.tqh_first;
- else
- st = st->list.tqe_next;
- return st;
+ db_symtabs[slot].start = 0;
+ db_symtabs[slot].end = 0;
+ db_symtabs[slot].name = 0;
+ db_symtabs[slot].private = 0;
}
/*
@@ -142,11 +213,11 @@ db_symiter(st)
char *
db_qualify(sym, symtabname)
db_sym_t sym;
- register char *symtabname;
+ const char *symtabname;
{
char *symname;
static char tmp[256];
- register char *s;
+ char *s;
db_symbol_values(sym, &symname, 0);
s = tmp;
@@ -172,7 +243,6 @@ db_eqname(src, dst, c)
return (FALSE);
}
-#ifdef DDB
boolean_t
db_value_of_name(name, valuep)
char *name;
@@ -187,6 +257,7 @@ db_value_of_name(name, valuep)
return (TRUE);
}
+
/*
* Lookup a symbol.
* If the symbol has a qualifier (e.g., ux:vm_map),
@@ -197,46 +268,155 @@ db_sym_t
db_lookup(symstr)
char *symstr;
{
- db_symtab_t st = NULL;
- db_sym_t sp = NULL;
- register char *cp;
+ db_sym_t sp;
+ int i;
+ int symtab_start = 0;
+ int symtab_end = MAXNOSYMTABS;
+ char *cp;
/*
* Look for, remove, and remember any symbol table specifier.
*/
- for (cp = symstr; *cp; cp++)
+ for (cp = symstr; *cp; cp++) {
if (*cp == ':') {
*cp = '\0';
- for (st = db_symiter(NULL);
- st != NULL;
- st = db_symiter(st))
- if (!strcmp(symstr, st->name))
+ for (i = 0; i < MAXNOSYMTABS; i++) {
+ if (db_symtabs[i].name &&
+ ! strcmp(symstr, db_symtabs[i].name)) {
+ symtab_start = i;
+ symtab_end = i + 1;
break;
+ }
+ }
*cp = ':';
- if (st == NULL) {
+ if (i == MAXNOSYMTABS) {
db_error("invalid symbol table name");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
symstr = cp+1;
}
+ }
/*
* Look in the specified set of symbol tables.
* Return on first match.
*/
- if (st != NULL)
- sp = X_db_lookup(st, symstr);
+ for (i = symtab_start; i < symtab_end; i++) {
+ if (db_symtabs[i].name &&
+ (sp = X_db_lookup(&db_symtabs[i], symstr))) {
+ db_last_symtab = &db_symtabs[i];
+ return sp;
+ }
+ }
+ return 0;
+}
+
+/* Private structure for passing args to db_sift() from db_sifting(). */
+struct db_sift_args {
+ char *symstr;
+ int mode;
+};
+
+/*
+ * Does the work of db_sifting(), called once for each
+ * symbol via X_db_forall(), prints out symbols matching
+ * criteria.
+ */
+static void
+db_sift(stab, sym, name, suffix, prefix, arg)
+ db_symtab_t *stab;
+ db_sym_t sym;
+ char *name;
+ char *suffix;
+ int prefix;
+ void *arg;
+{
+ char c, sc;
+ char *find, *p;
+ size_t len;
+ struct db_sift_args *dsa;
+
+ dsa = (struct db_sift_args*)arg;
+
+ find = dsa->symstr; /* String we're looking for. */
+ p = name; /* String we're searching within. */
+
+ /* Matching algorithm cribbed from strstr(), which is not
+ in the kernel. */
+ if ((c = *find++) != 0) {
+ len = strlen(find);
+ do {
+ do {
+ if ((sc = *p++) == 0)
+ return;
+ } while (sc != c);
+ } while (strncmp(p, find, len) != 0);
+ }
+ if (dsa->mode=='F') /* ala ls -F */
+ db_printf("%s%s ", name, suffix);
else
- for (st = db_symiter(NULL); st != NULL; st = db_symiter(st))
- if ((sp = X_db_lookup(st, symstr)) != NULL)
- break;
+ db_printf("%s ", name);
+}
- if (sp != NULL && st != NULL)
- db_last_symtab = st;
+/*
+ * "Sift" for a partial symbol.
+ * Named for the Sun OpenPROM command ("sifting").
+ * If the symbol has a qualifier (e.g., ux:vm_map),
+ * then only the specified symbol table will be searched;
+ * otherwise, all symbol tables will be searched..
+ *
+ * "mode" is how-to-display, set from modifiers.
+ */
+void
+db_sifting(symstr, mode)
+ char *symstr;
+ int mode;
+{
+ char *cp;
+ int i;
+ int symtab_start = 0;
+ int symtab_end = MAXNOSYMTABS;
+ struct db_sift_args dsa;
- return sp;
+ /*
+ * Look for, remove, and remember any symbol table specifier.
+ */
+ for (cp = symstr; *cp; cp++) {
+ if (*cp == ':') {
+ *cp = '\0';
+ for (i = 0; i < MAXNOSYMTABS; i++) {
+ if (db_symtabs[i].name &&
+ ! strcmp(symstr, db_symtabs[i].name)) {
+ symtab_start = i;
+ symtab_end = i + 1;
+ break;
+ }
+ }
+ *cp = ':';
+ if (i == MAXNOSYMTABS) {
+ db_error("invalid symbol table name");
+ /*NOTREACHED*/
+ }
+ symstr = cp+1;
+ }
+ }
+
+ /* Pass args to db_sift(). */
+ dsa.symstr = symstr;
+ dsa.mode = mode;
+
+ /*
+ * Look in the specified set of symbol tables.
+ */
+ for (i = symtab_start; i < symtab_end; i++)
+ if (db_symtabs[i].name) {
+ db_printf("Sifting table %s:\n", db_symtabs[i].name);
+ X_db_forall(&db_symtabs[i], db_sift, &dsa);
+ }
+
+ return;
}
-#endif
+
/*
* Does this symbol name appear in more than one symbol table?
@@ -249,16 +429,16 @@ db_symbol_is_ambiguous(sym)
db_sym_t sym;
{
char *sym_name;
- register db_symtab_t st;
- register
+ int i;
boolean_t found_once = FALSE;
if (!db_qualify_ambiguous_names)
return FALSE;
db_symbol_values(sym, &sym_name, 0);
- for (st = db_symiter(NULL); st != NULL; st = db_symiter(st)) {
- if (X_db_lookup(st, sym_name) != NULL) {
+ for (i = 0; i < MAXNOSYMTABS; i++) {
+ if (db_symtabs[i].name &&
+ X_db_lookup(&db_symtabs[i], sym_name)) {
if (found_once)
return TRUE;
found_once = TRUE;
@@ -273,22 +453,23 @@ db_symbol_is_ambiguous(sym)
*/
db_sym_t
db_search_symbol( val, strategy, offp)
- register db_addr_t val;
+ db_addr_t val;
db_strategy_t strategy;
db_expr_t *offp;
{
- register
- db_expr_t diff;
+ unsigned int diff;
db_expr_t newdiff;
- db_symtab_t st;
+ int i;
db_sym_t ret = DB_SYM_NULL, sym;
- newdiff = diff = -1;
+ newdiff = diff = ~0;
db_last_symtab = 0;
- for (st = db_symiter(NULL); st != NULL; st = db_symiter(st)) {
- sym = X_db_search_symbol(st, val, strategy, &newdiff);
- if (newdiff < diff || diff < 0) {
- db_last_symtab = st;
+ for (i = 0; i < MAXNOSYMTABS; i++) {
+ if (!db_symtabs[i].name)
+ continue;
+ sym = X_db_search_symbol(&db_symtabs[i], val, strategy, &newdiff);
+ if (newdiff < diff) {
+ db_last_symtab = &db_symtabs[i];
diff = newdiff;
ret = sym;
}
@@ -313,7 +494,7 @@ db_symbol_values(sym, namep, valuep)
return;
}
- X_db_symbol_values(sym, namep, &value);
+ X_db_symbol_values(db_last_symtab, sym, namep, &value);
if (db_symbol_is_ambiguous(sym))
*namep = db_qualify(sym, db_last_symtab->name);
@@ -341,8 +522,8 @@ db_symbol_values(sym, namep, valuep)
* add support for symbols in loadable driver modules.
*/
extern char end[];
-u_long db_lastsym = (u_long)end;
-db_expr_t db_maxoff = 0x10000000;
+unsigned long db_lastsym = (unsigned long)end;
+unsigned int db_maxoff = 0x10000000;
void
@@ -357,22 +538,22 @@ db_printsym(off, strategy)
int linenum;
db_sym_t cursym;
- if ((u_long)off <= db_lastsym) {
+ if (off <= db_lastsym) {
cursym = db_search_symbol(off, strategy, &d);
db_symbol_values(cursym, &name, &value);
if (name && (d < db_maxoff) && value) {
db_printf("%s", name);
- if (d)
+ if (d) {
db_printf("+%#r", d);
+ }
if (strategy == DB_STGY_PROC) {
- if (db_line_at_pc(cursym, &filename, &linenum,
- off))
- db_printf(" [%s:%d]", filename,
- linenum);
+ if (db_line_at_pc(cursym, &filename, &linenum, off))
+ db_printf(" [%s:%d]", filename, linenum);
}
return;
}
}
+
db_printf("%#ln", off);
return;
}
@@ -397,27 +578,90 @@ db_sym_numargs(sym, nargp, argnames)
return X_db_sym_numargs(db_last_symtab, sym, nargp, argnames);
}
+boolean_t
+X_db_sym_init(symsize, vss, vse, name)
+ int symsize;
+ void *vss, *vse;
+ const char *name;
+{
+
+ if (db_symformat != NULL)
+ return ((*db_symformat->sym_init)(symsize, vss, vse, name));
+ return (FALSE);
+}
+
+db_sym_t
+X_db_lookup(stab, symstr)
+ db_symtab_t *stab;
+ char *symstr;
+{
+
+ if (db_symformat != NULL)
+ return ((*db_symformat->sym_lookup)(stab, symstr));
+ return ((db_sym_t)0);
+}
+
+db_sym_t
+X_db_search_symbol(stab, off, strategy, diffp)
+ db_symtab_t *stab;
+ db_addr_t off;
+ db_strategy_t strategy;
+ db_expr_t *diffp;
+{
+
+ if (db_symformat != NULL)
+ return ((*db_symformat->sym_search)(stab, off, strategy,
+ diffp));
+ return ((db_sym_t)0);
+}
+
void
-db_stub_xh(sym, xh)
- db_symtab_t sym;
- struct exec *xh;
+X_db_symbol_values(stab, sym, namep, valuep)
+ db_symtab_t *stab;
+ db_sym_t sym;
+ char **namep;
+ db_expr_t *valuep;
{
- X_db_stub_xh(sym, xh);
+
+ if (db_symformat != NULL)
+ (*db_symformat->sym_value)(stab, sym, namep, valuep);
}
-int
-db_symtablen(sym)
- db_symtab_t sym;
+boolean_t
+X_db_line_at_pc(stab, cursym, filename, linenum, off)
+ db_symtab_t *stab;
+ db_sym_t cursym;
+ char **filename;
+ int *linenum;
+ db_expr_t off;
+{
+
+ if (db_symformat != NULL)
+ return ((*db_symformat->sym_line_at_pc)(stab, cursym,
+ filename, linenum, off));
+ return (FALSE);
+}
+
+boolean_t
+X_db_sym_numargs(stab, cursym, nargp, argnamep)
+ db_symtab_t *stab;
+ db_sym_t cursym;
+ int *nargp;
+ char **argnamep;
{
- return X_db_symtablen(sym);
+
+ if (db_symformat != NULL)
+ return ((*db_symformat->sym_numargs)(stab, cursym, nargp,
+ argnamep));
+ return (FALSE);
}
-int
-db_symatoff(sym, off, buf, len)
- db_symtab_t sym;
- int off;
- void *buf;
- int *len;
+void
+X_db_forall(stab, db_forall_func, arg)
+ db_symtab_t *stab;
+ db_forall_func_t db_forall_func;
+ void *arg;
{
- return X_db_symatoff(sym, off, buf, len);
+ if (db_symformat != NULL)
+ (*db_symformat->sym_forall)(stab, db_forall_func, arg);
}