]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/module.c
Merge tag 'iio-fixes-4.19a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23...
[linux.git] / kernel / module.c
index b046a32520d83aeeed519a72ae61972b4cc9870c..6746c85511fefe40f335207245df81d3e246a0c8 100644 (file)
@@ -529,12 +529,30 @@ static bool check_symbol(const struct symsearch *syms,
        return true;
 }
 
+static unsigned long kernel_symbol_value(const struct kernel_symbol *sym)
+{
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+       return (unsigned long)offset_to_ptr(&sym->value_offset);
+#else
+       return sym->value;
+#endif
+}
+
+static const char *kernel_symbol_name(const struct kernel_symbol *sym)
+{
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+       return offset_to_ptr(&sym->name_offset);
+#else
+       return sym->name;
+#endif
+}
+
 static int cmp_name(const void *va, const void *vb)
 {
        const char *a;
        const struct kernel_symbol *b;
        a = va; b = vb;
-       return strcmp(a, b->name);
+       return strcmp(a, kernel_symbol_name(b));
 }
 
 static bool find_symbol_in_section(const struct symsearch *syms,
@@ -2170,7 +2188,7 @@ void *__symbol_get(const char *symbol)
                sym = NULL;
        preempt_enable();
 
-       return sym ? (void *)sym->value : NULL;
+       return sym ? (void *)kernel_symbol_value(sym) : NULL;
 }
 EXPORT_SYMBOL_GPL(__symbol_get);
 
@@ -2200,10 +2218,12 @@ static int verify_export_symbols(struct module *mod)
 
        for (i = 0; i < ARRAY_SIZE(arr); i++) {
                for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
-                       if (find_symbol(s->name, &owner, NULL, true, false)) {
+                       if (find_symbol(kernel_symbol_name(s), &owner, NULL,
+                                       true, false)) {
                                pr_err("%s: exports duplicate symbol %s"
                                       " (owned by %s)\n",
-                                      mod->name, s->name, module_name(owner));
+                                      mod->name, kernel_symbol_name(s),
+                                      module_name(owner));
                                return -ENOEXEC;
                        }
                }
@@ -2252,7 +2272,7 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
                        ksym = resolve_symbol_wait(mod, info, name);
                        /* Ok if resolved.  */
                        if (ksym && !IS_ERR(ksym)) {
-                               sym[i].st_value = ksym->value;
+                               sym[i].st_value = kernel_symbol_value(ksym);
                                break;
                        }
 
@@ -2516,7 +2536,7 @@ static int is_exported(const char *name, unsigned long value,
                ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
        else
                ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
-       return ks != NULL && ks->value == value;
+       return ks != NULL && kernel_symbol_value(ks) == value;
 }
 
 /* As per nm */