2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
28 * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
29 * Import of Mac OS X kernel (~semeria)
31 * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez
32 * Import of OSF Mach kernel (~mburg)
34 * Revision 1.3.22.8 1996/07/31 09:07:24 paire
35 * Merged with nmk20b7_shared (1.3.47.1)
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.
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]
49 * Merged '64-bit safe' changes from DEC alpha port.
50 * [1995/11/21 18:03:41 jfraser]
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]
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]
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
65 * Prepend a "db_" to qsort and qsort_limit_search
66 * (collisions with the real qsort in stdlib.h)
69 * Added X_db_init for object independent formats.
72 * Merge with DIPC2_SHARED.
73 * [1995/01/05 13:32:53 alanl]
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]
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.
96 * Handle multiple, coexisting symbol table types.
98 * Revision 1.3.4.5 1993/10/20 18:58:55 gm
99 * CR9704: Removed symbol load printf.
101 * [1994/11/04 08:50:02 dwm]
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
108 * Prepend a "db_" to qsort and qsort_limit_search
109 * (collisions with the real qsort in stdlib.h)
112 * Added X_db_init for object independent formats.
115 * Merge with DIPC2_SHARED.
116 * [1995/01/05 13:32:53 alanl]
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]
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.
139 * Handle multiple, coexisting symbol table types.
141 * Revision 1.3.4.5 1993/10/20 18:58:55 gm
142 * CR9704: Removed symbol load printf.
144 * [1994/11/04 08:50:02 dwm]
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]
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]
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]
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]
164 * Installed ddb_init() routine in a symbol-independent file to call
165 * symbol-dependent and machine-dependent initialization routines.
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.
173 * Added new arguments to db_sym_print_completion() call.
176 * Added db_lookup_incomplete(), db_sym_parse_and_lookup_incomplete(),
177 * db_sym_print_completion() and db_completion_print() for support of
180 * [94/02/07 bernadat]
182 * Revision 1.3.15.4 1994/06/08 19:11:23 dswartz
184 * [1994/06/08 19:10:24 dswartz]
186 * Revision 1.3.20.2 1994/06/01 21:34:39 klj
187 * Initial preemption code base merge
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]
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
197 * [1994/02/03 20:47:22 bolinger]
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]
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]
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]
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]
216 * Added to OSF/1 R1.3 from NMK15.0.
217 * [1993/06/02 20:57:10 jeffc]
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]
224 * Upped MAXNOSYMTABS from 3 to 5. Now there is space for kernel,
225 * bootstrap, server, and emulator symbols - plus one for future
228 * Changed CHAR arg of db_eqname to UNSIGNED.
229 * Made arg types proper for db_line_at_pc().
233 * Sort large symbol tables to speedup lookup.
234 * Improved symbol lookup (use of max_offset, dichotomic search)
235 * [barbou@gr.osf.org]
237 * db_add_symbol_table now takes 3 additional arguments. Machine
238 * dependant modules must provide them. [barbou@gr.osf.org]
239 * [92/12/03 bernadat]
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]
245 * Revision 1.1 1992/09/30 02:01:25 robert
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]
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]
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.
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.
285 * Revision 2.9 91/07/31 17:31:14 dbg
286 * Add task pointer and space for string storage to symbol table
290 * Revision 2.8 91/07/09 23:16:08 danner
294 * Revision 2.7 91/05/14 15:35:54 mrt
295 * Correcting copyright
297 * Revision 2.6 91/03/16 14:42:40 rpd
298 * Changed the default db_maxoff to 4K.
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]
305 * Revision 2.4 90/10/25 14:44:05 rwd
306 * Changed db_printsym to print unsigned.
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]
313 * Revision 2.2 90/08/27 21:52:18 dbg
314 * Removed nlist.h. Fixed some type declarations.
315 * Qualifier character is ':'.
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
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]
336 * Revision 2.1 90/07/26 16:43:52 dbg
342 * Mach Operating System
343 * Copyright (c) 1991,1990 Carnegie Mellon University
344 * All Rights Reserved.
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.
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.
356 * Carnegie Mellon requests users of this software to return to
358 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
359 * School of Computer Science
360 * Carnegie Mellon University
361 * Pittsburgh PA 15213-3890
363 * any improvements or extensions that they make and grant Carnegie Mellon
364 * the rights to redistribute these changes.
369 * Author: David B. Golub, Carnegie Mellon University
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() */
382 #include <vm/vm_map.h> /* vm_map_t */
385 * Multiple symbol tables
387 * mach, bootstrap, name_server, default_pager, unix, 1 spare
389 #define MAXNOSYMTABS 6
391 db_symtab_t db_symtabs
[MAXNOSYMTABS
] = {{0}};
394 db_symtab_t
*db_last_symtab
;
396 unsigned long db_maxoff
= 0x4000;
398 unsigned long db_maxval
= (unsigned long)&end
;
399 natural_t db_minval
= 0x1000;
401 /* Prototypes for functions local to this file. XXX -- should be static!
403 static char *db_qualify(
405 register char *symtabname
);
412 boolean_t
db_symbol_is_ambiguous(char *name
);
414 void db_shorten_filename(char **filenamep
);
431 int (*compfun
)(char *, char *));
437 int (*compfun
)(char *, char *));
443 int (*compfun
)(char *, char *));
445 int no_print_completion(
448 int no_lookup_incomplete(
456 * Initialization routine for ddb.
466 * Add symbol table, with given name, to list of symbol tables.
476 unsigned long minsym
,
477 unsigned long maxsym
,
480 register db_symtab_t
*st
;
481 extern vm_map_t kernel_map
;
483 if (db_nsymtab
>= MAXNOSYMTABS
)
486 st
= &db_symtabs
[db_nsymtab
];
491 if (map_pointer
== (char *)kernel_map
||
492 (VM_MAX_ADDRESS
<= VM_MIN_KERNEL_ADDRESS
&&
493 VM_MIN_KERNEL_ADDRESS
<= minsym
))
496 st
->map_pointer
= map_pointer
;
497 strcpy(st
->name
, name
);
504 if (db_maxval
< maxsym
+ db_maxoff
)
505 db_maxval
= maxsym
+ db_maxoff
;
513 * db_qualify("vm_map", "ux") returns "ux::vm_map".
515 * Note: return value points to static data whose content is
516 * overwritten by each call... but in practice this seems okay.
521 register char *symtabname
)
523 static char tmp
[256];
527 while (*s
++ = *symtabname
++) {
531 while (*s
++ = *symname
++) {
543 if (!strcmp(src
, dst
))
546 return (!strcmp(src
+1,dst
));
557 sym
= db_lookup(name
);
558 if (sym
== DB_SYM_NULL
)
560 db_symbol_values(0, sym
, &name
, valuep
);
565 * Display list of possible completions for a symbol.
572 int symtab_start
= 0;
573 int symtab_end
= db_nsymtab
;
576 char *name
= (char *)0;
581 * Look for, remove, and remember any symbol table specifier.
583 for (cp
= symstr
; *cp
; cp
++) {
584 if (*cp
== ':' && cp
[1] == ':') {
586 for (i
= 0; i
< db_nsymtab
; i
++) {
587 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
601 * Look in the specified set of symbol tables.
602 * Return on first match.
604 for (i
= symtab_start
; i
< symtab_end
; i
++) {
605 if (X_db_print_completion(&db_symtabs
[i
], symstr
))
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.
617 db_lookup_incomplete(
622 int symtab_start
= 0;
623 int symtab_end
= db_nsymtab
;
626 char *name
= (char *)0;
631 * Look for, remove, and remember any symbol table specifier.
633 for (cp
= symstr
; *cp
; cp
++) {
634 if (*cp
== ':' && cp
[1] == ':') {
636 for (i
= 0; i
< db_nsymtab
; i
++) {
637 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
651 * Look in the specified set of symbol tables.
652 * Return on first match.
654 for (i
= symtab_start
; i
< symtab_end
; i
++) {
655 nsym
= X_db_lookup_incomplete(&db_symtabs
[i
], symstr
,
656 &name
, &len
, &toadd
);
659 len
= strlen(symstr
);
660 if (len
+ toadd
>= symlen
)
662 bcopy(&name
[len
], &symstr
[len
], toadd
);
663 symstr
[len
+ toadd
] = '\0';
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.
678 db_lookup(char *symstr
)
682 int symtab_start
= 0;
683 int symtab_end
= db_nsymtab
;
687 * Look for, remove, and remember any symbol table specifier.
689 for (cp
= symstr
; *cp
; cp
++) {
690 if (*cp
== ':' && cp
[1] == ':') {
692 for (i
= 0; i
< db_nsymtab
; i
++) {
693 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
701 db_error("Invalid symbol table name\n");
707 * Look in the specified set of symbol tables.
708 * Return on first match.
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
];
720 * Print a symbol completion
723 db_sym_print_completion(
730 if (stab
!= db_symtabs
)
731 db_printf("%s::", stab
->name
);
738 db_printf(" [static from %s", fname
);
740 db_printf(":%d", line
);
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.
755 db_sym_parse_and_print_completion(
756 int (*func
)(db_symtab_t
*,
768 * disassemble the symbol into components: [file_name:]symbol
770 component
[0] = symstr
;
772 for (p
= symstr
, n
= 1; *p
; p
++) {
777 component
[n
++] = p
+1;
782 sym_name
= component
[0];
784 sym_name
= component
[1];
786 nsym
= func(symtab
, sym_name
);
790 component
[1][-1] = ':';
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.
803 db_sym_parse_and_lookup_incomplete(
804 int (*func
)(db_symtab_t
*,
825 * disassemble the symbol into components: [file_name:]symbol
827 component
[0] = symstr
;
829 for (p
= symstr
, n
= 1; *p
; p
++) {
834 component
[n
++] = p
+1;
840 sym_name
= component
[0];
842 file_name
= component
[0];
843 sym_name
= component
[1];
845 nsym
= func(symtab
, file_name
, sym_name
, 0, (db_sym_t
*)0,
848 *toadd
= *len
- strlen(sym_name
);
851 component
[1][-1] = ':';
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.
864 db_sym_parse_and_lookup(
865 int (*func
)(db_symtab_t
*, char *, char *, int,
866 db_sym_t
*, char **, int *),
877 db_sym_t found
= DB_SYM_NULL
;
880 * disassemble the symbol into components:
881 * [file_name:]symbol[:line_nubmer]
883 component
[0] = symstr
;
884 component
[1] = component
[2] = 0;
885 for (p
= symstr
, n
= 1; *p
; p
++) {
890 component
[n
++] = p
+1;
898 if (*p
>= '0' && *p
<= '9') {
901 for (line_number
= 0; *p
; p
++) {
902 if (*p
< '0' || *p
> '9')
904 line_number
= line_number
*10 + *p
- '0';
910 for (p
= component
[0]; *p
&& *p
!= '.'; p
++);
912 file_name
= component
[0];
916 sym_name
= component
[0];
919 file_name
= component
[0];
920 sym_name
= component
[1];
922 (void) func(symtab
, file_name
, sym_name
, line_number
, &found
,
923 (char **)0, (int *)0);
927 component
[n
][-1] = ':';
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.
935 boolean_t db_qualify_ambiguous_names
= TRUE
;
938 db_symbol_is_ambiguous(char *name
)
942 boolean_t found_once
= FALSE
;
944 if (!db_qualify_ambiguous_names
)
947 for (i
= 0; i
< db_nsymtab
; i
++) {
948 if (X_db_lookup(&db_symtabs
[i
], name
)) {
958 * Find the closest symbol to val, and return its name
959 * and the difference between val and the symbol found.
961 unsigned int db_search_maxoff
= 0x4000;
963 db_search_task_symbol(
964 register db_addr_t val
,
965 db_strategy_t strategy
,
966 db_addr_t
*offp
, /* better be unsigned */
969 unsigned long diff
, newdiff
;
972 db_sym_t ret
= DB_SYM_NULL
, sym
;
973 vm_map_t map_for_val
;
975 if (task
== TASK_NULL
)
976 task
= db_current_task();
977 map_for_val
= (task
== TASK_NULL
)? VM_MAP_NULL
: task
->map
;
979 newdiff
= diff
= ~0UL;
981 for (sp
= &db_symtabs
[0], i
= 0;
984 if (((vm_map_t
)sp
->map_pointer
== VM_MAP_NULL
||
985 (vm_map_t
)sp
->map_pointer
== map_for_val
) &&
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
) {
995 if (diff
<= db_search_maxoff
)
1000 if (ret
== DB_SYM_NULL
&& map_for_val
!= VM_MAP_NULL
) {
1001 map_for_val
= VM_MAP_NULL
;
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.
1014 db_search_task_symbol_and_line(
1015 register db_addr_t val
,
1016 db_strategy_t strategy
,
1023 unsigned long diff
, newdiff
;
1026 db_sym_t ret
= DB_SYM_NULL
, sym
;
1027 vm_map_t map_for_val
;
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;
1040 filename
= (char *) 0;
1042 newdiff
= diff
= ~0UL;
1044 for (sp
= &db_symtabs
[0], i
= 0;
1047 if (((vm_map_t
)sp
->map_pointer
== VM_MAP_NULL
||
1048 (vm_map_t
)sp
->map_pointer
== map_for_val
) &&
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
,
1055 if (sym
&& newdiff
< diff
) {
1056 db_last_symtab
= sp
;
1059 *filenamep
= filename
;
1060 *linenump
= linenum
;
1062 if (diff
<= db_search_maxoff
)
1067 if (ret
== DB_SYM_NULL
&& map_for_val
!= VM_MAP_NULL
) {
1068 map_for_val
= VM_MAP_NULL
;
1073 db_shorten_filename(filenamep
);
1078 * Return name and value of a symbol
1090 if (sym
== DB_SYM_NULL
) {
1095 stab
= db_last_symtab
;
1097 X_db_symbol_values(stab
, sym
, &name
, &value
);
1099 if (db_symbol_is_ambiguous(name
)) {
1100 *namep
= db_qualify(name
, db_last_symtab
->name
);
1110 * Print a the closest symbol to value
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).
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).
1128 db_strategy_t strategy
,
1138 if (off
>= db_maxval
|| off
< db_minval
) {
1139 db_printf("%#n", off
);
1142 cursym
= db_search_task_symbol(off
, strategy
, &d
, task
);
1144 db_symbol_values(0, cursym
, &name
, &value
);
1145 if (name
== 0 || d
>= db_maxoff
|| value
== 0) {
1146 db_printf("%#n", off
);
1149 db_printf("%s", name
);
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
);
1156 db_printf(":%d", linenum
);
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.
1169 char null_sym
[] = "";
1172 db_get_sym(db_expr_t
*off
)
1179 cursym
= db_search_symbol(*off
, DB_STGY_ANY
, &d
);
1180 db_symbol_values(0, cursym
, &name
, &value
);
1191 db_strategy_t strategy
)
1193 db_task_printsym(off
, strategy
, TASK_NULL
);
1196 int db_short_filename
= 1;
1199 db_shorten_filename(char **filenamep
)
1201 char *cp
, *cp_slash
;
1205 for (cp
= cp_slash
= *filenamep
; *cp
; cp
++) {
1209 if (*cp_slash
== '/')
1210 *filenamep
= cp_slash
+1;
1224 db_strategy_t strategy
= DB_STGY_PROC
;
1226 if (off
>= db_maxval
|| off
< db_minval
) {
1227 db_printf("%#n", off
);
1230 cursym
= db_search_task_symbol(off
, strategy
, &d
, task
);
1232 db_symbol_values(0, cursym
, &name
, &value
);
1233 if (name
== 0 || d
>= db_maxoff
|| value
== 0) {
1236 if (db_line_at_pc(cursym
, &filename
, &linenum
, off
))
1251 if (db_last_symtab
== 0)
1253 if (X_db_line_at_pc( db_last_symtab
, sym
, filename
, linenum
, pc
)) {
1254 if (db_short_filename
)
1255 db_shorten_filename(filename
);
1262 int qsort_check
= 0;
1269 int (*compfun
)(char *, char *))
1271 if (nbelts
<= 0 || eltsize
<= 0 || compfun
== 0) {
1272 printf("qsort: invalid parameters\n");
1275 qsort_recur(table
, table
+ nbelts
* eltsize
, eltsize
, compfun
);
1278 qsort_checker(table
, nbelts
, eltsize
, compfun
);
1291 for (; size
>= sizeof (int); size
-= sizeof (int), a
++, b
++) {
1298 for (; size
> 0; size
--, aa
++, bb
++) {
1305 /* rotate the three elements to the left */
1317 for (; size
>= sizeof (int); size
-= sizeof (int), a
++, b
++, c
++) {
1326 for (; size
> 0; size
--, aa
++, bb
++, cc
++) {
1339 int (*compfun
)(char *, char *))
1342 char *sameleft
, *sameright
;
1345 if (left
+ eltsize
- 1 >= right
) {
1349 /* partition element (reference for "same"ness */
1350 sameleft
= left
+ (((right
- left
) / eltsize
) / 2) * eltsize
;
1351 sameright
= sameleft
;
1354 j
= right
- eltsize
;
1357 while (i
< sameleft
) {
1360 comp
= (*compfun
)(i
, sameleft
);
1363 * Move to the "same" partition.
1366 * Shift the left part of the "same" partition to
1367 * the left, so that "same" elements stay in their
1370 sameleft
-= eltsize
;
1371 qsort_swap((int *) i
, (int *) sameleft
, eltsize
);
1372 } else if (comp
< 0) {
1374 * Stay in the "left" partition.
1379 * Should be moved to the "right" partition.
1380 * Wait until the next loop finds an appropriate
1381 * place to store this element.
1387 while (j
> sameright
) {
1390 comp
= (*compfun
)(sameright
, j
);
1393 * Move to the right of the "same" partition.
1395 sameright
+= eltsize
;
1396 qsort_swap((int *) sameright
, (int *) j
, eltsize
);
1397 } else if (comp
> 0) {
1399 * Move to the "left" partition.
1401 if (i
== sameleft
) {
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.
1410 sameright
+= eltsize
;
1411 qsort_rotate((int *) sameleft
, (int*) sameright
,
1412 (int *) j
, eltsize
);
1413 sameleft
+= eltsize
;
1417 * Swap with the "left" partition element
1418 * waiting to be moved to the "right"
1421 qsort_swap((int *) i
, (int *) j
, eltsize
);
1424 * Go back to the 1st loop.
1431 * Stay in the "right" partition.
1437 if (i
!= sameleft
) {
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.
1444 sameleft
-= eltsize
;
1445 qsort_rotate((int *) sameright
, (int *) sameleft
, (int *) i
,
1447 sameright
-= eltsize
;
1450 * Go back to 1st loop.
1456 * The partitions are correct now. Recur on the smallest side only.
1458 if (sameleft
- left
>= right
- (sameright
+ eltsize
)) {
1459 qsort_recur(sameright
+ eltsize
, right
, eltsize
, compfun
);
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
1469 qsort_recur(left
, sameleft
, eltsize
, compfun
);
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.
1476 left
= sameright
+ eltsize
;
1486 int (*compfun
)(char *, char *))
1488 char *curr
, *prev
, *last
;
1491 curr
= prev
+ eltsize
;
1492 last
= table
+ (nbelts
* eltsize
);
1494 while (prev
< last
) {
1495 if ((*compfun
)(prev
, curr
) > 0) {
1496 printf("**** qsort_checker: error between 0x%x and 0x%x!!!\n", prev
, curr
);
1502 printf("qsort_checker: OK\n");
1505 int qsort_search_debug
= 0;
1508 db_qsort_limit_search(
1513 int (*compfun
)(char *, char *))
1515 register char *left
, *right
;
1516 char *oleft
, *oright
, *part
;
1520 oleft
= left
= *start
;
1521 oright
= right
= *end
;
1524 while (left
< right
) {
1526 part
= left
+ (((right
- left
) / eltsize
) / 2) * eltsize
;
1527 comp
= (*compfun
)(target
, part
);
1534 if (qsort_search_debug
> 1)
1535 printf(" [ Moved left from 0x%x to 0x%x]\n",
1537 } else if (comp
< 0) {
1541 if (qsort_search_debug
> 1)
1542 printf(" [ Moved right from 0x%x to 0x%x]\n",
1545 if (qsort_search_debug
> 1)
1546 printf(" [ FOUND! left=0x%x right=0x%x]\n",
1549 left
> *start
&& (*compfun
)(left
, part
) == 0;
1551 for (right
= part
+ eltsize
;
1552 right
< *end
&& (*compfun
)(right
, part
) == 0;
1560 if (qsort_search_debug
)
1561 printf("[ Limited from %x-%x to %x-%x in %d iters ]\n",
1562 *start
, *end
, oleft
, oright
, nbiter
);
1572 int (*compfun
)(char *, char *))
1578 end
= table
+ ((nbelts
-1) * eltsize
);
1581 for (p
= table
; p
< end
; p
+= eltsize
) {
1582 if ((*compfun
)(p
, p
+ eltsize
) > 0) {
1583 qsort_swap((int *) p
, (int *) (p
+ eltsize
),
1588 } while (sorted
== FALSE
);
1591 qsort_checker(table
, nbelts
, eltsize
, compfun
);
1594 vm_offset_t vm_min_inks_addr
= VM_MAX_KERNEL_ADDRESS
;
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
;
1610 char *clonee
, /* which symtab to clone */
1611 char *cloner
, /* in-kernel-server name */
1612 vm_offset_t base
) /* base address of cloner */
1614 db_symtab_t
*st
, *st_src
;
1618 extern vm_offset_t
kalloc(vm_size_t
);
1619 extern void db_clone_offsetXXX(char *, long);
1621 if (db_nsymtab
>= MAXNOSYMTABS
) {
1622 db_printf("db_clone_symtab: Too Many Symbol Tables\n");
1626 db_install_inks(base
);
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
);
1633 /* alloc new symbols */
1634 size
= (vm_size_t
)(st_src
->end
- st_src
->private);
1635 memp
= (char *)kalloc( round_page(size
) );
1637 db_printf("db_clone_symtab: no memory for symtab\n");
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 */
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
);
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
;
1663 db_symtab_cloneeXXX(
1666 db_symtab_t
*st
, *st_src
;
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
))
1672 return ((st_src
< st
) ? st_src
: 0);
1676 * Switch into symbol-table specific routines
1679 #if !defined(__alpha) && !defined(INTEL860)
1684 #include <ddb/db_aout.h>
1688 #include <ddb/db_coff.h>
1691 static void no_init(void)
1694 db_printf("Non-existent code for ddb init\n");
1697 static boolean_t
no_sym_init(
1703 db_printf("Non-existent code for init of symtab %s\n", name
);
1707 static db_sym_t
no_lookup(
1711 db_printf("Bogus lookup of symbol %s\n", symstr
);
1715 static db_sym_t
no_search(
1718 db_strategy_t strategy
,
1721 db_printf("Bogus search for offset %#Xn", off
);
1725 static boolean_t
no_line_at_pc(
1732 db_printf("Bogus search for pc %#X\n", pc
);
1736 static void no_symbol_values(
1741 db_printf("Bogus symbol value resolution\n");
1742 if (namep
) *namep
= NULL
;
1743 if (valuep
) *valuep
= 0;
1746 static db_sym_t
no_search_by_addr(
1755 db_printf("Bogus search for address %#X\n", off
);
1760 no_print_completion(
1764 db_printf("Bogus print completion: not supported\n");
1769 no_lookup_incomplete(
1776 db_printf("Bogus lookup incomplete: not supported\n");
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}
1785 struct db_sym_switch x_db
[] = {
1787 /* BSD a.out format (really, sdb/dbx(1) symtabs) */
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 */
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 */
1804 /* Machdep, not inited here */