2 * Copyright (c) 2000-2005 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 <kern/kalloc.h>
68 #include <ddb/db_sym.h>
69 #include <ddb/db_task_thread.h>
70 #include <ddb/db_command.h>
71 #include <ddb/db_output.h> /* For db_printf() */
73 #include <vm/vm_map.h> /* vm_map_t */
76 * Multiple symbol tables
78 * mach, bootstrap, name_server, default_pager, unix, 1 spare
80 #define MAXNOSYMTABS 6
82 db_symtab_t db_symtabs
[MAXNOSYMTABS
];
85 db_symtab_t
*db_last_symtab
;
87 unsigned long db_maxoff
= 0x4000;
89 unsigned long db_maxval
= (unsigned long)&end
;
90 natural_t db_minval
= 0x1000;
92 /* Prototypes for functions local to this file. XXX -- should be static!
94 static char *db_qualify(
96 register char *symtabname
);
103 boolean_t
db_symbol_is_ambiguous(char *name
);
105 void db_shorten_filename(char **filenamep
);
122 int (*compfun
)(char *, char *));
128 int (*compfun
)(char *, char *));
134 int (*compfun
)(char *, char *));
136 int no_print_completion(
139 int no_lookup_incomplete(
147 * Initialization routine for ddb.
156 extern vm_map_t kernel_map
;
158 * Add symbol table, with given name, to list of symbol tables.
168 unsigned long minsym
,
169 unsigned long maxsym
,
172 register db_symtab_t
*st
;
174 if (db_nsymtab
>= MAXNOSYMTABS
)
177 st
= &db_symtabs
[db_nsymtab
];
182 if (map_pointer
== (char *)kernel_map
||
183 (VM_MIN_KERNEL_ADDRESS
- VM_MAX_ADDRESS
> 0 &&
184 minsym
- VM_MIN_KERNEL_ADDRESS
> 0))
187 st
->map_pointer
= map_pointer
;
188 strcpy(st
->name
, name
);
195 if (db_maxval
< maxsym
+ db_maxoff
)
196 db_maxval
= maxsym
+ db_maxoff
;
204 * db_qualify("vm_map", "ux") returns "ux::vm_map".
206 * Note: return value points to static data whose content is
207 * overwritten by each call... but in practice this seems okay.
212 register char *symtabname
)
214 static char tmp
[256];
218 while ((*s
++ = *symtabname
++)) {
223 while ((*s
++ = *symname
++)) {
236 if (!strcmp(src
, dst
))
238 if (src
[0] == (char)c
)
239 return (!strcmp(src
+1,dst
));
250 sym
= db_lookup(name
);
251 if (sym
== DB_SYM_NULL
)
253 db_symbol_values(0, sym
, &name
, valuep
);
258 * Display list of possible completions for a symbol.
265 int symtab_start
= 0;
266 int symtab_end
= db_nsymtab
;
270 * Look for, remove, and remember any symbol table specifier.
272 for (cp
= symstr
; *cp
; cp
++) {
273 if (*cp
== ':' && cp
[1] == ':') {
275 for (i
= 0; i
< db_nsymtab
; i
++) {
276 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
290 * Look in the specified set of symbol tables.
291 * Return on first match.
293 for (i
= symtab_start
; i
< symtab_end
; i
++) {
294 if (X_db_print_completion(&db_symtabs
[i
], symstr
))
300 * Lookup a (perhaps incomplete) symbol.
301 * If the symbol has a qualifier (e.g., ux::vm_map),
302 * then only the specified symbol table will be searched;
303 * otherwise, all symbol tables will be searched.
306 db_lookup_incomplete(
311 int symtab_start
= 0;
312 int symtab_end
= db_nsymtab
;
315 char *name
= (char *)0;
320 * Look for, remove, and remember any symbol table specifier.
322 for (cp
= symstr
; *cp
; cp
++) {
323 if (*cp
== ':' && cp
[1] == ':') {
325 for (i
= 0; i
< db_nsymtab
; i
++) {
326 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
340 * Look in the specified set of symbol tables.
341 * Return on first match.
343 for (i
= symtab_start
; i
< symtab_end
; i
++) {
344 nsym
= X_db_lookup_incomplete(&db_symtabs
[i
], symstr
,
345 &name
, &len
, &toadd
);
348 len
= strlen(symstr
);
349 if (len
+ toadd
>= symlen
)
351 bcopy(&name
[len
], &symstr
[len
], toadd
);
352 symstr
[len
+ toadd
] = '\0';
362 * If the symbol has a qualifier (e.g., ux::vm_map),
363 * then only the specified symbol table will be searched;
364 * otherwise, all symbol tables will be searched.
367 db_lookup(const char *symstr
)
371 int symtab_start
= 0;
372 int symtab_end
= db_nsymtab
;
376 * Look for, remove, and remember any symbol table specifier.
378 for (cp
= symstr
; *cp
; cp
++) {
379 if (*cp
== ':' && cp
[1] == ':') {
381 for (i
= 0; i
< db_nsymtab
; i
++) {
382 if (! strcmp(symstr
, db_symtabs
[i
].name
)) {
390 db_error("Invalid symbol table name\n");
396 * Look in the specified set of symbol tables.
397 * Return on first match.
399 for (i
= symtab_start
; i
< symtab_end
; i
++) {
400 if ((sp
= X_db_lookup(&db_symtabs
[i
], symstr
))) {
401 db_last_symtab
= &db_symtabs
[i
];
409 * Print a symbol completion
412 db_sym_print_completion(
419 if (stab
!= db_symtabs
)
420 db_printf("%s::", stab
->name
);
427 db_printf(" [static from %s", fname
);
429 db_printf(":%d", line
);
436 * Common utility routine to parse a symbol string into a file
437 * name, a (possibly incomplete) symbol name without line number.
438 * This routine is called from aout_db_print_completion if the object
439 * dependent handler supports qualified search with a file name.
440 * It parses the symbol string, and call an object dependent routine
441 * with parsed file name and symbol name.
444 db_sym_parse_and_print_completion(
445 int (*func
)(db_symtab_t
*,
457 * disassemble the symbol into components: [file_name:]symbol
459 component
[0] = symstr
;
461 for (p
= symstr
, n
= 1; *p
; p
++) {
466 component
[n
++] = p
+1;
471 sym_name
= component
[0];
473 sym_name
= component
[1];
475 nsym
= func(symtab
, sym_name
);
479 component
[1][-1] = ':';
484 * Common utility routine to parse a symbol string into a file
485 * name, a (possibly incomplete) symbol name without line number.
486 * This routine is called from X_db_lookup_incomplete if the object
487 * dependent handler supports qualified search with a file name.
488 * It parses the symbol string, and call an object dependent routine
489 * with parsed file name and symbol name.
492 db_sym_parse_and_lookup_incomplete(
493 int (*func
)(db_symtab_t
*,
514 * disassemble the symbol into components: [file_name:]symbol
516 component
[0] = symstr
;
518 for (p
= symstr
, n
= 1; *p
; p
++) {
523 component
[n
++] = p
+1;
529 sym_name
= component
[0];
531 file_name
= component
[0];
532 sym_name
= component
[1];
534 nsym
= func(symtab
, file_name
, sym_name
, 0, (db_sym_t
*)0,
537 *toadd
= *len
- strlen(sym_name
);
540 component
[1][-1] = ':';
545 * Common utility routine to parse a symbol string into a file
546 * name, a symbol name and line number.
547 * This routine is called from aout_db_lookup if the object dependent
548 * handler supports qualified search with a file name or a line number.
549 * It parses the symbol string, and call an object dependent routine
550 * with parsed file name, symbol name and line number.
553 db_sym_parse_and_lookup(
554 int (*func
)(db_symtab_t
*, char *, char *, int,
555 db_sym_t
*, char **, int *),
566 db_sym_t found
= DB_SYM_NULL
;
569 * disassemble the symbol into components:
570 * [file_name:]symbol[:line_nubmer]
572 component
[0] = symstr
;
573 component
[1] = component
[2] = 0;
574 for (p
= symstr
, n
= 1; *p
; p
++) {
579 component
[n
++] = p
+1;
587 if (*p
>= '0' && *p
<= '9') {
590 for (line_number
= 0; *p
; p
++) {
591 if (*p
< '0' || *p
> '9')
593 line_number
= line_number
*10 + *p
- '0';
599 for (p
= component
[0]; *p
&& *p
!= '.'; p
++);
601 file_name
= component
[0];
605 sym_name
= component
[0];
608 file_name
= component
[0];
609 sym_name
= component
[1];
611 (void) func(symtab
, file_name
, sym_name
, line_number
, &found
,
612 (char **)0, (int *)0);
616 component
[n
][-1] = ':';
621 * Does this symbol name appear in more than one symbol table?
622 * Used by db_symbol_values to decide whether to qualify a symbol.
624 boolean_t db_qualify_ambiguous_names
= TRUE
;
627 db_symbol_is_ambiguous(char *name
)
631 boolean_t found_once
= FALSE
;
633 if (!db_qualify_ambiguous_names
)
636 for (i
= 0; i
< db_nsymtab
; i
++) {
637 if (X_db_lookup(&db_symtabs
[i
], name
)) {
647 * Find the closest symbol to val, and return its name
648 * and the difference between val and the symbol found.
650 unsigned int db_search_maxoff
= 0x4000;
652 db_search_task_symbol(
653 register db_addr_t val
,
654 db_strategy_t strategy
,
655 db_addr_t
*offp
, /* better be unsigned */
658 db_addr_t diff
, newdiff
;
661 db_sym_t ret
= DB_SYM_NULL
, sym
;
662 vm_map_t map_for_val
;
664 if (task
== TASK_NULL
)
665 task
= db_current_task();
666 map_for_val
= (task
== TASK_NULL
)? VM_MAP_NULL
: task
->map
;
670 for (sp
= &db_symtabs
[0], i
= 0;
673 if ((((vm_map_t
)sp
->map_pointer
== VM_MAP_NULL
) ||
674 ((vm_map_t
)sp
->map_pointer
== map_for_val
)) &&
675 ((sp
->maxsym
== 0) ||
676 ((val
>= (db_addr_t
)sp
->minsym
) &&
677 (val
<= (db_addr_t
)sp
->maxsym
)))) {
678 sym
= X_db_search_symbol(sp
, val
, strategy
,
679 (db_expr_t
*)&newdiff
);
680 if (newdiff
< diff
) {
684 if (diff
<= db_search_maxoff
)
689 if (ret
== DB_SYM_NULL
&& map_for_val
!= VM_MAP_NULL
) {
690 map_for_val
= VM_MAP_NULL
;
698 * Find the closest symbol to val, and return its name
699 * and the difference between val and the symbol found.
700 * Also return the filename and linenumber if available.
703 db_search_task_symbol_and_line(
704 register db_addr_t val
,
705 __unused db_strategy_t strategy
,
712 db_addr_t diff
, newdiff
;
715 db_sym_t ret
= DB_SYM_NULL
, sym
;
716 vm_map_t map_for_val
;
722 if (task
== TASK_NULL
)
723 task
= db_current_task();
724 map_for_val
= (task
== TASK_NULL
)? VM_MAP_NULL
: task
->map
;
725 *filenamep
= (char *) 0;
729 filename
= (char *) 0;
731 newdiff
= diff
= ~0UL;
733 for (sp
= &db_symtabs
[0], i
= 0;
736 if ((((vm_map_t
)sp
->map_pointer
== VM_MAP_NULL
) ||
737 ((vm_map_t
)sp
->map_pointer
== map_for_val
)) &&
738 ((sp
->maxsym
== 0) ||
739 ((val
>= (db_addr_t
)sp
->minsym
) &&
740 (val
<= (db_addr_t
)sp
->maxsym
)))) {
742 sym
= X_db_search_by_addr(sp
, val
, &filename
, &func
,
743 &linenum
, (db_expr_t
*)&newdiff
,
745 if (sym
&& newdiff
< diff
) {
749 *filenamep
= filename
;
752 if (diff
<= db_search_maxoff
)
757 if (ret
== DB_SYM_NULL
&& map_for_val
!= VM_MAP_NULL
) {
758 map_for_val
= VM_MAP_NULL
;
763 db_shorten_filename(filenamep
);
768 * Return name and value of a symbol
780 if (sym
== DB_SYM_NULL
) {
785 stab
= db_last_symtab
;
787 X_db_symbol_values(stab
, sym
, &name
, &value
);
789 if (db_symbol_is_ambiguous(name
)) {
790 *namep
= db_qualify(name
, db_last_symtab
->name
);
800 * Print a the closest symbol to value
802 * After matching the symbol according to the given strategy
803 * we print it in the name+offset format, provided the symbol's
804 * value is close enough (eg smaller than db_maxoff).
805 * We also attempt to print [filename:linenum] when applicable
806 * (eg for procedure names).
808 * If we could not find a reasonable name+offset representation,
809 * then we just print the value in hex. Small values might get
810 * bogus symbol associations, e.g. 3 might get some absolute
811 * value like _INCLUDE_VERSION or something, therefore we do
812 * not accept symbols whose value is zero (and use plain hex).
818 db_strategy_t strategy
,
828 if (off
>= db_maxval
|| off
< db_minval
) {
829 db_printf("%#lln", (unsigned long long)off
);
832 cursym
= db_search_task_symbol(off
, strategy
, &d
, task
);
834 db_symbol_values(0, cursym
, &name
, &value
);
835 if (name
== 0 || d
>= db_maxoff
|| value
== 0) {
836 db_printf("%#lln",(unsigned long long) off
);
839 db_printf("%s", name
);
841 db_printf("+%llx", (unsigned long long)d
);
842 if (strategy
== DB_STGY_PROC
) {
843 if (db_line_at_pc(cursym
, &filename
, &linenum
, off
)) {
844 db_printf(" [%s", filename
);
846 db_printf(":%d", linenum
);
853 * Return symbol name for a given offset and
854 * change the offset to be relative to this symbol.
855 * Very usefull for xpr, when you want to log offsets
856 * in a user friendly way.
859 char null_sym
[] = "";
862 db_get_sym(db_expr_t
*off
)
869 cursym
= db_search_symbol(*off
, DB_STGY_ANY
, &d
);
870 db_symbol_values(0, cursym
, &name
, &value
);
881 db_strategy_t strategy
)
883 db_task_printsym(off
, strategy
, TASK_NULL
);
886 int db_short_filename
= 1;
889 db_shorten_filename(char **filenamep
)
895 for (cp
= cp_slash
= *filenamep
; *cp
; cp
++) {
899 if (*cp_slash
== '/')
900 *filenamep
= cp_slash
+1;
914 db_strategy_t strategy
= DB_STGY_PROC
;
916 if (off
>= db_maxval
|| off
< db_minval
) {
917 db_printf("%#lln", (unsigned long long)off
);
920 cursym
= db_search_task_symbol(off
, strategy
, &d
, task
);
922 db_symbol_values(0, cursym
, &name
, &value
);
923 if (name
== 0 || d
>= db_maxoff
|| value
== 0) {
926 if (db_line_at_pc(cursym
, &filename
, &linenum
, off
))
941 if (db_last_symtab
== 0)
943 if (X_db_line_at_pc( db_last_symtab
, sym
, filename
, linenum
, pc
)) {
944 if (db_short_filename
)
945 db_shorten_filename(filename
);
959 int (*compfun
)(char *, char *))
961 if (nbelts
<= 0 || eltsize
<= 0 || compfun
== 0) {
962 printf("qsort: invalid parameters\n");
965 qsort_recur(table
, table
+ nbelts
* eltsize
, eltsize
, compfun
);
968 qsort_checker(table
, nbelts
, eltsize
, compfun
);
981 for (; size
>= (signed)sizeof (int); size
-= sizeof (int), a
++, b
++) {
988 for (; size
> 0; size
--, aa
++, bb
++) {
995 /* rotate the three elements to the left */
1007 for (; size
>= (signed)sizeof(int);
1008 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
= *db_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
< *db_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
, *db_end
, oleft
, oright
, nbiter
);
1263 int (*compfun
)(char *, char *))
1269 b_end
= table
+ ((nbelts
-1) * eltsize
);
1272 for (p
= table
; p
< b_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
;
1298 extern void db_clone_offsetXXX(char *, long);
1302 char *clonee
, /* which symtab to clone */
1303 char *cloner
, /* in-kernel-server name */
1304 vm_offset_t base
) /* base address of cloner */
1306 db_symtab_t
*st
, *st_src
;
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");
1388 no_sym_init(__unused
char *nstart
, __unused
char *nend
, const char *name
,
1389 __unused
char *task_addr
)
1391 db_printf("Non-existent code for init of symtab %s\n", name
);
1396 no_lookup(__unused db_symtab_t
*stab
, char *symstr
)
1398 db_printf("Bogus lookup of symbol %s\n", symstr
);
1403 no_search(__unused db_symtab_t
*stab
, db_addr_t off
,
1404 __unused db_strategy_t strategy
, __unused db_expr_t
*diffp
)
1406 db_printf("Bogus search for offset %#llXn", (unsigned long long)off
);
1411 no_line_at_pc(__unused db_symtab_t
*stab
, __unused db_sym_t sym
,
1412 __unused
char **file
, __unused
int *line
, db_expr_t pc
)
1414 db_printf("Bogus search for pc %#llX\n", (unsigned long long)pc
);
1419 no_symbol_values(__unused db_sym_t sym
, char **namep
, db_expr_t
*valuep
)
1421 db_printf("Bogus symbol value resolution\n");
1422 if (namep
) *namep
= NULL
;
1423 if (valuep
) *valuep
= 0;
1427 no_search_by_addr(__unused db_symtab_t
*stab
, db_addr_t off
,
1428 __unused
char **file
, __unused
char **func
,
1429 __unused
int *line
, __unused db_expr_t
*diffp
,
1432 db_printf("Bogus search for address %#llX\n", (unsigned long long)off
);
1437 no_print_completion(__unused db_symtab_t
*stab
, __unused
char *symstr
)
1439 db_printf("Bogus print completion: not supported\n");
1444 no_lookup_incomplete(__unused db_symtab_t
*stab
,
1445 __unused
char *symstr
, __unused
char **name
,
1446 __unused
int *len
, __unused
int *toadd
)
1448 db_printf("Bogus lookup incomplete: not supported\n");
1455 .sym_init = no_sym_init, \
1456 .lookup = no_lookup, \
1457 .search_symbol = no_search, \
1458 .line_at_pc = no_line_at_pc, \
1459 .symbol_values = no_symbol_values, \
1460 .search_by_addr = no_search_by_addr, \
1461 .print_completion = no_print_completion, \
1462 .lookup_incomplete = no_lookup_incomplete, \
1465 struct db_sym_switch x_db
[] = {
1467 /* BSD a.out format (really, sdb/dbx(1) symtabs) */
1470 #else /* DB_NO_AOUT */
1472 .init
= aout_db_init
,
1473 .sym_init
= aout_db_sym_init
,
1474 .lookup
= aout_db_lookup
,
1475 .search_symbol
= aout_db_search_symbol
,
1476 .line_at_pc
= aout_db_line_at_pc
,
1477 .symbol_values
= aout_db_symbol_values
,
1478 .search_by_addr
= aout_db_search_by_addr
,
1479 .print_completion
= aout_db_print_completion
,
1480 .lookup_incomplete
= aout_db_lookup_incomplete
,
1482 #endif /* DB_NO_AOUT */
1486 #else /* DB_NO_COFF */
1488 .init
= coff_db_init
,
1489 .sym_init
= coff_db_sym_init
,
1490 .lookup
= coff_db_lookup
,
1491 .search_symbol
= coff_db_search_symbol
,
1492 .line_at_pc
= coff_db_line_at_pc
,
1493 .symbol_values
= coff_db_symbol_values
,
1494 .search_by_addr
= coff_db_search_by_addr
,
1495 .print_completion
= coff_db_print_completion
,
1496 .lookup_incomplete
= coff_db_lookup_incomplete
,
1498 #endif /* DB_NO_COFF */
1500 /* Machdep, not inited here */