aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c134
1 files changed, 81 insertions, 53 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 99b46c32d579..fcbc0128810b 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -495,9 +495,9 @@ struct find_symbol_arg {
495 const struct kernel_symbol *sym; 495 const struct kernel_symbol *sym;
496}; 496};
497 497
498static bool check_symbol(const struct symsearch *syms, 498static bool check_exported_symbol(const struct symsearch *syms,
499 struct module *owner, 499 struct module *owner,
500 unsigned int symnum, void *data) 500 unsigned int symnum, void *data)
501{ 501{
502 struct find_symbol_arg *fsa = data; 502 struct find_symbol_arg *fsa = data;
503 503
@@ -555,9 +555,9 @@ static int cmp_name(const void *va, const void *vb)
555 return strcmp(a, kernel_symbol_name(b)); 555 return strcmp(a, kernel_symbol_name(b));
556} 556}
557 557
558static bool find_symbol_in_section(const struct symsearch *syms, 558static bool find_exported_symbol_in_section(const struct symsearch *syms,
559 struct module *owner, 559 struct module *owner,
560 void *data) 560 void *data)
561{ 561{
562 struct find_symbol_arg *fsa = data; 562 struct find_symbol_arg *fsa = data;
563 struct kernel_symbol *sym; 563 struct kernel_symbol *sym;
@@ -565,13 +565,14 @@ static bool find_symbol_in_section(const struct symsearch *syms,
565 sym = bsearch(fsa->name, syms->start, syms->stop - syms->start, 565 sym = bsearch(fsa->name, syms->start, syms->stop - syms->start,
566 sizeof(struct kernel_symbol), cmp_name); 566 sizeof(struct kernel_symbol), cmp_name);
567 567
568 if (sym != NULL && check_symbol(syms, owner, sym - syms->start, data)) 568 if (sym != NULL && check_exported_symbol(syms, owner,
569 sym - syms->start, data))
569 return true; 570 return true;
570 571
571 return false; 572 return false;
572} 573}
573 574
574/* Find a symbol and return it, along with, (optional) crc and 575/* Find an exported symbol and return it, along with, (optional) crc and
575 * (optional) module which owns it. Needs preempt disabled or module_mutex. */ 576 * (optional) module which owns it. Needs preempt disabled or module_mutex. */
576const struct kernel_symbol *find_symbol(const char *name, 577const struct kernel_symbol *find_symbol(const char *name,
577 struct module **owner, 578 struct module **owner,
@@ -585,7 +586,7 @@ const struct kernel_symbol *find_symbol(const char *name,
585 fsa.gplok = gplok; 586 fsa.gplok = gplok;
586 fsa.warn = warn; 587 fsa.warn = warn;
587 588
588 if (each_symbol_section(find_symbol_in_section, &fsa)) { 589 if (each_symbol_section(find_exported_symbol_in_section, &fsa)) {
589 if (owner) 590 if (owner)
590 *owner = fsa.owner; 591 *owner = fsa.owner;
591 if (crc) 592 if (crc)
@@ -1207,8 +1208,10 @@ static ssize_t store_uevent(struct module_attribute *mattr,
1207 struct module_kobject *mk, 1208 struct module_kobject *mk,
1208 const char *buffer, size_t count) 1209 const char *buffer, size_t count)
1209{ 1210{
1210 kobject_synth_uevent(&mk->kobj, buffer, count); 1211 int rc;
1211 return count; 1212
1213 rc = kobject_synth_uevent(&mk->kobj, buffer, count);
1214 return rc ? rc : count;
1212} 1215}
1213 1216
1214struct module_attribute module_uevent = 1217struct module_attribute module_uevent =
@@ -2198,7 +2201,7 @@ EXPORT_SYMBOL_GPL(__symbol_get);
2198 * 2201 *
2199 * You must hold the module_mutex. 2202 * You must hold the module_mutex.
2200 */ 2203 */
2201static int verify_export_symbols(struct module *mod) 2204static int verify_exported_symbols(struct module *mod)
2202{ 2205{
2203 unsigned int i; 2206 unsigned int i;
2204 struct module *owner; 2207 struct module *owner;
@@ -2519,10 +2522,10 @@ static void free_modinfo(struct module *mod)
2519 2522
2520#ifdef CONFIG_KALLSYMS 2523#ifdef CONFIG_KALLSYMS
2521 2524
2522/* lookup symbol in given range of kernel_symbols */ 2525/* Lookup exported symbol in given range of kernel_symbols */
2523static const struct kernel_symbol *lookup_symbol(const char *name, 2526static const struct kernel_symbol *lookup_exported_symbol(const char *name,
2524 const struct kernel_symbol *start, 2527 const struct kernel_symbol *start,
2525 const struct kernel_symbol *stop) 2528 const struct kernel_symbol *stop)
2526{ 2529{
2527 return bsearch(name, start, stop - start, 2530 return bsearch(name, start, stop - start,
2528 sizeof(struct kernel_symbol), cmp_name); 2531 sizeof(struct kernel_symbol), cmp_name);
@@ -2533,9 +2536,10 @@ static int is_exported(const char *name, unsigned long value,
2533{ 2536{
2534 const struct kernel_symbol *ks; 2537 const struct kernel_symbol *ks;
2535 if (!mod) 2538 if (!mod)
2536 ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); 2539 ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab);
2537 else 2540 else
2538 ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); 2541 ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms);
2542
2539 return ks != NULL && kernel_symbol_value(ks) == value; 2543 return ks != NULL && kernel_symbol_value(ks) == value;
2540} 2544}
2541 2545
@@ -2682,7 +2686,7 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
2682 2686
2683 /* Set types up while we still have access to sections. */ 2687 /* Set types up while we still have access to sections. */
2684 for (i = 0; i < mod->kallsyms->num_symtab; i++) 2688 for (i = 0; i < mod->kallsyms->num_symtab; i++)
2685 mod->kallsyms->symtab[i].st_info 2689 mod->kallsyms->symtab[i].st_size
2686 = elf_type(&mod->kallsyms->symtab[i], info); 2690 = elf_type(&mod->kallsyms->symtab[i], info);
2687 2691
2688 /* Now populate the cut down core kallsyms for after init. */ 2692 /* Now populate the cut down core kallsyms for after init. */
@@ -3093,6 +3097,11 @@ static int find_module_sections(struct module *mod, struct load_info *info)
3093 sizeof(*mod->tracepoints_ptrs), 3097 sizeof(*mod->tracepoints_ptrs),
3094 &mod->num_tracepoints); 3098 &mod->num_tracepoints);
3095#endif 3099#endif
3100#ifdef CONFIG_BPF_EVENTS
3101 mod->bpf_raw_events = section_objs(info, "__bpf_raw_tp_map",
3102 sizeof(*mod->bpf_raw_events),
3103 &mod->num_bpf_raw_events);
3104#endif
3096#ifdef HAVE_JUMP_LABEL 3105#ifdef HAVE_JUMP_LABEL
3097 mod->jump_entries = section_objs(info, "__jump_table", 3106 mod->jump_entries = section_objs(info, "__jump_table",
3098 sizeof(*mod->jump_entries), 3107 sizeof(*mod->jump_entries),
@@ -3592,7 +3601,7 @@ static int complete_formation(struct module *mod, struct load_info *info)
3592 mutex_lock(&module_mutex); 3601 mutex_lock(&module_mutex);
3593 3602
3594 /* Find duplicate symbols (must be called under lock). */ 3603 /* Find duplicate symbols (must be called under lock). */
3595 err = verify_export_symbols(mod); 3604 err = verify_exported_symbols(mod);
3596 if (err < 0) 3605 if (err < 0)
3597 goto out; 3606 goto out;
3598 3607
@@ -3911,18 +3920,22 @@ static inline int is_arm_mapping_symbol(const char *str)
3911 && (str[2] == '\0' || str[2] == '.'); 3920 && (str[2] == '\0' || str[2] == '.');
3912} 3921}
3913 3922
3914static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum) 3923static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum)
3915{ 3924{
3916 return kallsyms->strtab + kallsyms->symtab[symnum].st_name; 3925 return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
3917} 3926}
3918 3927
3919static const char *get_ksymbol(struct module *mod, 3928/*
3920 unsigned long addr, 3929 * Given a module and address, find the corresponding symbol and return its name
3921 unsigned long *size, 3930 * while providing its size and offset if needed.
3922 unsigned long *offset) 3931 */
3932static const char *find_kallsyms_symbol(struct module *mod,
3933 unsigned long addr,
3934 unsigned long *size,
3935 unsigned long *offset)
3923{ 3936{
3924 unsigned int i, best = 0; 3937 unsigned int i, best = 0;
3925 unsigned long nextval; 3938 unsigned long nextval, bestval;
3926 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); 3939 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
3927 3940
3928 /* At worse, next value is at end of module */ 3941 /* At worse, next value is at end of module */
@@ -3931,34 +3944,40 @@ static const char *get_ksymbol(struct module *mod,
3931 else 3944 else
3932 nextval = (unsigned long)mod->core_layout.base+mod->core_layout.text_size; 3945 nextval = (unsigned long)mod->core_layout.base+mod->core_layout.text_size;
3933 3946
3947 bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
3948
3934 /* Scan for closest preceding symbol, and next symbol. (ELF 3949 /* Scan for closest preceding symbol, and next symbol. (ELF
3935 starts real symbols at 1). */ 3950 starts real symbols at 1). */
3936 for (i = 1; i < kallsyms->num_symtab; i++) { 3951 for (i = 1; i < kallsyms->num_symtab; i++) {
3937 if (kallsyms->symtab[i].st_shndx == SHN_UNDEF) 3952 const Elf_Sym *sym = &kallsyms->symtab[i];
3953 unsigned long thisval = kallsyms_symbol_value(sym);
3954
3955 if (sym->st_shndx == SHN_UNDEF)
3938 continue; 3956 continue;
3939 3957
3940 /* We ignore unnamed symbols: they're uninformative 3958 /* We ignore unnamed symbols: they're uninformative
3941 * and inserted at a whim. */ 3959 * and inserted at a whim. */
3942 if (*symname(kallsyms, i) == '\0' 3960 if (*kallsyms_symbol_name(kallsyms, i) == '\0'
3943 || is_arm_mapping_symbol(symname(kallsyms, i))) 3961 || is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
3944 continue; 3962 continue;
3945 3963
3946 if (kallsyms->symtab[i].st_value <= addr 3964 if (thisval <= addr && thisval > bestval) {
3947 && kallsyms->symtab[i].st_value > kallsyms->symtab[best].st_value)
3948 best = i; 3965 best = i;
3949 if (kallsyms->symtab[i].st_value > addr 3966 bestval = thisval;
3950 && kallsyms->symtab[i].st_value < nextval) 3967 }
3951 nextval = kallsyms->symtab[i].st_value; 3968 if (thisval > addr && thisval < nextval)
3969 nextval = thisval;
3952 } 3970 }
3953 3971
3954 if (!best) 3972 if (!best)
3955 return NULL; 3973 return NULL;
3956 3974
3957 if (size) 3975 if (size)
3958 *size = nextval - kallsyms->symtab[best].st_value; 3976 *size = nextval - bestval;
3959 if (offset) 3977 if (offset)
3960 *offset = addr - kallsyms->symtab[best].st_value; 3978 *offset = addr - bestval;
3961 return symname(kallsyms, best); 3979
3980 return kallsyms_symbol_name(kallsyms, best);
3962} 3981}
3963 3982
3964void * __weak dereference_module_function_descriptor(struct module *mod, 3983void * __weak dereference_module_function_descriptor(struct module *mod,
@@ -3983,7 +4002,8 @@ const char *module_address_lookup(unsigned long addr,
3983 if (mod) { 4002 if (mod) {
3984 if (modname) 4003 if (modname)
3985 *modname = mod->name; 4004 *modname = mod->name;
3986 ret = get_ksymbol(mod, addr, size, offset); 4005
4006 ret = find_kallsyms_symbol(mod, addr, size, offset);
3987 } 4007 }
3988 /* Make a copy in here where it's safe */ 4008 /* Make a copy in here where it's safe */
3989 if (ret) { 4009 if (ret) {
@@ -4006,9 +4026,10 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
4006 if (within_module(addr, mod)) { 4026 if (within_module(addr, mod)) {
4007 const char *sym; 4027 const char *sym;
4008 4028
4009 sym = get_ksymbol(mod, addr, NULL, NULL); 4029 sym = find_kallsyms_symbol(mod, addr, NULL, NULL);
4010 if (!sym) 4030 if (!sym)
4011 goto out; 4031 goto out;
4032
4012 strlcpy(symname, sym, KSYM_NAME_LEN); 4033 strlcpy(symname, sym, KSYM_NAME_LEN);
4013 preempt_enable(); 4034 preempt_enable();
4014 return 0; 4035 return 0;
@@ -4031,7 +4052,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
4031 if (within_module(addr, mod)) { 4052 if (within_module(addr, mod)) {
4032 const char *sym; 4053 const char *sym;
4033 4054
4034 sym = get_ksymbol(mod, addr, size, offset); 4055 sym = find_kallsyms_symbol(mod, addr, size, offset);
4035 if (!sym) 4056 if (!sym)
4036 goto out; 4057 goto out;
4037 if (modname) 4058 if (modname)
@@ -4060,9 +4081,11 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
4060 continue; 4081 continue;
4061 kallsyms = rcu_dereference_sched(mod->kallsyms); 4082 kallsyms = rcu_dereference_sched(mod->kallsyms);
4062 if (symnum < kallsyms->num_symtab) { 4083 if (symnum < kallsyms->num_symtab) {
4063 *value = kallsyms->symtab[symnum].st_value; 4084 const Elf_Sym *sym = &kallsyms->symtab[symnum];
4064 *type = kallsyms->symtab[symnum].st_info; 4085
4065 strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN); 4086 *value = kallsyms_symbol_value(sym);
4087 *type = sym->st_size;
4088 strlcpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
4066 strlcpy(module_name, mod->name, MODULE_NAME_LEN); 4089 strlcpy(module_name, mod->name, MODULE_NAME_LEN);
4067 *exported = is_exported(name, *value, mod); 4090 *exported = is_exported(name, *value, mod);
4068 preempt_enable(); 4091 preempt_enable();
@@ -4074,15 +4097,19 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
4074 return -ERANGE; 4097 return -ERANGE;
4075} 4098}
4076 4099
4077static unsigned long mod_find_symname(struct module *mod, const char *name) 4100/* Given a module and name of symbol, find and return the symbol's value */
4101static unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name)
4078{ 4102{
4079 unsigned int i; 4103 unsigned int i;
4080 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); 4104 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
4081 4105
4082 for (i = 0; i < kallsyms->num_symtab; i++) 4106 for (i = 0; i < kallsyms->num_symtab; i++) {
4083 if (strcmp(name, symname(kallsyms, i)) == 0 && 4107 const Elf_Sym *sym = &kallsyms->symtab[i];
4084 kallsyms->symtab[i].st_shndx != SHN_UNDEF) 4108
4085 return kallsyms->symtab[i].st_value; 4109 if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 &&
4110 sym->st_shndx != SHN_UNDEF)
4111 return kallsyms_symbol_value(sym);
4112 }
4086 return 0; 4113 return 0;
4087} 4114}
4088 4115
@@ -4097,12 +4124,12 @@ unsigned long module_kallsyms_lookup_name(const char *name)
4097 preempt_disable(); 4124 preempt_disable();
4098 if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) { 4125 if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) {
4099 if ((mod = find_module_all(name, colon - name, false)) != NULL) 4126 if ((mod = find_module_all(name, colon - name, false)) != NULL)
4100 ret = mod_find_symname(mod, colon+1); 4127 ret = find_kallsyms_symbol_value(mod, colon+1);
4101 } else { 4128 } else {
4102 list_for_each_entry_rcu(mod, &modules, list) { 4129 list_for_each_entry_rcu(mod, &modules, list) {
4103 if (mod->state == MODULE_STATE_UNFORMED) 4130 if (mod->state == MODULE_STATE_UNFORMED)
4104 continue; 4131 continue;
4105 if ((ret = mod_find_symname(mod, name)) != 0) 4132 if ((ret = find_kallsyms_symbol_value(mod, name)) != 0)
4106 break; 4133 break;
4107 } 4134 }
4108 } 4135 }
@@ -4127,12 +4154,13 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
4127 if (mod->state == MODULE_STATE_UNFORMED) 4154 if (mod->state == MODULE_STATE_UNFORMED)
4128 continue; 4155 continue;
4129 for (i = 0; i < kallsyms->num_symtab; i++) { 4156 for (i = 0; i < kallsyms->num_symtab; i++) {
4157 const Elf_Sym *sym = &kallsyms->symtab[i];
4130 4158
4131 if (kallsyms->symtab[i].st_shndx == SHN_UNDEF) 4159 if (sym->st_shndx == SHN_UNDEF)
4132 continue; 4160 continue;
4133 4161
4134 ret = fn(data, symname(kallsyms, i), 4162 ret = fn(data, kallsyms_symbol_name(kallsyms, i),
4135 mod, kallsyms->symtab[i].st_value); 4163 mod, kallsyms_symbol_value(sym));
4136 if (ret != 0) 4164 if (ret != 0)
4137 return ret; 4165 return ret;
4138 } 4166 }