0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/kallsyms.h>
0010 #include <linux/buildid.h>
0011 #include <linux/bsearch.h>
0012 #include "internal.h"
0013
0014
0015 static const struct kernel_symbol *lookup_exported_symbol(const char *name,
0016 const struct kernel_symbol *start,
0017 const struct kernel_symbol *stop)
0018 {
0019 return bsearch(name, start, stop - start,
0020 sizeof(struct kernel_symbol), cmp_name);
0021 }
0022
0023 static int is_exported(const char *name, unsigned long value,
0024 const struct module *mod)
0025 {
0026 const struct kernel_symbol *ks;
0027
0028 if (!mod)
0029 ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab);
0030 else
0031 ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms);
0032
0033 return ks && kernel_symbol_value(ks) == value;
0034 }
0035
0036
0037 static char elf_type(const Elf_Sym *sym, const struct load_info *info)
0038 {
0039 const Elf_Shdr *sechdrs = info->sechdrs;
0040
0041 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
0042 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
0043 return 'v';
0044 else
0045 return 'w';
0046 }
0047 if (sym->st_shndx == SHN_UNDEF)
0048 return 'U';
0049 if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu)
0050 return 'a';
0051 if (sym->st_shndx >= SHN_LORESERVE)
0052 return '?';
0053 if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
0054 return 't';
0055 if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC &&
0056 sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
0057 if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
0058 return 'r';
0059 else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
0060 return 'g';
0061 else
0062 return 'd';
0063 }
0064 if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
0065 if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
0066 return 's';
0067 else
0068 return 'b';
0069 }
0070 if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
0071 ".debug")) {
0072 return 'n';
0073 }
0074 return '?';
0075 }
0076
0077 static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
0078 unsigned int shnum, unsigned int pcpundx)
0079 {
0080 const Elf_Shdr *sec;
0081
0082 if (src->st_shndx == SHN_UNDEF ||
0083 src->st_shndx >= shnum ||
0084 !src->st_name)
0085 return false;
0086
0087 #ifdef CONFIG_KALLSYMS_ALL
0088 if (src->st_shndx == pcpundx)
0089 return true;
0090 #endif
0091
0092 sec = sechdrs + src->st_shndx;
0093 if (!(sec->sh_flags & SHF_ALLOC)
0094 #ifndef CONFIG_KALLSYMS_ALL
0095 || !(sec->sh_flags & SHF_EXECINSTR)
0096 #endif
0097 || (sec->sh_entsize & INIT_OFFSET_MASK))
0098 return false;
0099
0100 return true;
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110 void layout_symtab(struct module *mod, struct load_info *info)
0111 {
0112 Elf_Shdr *symsect = info->sechdrs + info->index.sym;
0113 Elf_Shdr *strsect = info->sechdrs + info->index.str;
0114 const Elf_Sym *src;
0115 unsigned int i, nsrc, ndst, strtab_size = 0;
0116
0117
0118 symsect->sh_flags |= SHF_ALLOC;
0119 symsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, symsect,
0120 info->index.sym) | INIT_OFFSET_MASK;
0121 pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
0122
0123 src = (void *)info->hdr + symsect->sh_offset;
0124 nsrc = symsect->sh_size / sizeof(*src);
0125
0126
0127 for (ndst = i = 0; i < nsrc; i++) {
0128 if (i == 0 || is_livepatch_module(mod) ||
0129 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
0130 info->index.pcpu)) {
0131 strtab_size += strlen(&info->strtab[src[i].st_name]) + 1;
0132 ndst++;
0133 }
0134 }
0135
0136
0137 info->symoffs = ALIGN(mod->data_layout.size, symsect->sh_addralign ?: 1);
0138 info->stroffs = mod->data_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
0139 mod->data_layout.size += strtab_size;
0140
0141 info->core_typeoffs = mod->data_layout.size;
0142 mod->data_layout.size += ndst * sizeof(char);
0143 mod->data_layout.size = strict_align(mod->data_layout.size);
0144
0145
0146 strsect->sh_flags |= SHF_ALLOC;
0147 strsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, strsect,
0148 info->index.str) | INIT_OFFSET_MASK;
0149 pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
0150
0151
0152 mod->init_layout.size = ALIGN(mod->init_layout.size,
0153 __alignof__(struct mod_kallsyms));
0154 info->mod_kallsyms_init_off = mod->init_layout.size;
0155 mod->init_layout.size += sizeof(struct mod_kallsyms);
0156 info->init_typeoffs = mod->init_layout.size;
0157 mod->init_layout.size += nsrc * sizeof(char);
0158 mod->init_layout.size = strict_align(mod->init_layout.size);
0159 }
0160
0161
0162
0163
0164
0165
0166 void add_kallsyms(struct module *mod, const struct load_info *info)
0167 {
0168 unsigned int i, ndst;
0169 const Elf_Sym *src;
0170 Elf_Sym *dst;
0171 char *s;
0172 Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
0173 unsigned long strtab_size;
0174
0175
0176 mod->kallsyms = (void __rcu *)mod->init_layout.base +
0177 info->mod_kallsyms_init_off;
0178
0179 rcu_read_lock();
0180
0181 rcu_dereference(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
0182 rcu_dereference(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
0183
0184 rcu_dereference(mod->kallsyms)->strtab =
0185 (void *)info->sechdrs[info->index.str].sh_addr;
0186 rcu_dereference(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs;
0187
0188
0189
0190
0191
0192 mod->core_kallsyms.symtab = dst = mod->data_layout.base + info->symoffs;
0193 mod->core_kallsyms.strtab = s = mod->data_layout.base + info->stroffs;
0194 mod->core_kallsyms.typetab = mod->data_layout.base + info->core_typeoffs;
0195 strtab_size = info->core_typeoffs - info->stroffs;
0196 src = rcu_dereference(mod->kallsyms)->symtab;
0197 for (ndst = i = 0; i < rcu_dereference(mod->kallsyms)->num_symtab; i++) {
0198 rcu_dereference(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
0199 if (i == 0 || is_livepatch_module(mod) ||
0200 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
0201 info->index.pcpu)) {
0202 ssize_t ret;
0203
0204 mod->core_kallsyms.typetab[ndst] =
0205 rcu_dereference(mod->kallsyms)->typetab[i];
0206 dst[ndst] = src[i];
0207 dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
0208 ret = strscpy(s,
0209 &rcu_dereference(mod->kallsyms)->strtab[src[i].st_name],
0210 strtab_size);
0211 if (ret < 0)
0212 break;
0213 s += ret + 1;
0214 strtab_size -= ret + 1;
0215 }
0216 }
0217 rcu_read_unlock();
0218 mod->core_kallsyms.num_symtab = ndst;
0219 }
0220
0221 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
0222 void init_build_id(struct module *mod, const struct load_info *info)
0223 {
0224 const Elf_Shdr *sechdr;
0225 unsigned int i;
0226
0227 for (i = 0; i < info->hdr->e_shnum; i++) {
0228 sechdr = &info->sechdrs[i];
0229 if (!sect_empty(sechdr) && sechdr->sh_type == SHT_NOTE &&
0230 !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id,
0231 sechdr->sh_size))
0232 break;
0233 }
0234 }
0235 #else
0236 void init_build_id(struct module *mod, const struct load_info *info)
0237 {
0238 }
0239 #endif
0240
0241
0242
0243
0244
0245 static inline int is_arm_mapping_symbol(const char *str)
0246 {
0247 if (str[0] == '.' && str[1] == 'L')
0248 return true;
0249 return str[0] == '$' && strchr("axtd", str[1]) &&
0250 (str[2] == '\0' || str[2] == '.');
0251 }
0252
0253 static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum)
0254 {
0255 return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
0256 }
0257
0258
0259
0260
0261
0262 static const char *find_kallsyms_symbol(struct module *mod,
0263 unsigned long addr,
0264 unsigned long *size,
0265 unsigned long *offset)
0266 {
0267 unsigned int i, best = 0;
0268 unsigned long nextval, bestval;
0269 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
0270
0271
0272 if (within_module_init(addr, mod))
0273 nextval = (unsigned long)mod->init_layout.base + mod->init_layout.text_size;
0274 else
0275 nextval = (unsigned long)mod->core_layout.base + mod->core_layout.text_size;
0276
0277 bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
0278
0279
0280
0281
0282
0283 for (i = 1; i < kallsyms->num_symtab; i++) {
0284 const Elf_Sym *sym = &kallsyms->symtab[i];
0285 unsigned long thisval = kallsyms_symbol_value(sym);
0286
0287 if (sym->st_shndx == SHN_UNDEF)
0288 continue;
0289
0290
0291
0292
0293
0294 if (*kallsyms_symbol_name(kallsyms, i) == '\0' ||
0295 is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
0296 continue;
0297
0298 if (thisval <= addr && thisval > bestval) {
0299 best = i;
0300 bestval = thisval;
0301 }
0302 if (thisval > addr && thisval < nextval)
0303 nextval = thisval;
0304 }
0305
0306 if (!best)
0307 return NULL;
0308
0309 if (size)
0310 *size = nextval - bestval;
0311 if (offset)
0312 *offset = addr - bestval;
0313
0314 return kallsyms_symbol_name(kallsyms, best);
0315 }
0316
0317 void * __weak dereference_module_function_descriptor(struct module *mod,
0318 void *ptr)
0319 {
0320 return ptr;
0321 }
0322
0323
0324
0325
0326
0327 const char *module_address_lookup(unsigned long addr,
0328 unsigned long *size,
0329 unsigned long *offset,
0330 char **modname,
0331 const unsigned char **modbuildid,
0332 char *namebuf)
0333 {
0334 const char *ret = NULL;
0335 struct module *mod;
0336
0337 preempt_disable();
0338 mod = __module_address(addr);
0339 if (mod) {
0340 if (modname)
0341 *modname = mod->name;
0342 if (modbuildid) {
0343 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
0344 *modbuildid = mod->build_id;
0345 #else
0346 *modbuildid = NULL;
0347 #endif
0348 }
0349
0350 ret = find_kallsyms_symbol(mod, addr, size, offset);
0351 }
0352
0353 if (ret) {
0354 strncpy(namebuf, ret, KSYM_NAME_LEN - 1);
0355 ret = namebuf;
0356 }
0357 preempt_enable();
0358
0359 return ret;
0360 }
0361
0362 int lookup_module_symbol_name(unsigned long addr, char *symname)
0363 {
0364 struct module *mod;
0365
0366 preempt_disable();
0367 list_for_each_entry_rcu(mod, &modules, list) {
0368 if (mod->state == MODULE_STATE_UNFORMED)
0369 continue;
0370 if (within_module(addr, mod)) {
0371 const char *sym;
0372
0373 sym = find_kallsyms_symbol(mod, addr, NULL, NULL);
0374 if (!sym)
0375 goto out;
0376
0377 strscpy(symname, sym, KSYM_NAME_LEN);
0378 preempt_enable();
0379 return 0;
0380 }
0381 }
0382 out:
0383 preempt_enable();
0384 return -ERANGE;
0385 }
0386
0387 int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
0388 unsigned long *offset, char *modname, char *name)
0389 {
0390 struct module *mod;
0391
0392 preempt_disable();
0393 list_for_each_entry_rcu(mod, &modules, list) {
0394 if (mod->state == MODULE_STATE_UNFORMED)
0395 continue;
0396 if (within_module(addr, mod)) {
0397 const char *sym;
0398
0399 sym = find_kallsyms_symbol(mod, addr, size, offset);
0400 if (!sym)
0401 goto out;
0402 if (modname)
0403 strscpy(modname, mod->name, MODULE_NAME_LEN);
0404 if (name)
0405 strscpy(name, sym, KSYM_NAME_LEN);
0406 preempt_enable();
0407 return 0;
0408 }
0409 }
0410 out:
0411 preempt_enable();
0412 return -ERANGE;
0413 }
0414
0415 int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
0416 char *name, char *module_name, int *exported)
0417 {
0418 struct module *mod;
0419
0420 preempt_disable();
0421 list_for_each_entry_rcu(mod, &modules, list) {
0422 struct mod_kallsyms *kallsyms;
0423
0424 if (mod->state == MODULE_STATE_UNFORMED)
0425 continue;
0426 kallsyms = rcu_dereference_sched(mod->kallsyms);
0427 if (symnum < kallsyms->num_symtab) {
0428 const Elf_Sym *sym = &kallsyms->symtab[symnum];
0429
0430 *value = kallsyms_symbol_value(sym);
0431 *type = kallsyms->typetab[symnum];
0432 strscpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
0433 strscpy(module_name, mod->name, MODULE_NAME_LEN);
0434 *exported = is_exported(name, *value, mod);
0435 preempt_enable();
0436 return 0;
0437 }
0438 symnum -= kallsyms->num_symtab;
0439 }
0440 preempt_enable();
0441 return -ERANGE;
0442 }
0443
0444
0445 unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name)
0446 {
0447 unsigned int i;
0448 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
0449
0450 for (i = 0; i < kallsyms->num_symtab; i++) {
0451 const Elf_Sym *sym = &kallsyms->symtab[i];
0452
0453 if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 &&
0454 sym->st_shndx != SHN_UNDEF)
0455 return kallsyms_symbol_value(sym);
0456 }
0457 return 0;
0458 }
0459
0460 static unsigned long __module_kallsyms_lookup_name(const char *name)
0461 {
0462 struct module *mod;
0463 char *colon;
0464
0465 colon = strnchr(name, MODULE_NAME_LEN, ':');
0466 if (colon) {
0467 mod = find_module_all(name, colon - name, false);
0468 if (mod)
0469 return find_kallsyms_symbol_value(mod, colon + 1);
0470 return 0;
0471 }
0472
0473 list_for_each_entry_rcu(mod, &modules, list) {
0474 unsigned long ret;
0475
0476 if (mod->state == MODULE_STATE_UNFORMED)
0477 continue;
0478 ret = find_kallsyms_symbol_value(mod, name);
0479 if (ret)
0480 return ret;
0481 }
0482 return 0;
0483 }
0484
0485
0486 unsigned long module_kallsyms_lookup_name(const char *name)
0487 {
0488 unsigned long ret;
0489
0490
0491 preempt_disable();
0492 ret = __module_kallsyms_lookup_name(name);
0493 preempt_enable();
0494 return ret;
0495 }
0496
0497 #ifdef CONFIG_LIVEPATCH
0498 int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
0499 struct module *, unsigned long),
0500 void *data)
0501 {
0502 struct module *mod;
0503 unsigned int i;
0504 int ret = 0;
0505
0506 mutex_lock(&module_mutex);
0507 list_for_each_entry(mod, &modules, list) {
0508 struct mod_kallsyms *kallsyms;
0509
0510 if (mod->state == MODULE_STATE_UNFORMED)
0511 continue;
0512
0513
0514 preempt_disable();
0515 kallsyms = rcu_dereference_sched(mod->kallsyms);
0516 preempt_enable();
0517
0518 for (i = 0; i < kallsyms->num_symtab; i++) {
0519 const Elf_Sym *sym = &kallsyms->symtab[i];
0520
0521 if (sym->st_shndx == SHN_UNDEF)
0522 continue;
0523
0524 ret = fn(data, kallsyms_symbol_name(kallsyms, i),
0525 mod, kallsyms_symbol_value(sym));
0526 if (ret != 0)
0527 goto out;
0528 }
0529 }
0530 out:
0531 mutex_unlock(&module_mutex);
0532 return ret;
0533 }
0534 #endif