1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Module kallsyms support
5 * Copyright (C) 2010 Rusty Russell
8 #include <linux/module.h>
9 #include <linux/kallsyms.h>
10 #include <linux/buildid.h>
11 #include <linux/bsearch.h>
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)
19 return bsearch(name, start, stop - start,
20 sizeof(struct kernel_symbol), cmp_name);
23 static int is_exported(const char *name, unsigned long value,
24 const struct module *mod)
26 const struct kernel_symbol *ks;
29 ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab);
31 ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms);
33 return ks && kernel_symbol_value(ks) == value;
37 static char elf_type(const Elf_Sym *sym, const struct load_info *info)
39 const Elf_Shdr *sechdrs = info->sechdrs;
41 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
42 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
47 if (sym->st_shndx == SHN_UNDEF)
49 if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu)
51 if (sym->st_shndx >= SHN_LORESERVE)
53 if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
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))
59 else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
64 if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
65 if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
70 if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
77 static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
78 unsigned int shnum, unsigned int pcpundx)
82 if (src->st_shndx == SHN_UNDEF ||
83 src->st_shndx >= shnum ||
87 #ifdef CONFIG_KALLSYMS_ALL
88 if (src->st_shndx == pcpundx)
92 sec = sechdrs + src->st_shndx;
93 if (!(sec->sh_flags & SHF_ALLOC)
94 #ifndef CONFIG_KALLSYMS_ALL
95 || !(sec->sh_flags & SHF_EXECINSTR)
97 || (sec->sh_entsize & INIT_OFFSET_MASK))
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>.
110 void layout_symtab(struct module *mod, struct load_info *info)
112 Elf_Shdr *symsect = info->sechdrs + info->index.sym;
113 Elf_Shdr *strsect = info->sechdrs + info->index.str;
115 unsigned int i, nsrc, ndst, strtab_size = 0;
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);
123 src = (void *)info->hdr + symsect->sh_offset;
124 nsrc = symsect->sh_size / sizeof(*src);
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,
131 strtab_size += strlen(&info->strtab[src[i].st_name]) + 1;
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 info->core_typeoffs = mod->data_layout.size;
141 mod->data_layout.size += ndst * sizeof(char);
142 mod->data_layout.size = strict_align(mod->data_layout.size);
144 /* Put string table section at end of init part of module. */
145 strsect->sh_flags |= SHF_ALLOC;
146 strsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, strsect,
147 info->index.str) | INIT_OFFSET_MASK;
148 pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
150 /* We'll tack temporary mod_kallsyms on the end. */
151 mod->init_layout.size = ALIGN(mod->init_layout.size,
152 __alignof__(struct mod_kallsyms));
153 info->mod_kallsyms_init_off = mod->init_layout.size;
154 mod->init_layout.size += sizeof(struct mod_kallsyms);
155 info->init_typeoffs = mod->init_layout.size;
156 mod->init_layout.size += nsrc * sizeof(char);
157 mod->init_layout.size = strict_align(mod->init_layout.size);
161 * We use the full symtab and strtab which layout_symtab arranged to
162 * be appended to the init section. Later we switch to the cut-down
165 void add_kallsyms(struct module *mod, const struct load_info *info)
167 unsigned int i, ndst;
171 Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
173 /* Set up to point into init section. */
174 mod->kallsyms = (void __rcu *)mod->init_layout.base +
175 info->mod_kallsyms_init_off;
178 /* The following is safe since this pointer cannot change */
179 rcu_dereference_sched(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
180 rcu_dereference_sched(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
181 /* Make sure we get permanent strtab: don't use info->strtab. */
182 rcu_dereference_sched(mod->kallsyms)->strtab =
183 (void *)info->sechdrs[info->index.str].sh_addr;
184 rcu_dereference_sched(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs;
187 * Now populate the cut down core kallsyms for after init
188 * and set types up while we still have access to sections.
190 mod->core_kallsyms.symtab = dst = mod->data_layout.base + info->symoffs;
191 mod->core_kallsyms.strtab = s = mod->data_layout.base + info->stroffs;
192 mod->core_kallsyms.typetab = mod->data_layout.base + info->core_typeoffs;
193 src = rcu_dereference_sched(mod->kallsyms)->symtab;
194 for (ndst = i = 0; i < rcu_dereference_sched(mod->kallsyms)->num_symtab; i++) {
195 rcu_dereference_sched(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
196 if (i == 0 || is_livepatch_module(mod) ||
197 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
199 mod->core_kallsyms.typetab[ndst] =
200 rcu_dereference_sched(mod->kallsyms)->typetab[i];
202 dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
204 &rcu_dereference_sched(mod->kallsyms)->strtab[src[i].st_name],
209 mod->core_kallsyms.num_symtab = ndst;
212 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
213 void init_build_id(struct module *mod, const struct load_info *info)
215 const Elf_Shdr *sechdr;
218 for (i = 0; i < info->hdr->e_shnum; i++) {
219 sechdr = &info->sechdrs[i];
220 if (!sect_empty(sechdr) && sechdr->sh_type == SHT_NOTE &&
221 !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id,
227 void init_build_id(struct module *mod, const struct load_info *info)
233 * This ignores the intensely annoying "mapping symbols" found
234 * in ARM ELF files: $a, $t and $d.
236 static inline int is_arm_mapping_symbol(const char *str)
238 if (str[0] == '.' && str[1] == 'L')
240 return str[0] == '$' && strchr("axtd", str[1]) &&
241 (str[2] == '\0' || str[2] == '.');
244 static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum)
246 return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
250 * Given a module and address, find the corresponding symbol and return its name
251 * while providing its size and offset if needed.
253 static const char *find_kallsyms_symbol(struct module *mod,
256 unsigned long *offset)
258 unsigned int i, best = 0;
259 unsigned long nextval, bestval;
260 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
262 /* At worse, next value is at end of module */
263 if (within_module_init(addr, mod))
264 nextval = (unsigned long)mod->init_layout.base + mod->init_layout.text_size;
266 nextval = (unsigned long)mod->core_layout.base + mod->core_layout.text_size;
268 bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
271 * Scan for closest preceding symbol, and next symbol. (ELF
272 * starts real symbols at 1).
274 for (i = 1; i < kallsyms->num_symtab; i++) {
275 const Elf_Sym *sym = &kallsyms->symtab[i];
276 unsigned long thisval = kallsyms_symbol_value(sym);
278 if (sym->st_shndx == SHN_UNDEF)
282 * We ignore unnamed symbols: they're uninformative
283 * and inserted at a whim.
285 if (*kallsyms_symbol_name(kallsyms, i) == '\0' ||
286 is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
289 if (thisval <= addr && thisval > bestval) {
293 if (thisval > addr && thisval < nextval)
301 *size = nextval - bestval;
303 *offset = addr - bestval;
305 return kallsyms_symbol_name(kallsyms, best);
308 void * __weak dereference_module_function_descriptor(struct module *mod,
315 * For kallsyms to ask for address resolution. NULL means not found. Careful
316 * not to lock to avoid deadlock on oopses, simply disable preemption.
318 const char *module_address_lookup(unsigned long addr,
320 unsigned long *offset,
322 const unsigned char **modbuildid,
325 const char *ret = NULL;
329 mod = __module_address(addr);
332 *modname = mod->name;
334 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
335 *modbuildid = mod->build_id;
341 ret = find_kallsyms_symbol(mod, addr, size, offset);
343 /* Make a copy in here where it's safe */
345 strncpy(namebuf, ret, KSYM_NAME_LEN - 1);
353 int lookup_module_symbol_name(unsigned long addr, char *symname)
358 list_for_each_entry_rcu(mod, &modules, list) {
359 if (mod->state == MODULE_STATE_UNFORMED)
361 if (within_module(addr, mod)) {
364 sym = find_kallsyms_symbol(mod, addr, NULL, NULL);
368 strscpy(symname, sym, KSYM_NAME_LEN);
378 int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
379 unsigned long *offset, char *modname, char *name)
384 list_for_each_entry_rcu(mod, &modules, list) {
385 if (mod->state == MODULE_STATE_UNFORMED)
387 if (within_module(addr, mod)) {
390 sym = find_kallsyms_symbol(mod, addr, size, offset);
394 strscpy(modname, mod->name, MODULE_NAME_LEN);
396 strscpy(name, sym, KSYM_NAME_LEN);
406 int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
407 char *name, char *module_name, int *exported)
412 list_for_each_entry_rcu(mod, &modules, list) {
413 struct mod_kallsyms *kallsyms;
415 if (mod->state == MODULE_STATE_UNFORMED)
417 kallsyms = rcu_dereference_sched(mod->kallsyms);
418 if (symnum < kallsyms->num_symtab) {
419 const Elf_Sym *sym = &kallsyms->symtab[symnum];
421 *value = kallsyms_symbol_value(sym);
422 *type = kallsyms->typetab[symnum];
423 strscpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
424 strscpy(module_name, mod->name, MODULE_NAME_LEN);
425 *exported = is_exported(name, *value, mod);
429 symnum -= kallsyms->num_symtab;
435 /* Given a module and name of symbol, find and return the symbol's value */
436 unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name)
439 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
441 for (i = 0; i < kallsyms->num_symtab; i++) {
442 const Elf_Sym *sym = &kallsyms->symtab[i];
444 if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 &&
445 sym->st_shndx != SHN_UNDEF)
446 return kallsyms_symbol_value(sym);
451 /* Look for this name: can be of form module:name. */
452 unsigned long module_kallsyms_lookup_name(const char *name)
456 unsigned long ret = 0;
458 /* Don't lock: we're in enough trouble already. */
460 if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) {
461 if ((mod = find_module_all(name, colon - name, false)) != NULL)
462 ret = find_kallsyms_symbol_value(mod, colon + 1);
464 list_for_each_entry_rcu(mod, &modules, list) {
465 if (mod->state == MODULE_STATE_UNFORMED)
467 if ((ret = find_kallsyms_symbol_value(mod, name)) != 0)
475 #ifdef CONFIG_LIVEPATCH
476 int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
477 struct module *, unsigned long),
484 mutex_lock(&module_mutex);
485 list_for_each_entry(mod, &modules, list) {
486 struct mod_kallsyms *kallsyms;
488 if (mod->state == MODULE_STATE_UNFORMED)
491 /* Use rcu_dereference_sched() to remain compliant with the sparse tool */
493 kallsyms = rcu_dereference_sched(mod->kallsyms);
496 for (i = 0; i < kallsyms->num_symtab; i++) {
497 const Elf_Sym *sym = &kallsyms->symtab[i];
499 if (sym->st_shndx == SHN_UNDEF)
502 ret = fn(data, kallsyms_symbol_name(kallsyms, i),
503 mod, kallsyms_symbol_value(sym));
509 mutex_unlock(&module_mutex);
512 #endif /* CONFIG_LIVEPATCH */