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