[PATCH 14/16] modprobe, elfops: move strip_section() to elfops and refactor it

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

Signed-off-by: Andreas Robinson <andr345@xxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux