modules: add default loader hook implementations
authorJonas Bonn <jonas@southpole.se>
Thu, 30 Jun 2011 19:22:11 +0000 (21:22 +0200)
committerRusty Russell <rusty@rustcorp.com.au>
Sun, 24 Jul 2011 12:36:04 +0000 (22:06 +0930)
The module loader code allows architectures to hook into the code by
providing a small number of entry points that each arch must implement.
This patch provides __weakly linked generic implementations of these
entry points for architectures that don't need to do anything special.

Signed-off-by: Jonas Bonn <jonas@southpole.se>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
include/linux/moduleloader.h
kernel/module.c

index c1f40c2f7ffbdffae2ff037d17df5a8a6b857957..b2be02ebf453df40cb07ab7fdfa261903fa44c11 100644 (file)
@@ -5,7 +5,12 @@
 #include <linux/module.h>
 #include <linux/elf.h>
 
-/* These must be implemented by the specific architecture */
+/* These may be implemented by architectures that need to hook into the
+ * module loader code.  Architectures that don't need to do anything special
+ * can just rely on the 'weak' default hooks defined in kernel/module.c.
+ * Note, however, that at least one of apply_relocate or apply_relocate_add
+ * must be implemented by each architecture.
+ */
 
 /* Adjust arch-specific sections.  Return 0 on success.  */
 int module_frob_arch_sections(Elf_Ehdr *hdr,
index 795bdc7f5c3f270301abcb56e2f787550f36c6b9..6301d6e173caa6fbdf49da8c1e170b930989a9ef 100644 (file)
@@ -1697,6 +1697,15 @@ static void unset_module_core_ro_nx(struct module *mod) { }
 static void unset_module_init_ro_nx(struct module *mod) { }
 #endif
 
+void __weak module_free(struct module *mod, void *module_region)
+{
+       vfree(module_region);
+}
+
+void __weak module_arch_cleanup(struct module *mod)
+{
+}
+
 /* Free a module, remove from lists, etc. */
 static void free_module(struct module *mod)
 {
@@ -1851,6 +1860,26 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
        return ret;
 }
 
+int __weak apply_relocate(Elf_Shdr *sechdrs,
+                         const char *strtab,
+                         unsigned int symindex,
+                         unsigned int relsec,
+                         struct module *me)
+{
+       pr_err("module %s: REL relocation unsupported\n", me->name);
+       return -ENOEXEC;
+}
+
+int __weak apply_relocate_add(Elf_Shdr *sechdrs,
+                             const char *strtab,
+                             unsigned int symindex,
+                             unsigned int relsec,
+                             struct module *me)
+{
+       pr_err("module %s: RELA relocation unsupported\n", me->name);
+       return -ENOEXEC;
+}
+
 static int apply_relocations(struct module *mod, const struct load_info *info)
 {
        unsigned int i;
@@ -2235,6 +2264,11 @@ static void dynamic_debug_remove(struct _ddebug *debug)
                ddebug_remove_module(debug->modname);
 }
 
+void * __weak module_alloc(unsigned long size)
+{
+       return size == 0 ? NULL : vmalloc_exec(size);
+}
+
 static void *module_alloc_update_bounds(unsigned long size)
 {
        void *ret = module_alloc(size);
@@ -2645,6 +2679,14 @@ static void flush_module_icache(const struct module *mod)
        set_fs(old_fs);
 }
 
+int __weak module_frob_arch_sections(Elf_Ehdr *hdr,
+                                    Elf_Shdr *sechdrs,
+                                    char *secstrings,
+                                    struct module *mod)
+{
+       return 0;
+}
+
 static struct module *layout_and_allocate(struct load_info *info)
 {
        /* Module within temporary copy. */
@@ -2716,6 +2758,13 @@ static void module_deallocate(struct module *mod, struct load_info *info)
        module_free(mod, mod->module_core);
 }
 
+int __weak module_finalize(const Elf_Ehdr *hdr,
+                          const Elf_Shdr *sechdrs,
+                          struct module *me)
+{
+       return 0;
+}
+
 static int post_relocation(struct module *mod, const struct load_info *info)
 {
        /* Sort exception table now relocations are done. */