Annotation of XNU/osfmk/ddb/db_sym.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /*
                     26:  * HISTORY
                     27:  * 
                     28:  * Revision 1.1.1.1  1998/09/22 21:05:48  wsanchez
                     29:  * Import of Mac OS X kernel (~semeria)
                     30:  *
                     31:  * Revision 1.1.1.1  1998/03/07 02:26:09  wsanchez
                     32:  * Import of OSF Mach kernel (~mburg)
                     33:  *
                     34:  * Revision 1.3.22.8  1996/07/31  09:07:24  paire
                     35:  *     Merged with nmk20b7_shared (1.3.47.1)
                     36:  *     [96/07/24            paire]
                     37:  *
                     38:  * Revision 1.3.47.1  1996/06/13  12:36:08  bernadat
                     39:  *     Do not assume anymore that VM_MIN_KERNEL_ADDRESS
                     40:  *     is greater or equal than VM_MAX_ADDRESS.
                     41:  *     [96/05/23            bernadat]
                     42:  * 
                     43:  * Revision 1.3.22.7  1996/01/09  19:16:15  devrcs
                     44:  *     Added db_task_getlinenum() function. (steved)
                     45:  *     Make db_maxval & db_minval long int's for Alpha.
                     46:  *     Changed declarations of 'register foo' to 'register int foo'.
                     47:  *     [1995/12/01  21:42:29  jfraser]
                     48:  * 
                     49:  *     Merged '64-bit safe' changes from DEC alpha port.
                     50:  *     [1995/11/21  18:03:41  jfraser]
                     51:  * 
                     52:  * Revision 1.3.22.6  1995/02/28  01:58:46  dwm
                     53:  *     Merged with changes from 1.3.22.5
                     54:  *     [1995/02/28  01:53:47  dwm]
                     55:  * 
                     56:  *     mk6 CR1120 - Merge mk6pro_shared into cnmk_shared
                     57:  *     remove a couple local protos, now in .h file (for better or worse)
                     58:  *     [1995/02/28  01:12:51  dwm]
                     59:  * 
                     60:  * Revision 1.3.22.5  1995/02/23  21:43:43  alanl
                     61:  *     Move TR_INIT to model_dep.c (MACH_TR and MACH_KDB shouldn't
                     62:  *     be bound).
                     63:  *     [95/02/16            travos]
                     64:  * 
                     65:  *     Prepend a "db_" to qsort and qsort_limit_search
                     66:  *     (collisions with the real qsort in stdlib.h)
                     67:  *     [95/02/14            travos]
                     68:  * 
                     69:  *     Added X_db_init for object independent formats.
                     70:  *     [95/01/24            sjs]
                     71:  * 
                     72:  *     Merge with DIPC2_SHARED.
                     73:  *     [1995/01/05  13:32:53  alanl]
                     74:  * 
                     75:  * Revision 1.3.30.2  1994/12/22  20:36:15  bolinger
                     76:  *     Fix ri-osc CR881:  enable freer use of symbol table of collocated
                     77:  *     tasks.  No point in requiring task to be named for symbols to be
                     78:  *     usable.  Also fixed glitch in use of symtab cloning.
                     79:  *     [1994/12/22  20:34:55  bolinger]
                     80:  * 
                     81:  * Revision 1.3.30.1  1994/11/04  09:53:14  dwm
                     82:  *     mk6 CR668 - 1.3b26 merge
                     83:  *     add arg to *_db_search_by_addr() from mk6
                     84:  *     * Revision 1.3.4.9  1994/05/13  15:57:14  tmt
                     85:  *     Add hooks for catching calls to uninstalled symbol tables.
                     86:  *     Add XXX_search_by_addr() vectors.
                     87:  *     * Revision 1.3.4.8  1994/05/12  21:59:00  tmt
                     88:  *     Fix numerous db_sym_t/char * mixups.
                     89:  *     Fix and enable db_qualify_ambiguous_names.
                     90:  *     Make dif and newdiff unsigned in symbol searches.
                     91:  *     * Revision 1.3.4.7  1994/05/06  18:39:52  tmt
                     92:  *     Merged osc1.3dec/shared with osc1.3b19
                     93:  *     Fix function prototype declarations.
                     94:  *     Merge Alpha changes into osc1.312b source code.
                     95:  *     String protos.
                     96:  *     Handle multiple, coexisting symbol table types.
                     97:  *     64bit cleanup.
                     98:  *     Revision 1.3.4.5  1993/10/20  18:58:55  gm
                     99:  *     CR9704: Removed symbol load printf.
                    100:  *     * End1.3merge
                    101:  *     [1994/11/04  08:50:02  dwm]
                    102:  * 
                    103:  * Revision 1.3.22.5  1995/02/23  21:43:43  alanl
                    104:  *     Move TR_INIT to model_dep.c (MACH_TR and MACH_KDB shouldn't
                    105:  *     be bound).
                    106:  *     [95/02/16            travos]
                    107:  * 
                    108:  *     Prepend a "db_" to qsort and qsort_limit_search
                    109:  *     (collisions with the real qsort in stdlib.h)
                    110:  *     [95/02/14            travos]
                    111:  * 
                    112:  *     Added X_db_init for object independent formats.
                    113:  *     [95/01/24            sjs]
                    114:  * 
                    115:  *     Merge with DIPC2_SHARED.
                    116:  *     [1995/01/05  13:32:53  alanl]
                    117:  * 
                    118:  * Revision 1.3.30.2  1994/12/22  20:36:15  bolinger
                    119:  *     Fix ri-osc CR881:  enable freer use of symbol table of collocated
                    120:  *     tasks.  No point in requiring task to be named for symbols to be
                    121:  *     usable.  Also fixed glitch in use of symtab cloning.
                    122:  *     [1994/12/22  20:34:55  bolinger]
                    123:  * 
                    124:  * Revision 1.3.30.1  1994/11/04  09:53:14  dwm
                    125:  *     mk6 CR668 - 1.3b26 merge
                    126:  *     add arg to *_db_search_by_addr() from mk6
                    127:  *     * Revision 1.3.4.9  1994/05/13  15:57:14  tmt
                    128:  *     Add hooks for catching calls to uninstalled symbol tables.
                    129:  *     Add XXX_search_by_addr() vectors.
                    130:  *     * Revision 1.3.4.8  1994/05/12  21:59:00  tmt
                    131:  *     Fix numerous db_sym_t/char * mixups.
                    132:  *     Fix and enable db_qualify_ambiguous_names.
                    133:  *     Make dif and newdiff unsigned in symbol searches.
                    134:  *     * Revision 1.3.4.7  1994/05/06  18:39:52  tmt
                    135:  *     Merged osc1.3dec/shared with osc1.3b19
                    136:  *     Fix function prototype declarations.
                    137:  *     Merge Alpha changes into osc1.312b source code.
                    138:  *     String protos.
                    139:  *     Handle multiple, coexisting symbol table types.
                    140:  *     64bit cleanup.
                    141:  *     Revision 1.3.4.5  1993/10/20  18:58:55  gm
                    142:  *     CR9704: Removed symbol load printf.
                    143:  *     * End1.3merge
                    144:  *     [1994/11/04  08:50:02  dwm]
                    145:  * 
                    146:  * Revision 1.3.22.3  1994/09/23  01:21:37  ezf
                    147:  *     change marker to not FREE
                    148:  *     [1994/09/22  21:10:58  ezf]
                    149:  * 
                    150:  * Revision 1.3.22.2  1994/06/26  22:58:24  bolinger
                    151:  *     Suppress symbol table range output when table is unsorted, since output
                    152:  *     is meaningless in this case.
                    153:  *     [1994/06/23  20:19:02  bolinger]
                    154:  * 
                    155:  * Revision 1.3.22.1  1994/06/11  21:12:19  bolinger
                    156:  *     Merge up to NMK17.2.
                    157:  *     [1994/06/11  20:02:31  bolinger]
                    158:  * 
                    159:  * Revision 1.3.17.1  1994/02/08  10:58:40  bernadat
                    160:  *     Check result of X_db_line_at_pc() before
                    161:  *     invoking db_shorten_filename().
                    162:  *     [93/11/30            bernadat]
                    163:  * 
                    164:  *     Installed ddb_init() routine in a symbol-independent file to call
                    165:  *     symbol-dependent and machine-dependent initialization routines.
                    166:  *     [93/08/27            paire]
                    167:  * 
                    168:  *     Fixed db_shorten_filename() to gobble the last slash.
                    169:  *     Modified db_search_task_symbol_and_line() interface to return
                    170:  *     the number of a function arguments.
                    171:  *     [93/08/19            paire]
                    172:  * 
                    173:  *     Added new arguments to db_sym_print_completion() call.
                    174:  *     [93/08/18            paire]
                    175:  * 
                    176:  *     Added db_lookup_incomplete(), db_sym_parse_and_lookup_incomplete(),
                    177:  *     db_sym_print_completion() and db_completion_print() for support of
                    178:  *     symbol completion.
                    179:  *     [93/08/14            paire]
                    180:  *     [94/02/07            bernadat]
                    181:  * 
                    182:  * Revision 1.3.15.4  1994/06/08  19:11:23  dswartz
                    183:  *     Preemption merge.
                    184:  *     [1994/06/08  19:10:24  dswartz]
                    185:  * 
                    186:  * Revision 1.3.20.2  1994/06/01  21:34:39  klj
                    187:  *     Initial preemption code base merge
                    188:  * 
                    189:  * Revision 1.3.15.3  1994/02/10  02:28:15  bolinger
                    190:  *     Fix db_add_symbol_table() to increase db_maxval if highest-addressed
                    191:  *     symbol in new symtab is greater than its current value.
                    192:  *     [1994/02/09  21:42:12  bolinger]
                    193:  * 
                    194:  * Revision 1.3.15.2  1994/02/03  21:44:23  bolinger
                    195:  *     Update db_maxval when a symbol table is cloned for kernel-loaded
                    196:  *     server.
                    197:  *     [1994/02/03  20:47:22  bolinger]
                    198:  * 
                    199:  * Revision 1.3.15.1  1994/02/03  02:41:58  dwm
                    200:  *     Add short-term kludge to provide symbolic info on INKServer.
                    201:  *     [1994/02/03  02:31:17  dwm]
                    202:  * 
                    203:  * Revision 1.3.4.4  1993/08/11  20:38:11  elliston
                    204:  *     Add ANSI Prototypes.  CR #9523.
                    205:  *     [1993/08/11  03:33:59  elliston]
                    206:  * 
                    207:  * Revision 1.3.4.3  1993/07/27  18:28:09  elliston
                    208:  *     Add ANSI prototypes.  CR #9523.
                    209:  *     [1993/07/27  18:12:57  elliston]
                    210:  * 
                    211:  * Revision 1.3.4.2  1993/06/09  02:20:50  gm
                    212:  *     CR9176 - ANSI C violations: trailing tokens on CPP
                    213:  *     directives, extra semicolons after decl_ ..., asm keywords
                    214:  *     [1993/06/07  18:57:31  jeffc]
                    215:  * 
                    216:  *     Added to OSF/1 R1.3 from NMK15.0.
                    217:  *     [1993/06/02  20:57:10  jeffc]
                    218:  * 
                    219:  * Revision 1.3  1993/04/19  16:03:09  devrcs
                    220:  *     Protect db_line_at_pc() against null db_last_symtab.
                    221:  *     [1993/02/11  15:37:16  barbou]
                    222:  * 
                    223:  *     Changes from MK78:
                    224:  *     Upped MAXNOSYMTABS from 3 to 5. Now there is space for kernel,
                    225:  *      bootstrap, server, and emulator symbols - plus one for future
                    226:  *      expansion.
                    227:  *     [92/03/21            danner]
                    228:  *     Changed CHAR arg of db_eqname to UNSIGNED.
                    229:  *     Made arg types proper for db_line_at_pc().
                    230:  *     [92/05/16            jfriedl]
                    231:  *     [92/12/18            bruel]
                    232:  * 
                    233:  *     Sort large symbol tables to speedup lookup.
                    234:  *     Improved symbol lookup (use of max_offset, dichotomic search)
                    235:  *     [[email protected]]
                    236:  * 
                    237:  *     db_add_symbol_table now takes 3 additional arguments. Machine
                    238:  *     dependant modules must provide them. [[email protected]]
                    239:  *     [92/12/03            bernadat]
                    240:  * 
                    241:  * Revision 1.2  1992/11/25  01:04:42  robert
                    242:  *     integrate changes below for norma_14
                    243:  *     [1992/11/13  19:22:44  robert]
                    244:  * 
                    245:  * Revision 1.1  1992/09/30  02:01:25  robert
                    246:  *     Initial revision
                    247:  * 
                    248:  * $EndLog$
                    249:  */
                    250: /* CMU_HIST */
                    251: /*
                    252:  * Revision 2.10.4.1  92/02/18  18:38:53  jeffreyh
                    253:  *     Added db_get_sym(). Simple interface to get symbol names
                    254:  *     knowing the offset.
                    255:  *     [91/12/20            bernadat]
                    256:  * 
                    257:  *     Do not look for symbol names if address
                    258:  *     is to small or to large, otherwise get
                    259:  *     random names like INCLUDE_VERSION+??
                    260:  *     [91/06/25            bernadat]
                    261:  * 
                    262:  * Revision 2.10  91/10/09  16:02:30  af
                    263:  *      Revision 2.9.2.1  91/10/05  13:07:27  jeffreyh
                    264:  *             Changed symbol table name qualification syntax from "xxx:yyy"
                    265:  *               to "xxx::yyy" to allow "file:func:line" in "yyy" part.
                    266:  *                    "db_sym_parse_and_lookup" is also added for "yyy" part parsing.
                    267:  *             Replaced db_search_symbol with db_search_task_symbol, and moved
                    268:  *               it to "db_sym.h" as a macro.
                    269:  *             Added db_task_printsym, and changed db_printsym to call it.
                    270:  *             Added include "db_task_thread.h".
                    271:  *             Fixed infinite recursion of db_symbol_values.
                    272:  *             [91/08/29            tak]
                    273:  * 
                    274:  * Revision 2.9.2.1  91/10/05  13:07:27  jeffreyh
                    275:  *     Changed symbol table name qualification syntax from "xxx:yyy"
                    276:  *       to "xxx::yyy" to allow "file:func:line" in "yyy" part.
                    277:  *            "db_sym_parse_and_lookup" is also added for "yyy" part parsing.
                    278:  *     Replaced db_search_symbol with db_search_task_symbol, and moved
                    279:  *       it to "db_sym.h" as a macro.
                    280:  *     Added db_task_printsym, and changed db_printsym to call it.
                    281:  *     Added include "db_task_thread.h".
                    282:  *     Fixed infinite recursion of db_symbol_values.
                    283:  *     [91/08/29            tak]
                    284:  * 
                    285:  * Revision 2.9  91/07/31  17:31:14  dbg
                    286:  *     Add task pointer and space for string storage to symbol table
                    287:  *     descriptor.
                    288:  *     [91/07/31            dbg]
                    289:  * 
                    290:  * Revision 2.8  91/07/09  23:16:08  danner
                    291:  *     Changed a printf.
                    292:  *     [91/07/08            danner]
                    293:  * 
                    294:  * Revision 2.7  91/05/14  15:35:54  mrt
                    295:  *     Correcting copyright
                    296:  * 
                    297:  * Revision 2.6  91/03/16  14:42:40  rpd
                    298:  *     Changed the default db_maxoff to 4K.
                    299:  *     [91/03/10            rpd]
                    300:  * 
                    301:  * Revision 2.5  91/02/05  17:07:07  mrt
                    302:  *     Changed to new Mach copyright
                    303:  *     [91/01/31  16:19:17  mrt]
                    304:  * 
                    305:  * Revision 2.4  90/10/25  14:44:05  rwd
                    306:  *     Changed db_printsym to print unsigned.
                    307:  *     [90/10/19            rpd]
                    308:  * 
                    309:  * Revision 2.3  90/09/09  23:19:56  rpd
                    310:  *     Avoid totally incorrect guesses of symbol names for small values.
                    311:  *     [90/08/30  17:39:48  af]
                    312:  * 
                    313:  * Revision 2.2  90/08/27  21:52:18  dbg
                    314:  *     Removed nlist.h.  Fixed some type declarations.
                    315:  *     Qualifier character is ':'.
                    316:  *     [90/08/20            dbg]
                    317:  *     Modularized symtab info into a new db_symtab_t type.
                    318:  *     Modified db_add_symbol_table  and others accordingly.
                    319:  *     Defined db_sym_t, a new (opaque) type used to represent
                    320:  *     symbols.  This should support all sort of future symtable
                    321:  *     formats. Functions like db_qualify take a db_sym_t now.
                    322:  *     New db_symbol_values() function to explode the content
                    323:  *     of a db_sym_t.
                    324:  *     db_search_symbol() replaces db_find_sym_and_offset(), which is
                    325:  *     now a macro defined in our (new) header file.  This new
                    326:  *     function accepts more restrictive searches, which are
                    327:  *     entirely delegated to the symtab-specific code.
                    328:  *     Accordingly, db_printsym() accepts a strategy parameter.
                    329:  *     New db_line_at_pc() function.
                    330:  *     Renamed misleading db_eqsym into db_eqname.
                    331:  *     [90/08/20  10:47:06  af]
                    332:  * 
                    333:  *     Created.
                    334:  *     [90/07/25            dbg]
                    335:  * 
                    336:  * Revision 2.1  90/07/26  16:43:52  dbg
                    337:  * Created.
                    338:  * 
                    339:  */
                    340: /* CMU_ENDHIST */
                    341: /* 
                    342:  * Mach Operating System
                    343:  * Copyright (c) 1991,1990 Carnegie Mellon University
                    344:  * All Rights Reserved.
                    345:  * 
                    346:  * Permission to use, copy, modify and distribute this software and its
                    347:  * documentation is hereby granted, provided that both the copyright
                    348:  * notice and this permission notice appear in all copies of the
                    349:  * software, derivative works or modified versions, and any portions
                    350:  * thereof, and that both notices appear in supporting documentation.
                    351:  * 
                    352:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                    353:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                    354:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                    355:  * 
                    356:  * Carnegie Mellon requests users of this software to return to
                    357:  * 
                    358:  *  Software Distribution Coordinator  or  [email protected]
                    359:  *  School of Computer Science
                    360:  *  Carnegie Mellon University
                    361:  *  Pittsburgh PA 15213-3890
                    362:  * 
                    363:  * any improvements or extensions that they make and grant Carnegie Mellon
                    364:  * the rights to redistribute these changes.
                    365:  */
                    366: /*
                    367:  */
                    368: /*
                    369:  *     Author: David B. Golub, Carnegie Mellon University
                    370:  *     Date:   7/90
                    371:  */
                    372: 
                    373: #include <machine/db_machdep.h>
                    374: #include <string.h>                    /* For strcpy(), strcmp() */
                    375: #include <mach/std_types.h>
                    376: #include <kern/misc_protos.h>          /* For printf() */
                    377: #include <ddb/db_sym.h>
                    378: #include <ddb/db_task_thread.h>
                    379: #include <ddb/db_command.h>
                    380: #include <ddb/db_output.h>             /* For db_printf() */
                    381: 
                    382: #include <vm/vm_map.h> /* vm_map_t */
                    383: 
                    384: /*
                    385:  * Multiple symbol tables
                    386:  *
                    387:  * mach, bootstrap, name_server, default_pager, unix, 1 spare
                    388:  */
                    389: #define        MAXNOSYMTABS    6
                    390: 
                    391: db_symtab_t    db_symtabs[MAXNOSYMTABS] = {{0}};
                    392: int db_nsymtab = 0;
                    393: 
                    394: db_symtab_t    *db_last_symtab;
                    395: 
                    396: unsigned long  db_maxoff = 0x4000;
                    397: extern         char end;
                    398: unsigned long  db_maxval = (unsigned long)&end;
                    399: natural_t      db_minval = 0x1000;
                    400: 
                    401: /* Prototypes for functions local to this file.  XXX -- should be static!
                    402:  */
                    403: static char *db_qualify(
                    404:        char            *sym,
                    405:        register char   *symtabname);
                    406: 
                    407: boolean_t db_eqname(
                    408:        char            *src,
                    409:        char            *dst,
                    410:        unsigned        c);
                    411: 
                    412: boolean_t db_symbol_is_ambiguous(char *name);
                    413: 
                    414: void db_shorten_filename(char **filenamep);
                    415: 
                    416: void qsort_swap(
                    417:        register int    *a,
                    418:        register int    *b,
                    419:        register int    size);
                    420: 
                    421: void qsort_rotate(
                    422:        register int    *a,
                    423:        register int    *b,
                    424:        register int    *c,
                    425:        register int    size);
                    426: 
                    427: void qsort_recur(
                    428:        char    *left,
                    429:        char    *right,
                    430:        int     eltsize,
                    431:        int     (*compfun)(char *, char *));
                    432: 
                    433: void qsort_checker(
                    434:        char    *table,
                    435:        int     nbelts,
                    436:        int     eltsize,
                    437:        int     (*compfun)(char *, char *));
                    438: 
                    439: void bubble_sort(
                    440:        char    *table,
                    441:        int     nbelts,
                    442:        int     eltsize,
                    443:        int     (*compfun)(char *, char *));
                    444: 
                    445: int no_print_completion(
                    446:        db_symtab_t     *stab,
                    447:        char            *symstr );
                    448: int no_lookup_incomplete(
                    449:        db_symtab_t     *stab,
                    450:        char            *symstr,
                    451:        char            **name,
                    452:        int             *len,
                    453:        int             *toadd);
                    454: 
                    455: /*
                    456:  * Initialization routine for ddb.
                    457:  */
                    458: void
                    459: ddb_init(void)
                    460: {
                    461:        X_db_init();
                    462:        db_machdep_init();
                    463: }
                    464: 
                    465: /*
                    466:  * Add symbol table, with given name, to list of symbol tables.
                    467:  */
                    468: boolean_t
                    469: db_add_symbol_table(
                    470:        int             type,
                    471:        char            *start,
                    472:        char            *end,
                    473:        char            *name,
                    474:        char            *ref,
                    475:        char            *map_pointer,
                    476:        unsigned long   minsym,
                    477:        unsigned long   maxsym,
                    478:        boolean_t       sorted)
                    479: {
                    480:        register db_symtab_t *st;
                    481:        extern vm_map_t kernel_map;
                    482: 
                    483:        if (db_nsymtab >= MAXNOSYMTABS)
                    484:            return (FALSE);
                    485: 
                    486:        st = &db_symtabs[db_nsymtab];
                    487:        st->type = type;
                    488:        st->start = start;
                    489:        st->end = end;
                    490:        st->private = ref;
                    491:        if (map_pointer == (char *)kernel_map || 
                    492:            (VM_MAX_ADDRESS <= VM_MIN_KERNEL_ADDRESS &&
                    493:             VM_MIN_KERNEL_ADDRESS <= minsym))
                    494:                st->map_pointer = 0;
                    495:        else
                    496:                st->map_pointer = map_pointer;
                    497:        strcpy(st->name, name);
                    498:        st->minsym = minsym;
                    499:        st->maxsym = maxsym;
                    500:        if (maxsym == 0)
                    501:                st->sorted = FALSE;
                    502:        else {
                    503:                st->sorted = sorted;
                    504:                if (db_maxval < maxsym + db_maxoff)
                    505:                        db_maxval = maxsym + db_maxoff;
                    506:        }
                    507:        db_nsymtab++;
                    508: 
                    509:        return (TRUE);
                    510: }
                    511: 
                    512: /*
                    513:  *  db_qualify("vm_map", "ux") returns "ux::vm_map".
                    514:  *
                    515:  *  Note: return value points to static data whose content is
                    516:  *  overwritten by each call... but in practice this seems okay.
                    517:  */
                    518: static char *
                    519: db_qualify(
                    520:        char            *symname,
                    521:        register char   *symtabname)
                    522: {
                    523:        static char     tmp[256];
                    524:        register char   *s;
                    525: 
                    526:        s = tmp;
                    527:        while (*s++ = *symtabname++) {
                    528:        }
                    529:        s[-1] = ':';
                    530:        *s++ = ':';
                    531:        while (*s++ = *symname++) {
                    532:        }
                    533:        return tmp;
                    534: }
                    535: 
                    536: 
                    537: boolean_t
                    538: db_eqname(
                    539:        char            *src,
                    540:        char            *dst,
                    541:        unsigned        c)
                    542: {
                    543:        if (!strcmp(src, dst))
                    544:            return (TRUE);
                    545:        if (src[0] == c)
                    546:            return (!strcmp(src+1,dst));
                    547:        return (FALSE);
                    548: }
                    549: 
                    550: boolean_t
                    551: db_value_of_name(
                    552:        char            *name,
                    553:        db_expr_t       *valuep)
                    554: {
                    555:        db_sym_t        sym;
                    556: 
                    557:        sym = db_lookup(name);
                    558:        if (sym == DB_SYM_NULL)
                    559:            return (FALSE);
                    560:        db_symbol_values(0, sym, &name, valuep);
                    561:        return (TRUE);
                    562: }
                    563: 
                    564: /*
                    565:  * Display list of possible completions for a symbol.
                    566:  */
                    567: void
                    568: db_print_completion(
                    569:        char *symstr)
                    570: {
                    571:        register int i;
                    572:        int symtab_start = 0;
                    573:        int symtab_end = db_nsymtab;
                    574:        register char *cp;
                    575:        int nsym = 0;
                    576:        char *name = (char *)0;
                    577:        int len;
                    578:        int toadd;
                    579: 
                    580:        /*
                    581:         * Look for, remove, and remember any symbol table specifier.
                    582:         */
                    583:        for (cp = symstr; *cp; cp++) {
                    584:                if (*cp == ':' && cp[1] == ':') {
                    585:                        *cp = '\0';
                    586:                        for (i = 0; i < db_nsymtab; i++) {
                    587:                                if (! strcmp(symstr, db_symtabs[i].name)) {
                    588:                                        symtab_start = i;
                    589:                                        symtab_end = i + 1;
                    590:                                        break;
                    591:                                }
                    592:                        }
                    593:                        *cp = ':';
                    594:                        if (i == db_nsymtab)
                    595:                                return;
                    596:                        symstr = cp+2;
                    597:                }
                    598:        }
                    599: 
                    600:        /*
                    601:         * Look in the specified set of symbol tables.
                    602:         * Return on first match.
                    603:         */
                    604:        for (i = symtab_start; i < symtab_end; i++) {
                    605:                if (X_db_print_completion(&db_symtabs[i], symstr))
                    606:                        break;
                    607:        }
                    608: }
                    609: 
                    610: /*
                    611:  * Lookup a (perhaps incomplete) symbol.
                    612:  * If the symbol has a qualifier (e.g., ux::vm_map),
                    613:  * then only the specified symbol table will be searched;
                    614:  * otherwise, all symbol tables will be searched.
                    615:  */
                    616: int
                    617: db_lookup_incomplete(
                    618:        char *symstr,
                    619:        int symlen)
                    620: {
                    621:        register int i;
                    622:        int symtab_start = 0;
                    623:        int symtab_end = db_nsymtab;
                    624:        register char *cp;
                    625:        int nsym = 0;
                    626:        char *name = (char *)0;
                    627:        int len;
                    628:        int toadd;
                    629: 
                    630:        /*
                    631:         * Look for, remove, and remember any symbol table specifier.
                    632:         */
                    633:        for (cp = symstr; *cp; cp++) {
                    634:                if (*cp == ':' && cp[1] == ':') {
                    635:                        *cp = '\0';
                    636:                        for (i = 0; i < db_nsymtab; i++) {
                    637:                                if (! strcmp(symstr, db_symtabs[i].name)) {
                    638:                                        symtab_start = i;
                    639:                                        symtab_end = i + 1;
                    640:                                        break;
                    641:                                }
                    642:                        }
                    643:                        *cp = ':';
                    644:                        if (i == db_nsymtab)
                    645:                                return 0;
                    646:                        symstr = cp+2;
                    647:                }
                    648:        }
                    649: 
                    650:        /*
                    651:         * Look in the specified set of symbol tables.
                    652:         * Return on first match.
                    653:         */
                    654:        for (i = symtab_start; i < symtab_end; i++) {
                    655:                nsym = X_db_lookup_incomplete(&db_symtabs[i], symstr,
                    656:                                              &name, &len, &toadd);
                    657:                if (nsym > 0) {
                    658:                        if (toadd > 0) {
                    659:                                len = strlen(symstr);
                    660:                                if (len + toadd >= symlen)
                    661:                                        return 0;
                    662:                                bcopy(&name[len], &symstr[len], toadd);
                    663:                                symstr[len + toadd] = '\0';
                    664:                        }
                    665:                        break;
                    666:                }
                    667:        }
                    668:        return nsym;
                    669: }
                    670: 
                    671: /*
                    672:  * Lookup a symbol.
                    673:  * If the symbol has a qualifier (e.g., ux::vm_map),
                    674:  * then only the specified symbol table will be searched;
                    675:  * otherwise, all symbol tables will be searched.
                    676:  */
                    677: db_sym_t
                    678: db_lookup(char *symstr)
                    679: {
                    680:        db_sym_t sp;
                    681:        register int i;
                    682:        int symtab_start = 0;
                    683:        int symtab_end = db_nsymtab;
                    684:        register char *cp;
                    685: 
                    686:        /*
                    687:         * Look for, remove, and remember any symbol table specifier.
                    688:         */
                    689:        for (cp = symstr; *cp; cp++) {
                    690:                if (*cp == ':' && cp[1] == ':') {
                    691:                        *cp = '\0';
                    692:                        for (i = 0; i < db_nsymtab; i++) {
                    693:                                if (! strcmp(symstr, db_symtabs[i].name)) {
                    694:                                        symtab_start = i;
                    695:                                        symtab_end = i + 1;
                    696:                                        break;
                    697:                                }
                    698:                        }
                    699:                        *cp = ':';
                    700:                        if (i == db_nsymtab)
                    701:                                db_error("Invalid symbol table name\n");
                    702:                        symstr = cp+2;
                    703:                }
                    704:        }
                    705: 
                    706:        /*
                    707:         * Look in the specified set of symbol tables.
                    708:         * Return on first match.
                    709:         */
                    710:        for (i = symtab_start; i < symtab_end; i++) {
                    711:                if (sp = X_db_lookup(&db_symtabs[i], symstr)) {
                    712:                        db_last_symtab = &db_symtabs[i];
                    713:                        return sp;
                    714:                }
                    715:        }
                    716:        return 0;
                    717: }
                    718: 
                    719: /*
                    720:  * Print a symbol completion
                    721:  */
                    722: void
                    723: db_sym_print_completion(
                    724:        db_symtab_t *stab,
                    725:        char *name,
                    726:        int function,
                    727:        char *fname,
                    728:        int line)
                    729: {
                    730:        if (stab != db_symtabs)
                    731:                db_printf("%s::", stab->name);
                    732:        db_printf(name);
                    733:        if (function) {
                    734:            db_putchar('(');
                    735:            db_putchar(')');
                    736:        }
                    737:        if (fname) {
                    738:            db_printf(" [static from %s", fname);
                    739:            if (line > 0)
                    740:                db_printf(":%d", line);
                    741:            db_putchar(']');
                    742:        }
                    743:        db_putchar('\n');
                    744: }
                    745: 
                    746: /*
                    747:  * Common utility routine to parse a symbol string into a file
                    748:  * name, a (possibly incomplete) symbol name without line number.
                    749:  * This routine is called from aout_db_print_completion if the object
                    750:  * dependent handler supports qualified search with a file name.
                    751:  * It parses the symbol string, and call an object dependent routine
                    752:  * with parsed file name and symbol name.
                    753:  */ 
                    754: int
                    755: db_sym_parse_and_print_completion(
                    756:        int             (*func)(db_symtab_t *,
                    757:                                 char *),
                    758:        db_symtab_t     *symtab,
                    759:        char            *symstr)
                    760: {
                    761:        register        char *p;
                    762:        register int    n;
                    763:        char            *sym_name;
                    764:        char            *component[2];
                    765:        int             nsym;
                    766: 
                    767:        /*
                    768:         * disassemble the symbol into components: [file_name:]symbol
                    769:         */
                    770:        component[0] = symstr;
                    771:        component[1] = 0;
                    772:        for (p = symstr, n = 1; *p; p++) {
                    773:                if (*p == ':') {
                    774:                        if (n == 2)
                    775:                                break;
                    776:                        *p = 0;
                    777:                        component[n++] = p+1;
                    778:                }
                    779:        }
                    780:        if (*p == 0) {
                    781:                if (n == 1) {
                    782:                        sym_name = component[0];
                    783:                } else {
                    784:                        sym_name = component[1];
                    785:                }
                    786:                nsym = func(symtab, sym_name);
                    787:        } else
                    788:                nsym = 0;
                    789:        if (n == 2)
                    790:                component[1][-1] = ':';
                    791:        return nsym;
                    792: }
                    793: 
                    794: /*
                    795:  * Common utility routine to parse a symbol string into a file
                    796:  * name, a (possibly incomplete) symbol name without line number.
                    797:  * This routine is called from X_db_lookup_incomplete if the object
                    798:  * dependent handler supports qualified search with a file name.
                    799:  * It parses the symbol string, and call an object dependent routine
                    800:  * with parsed file name and symbol name.
                    801:  */ 
                    802: int
                    803: db_sym_parse_and_lookup_incomplete(
                    804:        int             (*func)(db_symtab_t *,
                    805:                                char *,
                    806:                                char *,
                    807:                                int,
                    808:                                db_sym_t*,
                    809:                                char **,
                    810:                                int *),
                    811:        db_symtab_t     *symtab,
                    812:        char            *symstr,
                    813:        char            **name,
                    814:        int             *len,
                    815:        int             *toadd)
                    816: {
                    817:        register        char *p;
                    818:        register int    n;
                    819:        char            *file_name = 0;
                    820:        char            *sym_name = 0;
                    821:        char            *component[2];
                    822:        int             nsym = 0;
                    823: 
                    824:        /*
                    825:         * disassemble the symbol into components: [file_name:]symbol
                    826:         */
                    827:        component[0] = symstr;
                    828:        component[1] = 0;
                    829:        for (p = symstr, n = 1; *p; p++) {
                    830:                if (*p == ':') {
                    831:                        if (n == 2)
                    832:                                break;
                    833:                        *p = 0;
                    834:                        component[n++] = p+1;
                    835:                }
                    836:        }
                    837:        if (*p == 0) {
                    838:                if (n == 1) {
                    839:                        file_name = 0;
                    840:                        sym_name = component[0];
                    841:                } else {
                    842:                        file_name = component[0];
                    843:                        sym_name = component[1];
                    844:                }
                    845:                nsym = func(symtab, file_name, sym_name, 0, (db_sym_t *)0,
                    846:                            name, len);
                    847:                if (nsym > 0)
                    848:                        *toadd = *len - strlen(sym_name);
                    849:        }
                    850:        if (n == 2)
                    851:                component[1][-1] = ':';
                    852:        return(nsym);
                    853: }
                    854: 
                    855: /*
                    856:  * Common utility routine to parse a symbol string into a file
                    857:  * name, a symbol name and line number.
                    858:  * This routine is called from aout_db_lookup if the object dependent
                    859:  * handler supports qualified search with a file name or a line number.
                    860:  * It parses the symbol string, and call an object dependent routine
                    861:  * with parsed file name, symbol name and line number.
                    862:  */ 
                    863: db_sym_t
                    864: db_sym_parse_and_lookup(
                    865:        int             (*func)(db_symtab_t *, char *, char *, int,
                    866:                                db_sym_t*, char **, int *),
                    867:        db_symtab_t     *symtab,
                    868:        char            *symstr)
                    869: {
                    870:        register        char *p;
                    871:        register int    n;
                    872:        int             n_name;
                    873:        int             line_number;
                    874:        char            *file_name = 0;
                    875:        char            *sym_name = 0;
                    876:        char            *component[3];
                    877:        db_sym_t        found = DB_SYM_NULL;
                    878: 
                    879:        /*
                    880:         * disassemble the symbol into components:
                    881:         *      [file_name:]symbol[:line_nubmer]
                    882:         */
                    883:        component[0] = symstr;
                    884:        component[1] = component[2] = 0;
                    885:        for (p = symstr, n = 1; *p; p++) {
                    886:                if (*p == ':') {
                    887:                        if (n >= 3)
                    888:                                break;
                    889:                        *p = 0;
                    890:                        component[n++] = p+1;
                    891:                }
                    892:        }
                    893:        if (*p != 0)
                    894:                goto out;
                    895:        line_number = 0;
                    896:        n_name = n;
                    897:        p = component[n-1];
                    898:        if (*p >= '0' && *p <= '9') {
                    899:                if (n == 1)
                    900:                        goto out;
                    901:                for (line_number = 0; *p; p++) {
                    902:                        if (*p < '0' || *p > '9')
                    903:                                goto out;
                    904:                        line_number = line_number*10 + *p - '0';
                    905:                }
                    906:                n_name--;
                    907:        } else if (n >= 3)
                    908:                goto out;
                    909:        if (n_name == 1) {
                    910:                for (p = component[0]; *p && *p != '.'; p++);
                    911:                if (*p == '.') {
                    912:                        file_name = component[0];
                    913:                        sym_name = 0;
                    914:                } else {
                    915:                        file_name = 0;
                    916:                        sym_name = component[0];
                    917:                }
                    918:        } else {
                    919:                file_name = component[0];
                    920:                sym_name = component[1];
                    921:        }
                    922:        (void) func(symtab, file_name, sym_name, line_number, &found,
                    923:                   (char **)0, (int *)0);
                    924:        
                    925: out:
                    926:        while (--n >= 1)
                    927:                component[n][-1] = ':';
                    928:        return(found);
                    929: }
                    930: 
                    931: /*
                    932:  * Does this symbol name appear in more than one symbol table?
                    933:  * Used by db_symbol_values to decide whether to qualify a symbol.
                    934:  */
                    935: boolean_t db_qualify_ambiguous_names = TRUE;
                    936: 
                    937: boolean_t
                    938: db_symbol_is_ambiguous(char *name)
                    939: {
                    940:        register int    i;
                    941:        register
                    942:        boolean_t       found_once = FALSE;
                    943: 
                    944:        if (!db_qualify_ambiguous_names)
                    945:                return FALSE;
                    946: 
                    947:        for (i = 0; i < db_nsymtab; i++) {
                    948:                if (X_db_lookup(&db_symtabs[i], name)) {
                    949:                        if (found_once)
                    950:                                return TRUE;
                    951:                        found_once = TRUE;
                    952:                }
                    953:        }
                    954:        return FALSE;
                    955: }
                    956: 
                    957: /*
                    958:  * Find the closest symbol to val, and return its name
                    959:  * and the difference between val and the symbol found.
                    960:  */
                    961: unsigned int db_search_maxoff = 0x4000;
                    962: db_sym_t
                    963: db_search_task_symbol(
                    964:        register db_addr_t      val,
                    965:        db_strategy_t           strategy,
                    966:        db_addr_t               *offp,  /* better be unsigned */
                    967:        task_t                  task)
                    968: {
                    969:        unsigned long   diff, newdiff;
                    970:        register int    i;
                    971:        db_symtab_t     *sp;
                    972:        db_sym_t        ret = DB_SYM_NULL, sym;
                    973:        vm_map_t        map_for_val;
                    974: 
                    975:        if (task == TASK_NULL)
                    976:            task = db_current_task();
                    977:        map_for_val = (task == TASK_NULL)? VM_MAP_NULL: task->map;
                    978: again:
                    979:        newdiff = diff = ~0UL;
                    980:        db_last_symtab = 0;
                    981:        for (sp = &db_symtabs[0], i = 0;
                    982:             i < db_nsymtab;
                    983:             sp++, i++) {
                    984:            if (((vm_map_t)sp->map_pointer == VM_MAP_NULL ||
                    985:                 (vm_map_t)sp->map_pointer == map_for_val) &&
                    986:                (sp->maxsym == 0 ||
                    987:                 ((unsigned long) val >= sp->minsym &&
                    988:                  (unsigned long) val <= sp->maxsym))) {
                    989:                sym = X_db_search_symbol(sp, val, strategy,
                    990:                                                (db_expr_t *)&newdiff);
                    991:                if (newdiff < diff) {
                    992:                    db_last_symtab = sp;
                    993:                    diff = newdiff;
                    994:                    ret = sym;
                    995:                    if (diff <= db_search_maxoff)
                    996:                        break;
                    997:                }
                    998:            }
                    999:        }
                   1000:        if (ret == DB_SYM_NULL && map_for_val != VM_MAP_NULL) {
                   1001:                map_for_val = VM_MAP_NULL;
                   1002:                goto again;
                   1003:        }
                   1004:        *offp = diff;
                   1005:        return ret;
                   1006: }
                   1007: 
                   1008: /*
                   1009:  * Find the closest symbol to val, and return its name
                   1010:  * and the difference between val and the symbol found.
                   1011:  * Also return the filename and linenumber if available.
                   1012:  */
                   1013: db_sym_t
                   1014: db_search_task_symbol_and_line(
                   1015:        register db_addr_t      val,
                   1016:        db_strategy_t           strategy,
                   1017:        db_expr_t               *offp,
                   1018:        char                    **filenamep,
                   1019:        int                     *linenump,
                   1020:        task_t                  task,
                   1021:        int                     *argsp)
                   1022: {
                   1023:        unsigned long   diff, newdiff;
                   1024:        register int    i;
                   1025:        db_symtab_t     *sp;
                   1026:        db_sym_t        ret = DB_SYM_NULL, sym;
                   1027:        vm_map_t        map_for_val;
                   1028:        char            *func;
                   1029:        char            *filename;
                   1030:        int             linenum;
                   1031:        int             args;
                   1032: 
                   1033:        if (task == TASK_NULL)
                   1034:            task = db_current_task();
                   1035:        map_for_val = (task == TASK_NULL)? VM_MAP_NULL: task->map;
                   1036:        *filenamep = (char *) 0;
                   1037:        *linenump = 0;
                   1038:        *argsp = -1;
                   1039:     again:
                   1040:        filename = (char *) 0;
                   1041:        linenum = 0;
                   1042:        newdiff = diff = ~0UL;
                   1043:        db_last_symtab = 0;
                   1044:        for (sp = &db_symtabs[0], i = 0;
                   1045:             i < db_nsymtab;
                   1046:             sp++, i++) {
                   1047:            if (((vm_map_t)sp->map_pointer == VM_MAP_NULL ||
                   1048:                 (vm_map_t)sp->map_pointer == map_for_val) &&
                   1049:                (sp->maxsym == 0 ||
                   1050:                 ((unsigned long) val >= sp->minsym &&
                   1051:                  (unsigned long) val <= sp->maxsym))) {
                   1052:                sym = X_db_search_by_addr(sp, val, &filename, &func,
                   1053:                                          &linenum, (db_expr_t *)&newdiff,
                   1054:                                          &args);
                   1055:                if (sym && newdiff < diff) {
                   1056:                    db_last_symtab = sp;
                   1057:                    diff = newdiff;
                   1058:                    ret = sym;
                   1059:                    *filenamep = filename;
                   1060:                    *linenump = linenum;
                   1061:                    *argsp = args;
                   1062:                    if (diff <= db_search_maxoff)
                   1063:                        break;
                   1064:                }
                   1065:            }
                   1066:        }
                   1067:        if (ret == DB_SYM_NULL && map_for_val != VM_MAP_NULL) {
                   1068:                map_for_val = VM_MAP_NULL;
                   1069:                goto again;
                   1070:        }
                   1071:        *offp = diff;
                   1072:        if (*filenamep)
                   1073:                db_shorten_filename(filenamep);
                   1074:        return ret;
                   1075: }
                   1076: 
                   1077: /*
                   1078:  * Return name and value of a symbol
                   1079:  */
                   1080: void
                   1081: db_symbol_values(
                   1082:        db_symtab_t     *stab,
                   1083:        db_sym_t        sym,
                   1084:        char            **namep,
                   1085:        db_expr_t       *valuep)
                   1086: {
                   1087:        db_expr_t       value;
                   1088:        char            *name;
                   1089: 
                   1090:        if (sym == DB_SYM_NULL) {
                   1091:                *namep = 0;
                   1092:                return;
                   1093:        }
                   1094:        if (stab == 0)
                   1095:                stab = db_last_symtab;
                   1096: 
                   1097:        X_db_symbol_values(stab, sym, &name, &value);
                   1098: 
                   1099:        if (db_symbol_is_ambiguous(name)) {
                   1100:                *namep = db_qualify(name, db_last_symtab->name);
                   1101:        }else {
                   1102:                *namep = name;
                   1103:        }
                   1104:        if (valuep)
                   1105:                *valuep = value;
                   1106: }
                   1107: 
                   1108: 
                   1109: /*
                   1110:  * Print a the closest symbol to value
                   1111:  *
                   1112:  * After matching the symbol according to the given strategy
                   1113:  * we print it in the name+offset format, provided the symbol's
                   1114:  * value is close enough (eg smaller than db_maxoff).
                   1115:  * We also attempt to print [filename:linenum] when applicable
                   1116:  * (eg for procedure names).
                   1117:  *
                   1118:  * If we could not find a reasonable name+offset representation,
                   1119:  * then we just print the value in hex.  Small values might get
                   1120:  * bogus symbol associations, e.g. 3 might get some absolute
                   1121:  * value like _INCLUDE_VERSION or something, therefore we do
                   1122:  * not accept symbols whose value is zero (and use plain hex).
                   1123:  */
                   1124: 
                   1125: void
                   1126: db_task_printsym(
                   1127:        db_expr_t       off,
                   1128:        db_strategy_t   strategy,
                   1129:        task_t          task)
                   1130: {
                   1131:        db_addr_t       d;
                   1132:        char            *filename;
                   1133:        char            *name;
                   1134:        db_expr_t       value;
                   1135:        int             linenum;
                   1136:        db_sym_t        cursym;
                   1137: 
                   1138:        if (off >= db_maxval || off < db_minval) {
                   1139:                db_printf("%#n", off);
                   1140:                return;
                   1141:        }
                   1142:        cursym = db_search_task_symbol(off, strategy, &d, task);
                   1143: 
                   1144:        db_symbol_values(0, cursym, &name, &value);
                   1145:        if (name == 0 || d >= db_maxoff || value == 0) {
                   1146:                db_printf("%#n", off);
                   1147:                return;
                   1148:        }
                   1149:        db_printf("%s", name);
                   1150:        if (d)
                   1151:                db_printf("+0x%x", d);
                   1152:        if (strategy == DB_STGY_PROC) {
                   1153:                if (db_line_at_pc(cursym, &filename, &linenum, off)) {
                   1154:                        db_printf(" [%s", filename);
                   1155:                        if (linenum > 0)
                   1156:                                db_printf(":%d", linenum);
                   1157:                        db_printf("]");
                   1158:                }
                   1159:        }
                   1160: }
                   1161: 
                   1162: /*
                   1163:  * Return symbol name for a given offset and
                   1164:  * change the offset to be relative to this symbol.
                   1165:  * Very usefull for xpr, when you want to log offsets
                   1166:  * in a user friendly way.
                   1167:  */
                   1168: 
                   1169: char null_sym[] = "";
                   1170: 
                   1171: char *
                   1172: db_get_sym(db_expr_t *off)
                   1173: {
                   1174:        db_sym_t        cursym;
                   1175:        db_expr_t       value;
                   1176:        char            *name;
                   1177:        db_addr_t       d;
                   1178: 
                   1179:        cursym = db_search_symbol(*off, DB_STGY_ANY, &d);
                   1180:        db_symbol_values(0, cursym, &name, &value);
                   1181:        if (name) 
                   1182:                *off = d;
                   1183:        else
                   1184:                name = null_sym;
                   1185:        return(name);
                   1186: }
                   1187: 
                   1188: void
                   1189: db_printsym(
                   1190:        db_expr_t       off,
                   1191:        db_strategy_t   strategy)
                   1192: {
                   1193:        db_task_printsym(off, strategy, TASK_NULL);
                   1194: }
                   1195: 
                   1196: int db_short_filename = 1;
                   1197: 
                   1198: void
                   1199: db_shorten_filename(char **filenamep)
                   1200: {
                   1201:        char *cp, *cp_slash;
                   1202: 
                   1203:        if (! *filenamep)
                   1204:                return;
                   1205:        for (cp = cp_slash = *filenamep; *cp; cp++) {
                   1206:                if (*cp == '/')
                   1207:                        cp_slash = cp;
                   1208:        }
                   1209:        if (*cp_slash == '/')
                   1210:                *filenamep = cp_slash+1;
                   1211: }
                   1212: 
                   1213: int
                   1214: db_task_getlinenum(
                   1215:        db_expr_t       off,
                   1216:        task_t          task)
                   1217: {
                   1218:        db_addr_t       d;
                   1219:        char            *filename;
                   1220:        char            *name;
                   1221:        db_expr_t       value;
                   1222:        int             linenum;
                   1223:        db_sym_t        cursym;
                   1224:        db_strategy_t   strategy = DB_STGY_PROC;
                   1225: 
                   1226:        if (off >= db_maxval || off < db_minval) {
                   1227:                db_printf("%#n", off);
                   1228:                return(-1);
                   1229:        }
                   1230:        cursym = db_search_task_symbol(off, strategy, &d, task);
                   1231: 
                   1232:        db_symbol_values(0, cursym, &name, &value);
                   1233:        if (name == 0 || d >= db_maxoff || value == 0) {
                   1234:                return(-1);
                   1235:        }
                   1236:        if (db_line_at_pc(cursym, &filename, &linenum, off))
                   1237:                return(linenum);
                   1238:        else
                   1239:                return(-1);
                   1240: }
                   1241: 
                   1242: boolean_t
                   1243: db_line_at_pc(
                   1244:        db_sym_t        sym,
                   1245:        char            **filename,
                   1246:        int             *linenum,
                   1247:        db_expr_t       pc)
                   1248: {
                   1249:        boolean_t result;
                   1250: 
                   1251:        if (db_last_symtab == 0)
                   1252:                return FALSE;
                   1253:        if (X_db_line_at_pc( db_last_symtab, sym, filename, linenum, pc)) {
                   1254:                if (db_short_filename)
                   1255:                        db_shorten_filename(filename);
                   1256:                result = TRUE;
                   1257:        } else 
                   1258:                result = FALSE;
                   1259:        return(result);
                   1260: }
                   1261: 
                   1262: int qsort_check = 0;
                   1263: 
                   1264: void
                   1265: db_qsort(
                   1266:        char    *table,
                   1267:        int     nbelts,
                   1268:        int     eltsize,
                   1269:        int     (*compfun)(char *, char *))
                   1270: {
                   1271:        if (nbelts <= 0 || eltsize <= 0 || compfun == 0) {
                   1272:                printf("qsort: invalid parameters\n");
                   1273:                return;
                   1274:        }
                   1275:        qsort_recur(table, table + nbelts * eltsize, eltsize, compfun);
                   1276: 
                   1277:        if (qsort_check)
                   1278:                qsort_checker(table, nbelts, eltsize, compfun);
                   1279: }
                   1280: 
                   1281: void
                   1282: qsort_swap(
                   1283:        register int    *a,
                   1284:        register int    *b,
                   1285:        register int    size)
                   1286: {
                   1287:        register int temp;
                   1288:        char *aa, *bb;
                   1289:        char ctemp;
                   1290: 
                   1291:        for (; size >= sizeof (int); size -= sizeof (int), a++, b++) {
                   1292:                temp = *a;
                   1293:                *a = *b;
                   1294:                *b = temp;
                   1295:        }
                   1296:        aa = (char *)a;
                   1297:        bb = (char *)b;
                   1298:        for (; size > 0; size--, aa++, bb++) {
                   1299:                ctemp = *aa;
                   1300:                *aa = *bb;
                   1301:                *bb = ctemp;
                   1302:        }
                   1303: }
                   1304: 
                   1305: /* rotate the three elements to the left */
                   1306: void
                   1307: qsort_rotate(
                   1308:        register int    *a,
                   1309:        register int    *b,
                   1310:        register int    *c,
                   1311:        register int    size)
                   1312: {
                   1313:        register int temp;
                   1314:        char *aa, *bb, *cc;
                   1315:        char ctemp;
                   1316: 
                   1317:        for (; size >= sizeof (int); size -= sizeof (int), a++, b++, c++) {
                   1318:                temp = *a;
                   1319:                *a = *c;
                   1320:                *c = *b;
                   1321:                *b = temp;
                   1322:        }
                   1323:        aa = (char *)a;
                   1324:        bb = (char *)b;
                   1325:        cc = (char *)c;
                   1326:        for (; size > 0; size--, aa++, bb++, cc++) {
                   1327:                ctemp = *aa;
                   1328:                *aa = *cc;
                   1329:                *cc = *bb;
                   1330:                *bb = ctemp;
                   1331:        }
                   1332: }
                   1333: 
                   1334: void
                   1335: qsort_recur(
                   1336:        char    *left,
                   1337:        char    *right,
                   1338:        int     eltsize,
                   1339:        int     (*compfun)(char *, char *))
                   1340: {
                   1341:        char *i, *j;
                   1342:        char *sameleft, *sameright;
                   1343: 
                   1344:     top:
                   1345:        if (left + eltsize - 1 >= right) {
                   1346:                return;
                   1347:        }
                   1348: 
                   1349:        /* partition element (reference for "same"ness */
                   1350:        sameleft = left + (((right - left) / eltsize) / 2) * eltsize;
                   1351:        sameright = sameleft;
                   1352: 
                   1353:        i = left;
                   1354:        j = right - eltsize;
                   1355: 
                   1356:     again:
                   1357:        while (i < sameleft) {
                   1358:                int comp;
                   1359: 
                   1360:                comp = (*compfun)(i, sameleft);
                   1361:                if (comp == 0) {
                   1362:                        /*
                   1363:                         * Move to the "same" partition.
                   1364:                         */
                   1365:                        /*
                   1366:                         * Shift the left part of the "same" partition to
                   1367:                         * the left, so that "same" elements stay in their
                   1368:                         * original order.
                   1369:                         */
                   1370:                        sameleft -= eltsize;
                   1371:                        qsort_swap((int *) i, (int *) sameleft, eltsize);
                   1372:                } else if (comp < 0) {
                   1373:                        /*
                   1374:                         * Stay in the "left" partition.
                   1375:                         */
                   1376:                        i += eltsize;
                   1377:                } else {
                   1378:                        /*
                   1379:                         * Should be moved to the "right" partition.
                   1380:                         * Wait until the next loop finds an appropriate
                   1381:                         * place to store this element.
                   1382:                         */
                   1383:                        break;
                   1384:                }
                   1385:        }
                   1386: 
                   1387:        while (j > sameright) {
                   1388:                int comp;
                   1389: 
                   1390:                comp = (*compfun)(sameright, j);
                   1391:                if (comp == 0) {
                   1392:                        /*
                   1393:                         * Move to the right of the "same" partition.
                   1394:                         */
                   1395:                        sameright += eltsize;
                   1396:                        qsort_swap((int *) sameright, (int *) j, eltsize);
                   1397:                } else if (comp > 0) {
                   1398:                        /*
                   1399:                         * Move to the "left" partition.
                   1400:                         */
                   1401:                        if (i == sameleft) {
                   1402:                                /*
                   1403:                                 * Unfortunately, the "left" partition
                   1404:                                 * has already been fully processed, so
                   1405:                                 * we have to shift the "same" partition
                   1406:                                 * to the right to free a "left" element.
                   1407:                                 * This is done by moving the leftest same
                   1408:                                 * to the right of the "same" partition.
                   1409:                                 */
                   1410:                                sameright += eltsize;
                   1411:                                qsort_rotate((int *) sameleft, (int*) sameright,
                   1412:                                             (int *) j, eltsize);
                   1413:                                sameleft += eltsize;
                   1414:                                i = sameleft;
                   1415:                        } else {
                   1416:                                /*
                   1417:                                 * Swap with the "left" partition element
                   1418:                                 * waiting to be moved to the "right"
                   1419:                                 * partition.
                   1420:                                 */
                   1421:                                qsort_swap((int *) i, (int *) j, eltsize);
                   1422:                                j -= eltsize;
                   1423:                                /*
                   1424:                                 * Go back to the 1st loop.
                   1425:                                 */
                   1426:                                i += eltsize;
                   1427:                                goto again;
                   1428:                        }
                   1429:                } else {
                   1430:                        /*
                   1431:                         * Stay in the "right" partition.
                   1432:                         */
                   1433:                        j -= eltsize;
                   1434:                }
                   1435:        }
                   1436:                        
                   1437:        if (i != sameleft) {
                   1438:                /*
                   1439:                 * The second loop completed (the"right" partition is ok),
                   1440:                 * but we have to go back to the first loop, and deal with
                   1441:                 * the element waiting for a place in the "right" partition.
                   1442:                 * Let's shift the "same" zone to the left.
                   1443:                 */
                   1444:                sameleft -= eltsize;
                   1445:                qsort_rotate((int *) sameright, (int *) sameleft, (int *) i,
                   1446:                             eltsize);
                   1447:                sameright -= eltsize;
                   1448:                j = sameright;
                   1449:                /*
                   1450:                 * Go back to 1st loop.
                   1451:                 */
                   1452:                goto again;
                   1453:        }
                   1454: 
                   1455:        /*
                   1456:         * The partitions are correct now. Recur on the smallest side only.
                   1457:         */
                   1458:        if (sameleft - left >= right - (sameright + eltsize)) {
                   1459:                qsort_recur(sameright + eltsize, right, eltsize, compfun);
                   1460:                /*
                   1461:                 * The "right" partition is now completely sorted.
                   1462:                 * The "same" partition is OK, so...
                   1463:                 * Ignore them, and start the loops again on the
                   1464:                 * "left" partition.
                   1465:                 */
                   1466:                right = sameleft;
                   1467:                goto top;
                   1468:        } else {
                   1469:                qsort_recur(left, sameleft, eltsize, compfun);
                   1470:                /*
                   1471:                 * The "left" partition is now completely sorted.
                   1472:                 * The "same" partition is OK, so ...
                   1473:                 * Ignore them, and start the loops again on the
                   1474:                 * "right" partition.
                   1475:                 */
                   1476:                left = sameright + eltsize;
                   1477:                goto top;
                   1478:        }
                   1479: }
                   1480: 
                   1481: void
                   1482: qsort_checker(
                   1483:        char    *table,
                   1484:        int     nbelts,
                   1485:        int     eltsize,
                   1486:        int     (*compfun)(char *, char *))
                   1487: {
                   1488:        char *curr, *prev, *last;
                   1489: 
                   1490:        prev = table;
                   1491:        curr = prev + eltsize;
                   1492:        last = table + (nbelts * eltsize);
                   1493: 
                   1494:        while (prev < last) {
                   1495:                if ((*compfun)(prev, curr) > 0) {
                   1496:                        printf("**** qsort_checker: error between 0x%x and 0x%x!!!\n", prev, curr);
                   1497:                        break;
                   1498:                }
                   1499:                prev = curr;
                   1500:                curr += eltsize;
                   1501:        }
                   1502:        printf("qsort_checker: OK\n");
                   1503: }
                   1504: 
                   1505: int qsort_search_debug = 0;
                   1506: 
                   1507: void
                   1508: db_qsort_limit_search(
                   1509:        char    *target,
                   1510:        char    **start,
                   1511:        char    **end,
                   1512:        int     eltsize,
                   1513:        int     (*compfun)(char *, char *))
                   1514: {
                   1515:        register char *left, *right;
                   1516:        char *oleft, *oright, *part;
                   1517:        int nbiter = 0;
                   1518:        int comp;
                   1519: 
                   1520:        oleft = left = *start;
                   1521:        oright = right = *end;
                   1522:        part = (char *) 0;
                   1523: 
                   1524:        while (left < right) {
                   1525:                nbiter++;
                   1526:                part = left + (((right - left) / eltsize) / 2) * eltsize;
                   1527:                comp = (*compfun)(target, part);
                   1528:                if (comp > 0) {
                   1529:                        oleft = left;
                   1530:                        oright = right;
                   1531:                        left = part;
                   1532:                        if (left == oleft)
                   1533:                                break;
                   1534:                        if (qsort_search_debug > 1)
                   1535:                                printf(" [ Moved left from 0x%x to 0x%x]\n",
                   1536:                                       oleft, left);
                   1537:                } else if (comp < 0) {
                   1538:                        oright = right;
                   1539:                        oleft = left;
                   1540:                        right = part;
                   1541:                        if (qsort_search_debug > 1)
                   1542:                                printf(" [ Moved right from 0x%x to 0x%x]\n",
                   1543:                                       oright, right);
                   1544:                } else {
                   1545:                        if (qsort_search_debug > 1)
                   1546:                                printf(" [ FOUND! left=0x%x right=0x%x]\n",
                   1547:                                       left, right);
                   1548:                        for (left = part;
                   1549:                             left > *start && (*compfun)(left, part) == 0;
                   1550:                             left -= eltsize);
                   1551:                        for (right = part + eltsize;
                   1552:                             right < *end && (*compfun)(right, part) == 0;
                   1553:                             right += eltsize);
                   1554:                        oright = right;
                   1555:                        oleft = left;
                   1556:                        break;
                   1557:                }
                   1558:        }
                   1559:        
                   1560:        if (qsort_search_debug)
                   1561:                printf("[ Limited from %x-%x to %x-%x in %d iters ]\n",
                   1562:                          *start, *end, oleft, oright, nbiter);
                   1563:        *start = oleft;
                   1564:        *end = oright;
                   1565: }
                   1566: 
                   1567: void
                   1568: bubble_sort(
                   1569:        char    *table,
                   1570:        int     nbelts,
                   1571:        int     eltsize,
                   1572:        int     (*compfun)(char *, char *))
                   1573: {
                   1574:        boolean_t sorted;
                   1575:        char *end;
                   1576:        register char *p;
                   1577: 
                   1578:        end = table + ((nbelts-1) * eltsize);
                   1579:        do {
                   1580:                sorted = TRUE;
                   1581:                for (p = table; p < end; p += eltsize) {
                   1582:                        if ((*compfun)(p, p + eltsize) > 0) {
                   1583:                                qsort_swap((int *) p, (int *) (p + eltsize),
                   1584:                                           eltsize);
                   1585:                                sorted = FALSE;
                   1586:                        }
                   1587:                }
                   1588:        } while (sorted == FALSE);
                   1589: 
                   1590:        if (qsort_check)
                   1591:                qsort_checker(table, nbelts, eltsize, compfun);
                   1592: }
                   1593: 
                   1594: vm_offset_t    vm_min_inks_addr = VM_MAX_KERNEL_ADDRESS;
                   1595: 
                   1596: void
                   1597: db_install_inks(
                   1598:       vm_offset_t base)
                   1599: {
                   1600:        /* save addr to demarcate kernel/inks boundary (1st time only)  */
                   1601:        if (vm_min_inks_addr == VM_MAX_KERNEL_ADDRESS) {
                   1602:                vm_min_inks_addr = base;
                   1603:                db_qualify_ambiguous_names = TRUE;
                   1604:        }
                   1605: }
                   1606: 
                   1607: 
                   1608: void
                   1609: db_clone_symtabXXX(
                   1610:        char *clonee,                   /* which symtab to clone        */
                   1611:        char *cloner,                   /* in-kernel-server name        */
                   1612:        vm_offset_t base)               /* base address of cloner       */
                   1613: {
                   1614:        db_symtab_t     *st, *st_src;
                   1615:        char *          memp;
                   1616:        vm_size_t       size;
                   1617:        long            offset;
                   1618:        extern vm_offset_t kalloc(vm_size_t);
                   1619:        extern void db_clone_offsetXXX(char *, long);
                   1620: 
                   1621:        if (db_nsymtab >= MAXNOSYMTABS) {
                   1622:            db_printf("db_clone_symtab: Too Many Symbol Tables\n");
                   1623:            return;
                   1624:        }
                   1625: 
                   1626:        db_install_inks(base);
                   1627: 
                   1628:        st = &db_symtabs[db_nsymtab];   /* destination symtab           */
                   1629:        if ((st_src = db_symtab_cloneeXXX(clonee)) == 0) {
                   1630:            db_printf("db_clone_symtab: clonee (%s) not found\n", clonee);
                   1631:            return;
                   1632:        }
                   1633:                                        /* alloc new symbols            */
                   1634:        size = (vm_size_t)(st_src->end - st_src->private);
                   1635:        memp = (char *)kalloc( round_page(size) );
                   1636:        if (!memp) {
                   1637:            db_printf("db_clone_symtab: no memory for symtab\n");
                   1638:            return;
                   1639:        }
                   1640: 
                   1641:        *st = *st_src;                  /* bulk copy src -> dest        */
                   1642:        strcpy(st->name, cloner);       /* new name                     */
                   1643:        st->private = memp;             /* copy symbols                 */
                   1644:        bcopy((const char *)st_src->private, st->private, size);
                   1645:        st->start = memp + sizeof(int); /* fixup pointers to symtab     */
                   1646:        st->end   = memp + *(int *)memp;
                   1647:        st->map_pointer = 0;            /* no map because kernel-loaded */
                   1648: 
                   1649:        /* Offset symbols, leaving strings pointing into st_src         */
                   1650:        offset      = base - st_src->minsym;
                   1651:        st->minsym  += offset;
                   1652:        st->maxsym  += offset;
                   1653:        db_clone_offsetXXX(memp, offset);
                   1654:        db_nsymtab++;
                   1655: 
                   1656:        db_printf( "[ cloned symbol table for %s: range 0x%x to 0x%x %s]\n",
                   1657:                  st->name, st->minsym, st->maxsym,
                   1658:                  st->sorted ? "(sorted) " : "");
                   1659:        db_maxval = (unsigned int)st->maxsym + db_maxoff;
                   1660: }
                   1661: 
                   1662: db_symtab_t *
                   1663: db_symtab_cloneeXXX(
                   1664:       char *clonee)
                   1665: {
                   1666:        db_symtab_t *st, *st_src;
                   1667: 
                   1668:        st = &db_symtabs[db_nsymtab];   /* destination symtab */
                   1669:        for (st_src = &db_symtabs[0]; st_src < st; ++st_src)
                   1670:                if (!strcmp(clonee, st_src->name))
                   1671:                        break;
                   1672:        return ((st_src < st) ? st_src : 0);
                   1673: }
                   1674: 
                   1675: /*
                   1676:  * Switch into symbol-table specific routines
                   1677:  */
                   1678: 
                   1679: #if    !defined(__alpha) && !defined(INTEL860)
                   1680: #define DB_NO_COFF
                   1681: #endif
                   1682: 
                   1683: #ifndef        DB_NO_AOUT
                   1684: #include <ddb/db_aout.h>
                   1685: #endif
                   1686: 
                   1687: #ifndef        DB_NO_COFF
                   1688: #include <ddb/db_coff.h>
                   1689: #endif
                   1690: 
                   1691: static void no_init(void)
                   1692: 
                   1693: {
                   1694:        db_printf("Non-existent code for ddb init\n");
                   1695: }
                   1696: 
                   1697: static boolean_t no_sym_init(
                   1698:        char *start,
                   1699:        char *end,
                   1700:        char *name,
                   1701:        char *task_addr)
                   1702: {
                   1703:        db_printf("Non-existent code for init of symtab %s\n", name);
                   1704:        return FALSE;
                   1705: }
                   1706: 
                   1707: static db_sym_t no_lookup(
                   1708:        db_symtab_t *stab,
                   1709:        char *symstr)
                   1710: {
                   1711:        db_printf("Bogus lookup of symbol %s\n", symstr);
                   1712:        return DB_SYM_NULL;
                   1713: }
                   1714: 
                   1715: static db_sym_t no_search(
                   1716:        db_symtab_t *stab,
                   1717:        db_addr_t off,
                   1718:        db_strategy_t strategy,
                   1719:        db_expr_t *diffp)
                   1720: {
                   1721:        db_printf("Bogus search for offset %#Xn", off);
                   1722:        return DB_SYM_NULL;
                   1723: }
                   1724: 
                   1725: static boolean_t no_line_at_pc(
                   1726:        db_symtab_t *stab,
                   1727:        db_sym_t sym,
                   1728:        char **file,
                   1729:        int *line,
                   1730:        db_expr_t pc)
                   1731: {
                   1732:        db_printf("Bogus search for pc %#X\n", pc);
                   1733:        return FALSE;
                   1734: }
                   1735: 
                   1736: static void no_symbol_values(
                   1737:        db_sym_t sym,
                   1738:        char **namep,
                   1739:        db_expr_t *valuep)
                   1740: {
                   1741:        db_printf("Bogus symbol value resolution\n");
                   1742:        if (namep) *namep = NULL;
                   1743:        if (valuep) *valuep = 0;
                   1744: }
                   1745: 
                   1746: static db_sym_t no_search_by_addr(
                   1747:        db_symtab_t *stab,
                   1748:        db_addr_t off,
                   1749:        char **file,
                   1750:        char **func,
                   1751:        int *line,
                   1752:        db_expr_t *diffp,
                   1753:        int *args)
                   1754: {
                   1755:        db_printf("Bogus search for address %#X\n", off);
                   1756:        return DB_SYM_NULL;
                   1757: }
                   1758:        
                   1759: int
                   1760: no_print_completion(
                   1761:        db_symtab_t     *stab,
                   1762:        char            *symstr )
                   1763: {
                   1764:        db_printf("Bogus print completion: not supported\n");
                   1765:        return 0;
                   1766: }
                   1767: 
                   1768: int
                   1769: no_lookup_incomplete(
                   1770:        db_symtab_t     *stab,
                   1771:        char            *symstr,
                   1772:        char            **name,
                   1773:        int             *len,
                   1774:        int             *toadd)
                   1775: {
                   1776:        db_printf("Bogus lookup incomplete: not supported\n");
                   1777:        return 0;
                   1778: }
                   1779: 
                   1780: #define NONE   \
                   1781:        { no_init, no_sym_init, no_lookup, no_search, \
                   1782:          no_line_at_pc, no_symbol_values, no_search_by_addr, \
                   1783:                  no_print_completion, no_lookup_incomplete}
                   1784: 
                   1785: struct db_sym_switch x_db[] = {
                   1786: 
                   1787:        /* BSD a.out format (really, sdb/dbx(1) symtabs) */
                   1788: #ifdef DB_NO_AOUT
                   1789:        NONE,
                   1790: #else  /* DB_NO_AOUT */
                   1791:        { aout_db_init, aout_db_sym_init, aout_db_lookup, aout_db_search_symbol,
                   1792:          aout_db_line_at_pc, aout_db_symbol_values, aout_db_search_by_addr,
                   1793:          aout_db_print_completion, aout_db_lookup_incomplete},
                   1794: #endif /* DB_NO_AOUT */
                   1795: 
                   1796: #ifdef DB_NO_COFF
                   1797:        NONE,
                   1798: #else  /* DB_NO_COFF */
                   1799:        { coff_db_init, coff_db_sym_init, coff_db_lookup, coff_db_search_symbol,
                   1800:          coff_db_line_at_pc, coff_db_symbol_values, coff_db_search_by_addr,
                   1801:          coff_db_print_completion, coff_db_lookup_incomplete },
                   1802: #endif /* DB_NO_COFF */
                   1803: 
                   1804:        /* Machdep, not inited here */
                   1805:        NONE
                   1806: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.