Linux Audio

Check our new training course

Loading...
v6.2
  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}
v6.13.7
  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}