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_aout.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_aout.c,v 1.15.4.1 1999/09/05 08:08:41 peter Exp $
   27  */
   28 
   29 /*
   30  *      Author: David B. Golub, Carnegie Mellon University
   31  *      Date:   7/90
   32  */
   33 /*
   34  * Symbol table routines for a.out format files.
   35  */
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 
   40 #include <machine/bootinfo.h>
   41 
   42 #include <ddb/ddb.h>
   43 #include <ddb/db_sym.h>
   44 
   45 #ifndef DB_NO_AOUT
   46 
   47 #define _AOUT_INCLUDE_
   48 #include <nlist.h>
   49 #include <stab.h>
   50 
   51 /*
   52  * An a.out symbol table as loaded into the kernel debugger:
   53  *
   54  * symtab       -> size of symbol entries, in bytes
   55  * sp           -> first symbol entry
   56  *                 ...
   57  * ep           -> last symbol entry + 1
   58  * strtab       == start of string table
   59  *                 size of string table in bytes,
   60  *                 including this word
   61  *              -> strings
   62  */
   63 
   64 static void     X_db_sym_init __P((int *symtab, char *esymtab, char *name));
   65 /*
   66  * Find pointers to the start and end of the symbol entries,
   67  * given a pointer to the start of the symbol table.
   68  */
   69 #define db_get_aout_symtab(symtab, sp, ep) \
   70         (sp = (struct nlist *)((symtab) + 1), \
   71          ep = (struct nlist *)((char *)sp + *(symtab)))
   72 
   73 static void
   74 X_db_sym_init(symtab, esymtab, name)
   75         int *   symtab;         /* pointer to start of symbol table */
   76         char *  esymtab;        /* pointer to end of string table,
   77                                    for checking - rounded up to integer
   78                                    boundary */
   79         char *  name;
   80 {
   81         register struct nlist   *sym_start, *sym_end;
   82         register struct nlist   *sp;
   83         register char * strtab;
   84         register int    strlen;
   85 
   86         if (*symtab < 4) {
   87                 printf ("DDB: no symbols\n");
   88                 return;
   89         }
   90 
   91         db_get_aout_symtab(symtab, sym_start, sym_end);
   92 
   93         strtab = (char *)sym_end;
   94         strlen = *(int *)strtab;
   95 
   96         if (strtab + ((strlen + sizeof(int) - 1) & ~(sizeof(int)-1))
   97             != esymtab)
   98         {
   99             db_printf("[ %s symbol table not valid ]\n", name);
  100             return;
  101         }
  102 
  103         db_printf("[ preserving %#x bytes of %s symbol table ]\n",
  104                 esymtab - (char *)symtab, name);
  105 
  106         for (sp = sym_start; sp < sym_end; sp++) {
  107             register int strx;
  108             strx = sp->n_un.n_strx;
  109             if (strx != 0) {
  110                 if (strx > strlen) {
  111                     db_printf("Bad string table index (%#x)\n", strx);
  112                     sp->n_un.n_name = 0;
  113                     continue;
  114                 }
  115                 sp->n_un.n_name = strtab + strx;
  116             }
  117         }
  118 
  119         db_add_symbol_table((char *)sym_start, (char *)sym_end, name,
  120                             (char *)symtab);
  121 }
  122 
  123 db_sym_t
  124 X_db_lookup(stab, symstr)
  125         db_symtab_t     *stab;
  126         char *          symstr;
  127 {
  128         register struct nlist *sp, *ep;
  129 
  130         sp = (struct nlist *)stab->start;
  131         ep = (struct nlist *)stab->end;
  132 
  133         for (; sp < ep; sp++) {
  134             if (sp->n_un.n_name == 0)
  135                 continue;
  136             if ((sp->n_type & N_STAB) == 0 &&
  137                 sp->n_un.n_name != 0 &&
  138                 db_eqname(sp->n_un.n_name, symstr, '_'))
  139             {
  140                 return ((db_sym_t)sp);
  141             }
  142         }
  143         return ((db_sym_t)0);
  144 }
  145 
  146 db_sym_t
  147 X_db_search_symbol(symtab, off, strategy, diffp)
  148         db_symtab_t *   symtab;
  149         register
  150         db_addr_t       off;
  151         db_strategy_t   strategy;
  152         db_expr_t       *diffp;         /* in/out */
  153 {
  154         register unsigned int   diff = *diffp;
  155         register struct nlist   *symp = 0;
  156         register struct nlist   *sp, *ep;
  157 
  158         sp = (struct nlist *)symtab->start;
  159         ep = (struct nlist *)symtab->end;
  160 
  161         for (; sp < ep; sp++) {
  162             if (sp->n_un.n_name == 0)
  163                 continue;
  164             if ((sp->n_type & N_STAB) != 0 || (sp->n_type & N_TYPE) == N_FN)
  165                 continue;
  166             if (off >= sp->n_value) {
  167                 if (off - sp->n_value < diff) {
  168                     diff = off - sp->n_value;
  169                     symp = sp;
  170                     if (diff == 0) {
  171                         if (strategy == DB_STGY_PROC &&
  172                                         sp->n_type == (N_TEXT|N_EXT))
  173                             break;
  174                         if (strategy == DB_STGY_ANY &&
  175                                         (sp->n_type & N_EXT))
  176                             break;
  177                     }
  178                 }
  179                 else if (off - sp->n_value == diff) {
  180                     if (symp == 0)
  181                         symp = sp;
  182                     else if ((symp->n_type & N_EXT) == 0 &&
  183                                 (sp->n_type & N_EXT) != 0)
  184                         symp = sp;      /* pick the external symbol */
  185                 }
  186             }
  187         }
  188         if (symp == 0) {
  189             *diffp = off;
  190         }
  191         else {
  192             *diffp = diff;
  193         }
  194         return ((db_sym_t)symp);
  195 }
  196 
  197 /*
  198  * Return the name and value for a symbol.
  199  */
  200 void
  201 X_db_symbol_values(sym, namep, valuep)
  202         db_sym_t        sym;
  203         char            **namep;
  204         db_expr_t       *valuep;
  205 {
  206         register struct nlist *sp;
  207 
  208         sp = (struct nlist *)sym;
  209         if (namep)
  210             *namep = sp->n_un.n_name;
  211         if (valuep)
  212             *valuep = sp->n_value;
  213 }
  214 
  215 
  216 boolean_t
  217 X_db_line_at_pc(symtab, cursym, filename, linenum, off)
  218         db_symtab_t *   symtab;
  219         db_sym_t        cursym;
  220         char            **filename;
  221         int             *linenum;
  222         db_expr_t       off;
  223 {
  224         register struct nlist   *sp, *ep;
  225         unsigned long           sodiff = -1UL, lndiff = -1UL, ln = 0;
  226         char                    *fname = NULL;
  227 
  228         sp = (struct nlist *)symtab->start;
  229         ep = (struct nlist *)symtab->end;
  230 
  231 /*
  232  * XXX - this used to remove "gcc_compiled.", but that is obsolete.  We
  233  * now remove unwanted names using symorder.
  234  */
  235 #define NEWSRC(str)     0
  236 
  237         for (; sp < ep; sp++) {
  238 
  239             /*
  240              * Prevent bogus linenumbers in case module not compiled
  241              * with debugging options
  242              */
  243 #if 0
  244             if (sp->n_value <= off && (off - sp->n_value) <= sodiff &&
  245                 NEWSRC(sp->n_un.n_name)) {
  246 #endif
  247             if ((sp->n_type & N_TYPE) == N_FN || NEWSRC(sp->n_un.n_name)) {
  248                 sodiff = lndiff = -1UL;
  249                 ln = 0;
  250                 fname = NULL;
  251             }
  252 
  253             if (sp->n_type == N_SO) {
  254                 if (sp->n_value <= off && (off - sp->n_value) < sodiff) {
  255                         sodiff = off - sp->n_value;
  256                         fname = sp->n_un.n_name;
  257                 }
  258                 continue;
  259             }
  260 
  261             if (sp->n_type != N_SLINE)
  262                 continue;
  263 
  264             if (sp->n_value > off)
  265                 break;
  266 
  267             if (off - sp->n_value < lndiff) {
  268                 lndiff = off - sp->n_value;
  269                 ln = sp->n_desc;
  270             }
  271         }
  272 
  273         if (fname != NULL && ln != 0) {
  274                 *filename = fname;
  275                 *linenum = ln;
  276                 return TRUE;
  277         }
  278 
  279         return (FALSE);
  280 }
  281 
  282 boolean_t
  283 X_db_sym_numargs(symtab, cursym, nargp, argnamep)
  284         db_symtab_t *   symtab;
  285         db_sym_t        cursym;
  286         int             *nargp;
  287         char            **argnamep;
  288 {
  289         register struct nlist   *sp, *ep;
  290         u_long                  addr;
  291         int                     maxnarg = *nargp, nargs = 0;
  292 
  293         if (cursym == NULL)
  294                 return FALSE;
  295 
  296         addr = ((struct nlist *)cursym)->n_value;
  297         sp = (struct nlist *)symtab->start;
  298         ep = (struct nlist *)symtab->end;
  299 
  300         for (; sp < ep; sp++) {
  301             if (sp->n_type == N_FUN && sp->n_value == addr) {
  302                 while (++sp < ep && sp->n_type == N_PSYM) {
  303                         if (nargs >= maxnarg)
  304                                 break;
  305                         nargs++;
  306                         *argnamep++ = sp->n_un.n_name?sp->n_un.n_name:"???";
  307                         {
  308                         /* XXX - remove trailers */
  309                         char *cp = *(argnamep-1);
  310                         while (*cp != '\0' && *cp != ':') cp++;
  311                         if (*cp == ':') *cp = '\0';
  312                         }
  313                 }
  314                 *nargp = nargs;
  315                 return TRUE;
  316             }
  317         }
  318         return FALSE;
  319 }
  320 
  321 /*
  322  * Initialization routine for a.out files.
  323  */
  324 void
  325 kdb_init(void)
  326 {
  327         if (bootinfo.bi_esymtab != bootinfo.bi_symtab)
  328                 X_db_sym_init((int *)bootinfo.bi_symtab,
  329                               (char *)((bootinfo.bi_esymtab + sizeof(int) - 1)
  330                                        & ~(sizeof(int) - 1)),
  331                               "kernel");
  332 }
  333 
  334 #if 0
  335 /*
  336  * Read symbol table from file.
  337  * (should be somewhere else)
  338  */
  339 #include <boot_ufs/file_io.h>
  340 #include <vm/vm_kern.h>
  341 
  342 read_symtab_from_file(fp, symtab_name)
  343         struct file     *fp;
  344         char *          symtab_name;
  345 {
  346         vm_size_t       resid;
  347         kern_return_t   result;
  348         vm_offset_t     symoff;
  349         vm_size_t       symsize;
  350         vm_offset_t     stroff;
  351         vm_size_t       strsize;
  352         vm_size_t       table_size;
  353         vm_offset_t     symtab;
  354 
  355         if (!get_symtab(fp, &symoff, &symsize)) {
  356             boot_printf("[ error %d reading %s file header ]\n",
  357                         result, symtab_name);
  358             return;
  359         }
  360 
  361         stroff = symoff + symsize;
  362         result = read_file(fp, (vm_offset_t)stroff,
  363                         (vm_offset_t)&strsize, sizeof(strsize), &resid);
  364         if (result || resid) {
  365             boot_printf("[ no valid symbol table present for %s ]\n",
  366                 symtab_name);
  367                 return;
  368         }
  369 
  370         table_size = sizeof(int) + symsize + strsize;
  371         table_size = (table_size + sizeof(int)-1) & ~(sizeof(int)-1);
  372 
  373         symtab = kmem_alloc_wired(kernel_map, table_size);
  374 
  375         *(int *)symtab = symsize;
  376 
  377         result = read_file(fp, symoff,
  378                         symtab + sizeof(int), symsize, &resid);
  379         if (result || resid) {
  380             boot_printf("[ error %d reading %s symbol table ]\n",
  381                         result, symtab_name);
  382             return;
  383         }
  384 
  385         result = read_file(fp, stroff,
  386                         symtab + sizeof(int) + symsize, strsize, &resid);
  387         if (result || resid) {
  388             boot_printf("[ error %d reading %s string table ]\n",
  389                         result, symtab_name);
  390             return;
  391         }
  392 
  393         X_db_sym_init((int *)symtab,
  394                         (char *)(symtab + table_size),
  395                         symtab_name);
  396 
  397 }
  398 #endif
  399 
  400 #endif  /* DB_NO_AOUT */

Cache object: 9fb756bf2315dcbc5e06a71df3d664ce


[ 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.