2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
59 * Author: David B. Golub, Carnegie Mellon University
63 #include <machine/db_machdep.h>
64 #include <string.h> /* For strcpy(), strcmp() */
65 #include <mach/std_types.h>
66 #include <kern/misc_protos.h> /* For printf() */
67 #include <ddb/db_sym.h>
68 #include <ddb/db_task_thread.h>
69 #include <ddb/db_command.h>
70 #include <ddb/db_output.h> /* For db_printf() */
72 #include <vm/vm_map.h> /* vm_map_t */
75 * Multiple symbol tables
77 * mach, bootstrap, name_server, default_pager, unix, 1 spare
79 #define MAXNOSYMTABS 6
81 db_symtab_t db_symtabs
[MAXNOSYMTABS
] = {{0}};
84 db_symtab_t
*db_last_symtab
;
86 unsigned long db_maxoff
= 0x4000;
88 unsigned long db_maxval
= (unsigned long)&end
;
89 natural_t db_minval
= 0x1000;
91 /* Prototypes for functions local to this file. XXX -- should be static!
93 static char *db_qualify(
95 register char *symtabname
);
102 boolean_t
db_symbol_is_ambiguous(char *name
);
104 void db_shorten_filename(char **filenamep
);
121 int (*compfun
)(char *, char *));
127 int (*compfun
)(char *, char *));
133 int (*compfun
)(char *, char *));
135 int no_print_completion(
138 int no_lookup_incomplete(
146 * Initialization routine for ddb.
156 * Add symbol table, with given name, to list of symbol tables.
166 unsigned long minsym
,
167 unsigned long maxsym
,
170 register db_symtab_t
*st
;
171 extern vm_map_t kernel_map
;
173 if (db_nsymtab
>= MAXNOSYMTABS
)
176 st
= &db_symtabs
[db_nsymtab
];
181 if (map_pointer
== (char *)kernel_map
||
182 (VM_MAX_ADDRESS
<= VM_MIN_KERNEL_ADDRESS
&&
183 VM_MIN_KERNEL_ADDRESS
<= minsym
))
186 st
->map_pointer
= map_pointer
;
187 strcpy(st
->name
, name
);
194 if (db_maxval
< maxsym
+ db_maxoff
)
195 db_maxval
= maxsym
+ db_maxoff
;
203 * db_qualify("vm_map", "ux") returns "ux::vm_map".
205 * Note: return value points to static data whose content is
206 * overwritten by each call... but in practice this seems okay.
211 register char *symtabname
)
213 static char tmp
[256];
217 while (*s
++ = *symtabname
++) {
221 while (*s
++ = *symname
++) {
233 if (!strcmp(src
, dst
))
236 return (!strcmp(src
+1,dst
));
247 sym
= db_lookup(name
);
248 if (sym
== DB_SYM_NULL
)
250 db_symbol_values(0, sym
, &name
, valuep
);
255 * Display list of possible completions for a symbol.
262 int symtab_start
= 0;
263 int symtab_end
= db_nsymtab
;
266 char *name
= (char *)0;
271 * Look for, remove, and remember any symbol table specifier.
273 for (cp
= symstr
; *cp
; cp
++) {
274 if (*cp
== ':' && cp
[1] == ':') {
276 for (i
= 0; i
< db_nsymtab
; i
++) {
277 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
291 * Look in the specified set of symbol tables.
292 * Return on first match.
294 for (i
= symtab_start
; i
< symtab_end
; i
++) {
295 if (X_db_print_completion(&db_symtabs
[i
], symstr
))
301 * Lookup a (perhaps incomplete) symbol.
302 * If the symbol has a qualifier (e.g., ux::vm_map),
303 * then only the specified symbol table will be searched;
304 * otherwise, all symbol tables will be searched.
307 db_lookup_incomplete(
312 int symtab_start
= 0;
313 int symtab_end
= db_nsymtab
;
316 char *name
= (char *)0;
321 * Look for, remove, and remember any symbol table specifier.
323 for (cp
= symstr
; *cp
; cp
++) {
324 if (*cp
== ':' && cp
[1] == ':') {
326 for (i
= 0; i
< db_nsymtab
; i
++) {
327 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
341 * Look in the specified set of symbol tables.
342 * Return on first match.
344 for (i
= symtab_start
; i
< symtab_end
; i
++) {
345 nsym
= X_db_lookup_incomplete(&db_symtabs
[i
], symstr
,
346 &name
, &len
, &toadd
);
349 len
= strlen(symstr
);
350 if (len
+ toadd
>= symlen
)
352 bcopy(&name
[len
], &symstr
[len
], toadd
);
353 symstr
[len
+ toadd
] = '\0';
363 * If the symbol has a qualifier (e.g., ux::vm_map),
364 * then only the specified symbol table will be searched;
365 * otherwise, all symbol tables will be searched.
368 db_lookup(char *symstr
)
372 int symtab_start
= 0;
373 int symtab_end
= db_nsymtab
;
377 * Look for, remove, and remember any symbol table specifier.
379 for (cp
= symstr
; *cp
; cp
++) {
380 if (*cp
== ':' && cp
[1] == ':') {
382 for (i
= 0; i
< db_nsymtab
; i
++) {
383 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
391 db_error("Invalid symbol table name\n");
397 * Look in the specified set of symbol tables.
398 * Return on first match.
400 for (i
= symtab_start
; i
< symtab_end
; i
++) {
401 if (sp
= X_db_lookup(&db_symtabs
[i
], symstr
)) {
402 db_last_symtab
= &db_symtabs
[i
];
410 * Print a symbol completion
413 db_sym_print_completion(
420 if (stab
!= db_symtabs
)
421 db_printf("%s::", stab
->name
);
428 db_printf(" [static from %s", fname
);
430 db_printf(":%d", line
);
437 * Common utility routine to parse a symbol string into a file
438 * name, a (possibly incomplete) symbol name without line number.
439 * This routine is called from aout_db_print_completion if the object
440 * dependent handler supports qualified search with a file name.
441 * It parses the symbol string, and call an object dependent routine
442 * with parsed file name and symbol name.
445 db_sym_parse_and_print_completion(
446 int (*func
)(db_symtab_t
*,
458 * disassemble the symbol into components: [file_name:]symbol
460 component
[0] = symstr
;
462 for (p
= symstr
, n
= 1; *p
; p
++) {
467 component
[n
++] = p
+1;
472 sym_name
= component
[0];
474 sym_name
= component
[1];
476 nsym
= func(symtab
, sym_name
);
480 component
[1][-1] = ':';
485 * Common utility routine to parse a symbol string into a file
486 * name, a (possibly incomplete) symbol name without line number.
487 * This routine is called from X_db_lookup_incomplete if the object
488 * dependent handler supports qualified search with a file name.
489 * It parses the symbol string, and call an object dependent routine
490 * with parsed file name and symbol name.
493 db_sym_parse_and_lookup_incomplete(
494 int (*func
)(db_symtab_t
*,
515 * disassemble the symbol into components: [file_name:]symbol
517 component
[0] = symstr
;
519 for (p
= symstr
, n
= 1; *p
; p
++) {
524 component
[n
++] = p
+1;
530 sym_name
= component
[0];
532 file_name
= component
[0];
533 sym_name
= component
[1];
535 nsym
= func(symtab
, file_name
, sym_name
, 0, (db_sym_t
*)0,
538 *toadd
= *len
- strlen(sym_name
);
541 component
[1][-1] = ':';
546 * Common utility routine to parse a symbol string into a file
547 * name, a symbol name and line number.
548 * This routine is called from aout_db_lookup if the object dependent
549 * handler supports qualified search with a file name or a line number.
550 * It parses the symbol string, and call an object dependent routine
551 * with parsed file name, symbol name and line number.
554 db_sym_parse_and_lookup(
555 int (*func
)(db_symtab_t
*, char *, char *, int,
556 db_sym_t
*, char **, int *),
567 db_sym_t found
= DB_SYM_NULL
;
570 * disassemble the symbol into components:
571 * [file_name:]symbol[:line_nubmer]
573 component
[0] = symstr
;
574 component
[1] = component
[2] = 0;
575 for (p
= symstr
, n
= 1; *p
; p
++) {
580 component
[n
++] = p
+1;
588 if (*p
>= '0' && *p
<= '9') {
591 for (line_number
= 0; *p
; p
++) {
592 if (*p
< '0' || *p
> '9')
594 line_number
= line_number
*10 + *p
- '0';
600 for (p
= component
[0]; *p
&& *p
!= '.'; p
++);
602 file_name
= component
[0];
606 sym_name
= component
[0];
609 file_name
= component
[0];
610 sym_name
= component
[1];
612 (void) func(symtab
, file_name
, sym_name
, line_number
, &found
,
613 (char **)0, (int *)0);
617 component
[n
][-1] = ':';
622 * Does this symbol name appear in more than one symbol table?
623 * Used by db_symbol_values to decide whether to qualify a symbol.
625 boolean_t db_qualify_ambiguous_names
= TRUE
;
628 db_symbol_is_ambiguous(char *name
)
632 boolean_t found_once
= FALSE
;
634 if (!db_qualify_ambiguous_names
)
637 for (i
= 0; i
< db_nsymtab
; i
++) {
638 if (X_db_lookup(&db_symtabs
[i
], name
)) {
648 * Find the closest symbol to val, and return its name
649 * and the difference between val and the symbol found.
651 unsigned int db_search_maxoff
= 0x4000;
653 db_search_task_symbol(
654 register db_addr_t val
,
655 db_strategy_t strategy
,
656 db_addr_t
*offp
, /* better be unsigned */
659 db_addr_t diff
, newdiff
;
662 db_sym_t ret
= DB_SYM_NULL
, sym
;
663 vm_map_t map_for_val
;
665 if (task
== TASK_NULL
)
666 task
= db_current_task();
667 map_for_val
= (task
== TASK_NULL
)? VM_MAP_NULL
: task
->map
;
671 for (sp
= &db_symtabs
[0], i
= 0;
674 if ((((vm_map_t
)sp
->map_pointer
== VM_MAP_NULL
) ||
675 ((vm_map_t
)sp
->map_pointer
== map_for_val
)) &&
676 ((sp
->maxsym
== 0) ||
677 ((val
>= (db_addr_t
)sp
->minsym
) &&
678 (val
<= (db_addr_t
)sp
->maxsym
)))) {
679 sym
= X_db_search_symbol(sp
, val
, strategy
,
680 (db_expr_t
*)&newdiff
);
681 if (newdiff
< diff
) {
685 if (diff
<= db_search_maxoff
)
690 if (ret
== DB_SYM_NULL
&& map_for_val
!= VM_MAP_NULL
) {
691 map_for_val
= VM_MAP_NULL
;
699 * Find the closest symbol to val, and return its name
700 * and the difference between val and the symbol found.
701 * Also return the filename and linenumber if available.
704 db_search_task_symbol_and_line(
705 register db_addr_t val
,
706 db_strategy_t strategy
,
713 db_addr_t diff
, newdiff
;
716 db_sym_t ret
= DB_SYM_NULL
, sym
;
717 vm_map_t map_for_val
;
723 if (task
== TASK_NULL
)
724 task
= db_current_task();
725 map_for_val
= (task
== TASK_NULL
)? VM_MAP_NULL
: task
->map
;
726 *filenamep
= (char *) 0;
730 filename
= (char *) 0;
732 newdiff
= diff
= ~0UL;
734 for (sp
= &db_symtabs
[0], i
= 0;
737 if ((((vm_map_t
)sp
->map_pointer
== VM_MAP_NULL
) ||
738 ((vm_map_t
)sp
->map_pointer
== map_for_val
)) &&
739 ((sp
->maxsym
== 0) ||
740 ((val
>= (db_addr_t
)sp
->minsym
) &&
741 (val
<= (db_addr_t
)sp
->maxsym
)))) {
743 sym
= X_db_search_by_addr(sp
, val
, &filename
, &func
,
744 &linenum
, (db_expr_t
*)&newdiff
,
746 if (sym
&& newdiff
< diff
) {
750 *filenamep
= filename
;
753 if (diff
<= db_search_maxoff
)
758 if (ret
== DB_SYM_NULL
&& map_for_val
!= VM_MAP_NULL
) {
759 map_for_val
= VM_MAP_NULL
;
764 db_shorten_filename(filenamep
);
769 * Return name and value of a symbol
781 if (sym
== DB_SYM_NULL
) {
786 stab
= db_last_symtab
;
788 X_db_symbol_values(stab
, sym
, &name
, &value
);
790 if (db_symbol_is_ambiguous(name
)) {
791 *namep
= db_qualify(name
, db_last_symtab
->name
);
801 * Print a the closest symbol to value
803 * After matching the symbol according to the given strategy
804 * we print it in the name+offset format, provided the symbol's
805 * value is close enough (eg smaller than db_maxoff).
806 * We also attempt to print [filename:linenum] when applicable
807 * (eg for procedure names).
809 * If we could not find a reasonable name+offset representation,
810 * then we just print the value in hex. Small values might get
811 * bogus symbol associations, e.g. 3 might get some absolute
812 * value like _INCLUDE_VERSION or something, therefore we do
813 * not accept symbols whose value is zero (and use plain hex).
819 db_strategy_t strategy
,
829 if (off
>= db_maxval
|| off
< db_minval
) {
830 db_printf("%#lln", (unsigned long long)off
);
833 cursym
= db_search_task_symbol(off
, strategy
, &d
, task
);
835 db_symbol_values(0, cursym
, &name
, &value
);
836 if (name
== 0 || d
>= db_maxoff
|| value
== 0) {
837 db_printf("%#lln",(unsigned long long) off
);
840 db_printf("%s", name
);
842 db_printf("+%llx", (unsigned long long)d
);
843 if (strategy
== DB_STGY_PROC
) {
844 if (db_line_at_pc(cursym
, &filename
, &linenum
, off
)) {
845 db_printf(" [%s", filename
);
847 db_printf(":%d", linenum
);
854 * Return symbol name for a given offset and
855 * change the offset to be relative to this symbol.
856 * Very usefull for xpr, when you want to log offsets
857 * in a user friendly way.
860 char null_sym
[] = "";
863 db_get_sym(db_expr_t
*off
)
870 cursym
= db_search_symbol(*off
, DB_STGY_ANY
, &d
);
871 db_symbol_values(0, cursym
, &name
, &value
);
882 db_strategy_t strategy
)
884 db_task_printsym(off
, strategy
, TASK_NULL
);
887 int db_short_filename
= 1;
890 db_shorten_filename(char **filenamep
)
896 for (cp
= cp_slash
= *filenamep
; *cp
; cp
++) {
900 if (*cp_slash
== '/')
901 *filenamep
= cp_slash
+1;
915 db_strategy_t strategy
= DB_STGY_PROC
;
917 if (off
>= db_maxval
|| off
< db_minval
) {
918 db_printf("%#lln", (unsigned long long)off
);
921 cursym
= db_search_task_symbol(off
, strategy
, &d
, task
);
923 db_symbol_values(0, cursym
, &name
, &value
);
924 if (name
== 0 || d
>= db_maxoff
|| value
== 0) {
927 if (db_line_at_pc(cursym
, &filename
, &linenum
, off
))
942 if (db_last_symtab
== 0)
944 if (X_db_line_at_pc( db_last_symtab
, sym
, filename
, linenum
, pc
)) {
945 if (db_short_filename
)
946 db_shorten_filename(filename
);
960 int (*compfun
)(char *, char *))
962 if (nbelts
<= 0 || eltsize
<= 0 || compfun
== 0) {
963 printf("qsort: invalid parameters\n");
966 qsort_recur(table
, table
+ nbelts
* eltsize
, eltsize
, compfun
);
969 qsort_checker(table
, nbelts
, eltsize
, compfun
);
982 for (; size
>= sizeof (int); size
-= sizeof (int), a
++, b
++) {
989 for (; size
> 0; size
--, aa
++, bb
++) {
996 /* rotate the three elements to the left */
1008 for (; size
>= sizeof (int); size
-= sizeof (int), a
++, b
++, c
++) {
1017 for (; size
> 0; size
--, aa
++, bb
++, cc
++) {
1030 int (*compfun
)(char *, char *))
1033 char *sameleft
, *sameright
;
1036 if (left
+ eltsize
- 1 >= right
) {
1040 /* partition element (reference for "same"ness */
1041 sameleft
= left
+ (((right
- left
) / eltsize
) / 2) * eltsize
;
1042 sameright
= sameleft
;
1045 j
= right
- eltsize
;
1048 while (i
< sameleft
) {
1051 comp
= (*compfun
)(i
, sameleft
);
1054 * Move to the "same" partition.
1057 * Shift the left part of the "same" partition to
1058 * the left, so that "same" elements stay in their
1061 sameleft
-= eltsize
;
1062 qsort_swap((int *) i
, (int *) sameleft
, eltsize
);
1063 } else if (comp
< 0) {
1065 * Stay in the "left" partition.
1070 * Should be moved to the "right" partition.
1071 * Wait until the next loop finds an appropriate
1072 * place to store this element.
1078 while (j
> sameright
) {
1081 comp
= (*compfun
)(sameright
, j
);
1084 * Move to the right of the "same" partition.
1086 sameright
+= eltsize
;
1087 qsort_swap((int *) sameright
, (int *) j
, eltsize
);
1088 } else if (comp
> 0) {
1090 * Move to the "left" partition.
1092 if (i
== sameleft
) {
1094 * Unfortunately, the "left" partition
1095 * has already been fully processed, so
1096 * we have to shift the "same" partition
1097 * to the right to free a "left" element.
1098 * This is done by moving the leftest same
1099 * to the right of the "same" partition.
1101 sameright
+= eltsize
;
1102 qsort_rotate((int *) sameleft
, (int*) sameright
,
1103 (int *) j
, eltsize
);
1104 sameleft
+= eltsize
;
1108 * Swap with the "left" partition element
1109 * waiting to be moved to the "right"
1112 qsort_swap((int *) i
, (int *) j
, eltsize
);
1115 * Go back to the 1st loop.
1122 * Stay in the "right" partition.
1128 if (i
!= sameleft
) {
1130 * The second loop completed (the"right" partition is ok),
1131 * but we have to go back to the first loop, and deal with
1132 * the element waiting for a place in the "right" partition.
1133 * Let's shift the "same" zone to the left.
1135 sameleft
-= eltsize
;
1136 qsort_rotate((int *) sameright
, (int *) sameleft
, (int *) i
,
1138 sameright
-= eltsize
;
1141 * Go back to 1st loop.
1147 * The partitions are correct now. Recur on the smallest side only.
1149 if (sameleft
- left
>= right
- (sameright
+ eltsize
)) {
1150 qsort_recur(sameright
+ eltsize
, right
, eltsize
, compfun
);
1152 * The "right" partition is now completely sorted.
1153 * The "same" partition is OK, so...
1154 * Ignore them, and start the loops again on the
1160 qsort_recur(left
, sameleft
, eltsize
, compfun
);
1162 * The "left" partition is now completely sorted.
1163 * The "same" partition is OK, so ...
1164 * Ignore them, and start the loops again on the
1165 * "right" partition.
1167 left
= sameright
+ eltsize
;
1177 int (*compfun
)(char *, char *))
1179 char *curr
, *prev
, *last
;
1182 curr
= prev
+ eltsize
;
1183 last
= table
+ (nbelts
* eltsize
);
1185 while (prev
< last
) {
1186 if ((*compfun
)(prev
, curr
) > 0) {
1187 printf("**** qsort_checker: error between 0x%x and 0x%x!!!\n", prev
, curr
);
1193 printf("qsort_checker: OK\n");
1196 int qsort_search_debug
= 0;
1199 db_qsort_limit_search(
1204 int (*compfun
)(char *, char *))
1206 register char *left
, *right
;
1207 char *oleft
, *oright
, *part
;
1211 oleft
= left
= *start
;
1212 oright
= right
= *end
;
1215 while (left
< right
) {
1217 part
= left
+ (((right
- left
) / eltsize
) / 2) * eltsize
;
1218 comp
= (*compfun
)(target
, part
);
1225 if (qsort_search_debug
> 1)
1226 printf(" [ Moved left from 0x%x to 0x%x]\n",
1228 } else if (comp
< 0) {
1232 if (qsort_search_debug
> 1)
1233 printf(" [ Moved right from 0x%x to 0x%x]\n",
1236 if (qsort_search_debug
> 1)
1237 printf(" [ FOUND! left=0x%x right=0x%x]\n",
1240 left
> *start
&& (*compfun
)(left
, part
) == 0;
1242 for (right
= part
+ eltsize
;
1243 right
< *end
&& (*compfun
)(right
, part
) == 0;
1251 if (qsort_search_debug
)
1252 printf("[ Limited from %x-%x to %x-%x in %d iters ]\n",
1253 *start
, *end
, oleft
, oright
, nbiter
);
1263 int (*compfun
)(char *, char *))
1269 end
= table
+ ((nbelts
-1) * eltsize
);
1272 for (p
= table
; p
< end
; p
+= eltsize
) {
1273 if ((*compfun
)(p
, p
+ eltsize
) > 0) {
1274 qsort_swap((int *) p
, (int *) (p
+ eltsize
),
1279 } while (sorted
== FALSE
);
1282 qsort_checker(table
, nbelts
, eltsize
, compfun
);
1285 vm_offset_t vm_min_inks_addr
= VM_MAX_KERNEL_ADDRESS
;
1291 /* save addr to demarcate kernel/inks boundary (1st time only) */
1292 if (vm_min_inks_addr
== VM_MAX_KERNEL_ADDRESS
) {
1293 vm_min_inks_addr
= base
;
1294 db_qualify_ambiguous_names
= TRUE
;
1301 char *clonee
, /* which symtab to clone */
1302 char *cloner
, /* in-kernel-server name */
1303 vm_offset_t base
) /* base address of cloner */
1305 db_symtab_t
*st
, *st_src
;
1309 extern void db_clone_offsetXXX(char *, long);
1311 if (db_nsymtab
>= MAXNOSYMTABS
) {
1312 db_printf("db_clone_symtab: Too Many Symbol Tables\n");
1316 db_install_inks(base
);
1318 st
= &db_symtabs
[db_nsymtab
]; /* destination symtab */
1319 if ((st_src
= db_symtab_cloneeXXX(clonee
)) == 0) {
1320 db_printf("db_clone_symtab: clonee (%s) not found\n", clonee
);
1323 /* alloc new symbols */
1324 size
= (vm_size_t
)(st_src
->end
- st_src
->private);
1325 memp
= (char *)kalloc( round_page(size
) );
1327 db_printf("db_clone_symtab: no memory for symtab\n");
1331 *st
= *st_src
; /* bulk copy src -> dest */
1332 strcpy(st
->name
, cloner
); /* new name */
1333 st
->private = memp
; /* copy symbols */
1334 bcopy((const char *)st_src
->private, st
->private, size
);
1335 st
->start
= memp
+ sizeof(int); /* fixup pointers to symtab */
1336 st
->end
= memp
+ *(int *)memp
;
1337 st
->map_pointer
= 0; /* no map because kernel-loaded */
1339 /* Offset symbols, leaving strings pointing into st_src */
1340 offset
= base
- st_src
->minsym
;
1341 st
->minsym
+= offset
;
1342 st
->maxsym
+= offset
;
1343 db_clone_offsetXXX(memp
, offset
);
1346 db_printf( "[ cloned symbol table for %s: range 0x%x to 0x%x %s]\n",
1347 st
->name
, st
->minsym
, st
->maxsym
,
1348 st
->sorted
? "(sorted) " : "");
1349 db_maxval
= (unsigned int)st
->maxsym
+ db_maxoff
;
1353 db_symtab_cloneeXXX(
1356 db_symtab_t
*st
, *st_src
;
1358 st
= &db_symtabs
[db_nsymtab
]; /* destination symtab */
1359 for (st_src
= &db_symtabs
[0]; st_src
< st
; ++st_src
)
1360 if (!strcmp(clonee
, st_src
->name
))
1362 return ((st_src
< st
) ? st_src
: 0);
1366 * Switch into symbol-table specific routines
1369 #if !defined(__alpha) && !defined(INTEL860)
1374 #include <ddb/db_aout.h>
1378 #include <ddb/db_coff.h>
1381 static void no_init(void)
1384 db_printf("Non-existent code for ddb init\n");
1387 static boolean_t
no_sym_init(
1393 db_printf("Non-existent code for init of symtab %s\n", name
);
1397 static db_sym_t
no_lookup(
1401 db_printf("Bogus lookup of symbol %s\n", symstr
);
1405 static db_sym_t
no_search(
1408 db_strategy_t strategy
,
1411 db_printf("Bogus search for offset %#llXn", (unsigned long long)off
);
1415 static boolean_t
no_line_at_pc(
1422 db_printf("Bogus search for pc %#llX\n", (unsigned long long)pc
);
1426 static void no_symbol_values(
1431 db_printf("Bogus symbol value resolution\n");
1432 if (namep
) *namep
= NULL
;
1433 if (valuep
) *valuep
= 0;
1436 static db_sym_t
no_search_by_addr(
1445 db_printf("Bogus search for address %#llX\n", (unsigned long long)off
);
1450 no_print_completion(
1454 db_printf("Bogus print completion: not supported\n");
1459 no_lookup_incomplete(
1466 db_printf("Bogus lookup incomplete: not supported\n");
1471 { no_init, no_sym_init, no_lookup, no_search, \
1472 no_line_at_pc, no_symbol_values, no_search_by_addr, \
1473 no_print_completion, no_lookup_incomplete}
1475 struct db_sym_switch x_db
[] = {
1477 /* BSD a.out format (really, sdb/dbx(1) symtabs) */
1480 #else /* DB_NO_AOUT */
1481 { aout_db_init
, aout_db_sym_init
, aout_db_lookup
, aout_db_search_symbol
,
1482 aout_db_line_at_pc
, aout_db_symbol_values
, aout_db_search_by_addr
,
1483 aout_db_print_completion
, aout_db_lookup_incomplete
},
1484 #endif /* DB_NO_AOUT */
1488 #else /* DB_NO_COFF */
1489 { coff_db_init
, coff_db_sym_init
, coff_db_lookup
, coff_db_search_symbol
,
1490 coff_db_line_at_pc
, coff_db_symbol_values
, coff_db_search_by_addr
,
1491 coff_db_print_completion
, coff_db_lookup_incomplete
},
1492 #endif /* DB_NO_COFF */
1494 /* Machdep, not inited here */