strip_section() now finds the section flags with get_section()
and handles files of opposite endianness.

Signed-off-by: Andreas Robinson <[email protected]>
---
 elfops.h      |    1 +
 elfops_core.c |   22 ++++++++++++++++++++++
 modprobe.c    |   46 ++--------------------------------------------
 3 files changed, 25 insertions(+), 44 deletions(-)

diff --git a/elfops.h b/elfops.h
index c30a7ae..c33793a 100644
--- a/elfops.h
+++ b/elfops.h
@@ -65,6 +65,7 @@ struct module_ops
                struct module_tables *tables);
        char *(*get_aliases)(struct elf_file *module, unsigned long *size);
        char *(*get_modinfo)(struct elf_file *module, unsigned long *size);
+       void (*strip_section)(struct elf_file *module, const char *secname);
 };
 
 extern struct module_ops mod_ops32, mod_ops64;
diff --git a/elfops_core.c b/elfops_core.c
index 64e353a..14eef96 100644
--- a/elfops_core.c
+++ b/elfops_core.c
@@ -3,12 +3,16 @@
 #define PERBIT(x) x##32
 #define ElfPERBIT(x) Elf32_##x
 #define ELFPERBIT(x) ELF32_##x
+/* 32-bit unsigned integer */
+#define Elf32_Uint Elf32_Word
 
 #elif defined(ELF64BIT)
 
 #define PERBIT(x) x##64
 #define ElfPERBIT(x) Elf64_##x
 #define ELFPERBIT(x) ELF64_##x
+/* 64-bit unsigned integer */
+#define Elf64_Uint Elf64_Xword
 
 #else
 #  error "Undefined ELF word length"
@@ -297,6 +301,23 @@ static void PERBIT(fetch_tables)(struct elf_file *module,
        }
 }
 
+/*
+ * strip_section - tell the kernel to ignore the named section
+ */
+static void PERBIT(strip_section)(struct elf_file *module, const char *secname)
+{
+       void *p;
+       ElfPERBIT(Shdr) *sechdr;
+       unsigned long secsize;
+
+       p = PERBIT(get_section)(module, secname, &sechdr, &secsize);
+       if (p) {
+               ElfPERBIT(Uint) mask;
+               mask = ~((ElfPERBIT(Uint))SHF_ALLOC);
+               sechdr->sh_flags &= END(mask, module->conv);
+       }
+}
+
 struct module_ops PERBIT(mod_ops) = {
        .load_section   = PERBIT(load_section),
        .load_symbols   = PERBIT(load_symbols),
@@ -304,6 +325,7 @@ struct module_ops PERBIT(mod_ops) = {
        .fetch_tables   = PERBIT(fetch_tables),
        .get_aliases    = PERBIT(get_aliases),
        .get_modinfo    = PERBIT(get_modinfo),
+       .strip_section  = PERBIT(strip_section),
 };
 
 #undef PERBIT
diff --git a/modprobe.c b/modprobe.c
index 906d620..a351a58 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -324,55 +324,13 @@ static void rename_module(struct elf_file *module,
                replace_modname(module, modstruct, len, oldname, newname);
 }
 
-/* Kernel told to ignore these sections if SHF_ALLOC not set. */
-static void invalidate_section32(struct elf_file *module, const char *secname)
-{
-       void *mod = module->data;
-       Elf32_Ehdr *hdr = mod;
-       Elf32_Shdr *sechdrs = mod + hdr->e_shoff;
-       const char *secnames = mod + sechdrs[hdr->e_shstrndx].sh_offset;
-       unsigned int i;
-
-       for (i = 1; i < hdr->e_shnum; i++)
-               if (streq(secnames+sechdrs[i].sh_name, secname))
-                       sechdrs[i].sh_flags &= ~SHF_ALLOC;
-}
-
-static void invalidate_section64(struct elf_file *module, const char *secname)
-{
-       void *mod = module->data;
-       Elf64_Ehdr *hdr = mod;
-       Elf64_Shdr *sechdrs = mod + hdr->e_shoff;
-       const char *secnames = mod + sechdrs[hdr->e_shstrndx].sh_offset;
-       unsigned int i;
-
-       for (i = 1; i < hdr->e_shnum; i++)
-               if (streq(secnames+sechdrs[i].sh_name, secname))
-                       sechdrs[i].sh_flags &= ~(unsigned long long)SHF_ALLOC;
-}
-
-static void strip_section(struct elf_file *module, const char *secname)
-{
-       switch (elf_ident(module->data, module->len, NULL)) {
-       case ELFCLASS32:
-               invalidate_section32(module, secname);
-               break;
-       case ELFCLASS64:
-               invalidate_section64(module, secname);
-               break;
-       default:
-               warn("Unknown module format in %s: not forcing version\n",
-                    module->pathname);
-       }
-}
-
 static void clear_magic(struct elf_file *module)
 {
        const char *p;
        unsigned long len;
 
        /* Old-style: __vermagic section */
-       strip_section(module, "__vermagic");
+       module->ops->strip_section(module, "__vermagic");
 
        /* New-style: in .modinfo section */
        p = module->ops->get_modinfo(module, &len);
@@ -731,7 +689,7 @@ static int insmod(struct list_head *list,
        if (newname)
                rename_module(module, mod->modname, newname);
        if (strip_modversion)
-               strip_section(module, "__versions");
+               module->ops->strip_section(module, "__versions");
        if (strip_vermagic)
                clear_magic(module);
 
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to