The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_sym.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Mach Operating System
    3  * Copyright (c) 1991,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  *
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  *
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  *
   16  * Carnegie Mellon requests users of this software to return to
   17  *
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  *
   23  * any improvements or extensions that they make and grant Carnegie the
   24  * rights to redistribute these changes.
   25  *
   26  * $FreeBSD: src/sys/ddb/db_sym.c,v 1.32 1999/08/28 00:41:10 peter Exp $
   27  */
   28 
   29 /*
   30  *      Author: David B. Golub, Carnegie Mellon University
   31  *      Date:   7/90
   32  */
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 
   36 #include <ddb/ddb.h>
   37 #include <ddb/db_sym.h>
   38 
   39 /*
   40  * Multiple symbol tables
   41  */
   42 #ifndef MAXNOSYMTABS
   43 #define MAXNOSYMTABS    3       /* mach, ux, emulator */
   44 #endif
   45 
   46 static db_symtab_t      db_symtabs[MAXNOSYMTABS] = {{0,},};
   47 static int db_nsymtab = 0;
   48 
   49 static db_symtab_t      *db_last_symtab; /* where last symbol was found */
   50 
   51 static c_db_sym_t       db_lookup ( const char *symstr);
   52 static char             *db_qualify (c_db_sym_t sym, char *symtabname);
   53 static boolean_t        db_symbol_is_ambiguous (c_db_sym_t sym);
   54 static boolean_t        db_line_at_pc (c_db_sym_t, char **, int *, 
   55                                 db_expr_t);
   56 
   57 /*
   58  * Add symbol table, with given name, to list of symbol tables.
   59  */
   60 void
   61 db_add_symbol_table(char *start, char *end, char *name, char *ref)
   62 {
   63         if (db_nsymtab >= MAXNOSYMTABS) {
   64                 kprintf ("No slots left for %s symbol table", name);
   65                 panic ("db_sym.c: db_add_symbol_table");
   66         }
   67 
   68         db_symtabs[db_nsymtab].start = start;
   69         db_symtabs[db_nsymtab].end = end;
   70         db_symtabs[db_nsymtab].name = name;
   71         db_symtabs[db_nsymtab].private = ref;
   72         db_nsymtab++;
   73 }
   74 
   75 /*
   76  *  db_qualify("vm_map", "ux") returns "unix:vm_map".
   77  *
   78  *  Note: return value points to static data whose content is
   79  *  overwritten by each call... but in practice this seems okay.
   80  */
   81 static char *
   82 db_qualify(c_db_sym_t sym, char *symtabname)
   83 {
   84         const char      *symname;
   85         static char     tmp[256];
   86 
   87         db_symbol_values(sym, &symname, 0);
   88         ksnprintf(tmp, sizeof(tmp), "%s:%s", symtabname, symname);
   89         return tmp;
   90 }
   91 
   92 
   93 boolean_t
   94 db_eqname(const char *src, const char *dst, int c)
   95 {
   96         if (!strcmp(src, dst))
   97             return (TRUE);
   98         if (src[0] == c)
   99             return (!strcmp(src+1,dst));
  100         return (FALSE);
  101 }
  102 
  103 boolean_t
  104 db_value_of_name(const char *name, db_expr_t *valuep)
  105 {
  106         c_db_sym_t      sym;
  107 
  108         sym = db_lookup(name);
  109         if (sym == C_DB_SYM_NULL)
  110             return (FALSE);
  111         db_symbol_values(sym, &name, valuep);
  112         return (TRUE);
  113 }
  114 
  115 
  116 /*
  117  * Lookup a symbol.
  118  * If the symbol has a qualifier (e.g., ux:vm_map),
  119  * then only the specified symbol table will be searched;
  120  * otherwise, all symbol tables will be searched.
  121  */
  122 static c_db_sym_t
  123 db_lookup(const char *symstr)
  124 {
  125         c_db_sym_t sp;
  126         int i;
  127         int symtab_start = 0;
  128         int symtab_end = db_nsymtab;
  129         const char *cp;
  130 
  131         /*
  132          * Look for, remove, and remember any symbol table specifier.
  133          */
  134         for (cp = symstr; *cp; cp++) {
  135                 if (*cp == ':') {
  136                         for (i = 0; i < db_nsymtab; i++) {
  137                                 int n = strlen(db_symtabs[i].name);
  138 
  139                                 if (
  140                                     n == (cp - symstr) &&
  141                                     strncmp(symstr, db_symtabs[i].name, n) == 0
  142                                 ) {
  143                                         symtab_start = i;
  144                                         symtab_end = i + 1;
  145                                         break;
  146                                 }
  147                         }
  148                         if (i == db_nsymtab) {
  149                                 db_error("invalid symbol table name");
  150                         }
  151                         symstr = cp+1;
  152                 }
  153         }
  154 
  155         /*
  156          * Look in the specified set of symbol tables.
  157          * Return on first match.
  158          */
  159         for (i = symtab_start; i < symtab_end; i++) {
  160                 sp = X_db_lookup(&db_symtabs[i], symstr);
  161                 if (sp) {
  162                         db_last_symtab = &db_symtabs[i];
  163                         return sp;
  164                 }
  165         }
  166         return 0;
  167 }
  168 
  169 /*
  170  * If TRUE, check across symbol tables for multiple occurrences
  171  * of a name.  Might slow things down quite a bit.
  172  */
  173 static volatile boolean_t db_qualify_ambiguous_names = FALSE;
  174 
  175 /*
  176  * Does this symbol name appear in more than one symbol table?
  177  * Used by db_symbol_values to decide whether to qualify a symbol.
  178  */
  179 static boolean_t
  180 db_symbol_is_ambiguous(c_db_sym_t sym)
  181 {
  182         const char      *sym_name;
  183         int     i;
  184         
  185         boolean_t       found_once = FALSE;
  186 
  187         if (!db_qualify_ambiguous_names)
  188                 return FALSE;
  189 
  190         db_symbol_values(sym, &sym_name, 0);
  191         for (i = 0; i < db_nsymtab; i++) {
  192                 if (X_db_lookup(&db_symtabs[i], sym_name)) {
  193                         if (found_once)
  194                                 return TRUE;
  195                         found_once = TRUE;
  196                 }
  197         }
  198         return FALSE;
  199 }
  200 
  201 /*
  202  * Find the closest symbol to val, and return its name
  203  * and the difference between val and the symbol found.
  204  */
  205 c_db_sym_t
  206 db_search_symbol(db_addr_t val, db_strategy_t strategy, db_expr_t *offp)
  207 {
  208         
  209         unsigned int    diff;
  210         size_t          newdiff;
  211         int     i;
  212         c_db_sym_t      ret = C_DB_SYM_NULL, sym;
  213 
  214         newdiff = diff = ~0;
  215         db_last_symtab = NULL;
  216         for (i = 0; i < db_nsymtab; i++) {
  217             sym = X_db_search_symbol(&db_symtabs[i], val, strategy, &newdiff);
  218             if (newdiff < diff) {
  219                 db_last_symtab = &db_symtabs[i];
  220                 diff = newdiff;
  221                 ret = sym;
  222             }
  223         }
  224         *offp = diff;
  225         return ret;
  226 }
  227 
  228 /*
  229  * Return name and value of a symbol
  230  */
  231 void
  232 db_symbol_values(c_db_sym_t sym, const char **namep, db_expr_t *valuep)
  233 {
  234         db_expr_t       value;
  235 
  236         if (sym == DB_SYM_NULL) {
  237                 *namep = NULL;
  238                 return;
  239         }
  240 
  241         X_db_symbol_values(db_last_symtab, sym, namep, &value);
  242 
  243         if (db_symbol_is_ambiguous(sym))
  244                 *namep = db_qualify(sym, db_last_symtab->name);
  245         if (valuep)
  246                 *valuep = value;
  247 }
  248 
  249 
  250 /*
  251  * Print a the closest symbol to value
  252  *
  253  * After matching the symbol according to the given strategy
  254  * we print it in the name+offset format, provided the symbol's
  255  * value is close enough (eg smaller than db_maxoff).
  256  * We also attempt to print [filename:linenum] when applicable
  257  * (eg for procedure names).
  258  *
  259  * If we could not find a reasonable name+offset representation,
  260  * then we just print the value in hex.  Small values might get
  261  * bogus symbol associations, e.g. 3 might get some absolute
  262  * value like _INCLUDE_VERSION or something, therefore we do
  263  * not accept symbols whose value is "small" (and use plain hex).
  264  */
  265 
  266 db_expr_t       db_maxoff = 0x10000;
  267 
  268 void
  269 db_printsym(db_expr_t off, db_strategy_t strategy)
  270 {
  271         db_expr_t       d;
  272         char            *filename;
  273         const char      *name;
  274         db_expr_t       value;
  275         int             linenum;
  276         c_db_sym_t      cursym;
  277 
  278         cursym = db_search_symbol(off, strategy, &d);
  279         db_symbol_values(cursym, &name, &value);
  280         if (name == NULL)
  281                 value = off;
  282         if (value >= DB_SMALL_VALUE_MIN && value <= DB_SMALL_VALUE_MAX) {
  283                 db_printf("%+#lr", (long)off);
  284                 return;
  285         }
  286         if (name == NULL || d >= (unsigned long)db_maxoff) {
  287                 db_printf("%#lr", (unsigned long)off);
  288                 return;
  289         }
  290         db_printf("%s", name);
  291         if (d)
  292                 db_printf("+%+#lr", (long)d);
  293         if (strategy == DB_STGY_PROC) {
  294                 if (db_line_at_pc(cursym, &filename, &linenum, off))
  295                         db_printf(" [%s:%d]", filename, linenum);
  296         }
  297 }
  298 
  299 static boolean_t
  300 db_line_at_pc(c_db_sym_t sym, char **filename, int *linenum, db_expr_t pc)
  301 {
  302         return X_db_line_at_pc( db_last_symtab, sym, filename, linenum, pc);
  303 }
  304 
  305 int
  306 db_sym_numargs(c_db_sym_t sym, int *nargp, char **argnames)
  307 {
  308         return X_db_sym_numargs(db_last_symtab, sym, nargp, argnames);
  309 }

Cache object: 5ed241eeafda97069aa951ad8dd77dde


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.