kallsyms.c (d93618da6b6d453c6a9684a3460ffd51b9b4ef2e) kallsyms.c (60443c88f3a89fd303a9e8c0e84895910675c316)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * kallsyms.c: in-kernel printing of symbolic oopses and stack traces.
4 *
5 * Rewritten and vastly simplified by Rusty Russell for in-kernel
6 * module loader:
7 * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
8 *

--- 173 unchanged lines hidden (view full) ---

182 if (res) {
183 *res = '\0';
184 return true;
185 }
186
187 return false;
188}
189
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * kallsyms.c: in-kernel printing of symbolic oopses and stack traces.
4 *
5 * Rewritten and vastly simplified by Rusty Russell for in-kernel
6 * module loader:
7 * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
8 *

--- 173 unchanged lines hidden (view full) ---

182 if (res) {
183 *res = '\0';
184 return true;
185 }
186
187 return false;
188}
189
190static int compare_symbol_name(const char *name, char *namebuf)
191{
192 int ret;
193
194 ret = strcmp(name, namebuf);
195 if (!ret)
196 return ret;
197
198 if (cleanup_symbol_name(namebuf) && !strcmp(name, namebuf))
199 return 0;
200
201 return ret;
202}
203
204static int kallsyms_lookup_names(const char *name,
205 unsigned int *start,
206 unsigned int *end)
207{
208 int ret;
209 int low, mid, high;
210 unsigned int seq, off;
211 char namebuf[KSYM_NAME_LEN];
212
213 low = 0;
214 high = kallsyms_num_syms - 1;
215
216 while (low <= high) {
217 mid = low + (high - low) / 2;
218 seq = kallsyms_seqs_of_names[mid];
219 off = get_symbol_offset(seq);
220 kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
221 ret = compare_symbol_name(name, namebuf);
222 if (ret > 0)
223 low = mid + 1;
224 else if (ret < 0)
225 high = mid - 1;
226 else
227 break;
228 }
229
230 if (low > high)
231 return -ESRCH;
232
233 low = mid;
234 while (low) {
235 seq = kallsyms_seqs_of_names[low - 1];
236 off = get_symbol_offset(seq);
237 kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
238 if (compare_symbol_name(name, namebuf))
239 break;
240 low--;
241 }
242 *start = low;
243
244 if (end) {
245 high = mid;
246 while (high < kallsyms_num_syms - 1) {
247 seq = kallsyms_seqs_of_names[high + 1];
248 off = get_symbol_offset(seq);
249 kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
250 if (compare_symbol_name(name, namebuf))
251 break;
252 high++;
253 }
254 *end = high;
255 }
256
257 return 0;
258}
259
190/* Lookup the address for this symbol. Returns 0 if not found. */
191unsigned long kallsyms_lookup_name(const char *name)
192{
260/* Lookup the address for this symbol. Returns 0 if not found. */
261unsigned long kallsyms_lookup_name(const char *name)
262{
193 char namebuf[KSYM_NAME_LEN];
194 unsigned long i;
195 unsigned int off;
263 int ret;
264 unsigned int i;
196
197 /* Skip the search for empty string. */
198 if (!*name)
199 return 0;
200
265
266 /* Skip the search for empty string. */
267 if (!*name)
268 return 0;
269
201 for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
202 off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
270 ret = kallsyms_lookup_names(name, &i, NULL);
271 if (!ret)
272 return kallsyms_sym_address(kallsyms_seqs_of_names[i]);
203
273
204 if (strcmp(namebuf, name) == 0)
205 return kallsyms_sym_address(i);
206
207 if (cleanup_symbol_name(namebuf) && strcmp(namebuf, name) == 0)
208 return kallsyms_sym_address(i);
209 }
210 return module_kallsyms_lookup_name(name);
211}
212
213/*
214 * Iterate over all symbols in vmlinux. For symbols from modules use
215 * module_kallsyms_on_each_symbol instead.
216 */
217int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,

--- 744 unchanged lines hidden ---
274 return module_kallsyms_lookup_name(name);
275}
276
277/*
278 * Iterate over all symbols in vmlinux. For symbols from modules use
279 * module_kallsyms_on_each_symbol instead.
280 */
281int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,

--- 744 unchanged lines hidden ---