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/module_symbol.h>
10 #include <linux/kallsyms.h>
11 #include <linux/buildid.h>
12 #include <linux/bsearch.h>
15 /* Lookup exported symbol in given range of kernel_symbols */
16 static const struct kernel_symbol
*lookup_exported_symbol(const char *name
,
17 const struct kernel_symbol
*start
,
18 const struct kernel_symbol
*stop
)
20 return bsearch(name
, start
, stop
- start
,
21 sizeof(struct kernel_symbol
), cmp_name
);
24 static int is_exported(const char *name
, unsigned long value
,
25 const struct module
*mod
)
27 const struct kernel_symbol
*ks
;
30 ks
= lookup_exported_symbol(name
, __start___ksymtab
, __stop___ksymtab
);
32 ks
= lookup_exported_symbol(name
, mod
->syms
, mod
->syms
+ mod
->num_syms
);
34 return ks
&& kernel_symbol_value(ks
) == value
;
38 static char elf_type(const Elf_Sym
*sym
, const struct load_info
*info
)
40 const Elf_Shdr
*sechdrs
= info
->sechdrs
;
42 if (ELF_ST_BIND(sym
->st_info
) == STB_WEAK
) {
43 if (ELF_ST_TYPE(sym
->st_info
) == STT_OBJECT
)
48 if (sym
->st_shndx
== SHN_UNDEF
)
50 if (sym
->st_shndx
== SHN_ABS
|| sym
->st_shndx
== info
->index
.pcpu
)
52 if (sym
->st_shndx
>= SHN_LORESERVE
)
54 if (sechdrs
[sym
->st_shndx
].sh_flags
& SHF_EXECINSTR
)
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
))
60 else if (sechdrs
[sym
->st_shndx
].sh_flags
& ARCH_SHF_SMALL
)
65 if (sechdrs
[sym
->st_shndx
].sh_type
== SHT_NOBITS
) {
66 if (sechdrs
[sym
->st_shndx
].sh_flags
& ARCH_SHF_SMALL
)
71 if (strstarts(info
->secstrings
+ sechdrs
[sym
->st_shndx
].sh_name
,
78 static bool is_core_symbol(const Elf_Sym
*src
, const Elf_Shdr
*sechdrs
,
79 unsigned int shnum
, unsigned int pcpundx
)
82 enum mod_mem_type type
;
84 if (src
->st_shndx
== SHN_UNDEF
||
85 src
->st_shndx
>= shnum
||
89 #ifdef CONFIG_KALLSYMS_ALL
90 if (src
->st_shndx
== pcpundx
)
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
)
100 || mod_mem_type_is_init(type
))
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>.
113 void layout_symtab(struct module
*mod
, struct load_info
*info
)
115 Elf_Shdr
*symsect
= info
->sechdrs
+ info
->index
.sym
;
116 Elf_Shdr
*strsect
= info
->sechdrs
+ info
->index
.str
;
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
];
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
);
128 src
= (void *)info
->hdr
+ symsect
->sh_offset
;
129 nsrc
= symsect
->sh_size
/ sizeof(*src
);
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
,
136 strtab_size
+= strlen(&info
->strtab
[src
[i
].st_name
]) + 1;
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);
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
);
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
;
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);
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
170 void add_kallsyms(struct module
*mod
, const struct load_info
*info
)
172 unsigned int i
, ndst
;
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
;
181 /* Set up to point into init section. */
182 mod
->kallsyms
= (void __rcu
*)init_data_base
+
183 info
->mod_kallsyms_init_off
;
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
;
195 * Now populate the cut down core kallsyms for after init
196 * and set types up while we still have access to sections.
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
,
210 mod
->core_kallsyms
.typetab
[ndst
] =
211 rcu_dereference(mod
->kallsyms
)->typetab
[i
];
213 dst
[ndst
++].st_name
= s
- mod
->core_kallsyms
.strtab
;
215 &rcu_dereference(mod
->kallsyms
)->strtab
[src
[i
].st_name
],
220 strtab_size
-= ret
+ 1;
224 mod
->core_kallsyms
.num_symtab
= ndst
;
227 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
228 void init_build_id(struct module
*mod
, const struct load_info
*info
)
230 const Elf_Shdr
*sechdr
;
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
,
242 void init_build_id(struct module
*mod
, const struct load_info
*info
)
247 static const char *kallsyms_symbol_name(struct mod_kallsyms
*kallsyms
, unsigned int symnum
)
249 return kallsyms
->strtab
+ kallsyms
->symtab
[symnum
].st_name
;
253 * Given a module and address, find the corresponding symbol and return its name
254 * while providing its size and offset if needed.
256 static const char *find_kallsyms_symbol(struct module
*mod
,
259 unsigned long *offset
)
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
;
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
];
270 mod_mem
= &mod
->mem
[MOD_TEXT
];
272 nextval
= (unsigned long)mod_mem
->base
+ mod_mem
->size
;
274 bestval
= kallsyms_symbol_value(&kallsyms
->symtab
[best
]);
277 * Scan for closest preceding symbol, and next symbol. (ELF
278 * starts real symbols at 1).
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
);
284 if (sym
->st_shndx
== SHN_UNDEF
)
288 * We ignore unnamed symbols: they're uninformative
289 * and inserted at a whim.
291 if (*kallsyms_symbol_name(kallsyms
, i
) == '\0' ||
292 is_mapping_symbol(kallsyms_symbol_name(kallsyms
, i
)))
295 if (thisval
<= addr
&& thisval
> bestval
) {
299 if (thisval
> addr
&& thisval
< nextval
)
307 *size
= nextval
- bestval
;
309 *offset
= addr
- bestval
;
311 return kallsyms_symbol_name(kallsyms
, best
);
314 void * __weak
dereference_module_function_descriptor(struct module
*mod
,
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.
324 int module_address_lookup(unsigned long addr
,
326 unsigned long *offset
,
328 const unsigned char **modbuildid
,
336 mod
= __module_address(addr
);
339 *modname
= mod
->name
;
341 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
342 *modbuildid
= mod
->build_id
;
348 sym
= find_kallsyms_symbol(mod
, addr
, size
, offset
);
351 ret
= strscpy(namebuf
, sym
, KSYM_NAME_LEN
);
358 int lookup_module_symbol_name(unsigned long addr
, char *symname
)
363 list_for_each_entry_rcu(mod
, &modules
, list
) {
364 if (mod
->state
== MODULE_STATE_UNFORMED
)
366 if (within_module(addr
, mod
)) {
369 sym
= find_kallsyms_symbol(mod
, addr
, NULL
, NULL
);
373 strscpy(symname
, sym
, KSYM_NAME_LEN
);
383 int module_get_kallsym(unsigned int symnum
, unsigned long *value
, char *type
,
384 char *name
, char *module_name
, int *exported
)
389 list_for_each_entry_rcu(mod
, &modules
, list
) {
390 struct mod_kallsyms
*kallsyms
;
392 if (mod
->state
== MODULE_STATE_UNFORMED
)
394 kallsyms
= rcu_dereference_sched(mod
->kallsyms
);
395 if (symnum
< kallsyms
->num_symtab
) {
396 const Elf_Sym
*sym
= &kallsyms
->symtab
[symnum
];
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
);
406 symnum
-= kallsyms
->num_symtab
;
412 /* Given a module and name of symbol, find and return the symbol's value */
413 static unsigned long __find_kallsyms_symbol_value(struct module
*mod
, const char *name
)
416 struct mod_kallsyms
*kallsyms
= rcu_dereference_sched(mod
->kallsyms
);
418 for (i
= 0; i
< kallsyms
->num_symtab
; i
++) {
419 const Elf_Sym
*sym
= &kallsyms
->symtab
[i
];
421 if (strcmp(name
, kallsyms_symbol_name(kallsyms
, i
)) == 0 &&
422 sym
->st_shndx
!= SHN_UNDEF
)
423 return kallsyms_symbol_value(sym
);
428 static unsigned long __module_kallsyms_lookup_name(const char *name
)
433 colon
= strnchr(name
, MODULE_NAME_LEN
, ':');
435 mod
= find_module_all(name
, colon
- name
, false);
437 return __find_kallsyms_symbol_value(mod
, colon
+ 1);
441 list_for_each_entry_rcu(mod
, &modules
, list
) {
444 if (mod
->state
== MODULE_STATE_UNFORMED
)
446 ret
= __find_kallsyms_symbol_value(mod
, name
);
453 /* Look for this name: can be of form module:name. */
454 unsigned long module_kallsyms_lookup_name(const char *name
)
458 /* Don't lock: we're in enough trouble already. */
460 ret
= __module_kallsyms_lookup_name(name
);
465 unsigned long find_kallsyms_symbol_value(struct module
*mod
, const char *name
)
470 ret
= __find_kallsyms_symbol_value(mod
, name
);
475 int module_kallsyms_on_each_symbol(const char *modname
,
476 int (*fn
)(void *, const char *, unsigned long),
483 mutex_lock(&module_mutex
);
484 list_for_each_entry(mod
, &modules
, list
) {
485 struct mod_kallsyms
*kallsyms
;
487 if (mod
->state
== MODULE_STATE_UNFORMED
)
490 if (modname
&& strcmp(modname
, mod
->name
))
493 /* Use rcu_dereference_sched() to remain compliant with the sparse tool */
495 kallsyms
= rcu_dereference_sched(mod
->kallsyms
);
498 for (i
= 0; i
< kallsyms
->num_symtab
; i
++) {
499 const Elf_Sym
*sym
= &kallsyms
->symtab
[i
];
501 if (sym
->st_shndx
== SHN_UNDEF
)
504 ret
= fn(data
, kallsyms_symbol_name(kallsyms
, i
),
505 kallsyms_symbol_value(sym
));
511 * The given module is found, the subsequent modules do not
512 * need to be compared.
518 mutex_unlock(&module_mutex
);