Loading...
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Module kallsyms support
4 *
5 * Copyright (C) 2010 Rusty Russell
6 */
7
8#include <linux/module.h>
9#include <linux/kallsyms.h>
10#include <linux/buildid.h>
11#include <linux/bsearch.h>
12#include "internal.h"
13
14/* Lookup exported symbol in given range of kernel_symbols */
15static const struct kernel_symbol *lookup_exported_symbol(const char *name,
16 const struct kernel_symbol *start,
17 const struct kernel_symbol *stop)
18{
19 return bsearch(name, start, stop - start,
20 sizeof(struct kernel_symbol), cmp_name);
21}
22
23static int is_exported(const char *name, unsigned long value,
24 const struct module *mod)
25{
26 const struct kernel_symbol *ks;
27
28 if (!mod)
29 ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab);
30 else
31 ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms);
32
33 return ks && kernel_symbol_value(ks) == value;
34}
35
36/* As per nm */
37static char elf_type(const Elf_Sym *sym, const struct load_info *info)
38{
39 const Elf_Shdr *sechdrs = info->sechdrs;
40
41 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
42 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
43 return 'v';
44 else
45 return 'w';
46 }
47 if (sym->st_shndx == SHN_UNDEF)
48 return 'U';
49 if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu)
50 return 'a';
51 if (sym->st_shndx >= SHN_LORESERVE)
52 return '?';
53 if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
54 return 't';
55 if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC &&
56 sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
57 if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
58 return 'r';
59 else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
60 return 'g';
61 else
62 return 'd';
63 }
64 if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
65 if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
66 return 's';
67 else
68 return 'b';
69 }
70 if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
71 ".debug")) {
72 return 'n';
73 }
74 return '?';
75}
76
77static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
78 unsigned int shnum, unsigned int pcpundx)
79{
80 const Elf_Shdr *sec;
81
82 if (src->st_shndx == SHN_UNDEF ||
83 src->st_shndx >= shnum ||
84 !src->st_name)
85 return false;
86
87#ifdef CONFIG_KALLSYMS_ALL
88 if (src->st_shndx == pcpundx)
89 return true;
90#endif
91
92 sec = sechdrs + src->st_shndx;
93 if (!(sec->sh_flags & SHF_ALLOC)
94#ifndef CONFIG_KALLSYMS_ALL
95 || !(sec->sh_flags & SHF_EXECINSTR)
96#endif
97 || (sec->sh_entsize & INIT_OFFSET_MASK))
98 return false;
99
100 return true;
101}
102
103/*
104 * We only allocate and copy the strings needed by the parts of symtab
105 * we keep. This is simple, but has the effect of making multiple
106 * copies of duplicates. We could be more sophisticated, see
107 * linux-kernel thread starting with
108 * <73defb5e4bca04a6431392cc341112b1@localhost>.
109 */
110void layout_symtab(struct module *mod, struct load_info *info)
111{
112 Elf_Shdr *symsect = info->sechdrs + info->index.sym;
113 Elf_Shdr *strsect = info->sechdrs + info->index.str;
114 const Elf_Sym *src;
115 unsigned int i, nsrc, ndst, strtab_size = 0;
116
117 /* Put symbol section at end of init part of module. */
118 symsect->sh_flags |= SHF_ALLOC;
119 symsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, symsect,
120 info->index.sym) | INIT_OFFSET_MASK;
121 pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
122
123 src = (void *)info->hdr + symsect->sh_offset;
124 nsrc = symsect->sh_size / sizeof(*src);
125
126 /* Compute total space required for the core symbols' strtab. */
127 for (ndst = i = 0; i < nsrc; i++) {
128 if (i == 0 || is_livepatch_module(mod) ||
129 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
130 info->index.pcpu)) {
131 strtab_size += strlen(&info->strtab[src[i].st_name]) + 1;
132 ndst++;
133 }
134 }
135
136 /* Append room for core symbols at end of core part. */
137 info->symoffs = ALIGN(mod->data_layout.size, symsect->sh_addralign ?: 1);
138 info->stroffs = mod->data_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
139 mod->data_layout.size += strtab_size;
140 /* Note add_kallsyms() computes strtab_size as core_typeoffs - stroffs */
141 info->core_typeoffs = mod->data_layout.size;
142 mod->data_layout.size += ndst * sizeof(char);
143 mod->data_layout.size = strict_align(mod->data_layout.size);
144
145 /* Put string table section at end of init part of module. */
146 strsect->sh_flags |= SHF_ALLOC;
147 strsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, strsect,
148 info->index.str) | INIT_OFFSET_MASK;
149 pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
150
151 /* We'll tack temporary mod_kallsyms on the end. */
152 mod->init_layout.size = ALIGN(mod->init_layout.size,
153 __alignof__(struct mod_kallsyms));
154 info->mod_kallsyms_init_off = mod->init_layout.size;
155 mod->init_layout.size += sizeof(struct mod_kallsyms);
156 info->init_typeoffs = mod->init_layout.size;
157 mod->init_layout.size += nsrc * sizeof(char);
158 mod->init_layout.size = strict_align(mod->init_layout.size);
159}
160
161/*
162 * We use the full symtab and strtab which layout_symtab arranged to
163 * be appended to the init section. Later we switch to the cut-down
164 * core-only ones.
165 */
166void add_kallsyms(struct module *mod, const struct load_info *info)
167{
168 unsigned int i, ndst;
169 const Elf_Sym *src;
170 Elf_Sym *dst;
171 char *s;
172 Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
173 unsigned long strtab_size;
174
175 /* Set up to point into init section. */
176 mod->kallsyms = (void __rcu *)mod->init_layout.base +
177 info->mod_kallsyms_init_off;
178
179 rcu_read_lock();
180 /* The following is safe since this pointer cannot change */
181 rcu_dereference(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
182 rcu_dereference(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
183 /* Make sure we get permanent strtab: don't use info->strtab. */
184 rcu_dereference(mod->kallsyms)->strtab =
185 (void *)info->sechdrs[info->index.str].sh_addr;
186 rcu_dereference(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs;
187
188 /*
189 * Now populate the cut down core kallsyms for after init
190 * and set types up while we still have access to sections.
191 */
192 mod->core_kallsyms.symtab = dst = mod->data_layout.base + info->symoffs;
193 mod->core_kallsyms.strtab = s = mod->data_layout.base + info->stroffs;
194 mod->core_kallsyms.typetab = mod->data_layout.base + info->core_typeoffs;
195 strtab_size = info->core_typeoffs - info->stroffs;
196 src = rcu_dereference(mod->kallsyms)->symtab;
197 for (ndst = i = 0; i < rcu_dereference(mod->kallsyms)->num_symtab; i++) {
198 rcu_dereference(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
199 if (i == 0 || is_livepatch_module(mod) ||
200 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
201 info->index.pcpu)) {
202 ssize_t ret;
203
204 mod->core_kallsyms.typetab[ndst] =
205 rcu_dereference(mod->kallsyms)->typetab[i];
206 dst[ndst] = src[i];
207 dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
208 ret = strscpy(s,
209 &rcu_dereference(mod->kallsyms)->strtab[src[i].st_name],
210 strtab_size);
211 if (ret < 0)
212 break;
213 s += ret + 1;
214 strtab_size -= ret + 1;
215 }
216 }
217 rcu_read_unlock();
218 mod->core_kallsyms.num_symtab = ndst;
219}
220
221#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
222void init_build_id(struct module *mod, const struct load_info *info)
223{
224 const Elf_Shdr *sechdr;
225 unsigned int i;
226
227 for (i = 0; i < info->hdr->e_shnum; i++) {
228 sechdr = &info->sechdrs[i];
229 if (!sect_empty(sechdr) && sechdr->sh_type == SHT_NOTE &&
230 !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id,
231 sechdr->sh_size))
232 break;
233 }
234}
235#else
236void init_build_id(struct module *mod, const struct load_info *info)
237{
238}
239#endif
240
241/*
242 * This ignores the intensely annoying "mapping symbols" found
243 * in ARM ELF files: $a, $t and $d.
244 */
245static inline int is_arm_mapping_symbol(const char *str)
246{
247 if (str[0] == '.' && str[1] == 'L')
248 return true;
249 return str[0] == '$' && strchr("axtd", str[1]) &&
250 (str[2] == '\0' || str[2] == '.');
251}
252
253static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum)
254{
255 return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
256}
257
258/*
259 * Given a module and address, find the corresponding symbol and return its name
260 * while providing its size and offset if needed.
261 */
262static const char *find_kallsyms_symbol(struct module *mod,
263 unsigned long addr,
264 unsigned long *size,
265 unsigned long *offset)
266{
267 unsigned int i, best = 0;
268 unsigned long nextval, bestval;
269 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
270
271 /* At worse, next value is at end of module */
272 if (within_module_init(addr, mod))
273 nextval = (unsigned long)mod->init_layout.base + mod->init_layout.text_size;
274 else
275 nextval = (unsigned long)mod->core_layout.base + mod->core_layout.text_size;
276
277 bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
278
279 /*
280 * Scan for closest preceding symbol, and next symbol. (ELF
281 * starts real symbols at 1).
282 */
283 for (i = 1; i < kallsyms->num_symtab; i++) {
284 const Elf_Sym *sym = &kallsyms->symtab[i];
285 unsigned long thisval = kallsyms_symbol_value(sym);
286
287 if (sym->st_shndx == SHN_UNDEF)
288 continue;
289
290 /*
291 * We ignore unnamed symbols: they're uninformative
292 * and inserted at a whim.
293 */
294 if (*kallsyms_symbol_name(kallsyms, i) == '\0' ||
295 is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
296 continue;
297
298 if (thisval <= addr && thisval > bestval) {
299 best = i;
300 bestval = thisval;
301 }
302 if (thisval > addr && thisval < nextval)
303 nextval = thisval;
304 }
305
306 if (!best)
307 return NULL;
308
309 if (size)
310 *size = nextval - bestval;
311 if (offset)
312 *offset = addr - bestval;
313
314 return kallsyms_symbol_name(kallsyms, best);
315}
316
317void * __weak dereference_module_function_descriptor(struct module *mod,
318 void *ptr)
319{
320 return ptr;
321}
322
323/*
324 * For kallsyms to ask for address resolution. NULL means not found. Careful
325 * not to lock to avoid deadlock on oopses, simply disable preemption.
326 */
327const char *module_address_lookup(unsigned long addr,
328 unsigned long *size,
329 unsigned long *offset,
330 char **modname,
331 const unsigned char **modbuildid,
332 char *namebuf)
333{
334 const char *ret = NULL;
335 struct module *mod;
336
337 preempt_disable();
338 mod = __module_address(addr);
339 if (mod) {
340 if (modname)
341 *modname = mod->name;
342 if (modbuildid) {
343#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
344 *modbuildid = mod->build_id;
345#else
346 *modbuildid = NULL;
347#endif
348 }
349
350 ret = find_kallsyms_symbol(mod, addr, size, offset);
351 }
352 /* Make a copy in here where it's safe */
353 if (ret) {
354 strncpy(namebuf, ret, KSYM_NAME_LEN - 1);
355 ret = namebuf;
356 }
357 preempt_enable();
358
359 return ret;
360}
361
362int lookup_module_symbol_name(unsigned long addr, char *symname)
363{
364 struct module *mod;
365
366 preempt_disable();
367 list_for_each_entry_rcu(mod, &modules, list) {
368 if (mod->state == MODULE_STATE_UNFORMED)
369 continue;
370 if (within_module(addr, mod)) {
371 const char *sym;
372
373 sym = find_kallsyms_symbol(mod, addr, NULL, NULL);
374 if (!sym)
375 goto out;
376
377 strscpy(symname, sym, KSYM_NAME_LEN);
378 preempt_enable();
379 return 0;
380 }
381 }
382out:
383 preempt_enable();
384 return -ERANGE;
385}
386
387int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
388 unsigned long *offset, char *modname, char *name)
389{
390 struct module *mod;
391
392 preempt_disable();
393 list_for_each_entry_rcu(mod, &modules, list) {
394 if (mod->state == MODULE_STATE_UNFORMED)
395 continue;
396 if (within_module(addr, mod)) {
397 const char *sym;
398
399 sym = find_kallsyms_symbol(mod, addr, size, offset);
400 if (!sym)
401 goto out;
402 if (modname)
403 strscpy(modname, mod->name, MODULE_NAME_LEN);
404 if (name)
405 strscpy(name, sym, KSYM_NAME_LEN);
406 preempt_enable();
407 return 0;
408 }
409 }
410out:
411 preempt_enable();
412 return -ERANGE;
413}
414
415int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
416 char *name, char *module_name, int *exported)
417{
418 struct module *mod;
419
420 preempt_disable();
421 list_for_each_entry_rcu(mod, &modules, list) {
422 struct mod_kallsyms *kallsyms;
423
424 if (mod->state == MODULE_STATE_UNFORMED)
425 continue;
426 kallsyms = rcu_dereference_sched(mod->kallsyms);
427 if (symnum < kallsyms->num_symtab) {
428 const Elf_Sym *sym = &kallsyms->symtab[symnum];
429
430 *value = kallsyms_symbol_value(sym);
431 *type = kallsyms->typetab[symnum];
432 strscpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
433 strscpy(module_name, mod->name, MODULE_NAME_LEN);
434 *exported = is_exported(name, *value, mod);
435 preempt_enable();
436 return 0;
437 }
438 symnum -= kallsyms->num_symtab;
439 }
440 preempt_enable();
441 return -ERANGE;
442}
443
444/* Given a module and name of symbol, find and return the symbol's value */
445unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name)
446{
447 unsigned int i;
448 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
449
450 for (i = 0; i < kallsyms->num_symtab; i++) {
451 const Elf_Sym *sym = &kallsyms->symtab[i];
452
453 if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 &&
454 sym->st_shndx != SHN_UNDEF)
455 return kallsyms_symbol_value(sym);
456 }
457 return 0;
458}
459
460static unsigned long __module_kallsyms_lookup_name(const char *name)
461{
462 struct module *mod;
463 char *colon;
464
465 colon = strnchr(name, MODULE_NAME_LEN, ':');
466 if (colon) {
467 mod = find_module_all(name, colon - name, false);
468 if (mod)
469 return find_kallsyms_symbol_value(mod, colon + 1);
470 return 0;
471 }
472
473 list_for_each_entry_rcu(mod, &modules, list) {
474 unsigned long ret;
475
476 if (mod->state == MODULE_STATE_UNFORMED)
477 continue;
478 ret = find_kallsyms_symbol_value(mod, name);
479 if (ret)
480 return ret;
481 }
482 return 0;
483}
484
485/* Look for this name: can be of form module:name. */
486unsigned long module_kallsyms_lookup_name(const char *name)
487{
488 unsigned long ret;
489
490 /* Don't lock: we're in enough trouble already. */
491 preempt_disable();
492 ret = __module_kallsyms_lookup_name(name);
493 preempt_enable();
494 return ret;
495}
496
497int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
498 struct module *, unsigned long),
499 void *data)
500{
501 struct module *mod;
502 unsigned int i;
503 int ret = 0;
504
505 mutex_lock(&module_mutex);
506 list_for_each_entry(mod, &modules, list) {
507 struct mod_kallsyms *kallsyms;
508
509 if (mod->state == MODULE_STATE_UNFORMED)
510 continue;
511
512 /* Use rcu_dereference_sched() to remain compliant with the sparse tool */
513 preempt_disable();
514 kallsyms = rcu_dereference_sched(mod->kallsyms);
515 preempt_enable();
516
517 for (i = 0; i < kallsyms->num_symtab; i++) {
518 const Elf_Sym *sym = &kallsyms->symtab[i];
519
520 if (sym->st_shndx == SHN_UNDEF)
521 continue;
522
523 ret = fn(data, kallsyms_symbol_name(kallsyms, i),
524 mod, kallsyms_symbol_value(sym));
525 if (ret != 0)
526 goto out;
527 }
528 }
529out:
530 mutex_unlock(&module_mutex);
531 return ret;
532}
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Module kallsyms support
4 *
5 * Copyright (C) 2010 Rusty Russell
6 */
7
8#include <linux/module.h>
9#include <linux/module_symbol.h>
10#include <linux/kallsyms.h>
11#include <linux/buildid.h>
12#include <linux/bsearch.h>
13#include "internal.h"
14
15/* Lookup exported symbol in given range of kernel_symbols */
16static const struct kernel_symbol *lookup_exported_symbol(const char *name,
17 const struct kernel_symbol *start,
18 const struct kernel_symbol *stop)
19{
20 return bsearch(name, start, stop - start,
21 sizeof(struct kernel_symbol), cmp_name);
22}
23
24static int is_exported(const char *name, unsigned long value,
25 const struct module *mod)
26{
27 const struct kernel_symbol *ks;
28
29 if (!mod)
30 ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab);
31 else
32 ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms);
33
34 return ks && kernel_symbol_value(ks) == value;
35}
36
37/* As per nm */
38static char elf_type(const Elf_Sym *sym, const struct load_info *info)
39{
40 const Elf_Shdr *sechdrs = info->sechdrs;
41
42 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
43 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
44 return 'v';
45 else
46 return 'w';
47 }
48 if (sym->st_shndx == SHN_UNDEF)
49 return 'U';
50 if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu)
51 return 'a';
52 if (sym->st_shndx >= SHN_LORESERVE)
53 return '?';
54 if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
55 return 't';
56 if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC &&
57 sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
58 if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
59 return 'r';
60 else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
61 return 'g';
62 else
63 return 'd';
64 }
65 if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
66 if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
67 return 's';
68 else
69 return 'b';
70 }
71 if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
72 ".debug")) {
73 return 'n';
74 }
75 return '?';
76}
77
78static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
79 unsigned int shnum, unsigned int pcpundx)
80{
81 const Elf_Shdr *sec;
82 enum mod_mem_type type;
83
84 if (src->st_shndx == SHN_UNDEF ||
85 src->st_shndx >= shnum ||
86 !src->st_name)
87 return false;
88
89#ifdef CONFIG_KALLSYMS_ALL
90 if (src->st_shndx == pcpundx)
91 return true;
92#endif
93
94 sec = sechdrs + src->st_shndx;
95 type = sec->sh_entsize >> SH_ENTSIZE_TYPE_SHIFT;
96 if (!(sec->sh_flags & SHF_ALLOC)
97#ifndef CONFIG_KALLSYMS_ALL
98 || !(sec->sh_flags & SHF_EXECINSTR)
99#endif
100 || mod_mem_type_is_init(type))
101 return false;
102
103 return true;
104}
105
106/*
107 * We only allocate and copy the strings needed by the parts of symtab
108 * we keep. This is simple, but has the effect of making multiple
109 * copies of duplicates. We could be more sophisticated, see
110 * linux-kernel thread starting with
111 * <73defb5e4bca04a6431392cc341112b1@localhost>.
112 */
113void layout_symtab(struct module *mod, struct load_info *info)
114{
115 Elf_Shdr *symsect = info->sechdrs + info->index.sym;
116 Elf_Shdr *strsect = info->sechdrs + info->index.str;
117 const Elf_Sym *src;
118 unsigned int i, nsrc, ndst, strtab_size = 0;
119 struct module_memory *mod_mem_data = &mod->mem[MOD_DATA];
120 struct module_memory *mod_mem_init_data = &mod->mem[MOD_INIT_DATA];
121
122 /* Put symbol section at end of init part of module. */
123 symsect->sh_flags |= SHF_ALLOC;
124 symsect->sh_entsize = module_get_offset_and_type(mod, MOD_INIT_DATA,
125 symsect, info->index.sym);
126 pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
127
128 src = (void *)info->hdr + symsect->sh_offset;
129 nsrc = symsect->sh_size / sizeof(*src);
130
131 /* Compute total space required for the core symbols' strtab. */
132 for (ndst = i = 0; i < nsrc; i++) {
133 if (i == 0 || is_livepatch_module(mod) ||
134 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
135 info->index.pcpu)) {
136 strtab_size += strlen(&info->strtab[src[i].st_name]) + 1;
137 ndst++;
138 }
139 }
140
141 /* Append room for core symbols at end of core part. */
142 info->symoffs = ALIGN(mod_mem_data->size, symsect->sh_addralign ?: 1);
143 info->stroffs = mod_mem_data->size = info->symoffs + ndst * sizeof(Elf_Sym);
144 mod_mem_data->size += strtab_size;
145 /* Note add_kallsyms() computes strtab_size as core_typeoffs - stroffs */
146 info->core_typeoffs = mod_mem_data->size;
147 mod_mem_data->size += ndst * sizeof(char);
148
149 /* Put string table section at end of init part of module. */
150 strsect->sh_flags |= SHF_ALLOC;
151 strsect->sh_entsize = module_get_offset_and_type(mod, MOD_INIT_DATA,
152 strsect, info->index.str);
153 pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
154
155 /* We'll tack temporary mod_kallsyms on the end. */
156 mod_mem_init_data->size = ALIGN(mod_mem_init_data->size,
157 __alignof__(struct mod_kallsyms));
158 info->mod_kallsyms_init_off = mod_mem_init_data->size;
159
160 mod_mem_init_data->size += sizeof(struct mod_kallsyms);
161 info->init_typeoffs = mod_mem_init_data->size;
162 mod_mem_init_data->size += nsrc * sizeof(char);
163}
164
165/*
166 * We use the full symtab and strtab which layout_symtab arranged to
167 * be appended to the init section. Later we switch to the cut-down
168 * core-only ones.
169 */
170void add_kallsyms(struct module *mod, const struct load_info *info)
171{
172 unsigned int i, ndst;
173 const Elf_Sym *src;
174 Elf_Sym *dst;
175 char *s;
176 Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
177 unsigned long strtab_size;
178 void *data_base = mod->mem[MOD_DATA].base;
179 void *init_data_base = mod->mem[MOD_INIT_DATA].base;
180
181 /* Set up to point into init section. */
182 mod->kallsyms = (void __rcu *)init_data_base +
183 info->mod_kallsyms_init_off;
184
185 rcu_read_lock();
186 /* The following is safe since this pointer cannot change */
187 rcu_dereference(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
188 rcu_dereference(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
189 /* Make sure we get permanent strtab: don't use info->strtab. */
190 rcu_dereference(mod->kallsyms)->strtab =
191 (void *)info->sechdrs[info->index.str].sh_addr;
192 rcu_dereference(mod->kallsyms)->typetab = init_data_base + info->init_typeoffs;
193
194 /*
195 * Now populate the cut down core kallsyms for after init
196 * and set types up while we still have access to sections.
197 */
198 mod->core_kallsyms.symtab = dst = data_base + info->symoffs;
199 mod->core_kallsyms.strtab = s = data_base + info->stroffs;
200 mod->core_kallsyms.typetab = data_base + info->core_typeoffs;
201 strtab_size = info->core_typeoffs - info->stroffs;
202 src = rcu_dereference(mod->kallsyms)->symtab;
203 for (ndst = i = 0; i < rcu_dereference(mod->kallsyms)->num_symtab; i++) {
204 rcu_dereference(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
205 if (i == 0 || is_livepatch_module(mod) ||
206 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
207 info->index.pcpu)) {
208 ssize_t ret;
209
210 mod->core_kallsyms.typetab[ndst] =
211 rcu_dereference(mod->kallsyms)->typetab[i];
212 dst[ndst] = src[i];
213 dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
214 ret = strscpy(s,
215 &rcu_dereference(mod->kallsyms)->strtab[src[i].st_name],
216 strtab_size);
217 if (ret < 0)
218 break;
219 s += ret + 1;
220 strtab_size -= ret + 1;
221 }
222 }
223 rcu_read_unlock();
224 mod->core_kallsyms.num_symtab = ndst;
225}
226
227#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
228void init_build_id(struct module *mod, const struct load_info *info)
229{
230 const Elf_Shdr *sechdr;
231 unsigned int i;
232
233 for (i = 0; i < info->hdr->e_shnum; i++) {
234 sechdr = &info->sechdrs[i];
235 if (!sect_empty(sechdr) && sechdr->sh_type == SHT_NOTE &&
236 !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id,
237 sechdr->sh_size))
238 break;
239 }
240}
241#else
242void init_build_id(struct module *mod, const struct load_info *info)
243{
244}
245#endif
246
247static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum)
248{
249 return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
250}
251
252/*
253 * Given a module and address, find the corresponding symbol and return its name
254 * while providing its size and offset if needed.
255 */
256static const char *find_kallsyms_symbol(struct module *mod,
257 unsigned long addr,
258 unsigned long *size,
259 unsigned long *offset)
260{
261 unsigned int i, best = 0;
262 unsigned long nextval, bestval;
263 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
264 struct module_memory *mod_mem;
265
266 /* At worse, next value is at end of module */
267 if (within_module_init(addr, mod))
268 mod_mem = &mod->mem[MOD_INIT_TEXT];
269 else
270 mod_mem = &mod->mem[MOD_TEXT];
271
272 nextval = (unsigned long)mod_mem->base + mod_mem->size;
273
274 bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
275
276 /*
277 * Scan for closest preceding symbol, and next symbol. (ELF
278 * starts real symbols at 1).
279 */
280 for (i = 1; i < kallsyms->num_symtab; i++) {
281 const Elf_Sym *sym = &kallsyms->symtab[i];
282 unsigned long thisval = kallsyms_symbol_value(sym);
283
284 if (sym->st_shndx == SHN_UNDEF)
285 continue;
286
287 /*
288 * We ignore unnamed symbols: they're uninformative
289 * and inserted at a whim.
290 */
291 if (*kallsyms_symbol_name(kallsyms, i) == '\0' ||
292 is_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
293 continue;
294
295 if (thisval <= addr && thisval > bestval) {
296 best = i;
297 bestval = thisval;
298 }
299 if (thisval > addr && thisval < nextval)
300 nextval = thisval;
301 }
302
303 if (!best)
304 return NULL;
305
306 if (size)
307 *size = nextval - bestval;
308 if (offset)
309 *offset = addr - bestval;
310
311 return kallsyms_symbol_name(kallsyms, best);
312}
313
314void * __weak dereference_module_function_descriptor(struct module *mod,
315 void *ptr)
316{
317 return ptr;
318}
319
320/*
321 * For kallsyms to ask for address resolution. NULL means not found. Careful
322 * not to lock to avoid deadlock on oopses, simply disable preemption.
323 */
324int module_address_lookup(unsigned long addr,
325 unsigned long *size,
326 unsigned long *offset,
327 char **modname,
328 const unsigned char **modbuildid,
329 char *namebuf)
330{
331 const char *sym;
332 int ret = 0;
333 struct module *mod;
334
335 preempt_disable();
336 mod = __module_address(addr);
337 if (mod) {
338 if (modname)
339 *modname = mod->name;
340 if (modbuildid) {
341#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
342 *modbuildid = mod->build_id;
343#else
344 *modbuildid = NULL;
345#endif
346 }
347
348 sym = find_kallsyms_symbol(mod, addr, size, offset);
349
350 if (sym)
351 ret = strscpy(namebuf, sym, KSYM_NAME_LEN);
352 }
353 preempt_enable();
354
355 return ret;
356}
357
358int lookup_module_symbol_name(unsigned long addr, char *symname)
359{
360 struct module *mod;
361
362 preempt_disable();
363 list_for_each_entry_rcu(mod, &modules, list) {
364 if (mod->state == MODULE_STATE_UNFORMED)
365 continue;
366 if (within_module(addr, mod)) {
367 const char *sym;
368
369 sym = find_kallsyms_symbol(mod, addr, NULL, NULL);
370 if (!sym)
371 goto out;
372
373 strscpy(symname, sym, KSYM_NAME_LEN);
374 preempt_enable();
375 return 0;
376 }
377 }
378out:
379 preempt_enable();
380 return -ERANGE;
381}
382
383int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
384 char *name, char *module_name, int *exported)
385{
386 struct module *mod;
387
388 preempt_disable();
389 list_for_each_entry_rcu(mod, &modules, list) {
390 struct mod_kallsyms *kallsyms;
391
392 if (mod->state == MODULE_STATE_UNFORMED)
393 continue;
394 kallsyms = rcu_dereference_sched(mod->kallsyms);
395 if (symnum < kallsyms->num_symtab) {
396 const Elf_Sym *sym = &kallsyms->symtab[symnum];
397
398 *value = kallsyms_symbol_value(sym);
399 *type = kallsyms->typetab[symnum];
400 strscpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
401 strscpy(module_name, mod->name, MODULE_NAME_LEN);
402 *exported = is_exported(name, *value, mod);
403 preempt_enable();
404 return 0;
405 }
406 symnum -= kallsyms->num_symtab;
407 }
408 preempt_enable();
409 return -ERANGE;
410}
411
412/* Given a module and name of symbol, find and return the symbol's value */
413static unsigned long __find_kallsyms_symbol_value(struct module *mod, const char *name)
414{
415 unsigned int i;
416 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
417
418 for (i = 0; i < kallsyms->num_symtab; i++) {
419 const Elf_Sym *sym = &kallsyms->symtab[i];
420
421 if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 &&
422 sym->st_shndx != SHN_UNDEF)
423 return kallsyms_symbol_value(sym);
424 }
425 return 0;
426}
427
428static unsigned long __module_kallsyms_lookup_name(const char *name)
429{
430 struct module *mod;
431 char *colon;
432
433 colon = strnchr(name, MODULE_NAME_LEN, ':');
434 if (colon) {
435 mod = find_module_all(name, colon - name, false);
436 if (mod)
437 return __find_kallsyms_symbol_value(mod, colon + 1);
438 return 0;
439 }
440
441 list_for_each_entry_rcu(mod, &modules, list) {
442 unsigned long ret;
443
444 if (mod->state == MODULE_STATE_UNFORMED)
445 continue;
446 ret = __find_kallsyms_symbol_value(mod, name);
447 if (ret)
448 return ret;
449 }
450 return 0;
451}
452
453/* Look for this name: can be of form module:name. */
454unsigned long module_kallsyms_lookup_name(const char *name)
455{
456 unsigned long ret;
457
458 /* Don't lock: we're in enough trouble already. */
459 preempt_disable();
460 ret = __module_kallsyms_lookup_name(name);
461 preempt_enable();
462 return ret;
463}
464
465unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name)
466{
467 unsigned long ret;
468
469 preempt_disable();
470 ret = __find_kallsyms_symbol_value(mod, name);
471 preempt_enable();
472 return ret;
473}
474
475int module_kallsyms_on_each_symbol(const char *modname,
476 int (*fn)(void *, const char *, unsigned long),
477 void *data)
478{
479 struct module *mod;
480 unsigned int i;
481 int ret = 0;
482
483 mutex_lock(&module_mutex);
484 list_for_each_entry(mod, &modules, list) {
485 struct mod_kallsyms *kallsyms;
486
487 if (mod->state == MODULE_STATE_UNFORMED)
488 continue;
489
490 if (modname && strcmp(modname, mod->name))
491 continue;
492
493 /* Use rcu_dereference_sched() to remain compliant with the sparse tool */
494 preempt_disable();
495 kallsyms = rcu_dereference_sched(mod->kallsyms);
496 preempt_enable();
497
498 for (i = 0; i < kallsyms->num_symtab; i++) {
499 const Elf_Sym *sym = &kallsyms->symtab[i];
500
501 if (sym->st_shndx == SHN_UNDEF)
502 continue;
503
504 ret = fn(data, kallsyms_symbol_name(kallsyms, i),
505 kallsyms_symbol_value(sym));
506 if (ret != 0)
507 goto out;
508 }
509
510 /*
511 * The given module is found, the subsequent modules do not
512 * need to be compared.
513 */
514 if (modname)
515 break;
516 }
517out:
518 mutex_unlock(&module_mutex);
519 return ret;
520}