Annotation of XNU/osfmk/ddb/db_sym.c, revision 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.