aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Robinson <andr345@gmail.com>2009-05-14 18:22:23 +0200
committerAndreas Robinson <andr345@gmail.com>2009-05-15 15:44:54 +0200
commit45ec2644e6970f28fbf2acc789391de3e649f154 (patch)
tree187c58aadca71636fab1ae6e3774039cf1d8b767
parentd1e6992067f6b06b572430d1ea90d88ec87f4221 (diff)
downloadmodule-init-tools-45ec2644e6970f28fbf2acc789391de3e649f154.tar.gz
modprobe, elfops: move strip_section() to elfops and refactor it
strip_section() now finds the section flags with get_section() and handles files of opposite endianness. Signed-off-by: Andreas Robinson <andr345@gmail.com>
-rw-r--r--elfops.h1
-rw-r--r--elfops_core.c22
-rw-r--r--modprobe.c46
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);