source: mainline/kernel/generic/src/debug/symtab.c@ 06b785f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 06b785f was 06b785f, checked in by Jiri Svoboda <jirik.svoboda@…>, 16 years ago

strlen() → str_size().

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/*
2 * Copyright (c) 2005 Ondrej Palkovsky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup genericdebug
30 * @{
31 */
32
33/**
34 * @file
35 * @brief Kernel symbol resolver.
36 */
37
38#include <symtab.h>
39#include <byteorder.h>
40#include <string.h>
41#include <print.h>
42#include <arch/types.h>
43#include <typedefs.h>
44#include <errno.h>
45
46/** Get name of symbol that seems most likely to correspond to address.
47 *
48 * @param addr Address.
49 * @param name Place to store pointer to the symbol name.
50 *
51 * @return Zero on success or negative error code, ENOENT if not found,
52 * ENOTSUP if symbol table not available.
53 */
54int symtab_name_lookup(unative_t addr, char **name)
55{
56#ifdef CONFIG_SYMTAB
57 count_t i;
58
59 for (i = 1; symbol_table[i].address_le; ++i) {
60 if (addr < uint64_t_le2host(symbol_table[i].address_le))
61 break;
62 }
63 if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) {
64 *name = symbol_table[i - 1].symbol_name;
65 return EOK;
66 }
67
68 *name = NULL;
69 return ENOENT;
70#else
71 *name = NULL;
72 return ENOTSUP;
73#endif
74}
75
76/** Lookup symbol by address and format for display.
77 *
78 * Returns name of closest corresponding symbol, "Not found" if none exists
79 * or "N/A" if no symbol information is available.
80 *
81 * @param addr Address.
82 * @param name Place to store pointer to the symbol name.
83 *
84 * @return Pointer to a human-readable string.
85 */
86char *symtab_fmt_name_lookup(unative_t addr)
87{
88 int rc;
89 char *name;
90
91 rc = symtab_name_lookup(addr, &name);
92 switch (rc) {
93 case EOK: return name;
94 case ENOENT: return "Not found";
95 default: return "N/A";
96 }
97}
98
99#ifdef CONFIG_SYMTAB
100
101/** Find symbols that match the parameter forward and print them.
102 *
103 * @param name - search string
104 * @param startpos - starting position, changes to found position
105 * @return Pointer to the part of string that should be completed or NULL
106 */
107static char * symtab_search_one(const char *name, int *startpos)
108{
109 unsigned int namelen = str_size(name);
110 char *curname;
111 int i, j;
112 int colonoffset = -1;
113
114 for (i = 0; name[i]; i++)
115 if (name[i] == ':') {
116 colonoffset = i;
117 break;
118 }
119
120 for (i = *startpos; symbol_table[i].address_le; ++i) {
121 /* Find a ':' in name */
122 curname = symbol_table[i].symbol_name;
123 for (j = 0; curname[j] && curname[j] != ':'; j++)
124 ;
125 if (!curname[j])
126 continue;
127 j -= colonoffset;
128 curname += j;
129 if (str_size(curname) < namelen)
130 continue;
131 if (strncmp(curname, name, namelen) == 0) {
132 *startpos = i;
133 return curname + namelen;
134 }
135 }
136 return NULL;
137}
138
139#endif
140
141/** Return address that corresponds to the entry
142 *
143 * Search symbol table, and if there is one match, return it
144 *
145 * @param name Name of the symbol
146 * @param addr Place to store symbol address
147 *
148 * @return Zero on success, ENOENT - not found, EOVERFLOW - duplicate
149 * symbol, ENOTSUP - no symbol information available.
150 */
151int symtab_addr_lookup(const char *name, uintptr_t *addr)
152{
153#ifdef CONFIG_SYMTAB
154 count_t found = 0;
155 char *hint;
156 int i;
157
158 i = 0;
159 while ((hint = symtab_search_one(name, &i))) {
160 if (!str_size(hint)) {
161 *addr = uint64_t_le2host(symbol_table[i].address_le);
162 found++;
163 }
164 i++;
165 }
166 if (found > 1)
167 return EOVERFLOW;
168 if (found < 1)
169 return ENOENT;
170 return EOK;
171#else
172 return ENOTSUP;
173#endif
174}
175
176/** Find symbols that match parameter and prints them */
177void symtab_print_search(const char *name)
178{
179#ifdef CONFIG_SYMTAB
180 int i;
181 uintptr_t addr;
182 char *realname;
183
184
185 i = 0;
186 while (symtab_search_one(name, &i)) {
187 addr = uint64_t_le2host(symbol_table[i].address_le);
188 realname = symbol_table[i].symbol_name;
189 printf("%p: %s\n", addr, realname);
190 i++;
191 }
192#else
193 printf("No symbol information available.\n");
194#endif
195}
196
197/** Symtab completion
198 *
199 * @param input - Search string, completes to symbol name
200 * @returns - 0 - nothing found, 1 - success, >1 print duplicates
201 */
202int symtab_compl(char *input)
203{
204#ifdef CONFIG_SYMTAB
205 char output[MAX_SYMBOL_NAME + 1];
206 int startpos = 0;
207 char *foundtxt;
208 int found = 0;
209 int i;
210 char *name = input;
211
212 /* Allow completion of pointers */
213 if (name[0] == '*' || name[0] == '&')
214 name++;
215
216 /* Do not print everything */
217 if (!str_size(name))
218 return 0;
219
220
221 output[0] = '\0';
222
223 while ((foundtxt = symtab_search_one(name, &startpos))) {
224 startpos++;
225 if (!found)
226 strncpy(output, foundtxt, str_size(foundtxt) + 1);
227 else {
228 for (i = 0; output[i] && foundtxt[i] &&
229 output[i] == foundtxt[i]; i++)
230 ;
231 output[i] = '\0';
232 }
233 found++;
234 }
235 if (!found)
236 return 0;
237
238 if (found > 1 && !str_size(output)) {
239 printf("\n");
240 startpos = 0;
241 while ((foundtxt = symtab_search_one(name, &startpos))) {
242 printf("%s\n", symbol_table[startpos].symbol_name);
243 startpos++;
244 }
245 }
246 strncpy(input, output, MAX_SYMBOL_NAME);
247 return found;
248#else
249 return 0;
250#endif
251}
252
253/** @}
254 */
Note: See TracBrowser for help on using the repository browser.