Line data Source code
1 : /* $OpenBSD: db_sym.c,v 1.53 2017/05/30 15:39:05 mpi Exp $ */
2 : /* $NetBSD: db_sym.c,v 1.24 2000/08/11 22:50:47 tv Exp $ */
3 :
4 : /*
5 : * Mach Operating System
6 : * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
7 : * All Rights Reserved.
8 : *
9 : * Permission to use, copy, modify and distribute this software and its
10 : * documentation is hereby granted, provided that both the copyright
11 : * notice and this permission notice appear in all copies of the
12 : * software, derivative works or modified versions, and any portions
13 : * thereof, and that both notices appear in supporting documentation.
14 : *
15 : * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 : * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
17 : * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 : *
19 : * Carnegie Mellon requests users of this software to return to
20 : *
21 : * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 : * School of Computer Science
23 : * Carnegie Mellon University
24 : * Pittsburgh PA 15213-3890
25 : *
26 : * any improvements or extensions that they make and grant Carnegie Mellon
27 : * the rights to redistribute these changes.
28 : */
29 :
30 : #include <sys/param.h>
31 : #include <sys/systm.h>
32 :
33 : #include <machine/db_machdep.h>
34 :
35 : #include <ddb/db_lex.h>
36 : #include <ddb/db_sym.h>
37 : #include <ddb/db_output.h>
38 : #include <ddb/db_command.h>
39 :
40 : extern char end[];
41 :
42 : /*
43 : * Initialize the kernel debugger by initializing the master symbol
44 : * table. Note that if initializing the master symbol table fails,
45 : * no other symbol tables can be loaded.
46 : */
47 : void
48 0 : ddb_init(void)
49 : {
50 : const char *name = "bsd";
51 : extern char *esym;
52 : #if defined(__sparc64__) || defined(__mips__) || defined(__amd64__) || \
53 : defined(__i386__)
54 : extern char *ssym;
55 : #endif
56 : char *xssym, *xesym;
57 :
58 0 : xesym = esym;
59 : #if defined(__sparc64__) || defined(__mips__) || defined(__amd64__) || \
60 : defined(__i386__)
61 0 : xssym = ssym;
62 : #else
63 : xssym = (char *)&end;
64 : #endif
65 : /*
66 : * Do this check now for the master symbol table to avoid printing
67 : * the message N times.
68 : */
69 0 : if ((((vaddr_t)xssym) & (sizeof(long) - 1)) != 0) {
70 0 : printf("[ %s symbol table has bad start address %p ]\n",
71 : name, xssym);
72 0 : return;
73 : }
74 :
75 0 : if (xesym != NULL && xesym != xssym) {
76 0 : if (db_elf_sym_init((vaddr_t)xesym - (vaddr_t)xssym, xssym,
77 0 : xesym, name) == 1)
78 0 : return;
79 : }
80 :
81 0 : printf("[ no symbol table formats found ]\n");
82 0 : }
83 :
84 : int
85 0 : db_eqname(char *src, char *dst, int c)
86 : {
87 0 : if (!strcmp(src, dst))
88 0 : return (1);
89 0 : if (src[0] == c)
90 0 : return (!strcmp(src+1,dst));
91 0 : return (0);
92 0 : }
93 :
94 : /*
95 : * Find the closest symbol to val, and return its name
96 : * and the difference between val and the symbol found.
97 : */
98 : Elf_Sym *
99 0 : db_search_symbol(db_addr_t val, db_strategy_t strategy, db_expr_t *offp)
100 : {
101 : unsigned int diff;
102 0 : db_expr_t newdiff;
103 : Elf_Sym *ret = NULL, *sym;
104 :
105 0 : newdiff = diff = ~0;
106 0 : sym = db_elf_sym_search(val, strategy, &newdiff);
107 0 : if (newdiff < diff) {
108 0 : diff = newdiff;
109 : ret = sym;
110 0 : }
111 0 : *offp = diff;
112 0 : return ret;
113 0 : }
114 :
115 : /*
116 : * Print a the closest symbol to value
117 : *
118 : * After matching the symbol according to the given strategy
119 : * we print it in the name+offset format, provided the symbol's
120 : * value is close enough (eg smaller than db_maxoff).
121 : * We also attempt to print [filename:linenum] when applicable
122 : * (eg for procedure names).
123 : *
124 : * If we could not find a reasonable name+offset representation,
125 : * then we just print the value in hex. Small values might get
126 : * bogus symbol associations, e.g. 3 might get some absolute
127 : * value like _INCLUDE_VERSION or something, therefore we do
128 : * not accept symbols whose value is zero (and use plain hex).
129 : * Also, avoid printing as "end+0x????" which is useless.
130 : * The variable db_lastsym is used instead of "end" in case we
131 : * add support for symbols in loadable driver modules.
132 : */
133 : unsigned long db_lastsym = (unsigned long)end;
134 : unsigned int db_maxoff = 0x10000000;
135 :
136 :
137 : void
138 0 : db_printsym(db_expr_t off, db_strategy_t strategy,
139 : int (*pr)(const char *, ...))
140 : {
141 0 : db_expr_t d;
142 0 : char *filename;
143 0 : char *name;
144 0 : db_expr_t value;
145 0 : int linenum;
146 : Elf_Sym *cursym;
147 0 : char buf[DB_FORMAT_BUF_SIZE];
148 :
149 0 : if (off <= db_lastsym) {
150 0 : cursym = db_search_symbol(off, strategy, &d);
151 0 : db_symbol_values(cursym, &name, &value);
152 0 : if (name && (d < db_maxoff) && value) {
153 0 : (*pr)("%s", name);
154 0 : if (d) {
155 0 : (*pr)("+%s", db_format(buf, sizeof(buf),
156 : d, DB_FORMAT_R, 1, 0));
157 0 : }
158 0 : if (strategy == DB_STGY_PROC) {
159 0 : if (db_elf_line_at_pc(cursym, &filename,
160 : &linenum, off))
161 0 : (*pr)(" [%s:%d]", filename, linenum);
162 : }
163 0 : return;
164 : }
165 : }
166 :
167 0 : (*pr)("%s", db_format(buf, sizeof(buf), off, DB_FORMAT_N, 1, 0));
168 0 : return;
169 0 : }
|