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