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:
parent
494e4c93a6
commit
41ebaaaf09
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
123
sys/ddb/db_sym.c
123
sys/ddb/db_sym.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 *));
|
||||
|
|
Loading…
Reference in New Issue