Merge tag 'drm-misc-fixes-2022-07-21' of git://anongit.freedesktop.org/drm/drm-misc...
[linux-2.6-microblaze.git] / kernel / module / kallsyms.c
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 */
15 static 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
23 static 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 */
37 static 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
77 static 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  */
110 void 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  */
166 void 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)
222 void 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
236 void 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  */
245 static 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
253 static 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  */
262 static 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
317 void * __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  */
327 const 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
362 int 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         }
382 out:
383         preempt_enable();
384         return -ERANGE;
385 }
386
387 int 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         }
410 out:
411         preempt_enable();
412         return -ERANGE;
413 }
414
415 int 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 */
445 unsigned 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
460 /* Look for this name: can be of form module:name. */
461 unsigned long module_kallsyms_lookup_name(const char *name)
462 {
463         struct module *mod;
464         char *colon;
465         unsigned long ret = 0;
466
467         /* Don't lock: we're in enough trouble already. */
468         preempt_disable();
469         if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) {
470                 if ((mod = find_module_all(name, colon - name, false)) != NULL)
471                         ret = find_kallsyms_symbol_value(mod, colon + 1);
472         } else {
473                 list_for_each_entry_rcu(mod, &modules, list) {
474                         if (mod->state == MODULE_STATE_UNFORMED)
475                                 continue;
476                         if ((ret = find_kallsyms_symbol_value(mod, name)) != 0)
477                                 break;
478                 }
479         }
480         preempt_enable();
481         return ret;
482 }
483
484 #ifdef CONFIG_LIVEPATCH
485 int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
486                                              struct module *, unsigned long),
487                                    void *data)
488 {
489         struct module *mod;
490         unsigned int i;
491         int ret = 0;
492
493         mutex_lock(&module_mutex);
494         list_for_each_entry(mod, &modules, list) {
495                 struct mod_kallsyms *kallsyms;
496
497                 if (mod->state == MODULE_STATE_UNFORMED)
498                         continue;
499
500                 /* Use rcu_dereference_sched() to remain compliant with the sparse tool */
501                 preempt_disable();
502                 kallsyms = rcu_dereference_sched(mod->kallsyms);
503                 preempt_enable();
504
505                 for (i = 0; i < kallsyms->num_symtab; i++) {
506                         const Elf_Sym *sym = &kallsyms->symtab[i];
507
508                         if (sym->st_shndx == SHN_UNDEF)
509                                 continue;
510
511                         ret = fn(data, kallsyms_symbol_name(kallsyms, i),
512                                  mod, kallsyms_symbol_value(sym));
513                         if (ret != 0)
514                                 goto out;
515                 }
516         }
517 out:
518         mutex_unlock(&module_mutex);
519         return ret;
520 }
521 #endif /* CONFIG_LIVEPATCH */