2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
23 * @APPLE_LICENSE_HEADER_END@
31 * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
32 * Import of Mac OS X kernel (~semeria)
34 * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez
35 * Import of OSF Mach kernel (~mburg)
37 * Revision 1.3.22.8 1996/07/31 09:07:24 paire
38 * Merged with nmk20b7_shared (1.3.47.1)
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.
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]
52 * Merged '64-bit safe' changes from DEC alpha port.
53 * [1995/11/21 18:03:41 jfraser]
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]
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]
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
68 * Prepend a "db_" to qsort and qsort_limit_search
69 * (collisions with the real qsort in stdlib.h)
72 * Added X_db_init for object independent formats.
75 * Merge with DIPC2_SHARED.
76 * [1995/01/05 13:32:53 alanl]
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]
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.
99 * Handle multiple, coexisting symbol table types.
101 * Revision 1.3.4.5 1993/10/20 18:58:55 gm
102 * CR9704: Removed symbol load printf.
104 * [1994/11/04 08:50:02 dwm]
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
111 * Prepend a "db_" to qsort and qsort_limit_search
112 * (collisions with the real qsort in stdlib.h)
115 * Added X_db_init for object independent formats.
118 * Merge with DIPC2_SHARED.
119 * [1995/01/05 13:32:53 alanl]
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]
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.
142 * Handle multiple, coexisting symbol table types.
144 * Revision 1.3.4.5 1993/10/20 18:58:55 gm
145 * CR9704: Removed symbol load printf.
147 * [1994/11/04 08:50:02 dwm]
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]
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]
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]
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]
167 * Installed ddb_init() routine in a symbol-independent file to call
168 * symbol-dependent and machine-dependent initialization routines.
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.
176 * Added new arguments to db_sym_print_completion() call.
179 * Added db_lookup_incomplete(), db_sym_parse_and_lookup_incomplete(),
180 * db_sym_print_completion() and db_completion_print() for support of
183 * [94/02/07 bernadat]
185 * Revision 1.3.15.4 1994/06/08 19:11:23 dswartz
187 * [1994/06/08 19:10:24 dswartz]
189 * Revision 1.3.20.2 1994/06/01 21:34:39 klj
190 * Initial preemption code base merge
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]
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
200 * [1994/02/03 20:47:22 bolinger]
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]
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]
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]
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]
219 * Added to OSF/1 R1.3 from NMK15.0.
220 * [1993/06/02 20:57:10 jeffc]
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]
227 * Upped MAXNOSYMTABS from 3 to 5. Now there is space for kernel,
228 * bootstrap, server, and emulator symbols - plus one for future
231 * Changed CHAR arg of db_eqname to UNSIGNED.
232 * Made arg types proper for db_line_at_pc().
236 * Sort large symbol tables to speedup lookup.
237 * Improved symbol lookup (use of max_offset, dichotomic search)
238 * [barbou@gr.osf.org]
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]
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]
248 * Revision 1.1 1992/09/30 02:01:25 robert
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]
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]
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.
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.
288 * Revision 2.9 91/07/31 17:31:14 dbg
289 * Add task pointer and space for string storage to symbol table
293 * Revision 2.8 91/07/09 23:16:08 danner
297 * Revision 2.7 91/05/14 15:35:54 mrt
298 * Correcting copyright
300 * Revision 2.6 91/03/16 14:42:40 rpd
301 * Changed the default db_maxoff to 4K.
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]
308 * Revision 2.4 90/10/25 14:44:05 rwd
309 * Changed db_printsym to print unsigned.
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]
316 * Revision 2.2 90/08/27 21:52:18 dbg
317 * Removed nlist.h. Fixed some type declarations.
318 * Qualifier character is ':'.
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
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]
339 * Revision 2.1 90/07/26 16:43:52 dbg
345 * Mach Operating System
346 * Copyright (c) 1991,1990 Carnegie Mellon University
347 * All Rights Reserved.
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.
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.
359 * Carnegie Mellon requests users of this software to return to
361 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
362 * School of Computer Science
363 * Carnegie Mellon University
364 * Pittsburgh PA 15213-3890
366 * any improvements or extensions that they make and grant Carnegie Mellon
367 * the rights to redistribute these changes.
372 * Author: David B. Golub, Carnegie Mellon University
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() */
385 #include <vm/vm_map.h> /* vm_map_t */
388 * Multiple symbol tables
390 * mach, bootstrap, name_server, default_pager, unix, 1 spare
392 #define MAXNOSYMTABS 6
394 db_symtab_t db_symtabs
[MAXNOSYMTABS
] = {{0}};
397 db_symtab_t
*db_last_symtab
;
399 unsigned long db_maxoff
= 0x4000;
401 unsigned long db_maxval
= (unsigned long)&end
;
402 natural_t db_minval
= 0x1000;
404 /* Prototypes for functions local to this file. XXX -- should be static!
406 static char *db_qualify(
408 register char *symtabname
);
415 boolean_t
db_symbol_is_ambiguous(char *name
);
417 void db_shorten_filename(char **filenamep
);
434 int (*compfun
)(char *, char *));
440 int (*compfun
)(char *, char *));
446 int (*compfun
)(char *, char *));
448 int no_print_completion(
451 int no_lookup_incomplete(
459 * Initialization routine for ddb.
469 * Add symbol table, with given name, to list of symbol tables.
479 unsigned long minsym
,
480 unsigned long maxsym
,
483 register db_symtab_t
*st
;
484 extern vm_map_t kernel_map
;
486 if (db_nsymtab
>= MAXNOSYMTABS
)
489 st
= &db_symtabs
[db_nsymtab
];
494 if (map_pointer
== (char *)kernel_map
||
495 (VM_MAX_ADDRESS
<= VM_MIN_KERNEL_ADDRESS
&&
496 VM_MIN_KERNEL_ADDRESS
<= minsym
))
499 st
->map_pointer
= map_pointer
;
500 strcpy(st
->name
, name
);
507 if (db_maxval
< maxsym
+ db_maxoff
)
508 db_maxval
= maxsym
+ db_maxoff
;
516 * db_qualify("vm_map", "ux") returns "ux::vm_map".
518 * Note: return value points to static data whose content is
519 * overwritten by each call... but in practice this seems okay.
524 register char *symtabname
)
526 static char tmp
[256];
530 while (*s
++ = *symtabname
++) {
534 while (*s
++ = *symname
++) {
546 if (!strcmp(src
, dst
))
549 return (!strcmp(src
+1,dst
));
560 sym
= db_lookup(name
);
561 if (sym
== DB_SYM_NULL
)
563 db_symbol_values(0, sym
, &name
, valuep
);
568 * Display list of possible completions for a symbol.
575 int symtab_start
= 0;
576 int symtab_end
= db_nsymtab
;
579 char *name
= (char *)0;
584 * Look for, remove, and remember any symbol table specifier.
586 for (cp
= symstr
; *cp
; cp
++) {
587 if (*cp
== ':' && cp
[1] == ':') {
589 for (i
= 0; i
< db_nsymtab
; i
++) {
590 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
604 * Look in the specified set of symbol tables.
605 * Return on first match.
607 for (i
= symtab_start
; i
< symtab_end
; i
++) {
608 if (X_db_print_completion(&db_symtabs
[i
], symstr
))
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.
620 db_lookup_incomplete(
625 int symtab_start
= 0;
626 int symtab_end
= db_nsymtab
;
629 char *name
= (char *)0;
634 * Look for, remove, and remember any symbol table specifier.
636 for (cp
= symstr
; *cp
; cp
++) {
637 if (*cp
== ':' && cp
[1] == ':') {
639 for (i
= 0; i
< db_nsymtab
; i
++) {
640 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
654 * Look in the specified set of symbol tables.
655 * Return on first match.
657 for (i
= symtab_start
; i
< symtab_end
; i
++) {
658 nsym
= X_db_lookup_incomplete(&db_symtabs
[i
], symstr
,
659 &name
, &len
, &toadd
);
662 len
= strlen(symstr
);
663 if (len
+ toadd
>= symlen
)
665 bcopy(&name
[len
], &symstr
[len
], toadd
);
666 symstr
[len
+ toadd
] = '\0';
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.
681 db_lookup(char *symstr
)
685 int symtab_start
= 0;
686 int symtab_end
= db_nsymtab
;
690 * Look for, remove, and remember any symbol table specifier.
692 for (cp
= symstr
; *cp
; cp
++) {
693 if (*cp
== ':' && cp
[1] == ':') {
695 for (i
= 0; i
< db_nsymtab
; i
++) {
696 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
704 db_error("Invalid symbol table name\n");
710 * Look in the specified set of symbol tables.
711 * Return on first match.
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
];
723 * Print a symbol completion
726 db_sym_print_completion(
733 if (stab
!= db_symtabs
)
734 db_printf("%s::", stab
->name
);
741 db_printf(" [static from %s", fname
);
743 db_printf(":%d", line
);
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.
758 db_sym_parse_and_print_completion(
759 int (*func
)(db_symtab_t
*,
771 * disassemble the symbol into components: [file_name:]symbol
773 component
[0] = symstr
;
775 for (p
= symstr
, n
= 1; *p
; p
++) {
780 component
[n
++] = p
+1;
785 sym_name
= component
[0];
787 sym_name
= component
[1];
789 nsym
= func(symtab
, sym_name
);
793 component
[1][-1] = ':';
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.
806 db_sym_parse_and_lookup_incomplete(
807 int (*func
)(db_symtab_t
*,
828 * disassemble the symbol into components: [file_name:]symbol
830 component
[0] = symstr
;
832 for (p
= symstr
, n
= 1; *p
; p
++) {
837 component
[n
++] = p
+1;
843 sym_name
= component
[0];
845 file_name
= component
[0];
846 sym_name
= component
[1];
848 nsym
= func(symtab
, file_name
, sym_name
, 0, (db_sym_t
*)0,
851 *toadd
= *len
- strlen(sym_name
);
854 component
[1][-1] = ':';
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.
867 db_sym_parse_and_lookup(
868 int (*func
)(db_symtab_t
*, char *, char *, int,
869 db_sym_t
*, char **, int *),
880 db_sym_t found
= DB_SYM_NULL
;
883 * disassemble the symbol into components:
884 * [file_name:]symbol[:line_nubmer]
886 component
[0] = symstr
;
887 component
[1] = component
[2] = 0;
888 for (p
= symstr
, n
= 1; *p
; p
++) {
893 component
[n
++] = p
+1;
901 if (*p
>= '0' && *p
<= '9') {
904 for (line_number
= 0; *p
; p
++) {
905 if (*p
< '0' || *p
> '9')
907 line_number
= line_number
*10 + *p
- '0';
913 for (p
= component
[0]; *p
&& *p
!= '.'; p
++);
915 file_name
= component
[0];
919 sym_name
= component
[0];
922 file_name
= component
[0];
923 sym_name
= component
[1];
925 (void) func(symtab
, file_name
, sym_name
, line_number
, &found
,
926 (char **)0, (int *)0);
930 component
[n
][-1] = ':';
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.
938 boolean_t db_qualify_ambiguous_names
= TRUE
;
941 db_symbol_is_ambiguous(char *name
)
945 boolean_t found_once
= FALSE
;
947 if (!db_qualify_ambiguous_names
)
950 for (i
= 0; i
< db_nsymtab
; i
++) {
951 if (X_db_lookup(&db_symtabs
[i
], name
)) {
961 * Find the closest symbol to val, and return its name
962 * and the difference between val and the symbol found.
964 unsigned int db_search_maxoff
= 0x4000;
966 db_search_task_symbol(
967 register db_addr_t val
,
968 db_strategy_t strategy
,
969 db_addr_t
*offp
, /* better be unsigned */
972 unsigned long diff
, newdiff
;
975 db_sym_t ret
= DB_SYM_NULL
, sym
;
976 vm_map_t map_for_val
;
978 if (task
== TASK_NULL
)
979 task
= db_current_task();
980 map_for_val
= (task
== TASK_NULL
)? VM_MAP_NULL
: task
->map
;
982 newdiff
= diff
= ~0UL;
984 for (sp
= &db_symtabs
[0], i
= 0;
987 if (((vm_map_t
)sp
->map_pointer
== VM_MAP_NULL
||
988 (vm_map_t
)sp
->map_pointer
== map_for_val
) &&
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
) {
998 if (diff
<= db_search_maxoff
)
1003 if (ret
== DB_SYM_NULL
&& map_for_val
!= VM_MAP_NULL
) {
1004 map_for_val
= VM_MAP_NULL
;
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.
1017 db_search_task_symbol_and_line(
1018 register db_addr_t val
,
1019 db_strategy_t strategy
,
1026 unsigned long diff
, newdiff
;
1029 db_sym_t ret
= DB_SYM_NULL
, sym
;
1030 vm_map_t map_for_val
;
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;
1043 filename
= (char *) 0;
1045 newdiff
= diff
= ~0UL;
1047 for (sp
= &db_symtabs
[0], i
= 0;
1050 if (((vm_map_t
)sp
->map_pointer
== VM_MAP_NULL
||
1051 (vm_map_t
)sp
->map_pointer
== map_for_val
) &&
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
,
1058 if (sym
&& newdiff
< diff
) {
1059 db_last_symtab
= sp
;
1062 *filenamep
= filename
;
1063 *linenump
= linenum
;
1065 if (diff
<= db_search_maxoff
)
1070 if (ret
== DB_SYM_NULL
&& map_for_val
!= VM_MAP_NULL
) {
1071 map_for_val
= VM_MAP_NULL
;
1076 db_shorten_filename(filenamep
);
1081 * Return name and value of a symbol
1093 if (sym
== DB_SYM_NULL
) {
1098 stab
= db_last_symtab
;
1100 X_db_symbol_values(stab
, sym
, &name
, &value
);
1102 if (db_symbol_is_ambiguous(name
)) {
1103 *namep
= db_qualify(name
, db_last_symtab
->name
);
1113 * Print a the closest symbol to value
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).
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).
1131 db_strategy_t strategy
,
1141 if (off
>= db_maxval
|| off
< db_minval
) {
1142 db_printf("%#n", off
);
1145 cursym
= db_search_task_symbol(off
, strategy
, &d
, task
);
1147 db_symbol_values(0, cursym
, &name
, &value
);
1148 if (name
== 0 || d
>= db_maxoff
|| value
== 0) {
1149 db_printf("%#n", off
);
1152 db_printf("%s", name
);
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
);
1159 db_printf(":%d", linenum
);
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.
1172 char null_sym
[] = "";
1175 db_get_sym(db_expr_t
*off
)
1182 cursym
= db_search_symbol(*off
, DB_STGY_ANY
, &d
);
1183 db_symbol_values(0, cursym
, &name
, &value
);
1194 db_strategy_t strategy
)
1196 db_task_printsym(off
, strategy
, TASK_NULL
);
1199 int db_short_filename
= 1;
1202 db_shorten_filename(char **filenamep
)
1204 char *cp
, *cp_slash
;
1208 for (cp
= cp_slash
= *filenamep
; *cp
; cp
++) {
1212 if (*cp_slash
== '/')
1213 *filenamep
= cp_slash
+1;
1227 db_strategy_t strategy
= DB_STGY_PROC
;
1229 if (off
>= db_maxval
|| off
< db_minval
) {
1230 db_printf("%#n", off
);
1233 cursym
= db_search_task_symbol(off
, strategy
, &d
, task
);
1235 db_symbol_values(0, cursym
, &name
, &value
);
1236 if (name
== 0 || d
>= db_maxoff
|| value
== 0) {
1239 if (db_line_at_pc(cursym
, &filename
, &linenum
, off
))
1254 if (db_last_symtab
== 0)
1256 if (X_db_line_at_pc( db_last_symtab
, sym
, filename
, linenum
, pc
)) {
1257 if (db_short_filename
)
1258 db_shorten_filename(filename
);
1265 int qsort_check
= 0;
1272 int (*compfun
)(char *, char *))
1274 if (nbelts
<= 0 || eltsize
<= 0 || compfun
== 0) {
1275 printf("qsort: invalid parameters\n");
1278 qsort_recur(table
, table
+ nbelts
* eltsize
, eltsize
, compfun
);
1281 qsort_checker(table
, nbelts
, eltsize
, compfun
);
1294 for (; size
>= sizeof (int); size
-= sizeof (int), a
++, b
++) {
1301 for (; size
> 0; size
--, aa
++, bb
++) {
1308 /* rotate the three elements to the left */
1320 for (; size
>= sizeof (int); size
-= sizeof (int), a
++, b
++, c
++) {
1329 for (; size
> 0; size
--, aa
++, bb
++, cc
++) {
1342 int (*compfun
)(char *, char *))
1345 char *sameleft
, *sameright
;
1348 if (left
+ eltsize
- 1 >= right
) {
1352 /* partition element (reference for "same"ness */
1353 sameleft
= left
+ (((right
- left
) / eltsize
) / 2) * eltsize
;
1354 sameright
= sameleft
;
1357 j
= right
- eltsize
;
1360 while (i
< sameleft
) {
1363 comp
= (*compfun
)(i
, sameleft
);
1366 * Move to the "same" partition.
1369 * Shift the left part of the "same" partition to
1370 * the left, so that "same" elements stay in their
1373 sameleft
-= eltsize
;
1374 qsort_swap((int *) i
, (int *) sameleft
, eltsize
);
1375 } else if (comp
< 0) {
1377 * Stay in the "left" partition.
1382 * Should be moved to the "right" partition.
1383 * Wait until the next loop finds an appropriate
1384 * place to store this element.
1390 while (j
> sameright
) {
1393 comp
= (*compfun
)(sameright
, j
);
1396 * Move to the right of the "same" partition.
1398 sameright
+= eltsize
;
1399 qsort_swap((int *) sameright
, (int *) j
, eltsize
);
1400 } else if (comp
> 0) {
1402 * Move to the "left" partition.
1404 if (i
== sameleft
) {
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.
1413 sameright
+= eltsize
;
1414 qsort_rotate((int *) sameleft
, (int*) sameright
,
1415 (int *) j
, eltsize
);
1416 sameleft
+= eltsize
;
1420 * Swap with the "left" partition element
1421 * waiting to be moved to the "right"
1424 qsort_swap((int *) i
, (int *) j
, eltsize
);
1427 * Go back to the 1st loop.
1434 * Stay in the "right" partition.
1440 if (i
!= sameleft
) {
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.
1447 sameleft
-= eltsize
;
1448 qsort_rotate((int *) sameright
, (int *) sameleft
, (int *) i
,
1450 sameright
-= eltsize
;
1453 * Go back to 1st loop.
1459 * The partitions are correct now. Recur on the smallest side only.
1461 if (sameleft
- left
>= right
- (sameright
+ eltsize
)) {
1462 qsort_recur(sameright
+ eltsize
, right
, eltsize
, compfun
);
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
1472 qsort_recur(left
, sameleft
, eltsize
, compfun
);
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.
1479 left
= sameright
+ eltsize
;
1489 int (*compfun
)(char *, char *))
1491 char *curr
, *prev
, *last
;
1494 curr
= prev
+ eltsize
;
1495 last
= table
+ (nbelts
* eltsize
);
1497 while (prev
< last
) {
1498 if ((*compfun
)(prev
, curr
) > 0) {
1499 printf("**** qsort_checker: error between 0x%x and 0x%x!!!\n", prev
, curr
);
1505 printf("qsort_checker: OK\n");
1508 int qsort_search_debug
= 0;
1511 db_qsort_limit_search(
1516 int (*compfun
)(char *, char *))
1518 register char *left
, *right
;
1519 char *oleft
, *oright
, *part
;
1523 oleft
= left
= *start
;
1524 oright
= right
= *end
;
1527 while (left
< right
) {
1529 part
= left
+ (((right
- left
) / eltsize
) / 2) * eltsize
;
1530 comp
= (*compfun
)(target
, part
);
1537 if (qsort_search_debug
> 1)
1538 printf(" [ Moved left from 0x%x to 0x%x]\n",
1540 } else if (comp
< 0) {
1544 if (qsort_search_debug
> 1)
1545 printf(" [ Moved right from 0x%x to 0x%x]\n",
1548 if (qsort_search_debug
> 1)
1549 printf(" [ FOUND! left=0x%x right=0x%x]\n",
1552 left
> *start
&& (*compfun
)(left
, part
) == 0;
1554 for (right
= part
+ eltsize
;
1555 right
< *end
&& (*compfun
)(right
, part
) == 0;
1563 if (qsort_search_debug
)
1564 printf("[ Limited from %x-%x to %x-%x in %d iters ]\n",
1565 *start
, *end
, oleft
, oright
, nbiter
);
1575 int (*compfun
)(char *, char *))
1581 end
= table
+ ((nbelts
-1) * eltsize
);
1584 for (p
= table
; p
< end
; p
+= eltsize
) {
1585 if ((*compfun
)(p
, p
+ eltsize
) > 0) {
1586 qsort_swap((int *) p
, (int *) (p
+ eltsize
),
1591 } while (sorted
== FALSE
);
1594 qsort_checker(table
, nbelts
, eltsize
, compfun
);
1597 vm_offset_t vm_min_inks_addr
= VM_MAX_KERNEL_ADDRESS
;
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
;
1613 char *clonee
, /* which symtab to clone */
1614 char *cloner
, /* in-kernel-server name */
1615 vm_offset_t base
) /* base address of cloner */
1617 db_symtab_t
*st
, *st_src
;
1621 extern vm_offset_t
kalloc(vm_size_t
);
1622 extern void db_clone_offsetXXX(char *, long);
1624 if (db_nsymtab
>= MAXNOSYMTABS
) {
1625 db_printf("db_clone_symtab: Too Many Symbol Tables\n");
1629 db_install_inks(base
);
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
);
1636 /* alloc new symbols */
1637 size
= (vm_size_t
)(st_src
->end
- st_src
->private);
1638 memp
= (char *)kalloc( round_page(size
) );
1640 db_printf("db_clone_symtab: no memory for symtab\n");
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 */
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
);
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
;
1666 db_symtab_cloneeXXX(
1669 db_symtab_t
*st
, *st_src
;
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
))
1675 return ((st_src
< st
) ? st_src
: 0);
1679 * Switch into symbol-table specific routines
1682 #if !defined(__alpha) && !defined(INTEL860)
1687 #include <ddb/db_aout.h>
1691 #include <ddb/db_coff.h>
1694 static void no_init(void)
1697 db_printf("Non-existent code for ddb init\n");
1700 static boolean_t
no_sym_init(
1706 db_printf("Non-existent code for init of symtab %s\n", name
);
1710 static db_sym_t
no_lookup(
1714 db_printf("Bogus lookup of symbol %s\n", symstr
);
1718 static db_sym_t
no_search(
1721 db_strategy_t strategy
,
1724 db_printf("Bogus search for offset %#Xn", off
);
1728 static boolean_t
no_line_at_pc(
1735 db_printf("Bogus search for pc %#X\n", pc
);
1739 static void no_symbol_values(
1744 db_printf("Bogus symbol value resolution\n");
1745 if (namep
) *namep
= NULL
;
1746 if (valuep
) *valuep
= 0;
1749 static db_sym_t
no_search_by_addr(
1758 db_printf("Bogus search for address %#X\n", off
);
1763 no_print_completion(
1767 db_printf("Bogus print completion: not supported\n");
1772 no_lookup_incomplete(
1779 db_printf("Bogus lookup incomplete: not supported\n");
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}
1788 struct db_sym_switch x_db
[] = {
1790 /* BSD a.out format (really, sdb/dbx(1) symtabs) */
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 */
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 */
1807 /* Machdep, not inited here */