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$
   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 #if !defined(__ELF__) && !defined(__alpha__)
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 
   42 #include <machine/bootinfo.h>
   43 
   44 #include <ddb/ddb.h>
   45 #include <ddb/db_sym.h>
   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(symtab, sym, namep, valuep)
  202         db_symtab_t     *symtab;
  203         db_sym_t        sym;
  204         char            **namep;
  205         db_expr_t       *valuep;
  206 {
  207         register struct nlist *sp;
  208 
  209         sp = (struct nlist *)sym;
  210         if (namep)
  211             *namep = sp->n_un.n_name;
  212         if (valuep)
  213             *valuep = sp->n_value;
  214 }
  215 
  216 
  217 boolean_t
  218 X_db_line_at_pc(symtab, cursym, filename, linenum, off)
  219         db_symtab_t *   symtab;
  220         db_sym_t        cursym;
  221         char            **filename;
  222         int             *linenum;
  223         db_expr_t       off;
  224 {
  225         register struct nlist   *sp, *ep;
  226         unsigned long           sodiff = -1UL, lndiff = -1UL, ln = 0;
  227         char                    *fname = NULL;
  228 
  229         sp = (struct nlist *)symtab->start;
  230         ep = (struct nlist *)symtab->end;
  231 
  232 /*
  233  * XXX - this used to remove "gcc_compiled.", but that is obsolete.  We
  234  * now remove unwanted names using symorder.
  235  */
  236 #define NEWSRC(str)     0
  237 
  238         for (; sp < ep; sp++) {
  239 
  240             /*
  241              * Prevent bogus linenumbers in case module not compiled
  242              * with debugging options
  243              */
  244 #if 0
  245             if (sp->n_value <= off && (off - sp->n_value) <= sodiff &&
  246                 NEWSRC(sp->n_un.n_name)) {
  247 #endif
  248             if ((sp->n_type & N_TYPE) == N_FN || NEWSRC(sp->n_un.n_name)) {
  249                 sodiff = lndiff = -1UL;
  250                 ln = 0;
  251                 fname = NULL;
  252             }
  253 
  254             if (sp->n_type == N_SO && *sp->n_un.n_name != '/') {
  255                 if (sp->n_value <= off && (off - sp->n_value) < sodiff) {
  256                         sodiff = off - sp->n_value;
  257                         fname = sp->n_un.n_name;
  258                 }
  259                 continue;
  260             }
  261 
  262             if (sp->n_type != N_SLINE)
  263                 continue;
  264 
  265             if (sp->n_value > off)
  266                 break;
  267 
  268             if (off - sp->n_value < lndiff) {
  269                 lndiff = off - sp->n_value;
  270                 ln = sp->n_desc;
  271             }
  272         }
  273 
  274         if (fname != NULL && ln != 0) {
  275                 *filename = fname;
  276                 *linenum = ln;
  277                 return TRUE;
  278         }
  279 
  280         return (FALSE);
  281 }
  282 
  283 boolean_t
  284 X_db_sym_numargs(symtab, cursym, nargp, argnamep)
  285         db_symtab_t *   symtab;
  286         db_sym_t        cursym;
  287         int             *nargp;
  288         char            **argnamep;
  289 {
  290         register struct nlist   *sp, *ep;
  291         u_long                  addr;
  292         int                     maxnarg = *nargp, nargs = 0;
  293 
  294         if (cursym == NULL)
  295                 return FALSE;
  296 
  297         addr = ((struct nlist *)cursym)->n_value;
  298         sp = (struct nlist *)symtab->start;
  299         ep = (struct nlist *)symtab->end;
  300 
  301         for (; sp < ep; sp++) {
  302             if (sp->n_type == N_FUN && sp->n_value == addr) {
  303                 while (++sp < ep && sp->n_type == N_PSYM) {
  304                         if (nargs >= maxnarg)
  305                                 break;
  306                         nargs++;
  307                         *argnamep++ = sp->n_un.n_name?sp->n_un.n_name:"???";
  308                         {
  309                         /* XXX - remove trailers */
  310                         char *cp = *(argnamep-1);
  311                         while (*cp != '\0' && *cp != ':') cp++;
  312                         if (*cp == ':') *cp = '\0';
  313                         }
  314                 }
  315                 *nargp = nargs;
  316                 return TRUE;
  317             }
  318         }
  319         return FALSE;
  320 }
  321 
  322 /*
  323  * Initialization routine for a.out files.
  324  */
  325 void
  326 kdb_init()
  327 {
  328 #ifdef __i386__
  329         if (bootinfo.bi_esymtab != bootinfo.bi_symtab)
  330                 X_db_sym_init((int *)bootinfo.bi_symtab,
  331                               (char *)((bootinfo.bi_esymtab + sizeof(int) - 1)
  332                                        & ~(sizeof(int) - 1)),
  333                               "kernel");
  334 #endif
  335 }
  336 
  337 #if 0
  338 /*
  339  * Read symbol table from file.
  340  * (should be somewhere else)
  341  */
  342 #include <boot_ufs/file_io.h>
  343 #include <vm/vm_kern.h>
  344 
  345 read_symtab_from_file(fp, symtab_name)
  346         struct file     *fp;
  347         char *          symtab_name;
  348 {
  349         vm_size_t       resid;
  350         kern_return_t   result;
  351         vm_offset_t     symoff;
  352         vm_size_t       symsize;
  353         vm_offset_t     stroff;
  354         vm_size_t       strsize;
  355         vm_size_t       table_size;
  356         vm_offset_t     symtab;
  357 
  358         if (!get_symtab(fp, &symoff, &symsize)) {
  359             boot_printf("[ error %d reading %s file header ]\n",
  360                         result, symtab_name);
  361             return;
  362         }
  363 
  364         stroff = symoff + symsize;
  365         result = read_file(fp, (vm_offset_t)stroff,
  366                         (vm_offset_t)&strsize, sizeof(strsize), &resid);
  367         if (result || resid) {
  368             boot_printf("[ no valid symbol table present for %s ]\n",
  369                 symtab_name);
  370                 return;
  371         }
  372 
  373         table_size = sizeof(int) + symsize + strsize;
  374         table_size = (table_size + sizeof(int)-1) & ~(sizeof(int)-1);
  375 
  376         symtab = kmem_alloc_wired(kernel_map, table_size);
  377 
  378         *(int *)symtab = symsize;
  379 
  380         result = read_file(fp, symoff,
  381                         symtab + sizeof(int), symsize, &resid);
  382         if (result || resid) {
  383             boot_printf("[ error %d reading %s symbol table ]\n",
  384                         result, symtab_name);
  385             return;
  386         }
  387 
  388         result = read_file(fp, stroff,
  389                         symtab + sizeof(int) + symsize, strsize, &resid);
  390         if (result || resid) {
  391             boot_printf("[ error %d reading %s string table ]\n",
  392                         result, symtab_name);
  393             return;
  394         }
  395 
  396         X_db_sym_init((int *)symtab,
  397                         (char *)(symtab + table_size),
  398                         symtab_name);
  399 
  400 }
  401 #endif
  402 #endif

Cache object: bfc4ab9e67752c44ab0df470690e7b95


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