Add a "sifting" command to ddb (named from the Sun OpenPROM command of

the same name); it searches the symbol table(s) for all symbols matching
a given substring, and prints.

Extremely useful for when you forget that critical symbol name.

Also, with /F support (cf. "ls -F") to print a char indicating the
symbol type.
This commit is contained in:
jhawk 2000-05-22 14:49:10 +00:00
parent 494e4c93a6
commit 41ebaaaf09
7 changed files with 312 additions and 7 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ddb.4,v 1.45 2000/05/22 11:46:07 jhawk Exp $
.\" $NetBSD: ddb.4,v 1.46 2000/05/22 14:49:11 jhawk Exp $
.\"
.\" Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -587,6 +587,42 @@ If not supported, incorrect information will be displayed.
.It Ic "show watches"
Display all watchpoints.
.It Xo
.Ic sifting Ns Op Cm /F
.Ar string
.Xc
Search the symbol tables for all symbols of which
.Ar string
is a substring, and display them. If
.Cm /F
is specified, a character is displayed immediately after each symbol
name indicating the type of symbol.
.Pp
For
.Ns Xr a.out 5 -format
symbol tables,
absolute symbols display
.Sy @ ,
text segment symbols display
.Sy * ,
data segment symbols display
.Sy + ,
.Tn BSS
segment symbols display
.Sy - ,
and filename symbols display
.Sy / .
For
.Tn ELF Ns -format
symbol tables,
object symbols display
.Sy + ,
function symbols display
.Sy * ,
section symbols display
.Sy & ,
and file symbols display
.Sy / .
.It Xo
.Ic step Ns Op Cm /p
.Op Cm , Ns Ar count
.Xc

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_aout.c,v 1.27 2000/03/30 11:31:26 augustss Exp $ */
/* $NetBSD: db_aout.c,v 1.28 2000/05/22 14:49:10 jhawk Exp $ */
/*
* Mach Operating System
@ -51,6 +51,8 @@ boolean_t db_aout_line_at_pc __P((db_symtab_t *, db_sym_t,
char **, int *, db_expr_t));
boolean_t db_aout_sym_numargs __P((db_symtab_t *, db_sym_t, int *,
char **));
void db_aout_forall __P((db_symtab_t *,
db_forall_func_t db_forall_func, void *));
db_symformat_t db_symformat_aout = {
"a.out",
@ -60,6 +62,7 @@ db_symformat_t db_symformat_aout = {
db_aout_symbol_values,
db_aout_line_at_pc,
db_aout_sym_numargs,
db_aout_forall
};
/*
@ -346,4 +349,49 @@ db_aout_sym_numargs(symtab, cursym, nargp, argnamep)
}
return FALSE;
}
void
db_aout_forall(stab, db_forall_func, arg)
db_symtab_t *stab;
db_forall_func_t db_forall_func;
void *arg;
{
static char suffix[2];
struct nlist *sp, *ep;
sp = (struct nlist *)stab->start;
ep = (struct nlist *)stab->end;
for (; sp < ep; sp++) {
if (sp->n_un.n_name == 0)
continue;
if ((sp->n_type & N_STAB) == 0 && sp->n_un.n_name != 0) {
suffix[1] = '\0';
switch(sp->n_type & N_TYPE) {
case N_ABS:
suffix[0] = '@';
break;
case N_TEXT:
suffix[0] = '*';
break;
case N_DATA:
suffix[0] = '+';
break;
case N_BSS:
suffix[0] = '-';
break;
case N_FN:
suffix[0] = '/';
break;
default:
suffix[0] = '\0';
}
(*db_forall_func)(stab, (db_sym_t)sp, sp->n_un.n_name,
suffix, '_', arg);
}
}
return;
}
#endif /* DB_AOUT_SYMBOLS */

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_command.c,v 1.40 2000/05/20 03:08:41 jhawk Exp $ */
/* $NetBSD: db_command.c,v 1.41 2000/05/22 14:49:10 jhawk Exp $ */
/*
* Mach Operating System
@ -481,6 +481,7 @@ struct db_command db_command_table[] = {
{ "search", db_search_cmd, CS_OWN|CS_SET_DOT, NULL },
{ "set", db_set_cmd, CS_OWN, NULL },
{ "show", NULL, 0, db_show_cmds },
{ "sifting", db_sifting_cmd, CS_OWN, NULL },
{ "step", db_single_step_cmd, 0, NULL },
{ "sync", db_sync_cmd, CS_OWN, NULL },
{ "trace", db_stack_trace_cmd, 0, NULL },
@ -645,6 +646,40 @@ db_reboot_cmd(addr, have_addr, count, modif)
cpu_reboot((int)bootflags, NULL);
}
void
db_sifting_cmd(addr, have_addr, count, omodif)
db_expr_t addr;
int have_addr;
db_expr_t count;
char * omodif;
{
int mode, t;
t = db_read_token();
if (t == tSLASH) {
t = db_read_token();
if (t != tIDENT) {
bad_modifier:
db_printf("Bad modifier\n");
db_flush_lex();
return;
}
if (!strcmp(db_tok_string, "F"))
mode = 'F';
else
goto bad_modifier;
t = db_read_token();
} else
mode = 0;
if (t==tIDENT)
db_sifting(db_tok_string, mode);
else {
db_printf("Bad argument (non-string)\n");
db_flush_lex();
}
}
void
db_sync_cmd(addr, have_addr, count, modif)
db_expr_t addr;

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_command.h,v 1.15 2000/04/10 02:22:13 chs Exp $ */
/* $NetBSD: db_command.h,v 1.16 2000/05/22 14:49:10 jhawk Exp $ */
/*
* Mach Operating System
@ -48,6 +48,7 @@ void db_command_loop __P((void));
void db_error __P((char *));
void db_fncall __P((db_expr_t, int, db_expr_t, char *));
void db_reboot_cmd __P((db_expr_t, int, db_expr_t, char *));
void db_sifting_cmd __P((db_expr_t, int, db_expr_t, char *));
void db_sync_cmd __P((db_expr_t, int, db_expr_t, char *));
db_addr_t db_dot; /* current location */

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_elf.c,v 1.10 1999/10/25 13:55:06 kleink Exp $ */
/* $NetBSD: db_elf.c,v 1.11 2000/05/22 14:49:10 jhawk Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -75,6 +75,8 @@ boolean_t db_elf_line_at_pc __P((db_symtab_t *, db_sym_t,
char **, int *, db_expr_t));
boolean_t db_elf_sym_numargs __P((db_symtab_t *, db_sym_t, int *,
char **));
void db_elf_forall __P((db_symtab_t *,
db_forall_func_t db_forall_func, void *));
db_symformat_t db_symformat_elf = {
"ELF",
@ -84,6 +86,7 @@ db_symformat_t db_symformat_elf = {
db_elf_symbol_values,
db_elf_line_at_pc,
db_elf_sym_numargs,
db_elf_forall
};
/*
@ -397,4 +400,46 @@ db_elf_sym_numargs(symtab, cursym, nargp, argnamep)
*/
return (FALSE);
}
void
db_elf_forall(stab, db_forall_func, arg)
db_symtab_t *stab;
db_forall_func_t db_forall_func;
void *arg;
{
char *strtab;
static char suffix[2];
Elf_Sym *symp, *symtab_start, *symtab_end;
symtab_start = STAB_TO_SYMSTART(stab);
symtab_end = STAB_TO_SYMEND(stab);
strtab = db_elf_find_strtab(stab);
if (strtab == NULL)
return;
for (symp = symtab_start; symp < symtab_end; symp++)
if (symp->st_name != 0) {
suffix[1] = '\0';
switch (ELFDEFNNAME(ST_TYPE)(symp->st_info)) {
case STT_OBJECT:
suffix[0] = '+';
break;
case STT_FUNC:
suffix[0] = '*';
break;
case STT_SECTION:
suffix[0] = '&';
break;
case STT_FILE:
suffix[0] = '/';
break;
default:
suffix[0] = '\0';
}
(*db_forall_func)(stab, (db_sym_t)symp,
strtab + symp->st_name, suffix, 0, arg);
}
return;
}
#endif /* DB_ELF_SYMBOLS */

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_sym.c,v 1.19 2000/03/30 11:31:27 augustss Exp $ */
/* $NetBSD: db_sym.c,v 1.20 2000/05/22 14:49:10 jhawk Exp $ */
/*
* Mach Operating System
@ -32,6 +32,7 @@
#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>
@ -53,6 +54,7 @@ db_symtab_t db_symtabs[MAXNOSYMTABS] = {{0,},};
db_symtab_t *db_last_symtab;
static char *db_qualify __P((db_sym_t, const char *));
static db_forall_func_t db_sift;
/*
* Put the most picky symbol table formats at the top!
@ -79,6 +81,8 @@ 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 **));
void X_db_forall __P((db_symtab_t *,
db_forall_func_t db_forall_func, void *));
/*
* Initialize the kernel debugger by initializing the master symbol
@ -279,6 +283,113 @@ db_lookup(symstr)
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
db_printf("%s ", name);
}
/*
* "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;
/*
* 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;
}
/*
* Does this symbol name appear in more than one symbol table?
* Used by db_symbol_values to decide whether to qualify a symbol.
@ -514,3 +625,13 @@ X_db_sym_numargs(stab, cursym, nargp, argnamep)
argnamep));
return (FALSE);
}
void
X_db_forall(stab, db_forall_func, arg)
db_symtab_t *stab;
db_forall_func_t db_forall_func;
void *arg;
{
if (db_symformat != NULL)
(*db_symformat->sym_forall)(stab, db_forall_func, arg);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_sym.h,v 1.11 1999/04/12 20:38:21 pk Exp $ */
/* $NetBSD: db_sym.h,v 1.12 2000/05/22 14:49:10 jhawk Exp $ */
/*
* Mach Operating System
@ -61,6 +61,20 @@ typedef int db_strategy_t; /* search strategy */
#define DB_STGY_XTRN 1 /* only external symbols */
#define DB_STGY_PROC 2 /* only procedures */
/*
* Internal db_forall function calling convention:
*
* (*db_forall_func)(stab, sym, name, suffix, prefix, arg);
*
* stab is the symbol table, symbol the (opaque) symbol pointer,
* name the name of the symbol, suffix a string representing
* the type, prefix an initial ignorable function prefix (e.g. "_"
* in a.out), and arg an opaque argument to be passed in.
*/
typedef void (db_forall_func_t)
__P((db_symtab_t *, db_sym_t, char *, char *, int, void *));
/*
* A symbol table may be in one of many formats. All symbol tables
* must be of the same format as the master kernel symbol table.
@ -77,6 +91,8 @@ typedef struct {
char **, int *, db_expr_t));
boolean_t (*sym_numargs) __P((db_symtab_t *, db_sym_t, int *,
char **));
void (*sym_forall) __P((db_symtab_t *,
db_forall_func_t *db_forall_func, void *));
} db_symformat_t;
extern boolean_t db_qualify_ambiguous_names;
@ -102,6 +118,9 @@ int db_value_of_name __P((char *, db_expr_t *));
db_sym_t db_lookup __P((char *));
void db_sifting __P((char *, int));
/* print partially matching symbol names */
boolean_t db_symbol_is_ambiguous __P((db_sym_t));
db_sym_t db_search_symbol __P((db_addr_t, db_strategy_t, db_expr_t *));