linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch 0/4] module: merge module_32.c and module_64.c
@ 2009-05-26  8:35 Amerigo Wang
  2009-05-26  8:35 ` [Patch 1/4] x86 module: merge the same functions in " Amerigo Wang
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Amerigo Wang @ 2009-05-26  8:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, mingo, jdike, Amerigo Wang, rusty


This patch set aims to merge module_32.c and module_64.c into
module.c. And plus some other related fixes.

Please apply in order.

I have tested this patch set on x86_64, and uml over x86_64,
and compile tested on i386. It looks fine.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Ingo Molnar <mingo@elte.hu>

 arch/um/sys-i386/Makefile      |    2 
 arch/um/sys-x86_64/Makefile    |    4 
 arch/um/sys-x86_64/um_module.c |   21 ---
 arch/x86/kernel/Makefile       |    4 
 arch/x86/kernel/module.c       |  262 ++++++++++++++++++++++++++++++++++++++++-
 arch/x86/kernel/module_32.c    |  152 -----------------------
 arch/x86/kernel/module_64.c    |  194 ------------------------------
 7 files changed, 264 insertions(+), 375 deletions(-)


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Patch 1/4] x86 module: merge the same functions in module_32.c and module_64.c
  2009-05-26  8:35 [Patch 0/4] module: merge module_32.c and module_64.c Amerigo Wang
@ 2009-05-26  8:35 ` Amerigo Wang
  2009-05-26  8:35 ` [Patch 2/4] x86 module: merge the rest functions with macros Amerigo Wang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: Amerigo Wang @ 2009-05-26  8:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, rusty, jdike, mingo, Amerigo Wang


Merge the same functions both in module_32.c and module_64.c into
module.c.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu> 

---
Index: linux-2.6/arch/x86/kernel/module.c
===================================================================
--- /dev/null
+++ linux-2.6/arch/x86/kernel/module.c
@@ -0,0 +1,98 @@
+/*  Kernel module help for x86.
+    Copyright (C) 2001 Rusty Russell.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/mm.h>
+
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt...)
+#endif
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+	   table entries. */
+}
+
+/* We don't need anything special. */
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+			      Elf_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *mod)
+{
+	return 0;
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
+		*para = NULL;
+	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
+		if (!strcmp(".text", secstrings + s->sh_name))
+			text = s;
+		if (!strcmp(".altinstructions", secstrings + s->sh_name))
+			alt = s;
+		if (!strcmp(".smp_locks", secstrings + s->sh_name))
+			locks = s;
+		if (!strcmp(".parainstructions", secstrings + s->sh_name))
+			para = s;
+	}
+
+	if (alt) {
+		/* patch .altinstructions */
+		void *aseg = (void *)alt->sh_addr;
+		apply_alternatives(aseg, aseg + alt->sh_size);
+	}
+	if (locks && text) {
+		void *lseg = (void *)locks->sh_addr;
+		void *tseg = (void *)text->sh_addr;
+		alternatives_smp_module_add(me, me->name,
+					    lseg, lseg + locks->sh_size,
+					    tseg, tseg + text->sh_size);
+	}
+
+	if (para) {
+		void *pseg = (void *)para->sh_addr;
+		apply_paravirt(pseg, pseg + para->sh_size);
+	}
+
+	return module_bug_finalize(hdr, sechdrs, me);
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+	alternatives_smp_module_del(mod);
+	module_bug_cleanup(mod);
+}
Index: linux-2.6/arch/x86/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/x86/kernel/Makefile
+++ linux-2.6/arch/x86/kernel/Makefile
@@ -72,7 +72,7 @@ obj-$(CONFIG_KEXEC)		+= machine_kexec_$(
 obj-$(CONFIG_KEXEC)		+= relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_MODULES)		+= module_$(BITS).o
+obj-$(CONFIG_MODULES)		+= module.o module_$(BITS).o
 obj-$(CONFIG_EFI) 		+= efi.o efi_$(BITS).o efi_stub_$(BITS).o
 obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault_32.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
Index: linux-2.6/arch/x86/kernel/module_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module_32.c
+++ linux-2.6/arch/x86/kernel/module_32.c
@@ -37,23 +37,6 @@ void *module_alloc(unsigned long size)
 }
 
 
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-	vfree(module_region);
-	/* FIXME: If module_region == mod->init_region, trim exception
-	   table entries. */
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-			      Elf_Shdr *sechdrs,
-			      char *secstrings,
-			      struct module *mod)
-{
-	return 0;
-}
-
 int apply_relocate(Elf32_Shdr *sechdrs,
 		   const char *strtab,
 		   unsigned int symindex,
@@ -105,48 +88,3 @@ int apply_relocate_add(Elf32_Shdr *sechd
 	return -ENOEXEC;
 }
 
-int module_finalize(const Elf_Ehdr *hdr,
-		    const Elf_Shdr *sechdrs,
-		    struct module *me)
-{
-	const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
-		*para = NULL;
-	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-
-	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
-		if (!strcmp(".text", secstrings + s->sh_name))
-			text = s;
-		if (!strcmp(".altinstructions", secstrings + s->sh_name))
-			alt = s;
-		if (!strcmp(".smp_locks", secstrings + s->sh_name))
-			locks = s;
-		if (!strcmp(".parainstructions", secstrings + s->sh_name))
-			para = s;
-	}
-
-	if (alt) {
-		/* patch .altinstructions */
-		void *aseg = (void *)alt->sh_addr;
-		apply_alternatives(aseg, aseg + alt->sh_size);
-	}
-	if (locks && text) {
-		void *lseg = (void *)locks->sh_addr;
-		void *tseg = (void *)text->sh_addr;
-		alternatives_smp_module_add(me, me->name,
-					    lseg, lseg + locks->sh_size,
-					    tseg, tseg + text->sh_size);
-	}
-
-	if (para) {
-		void *pseg = (void *)para->sh_addr;
-		apply_paravirt(pseg, pseg + para->sh_size);
-	}
-
-	return module_bug_finalize(hdr, sechdrs, me);
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-	alternatives_smp_module_del(mod);
-	module_bug_cleanup(mod);
-}
Index: linux-2.6/arch/x86/kernel/module_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module_64.c
+++ linux-2.6/arch/x86/kernel/module_64.c
@@ -33,13 +33,6 @@
 #define DEBUGP(fmt...)
 
 #ifndef CONFIG_UML
-void module_free(struct module *mod, void *module_region)
-{
-	vfree(module_region);
-	/* FIXME: If module_region == mod->init_region, trim exception
-	   table entries. */
-}
-
 void *module_alloc(unsigned long size)
 {
 	struct vm_struct *area;
@@ -58,15 +51,6 @@ void *module_alloc(unsigned long size)
 }
 #endif
 
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-			      Elf_Shdr *sechdrs,
-			      char *secstrings,
-			      struct module *mod)
-{
-	return 0;
-}
-
 int apply_relocate_add(Elf64_Shdr *sechdrs,
 		   const char *strtab,
 		   unsigned int symindex,
@@ -147,48 +131,3 @@ int apply_relocate(Elf_Shdr *sechdrs,
 	return -ENOSYS;
 }
 
-int module_finalize(const Elf_Ehdr *hdr,
-		    const Elf_Shdr *sechdrs,
-		    struct module *me)
-{
-	const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
-		*para = NULL;
-	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-
-	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
-		if (!strcmp(".text", secstrings + s->sh_name))
-			text = s;
-		if (!strcmp(".altinstructions", secstrings + s->sh_name))
-			alt = s;
-		if (!strcmp(".smp_locks", secstrings + s->sh_name))
-			locks = s;
-		if (!strcmp(".parainstructions", secstrings + s->sh_name))
-			para = s;
-	}
-
-	if (alt) {
-		/* patch .altinstructions */
-		void *aseg = (void *)alt->sh_addr;
-		apply_alternatives(aseg, aseg + alt->sh_size);
-	}
-	if (locks && text) {
-		void *lseg = (void *)locks->sh_addr;
-		void *tseg = (void *)text->sh_addr;
-		alternatives_smp_module_add(me, me->name,
-					    lseg, lseg + locks->sh_size,
-					    tseg, tseg + text->sh_size);
-	}
-
-	if (para) {
-		void *pseg = (void *)para->sh_addr;
-		apply_paravirt(pseg, pseg + para->sh_size);
-	}
-
-	return module_bug_finalize(hdr, sechdrs, me);
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-	alternatives_smp_module_del(mod);
-	module_bug_cleanup(mod);
-}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Patch 2/4] x86 module: merge the rest functions with macros
  2009-05-26  8:35 [Patch 0/4] module: merge module_32.c and module_64.c Amerigo Wang
  2009-05-26  8:35 ` [Patch 1/4] x86 module: merge the same functions in " Amerigo Wang
@ 2009-05-26  8:35 ` Amerigo Wang
  2009-05-26  9:21   ` Christoph Hellwig
  2009-05-26  8:35 ` [Patch 3/4] uml module: fix uml build process due to this merge Amerigo Wang
  2009-05-26  8:35 ` [Patch 4/4] module: trim exception table in module_free() Amerigo Wang
  3 siblings, 1 reply; 15+ messages in thread
From: Amerigo Wang @ 2009-05-26  8:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, rusty, jdike, mingo, Amerigo Wang


Merge the rest functions together, with preprocessing directives.
Finally remove module_{32|64}.c.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>

---
Index: linux-2.6/arch/x86/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/x86/kernel/Makefile
+++ linux-2.6/arch/x86/kernel/Makefile
@@ -72,7 +72,7 @@ obj-$(CONFIG_KEXEC)		+= machine_kexec_$(
 obj-$(CONFIG_KEXEC)		+= relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_MODULES)		+= module.o module_$(BITS).o
+obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_EFI) 		+= efi.o efi_$(BITS).o efi_stub_$(BITS).o
 obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault_32.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
Index: linux-2.6/arch/x86/kernel/module.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module.c
+++ linux-2.6/arch/x86/kernel/module.c
@@ -34,6 +34,32 @@
 #define DEBUGP(fmt...)
 #endif
 
+#if defined(CONFIG_UML) || defined(CONFIG_X86_32)
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return vmalloc_exec(size);
+}
+#else /*X86_64*/
+void *module_alloc(unsigned long size)
+{
+	struct vm_struct *area;
+
+	if (!size)
+		return NULL;
+	size = PAGE_ALIGN(size);
+	if (size > MODULES_LEN)
+		return NULL;
+
+	area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
+	if (!area)
+		return NULL;
+
+	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
+}
+#endif
+
 /* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
 {
@@ -51,6 +77,140 @@ int module_frob_arch_sections(Elf_Ehdr *
 	return 0;
 }
 
+#ifdef CONFIG_X86_32
+int apply_relocate(Elf32_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	unsigned int i;
+	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	uint32_t *location;
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(rel[i].r_info);
+
+		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_386_32:
+			/* We add the value into the location given */
+			*location += sym->st_value;
+			break;
+		case R_386_PC32:
+			/* Add the value, subtract its postition */
+			*location += sym->st_value - (uint32_t)location;
+			break;
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+			       me->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+	       me->name);
+	return -ENOEXEC;
+}
+#else /*X86_64*/
+int apply_relocate_add(Elf64_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	unsigned int i;
+	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf64_Sym *sym;
+	void *loc;
+	u64 val;
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
+			+ ELF64_R_SYM(rel[i].r_info);
+
+		DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
+			(int)ELF64_R_TYPE(rel[i].r_info),
+			sym->st_value, rel[i].r_addend, (u64)loc);
+
+		val = sym->st_value + rel[i].r_addend;
+
+		switch (ELF64_R_TYPE(rel[i].r_info)) {
+		case R_X86_64_NONE:
+			break;
+		case R_X86_64_64:
+			*(u64 *)loc = val;
+			break;
+		case R_X86_64_32:
+			*(u32 *)loc = val;
+			if (val != *(u32 *)loc)
+				goto overflow;
+			break;
+		case R_X86_64_32S:
+			*(s32 *)loc = val;
+			if ((s64)val != *(s32 *)loc)
+				goto overflow;
+			break;
+		case R_X86_64_PC32:
+			val -= (u64)loc;
+			*(u32 *)loc = val;
+#if 0
+			if ((s64)val != *(s32 *)loc)
+				goto overflow;
+#endif
+			break;
+		default:
+			printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n",
+			       me->name, ELF64_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+
+overflow:
+	printk(KERN_ERR "overflow in relocation type %d val %Lx\n",
+	       (int)ELF64_R_TYPE(rel[i].r_info), val);
+	printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n",
+	       me->name);
+	return -ENOEXEC;
+}
+
+int apply_relocate(Elf_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	printk(KERN_ERR "non add relocation not supported\n");
+	return -ENOSYS;
+}
+
+#endif
+
 int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
Index: linux-2.6/arch/x86/kernel/module_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module_32.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*  Kernel module help for i386.
-    Copyright (C) 2001 Rusty Russell.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/bug.h>
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt...)
-#endif
-
-void *module_alloc(unsigned long size)
-{
-	if (size == 0)
-		return NULL;
-	return vmalloc_exec(size);
-}
-
-
-int apply_relocate(Elf32_Shdr *sechdrs,
-		   const char *strtab,
-		   unsigned int symindex,
-		   unsigned int relsec,
-		   struct module *me)
-{
-	unsigned int i;
-	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
-	Elf32_Sym *sym;
-	uint32_t *location;
-
-	DEBUGP("Applying relocate section %u to %u\n", relsec,
-	       sechdrs[relsec].sh_info);
-	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
-		/* This is where to make the change */
-		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
-			+ rel[i].r_offset;
-		/* This is the symbol it is referring to.  Note that all
-		   undefined symbols have been resolved.  */
-		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
-			+ ELF32_R_SYM(rel[i].r_info);
-
-		switch (ELF32_R_TYPE(rel[i].r_info)) {
-		case R_386_32:
-			/* We add the value into the location given */
-			*location += sym->st_value;
-			break;
-		case R_386_PC32:
-			/* Add the value, subtract its postition */
-			*location += sym->st_value - (uint32_t)location;
-			break;
-		default:
-			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
-			       me->name, ELF32_R_TYPE(rel[i].r_info));
-			return -ENOEXEC;
-		}
-	}
-	return 0;
-}
-
-int apply_relocate_add(Elf32_Shdr *sechdrs,
-		       const char *strtab,
-		       unsigned int symindex,
-		       unsigned int relsec,
-		       struct module *me)
-{
-	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
-	       me->name);
-	return -ENOEXEC;
-}
-
Index: linux-2.6/arch/x86/kernel/module_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module_64.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*  Kernel module help for x86-64
-    Copyright (C) 2001 Rusty Russell.
-    Copyright (C) 2002,2003 Andi Kleen, SuSE Labs.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/bug.h>
-
-#include <asm/system.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#define DEBUGP(fmt...)
-
-#ifndef CONFIG_UML
-void *module_alloc(unsigned long size)
-{
-	struct vm_struct *area;
-
-	if (!size)
-		return NULL;
-	size = PAGE_ALIGN(size);
-	if (size > MODULES_LEN)
-		return NULL;
-
-	area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
-	if (!area)
-		return NULL;
-
-	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
-}
-#endif
-
-int apply_relocate_add(Elf64_Shdr *sechdrs,
-		   const char *strtab,
-		   unsigned int symindex,
-		   unsigned int relsec,
-		   struct module *me)
-{
-	unsigned int i;
-	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
-	Elf64_Sym *sym;
-	void *loc;
-	u64 val;
-
-	DEBUGP("Applying relocate section %u to %u\n", relsec,
-	       sechdrs[relsec].sh_info);
-	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
-		/* This is where to make the change */
-		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
-			+ rel[i].r_offset;
-
-		/* This is the symbol it is referring to.  Note that all
-		   undefined symbols have been resolved.  */
-		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
-			+ ELF64_R_SYM(rel[i].r_info);
-
-		DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
-			(int)ELF64_R_TYPE(rel[i].r_info),
-			sym->st_value, rel[i].r_addend, (u64)loc);
-
-		val = sym->st_value + rel[i].r_addend;
-
-		switch (ELF64_R_TYPE(rel[i].r_info)) {
-		case R_X86_64_NONE:
-			break;
-		case R_X86_64_64:
-			*(u64 *)loc = val;
-			break;
-		case R_X86_64_32:
-			*(u32 *)loc = val;
-			if (val != *(u32 *)loc)
-				goto overflow;
-			break;
-		case R_X86_64_32S:
-			*(s32 *)loc = val;
-			if ((s64)val != *(s32 *)loc)
-				goto overflow;
-			break;
-		case R_X86_64_PC32:
-			val -= (u64)loc;
-			*(u32 *)loc = val;
-#if 0
-			if ((s64)val != *(s32 *)loc)
-				goto overflow;
-#endif
-			break;
-		default:
-			printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n",
-			       me->name, ELF64_R_TYPE(rel[i].r_info));
-			return -ENOEXEC;
-		}
-	}
-	return 0;
-
-overflow:
-	printk(KERN_ERR "overflow in relocation type %d val %Lx\n",
-	       (int)ELF64_R_TYPE(rel[i].r_info), val);
-	printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n",
-	       me->name);
-	return -ENOEXEC;
-}
-
-int apply_relocate(Elf_Shdr *sechdrs,
-		   const char *strtab,
-		   unsigned int symindex,
-		   unsigned int relsec,
-		   struct module *me)
-{
-	printk(KERN_ERR "non add relocation not supported\n");
-	return -ENOSYS;
-}
-

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Patch 3/4] uml module: fix uml build process due to this merge
  2009-05-26  8:35 [Patch 0/4] module: merge module_32.c and module_64.c Amerigo Wang
  2009-05-26  8:35 ` [Patch 1/4] x86 module: merge the same functions in " Amerigo Wang
  2009-05-26  8:35 ` [Patch 2/4] x86 module: merge the rest functions with macros Amerigo Wang
@ 2009-05-26  8:35 ` Amerigo Wang
  2009-05-26  8:35 ` [Patch 4/4] module: trim exception table in module_free() Amerigo Wang
  3 siblings, 0 replies; 15+ messages in thread
From: Amerigo Wang @ 2009-05-26  8:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, rusty, jdike, mingo, Amerigo Wang


Due to the previous merge, uml needs to be fixed.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Jeff Dike <jdike@addtoit.com>

---
Index: linux-2.6/arch/um/sys-i386/Makefile
===================================================================
--- linux-2.6.orig/arch/um/sys-i386/Makefile
+++ linux-2.6/arch/um/sys-i386/Makefile
@@ -8,7 +8,7 @@ obj-y = bug.o bugs.o checksum.o delay.o 
 
 subarch-obj-y = lib/semaphore_32.o lib/string_32.o
 subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
-subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o
+subarch-obj-$(CONFIG_MODULES) += kernel/module.o
 
 USER_OBJS := bugs.o ptrace_user.o fault.o
 
Index: linux-2.6/arch/um/sys-x86_64/Makefile
===================================================================
--- linux-2.6.orig/arch/um/sys-x86_64/Makefile
+++ linux-2.6/arch/um/sys-x86_64/Makefile
@@ -8,10 +8,8 @@ obj-y = bug.o bugs.o delay.o fault.o ldt
 	setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \
 	sysrq.o ksyms.o tls.o
 
-obj-$(CONFIG_MODULES) += um_module.o
-
 subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
-subarch-obj-$(CONFIG_MODULES) += kernel/module_64.o
+subarch-obj-$(CONFIG_MODULES) += kernel/module.o
 
 ldt-y = ../sys-i386/ldt.o
 
Index: linux-2.6/arch/um/sys-x86_64/um_module.c
===================================================================
--- linux-2.6.orig/arch/um/sys-x86_64/um_module.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <linux/vmalloc.h>
-#include <linux/moduleloader.h>
-
-/* Copied from i386 arch/i386/kernel/module.c */
-void *module_alloc(unsigned long size)
-{
-	if (size == 0)
-		return NULL;
-	return vmalloc_exec(size);
-}
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-	vfree(module_region);
-	/*
-	 * FIXME: If module_region == mod->init_region, trim exception
-	 * table entries.
-	 */
-}
-

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Patch 4/4] module: trim exception table in module_free()
  2009-05-26  8:35 [Patch 0/4] module: merge module_32.c and module_64.c Amerigo Wang
                   ` (2 preceding siblings ...)
  2009-05-26  8:35 ` [Patch 3/4] uml module: fix uml build process due to this merge Amerigo Wang
@ 2009-05-26  8:35 ` Amerigo Wang
  2009-05-27  2:21   ` Rusty Russell
  3 siblings, 1 reply; 15+ messages in thread
From: Amerigo Wang @ 2009-05-26  8:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, rusty, jdike, mingo, Amerigo Wang


Just as the comment said, trim the exception table entries when
module_free() mod->module_init.

Signed-off-by: WANG Cong <amwang@redhat.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>

---
Index: linux-2.6/arch/x86/kernel/module.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/module.c
+++ linux-2.6/arch/x86/kernel/module.c
@@ -64,8 +64,8 @@ void *module_alloc(unsigned long size)
 void module_free(struct module *mod, void *module_region)
 {
 	vfree(module_region);
-	/* FIXME: If module_region == mod->init_region, trim exception
-	   table entries. */
+	if (module_region == mod->module_init)
+		mod->num_exentries = 0;
 }
 
 /* We don't need anything special. */

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 2/4] x86 module: merge the rest functions with macros
  2009-05-26  8:35 ` [Patch 2/4] x86 module: merge the rest functions with macros Amerigo Wang
@ 2009-05-26  9:21   ` Christoph Hellwig
  2009-05-26 10:02     ` Amerigo Wang
  0 siblings, 1 reply; 15+ messages in thread
From: Christoph Hellwig @ 2009-05-26  9:21 UTC (permalink / raw)
  To: Amerigo Wang; +Cc: linux-kernel, akpm, rusty, jdike, mingo

On Tue, May 26, 2009 at 04:35:22AM -0400, Amerigo Wang wrote:
> +#if defined(CONFIG_UML) || defined(CONFIG_X86_32)
> +void *module_alloc(unsigned long size)
> +{
> +	if (size == 0)
> +		return NULL;
> +	return vmalloc_exec(size);
> +}
> +#else /*X86_64*/
> +void *module_alloc(unsigned long size)
> +{
> +	struct vm_struct *area;
> +
> +	if (!size)
> +		return NULL;
> +	size = PAGE_ALIGN(size);
> +	if (size > MODULES_LEN)
> +		return NULL;
> +
> +	area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
> +	if (!area)
> +		return NULL;
> +
> +	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
> +}
> +#endif

vmalloc_exec basically expands to the x86-64 version of that code, just
using VMALLOC_START/VMALLOC_END instead of MODULES_VADDR/MODULES_END.

So instead of having two variants it would be better to use the x86-64
unconditionally and define MODULES_VADDR/MODULES_END to
VMALLOC_START/VMALLOC_END to 32bit and uml.

And that part should be a patch of it's own, not mixed with others.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 2/4] x86 module: merge the rest functions with macros
  2009-05-26  9:21   ` Christoph Hellwig
@ 2009-05-26 10:02     ` Amerigo Wang
  0 siblings, 0 replies; 15+ messages in thread
From: Amerigo Wang @ 2009-05-26 10:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-kernel, akpm, rusty, jdike, mingo

Christoph Hellwig wrote:
> On Tue, May 26, 2009 at 04:35:22AM -0400, Amerigo Wang wrote:
>   
>> +#if defined(CONFIG_UML) || defined(CONFIG_X86_32)
>> +void *module_alloc(unsigned long size)
>> +{
>> +	if (size == 0)
>> +		return NULL;
>> +	return vmalloc_exec(size);
>> +}
>> +#else /*X86_64*/
>> +void *module_alloc(unsigned long size)
>> +{
>> +	struct vm_struct *area;
>> +
>> +	if (!size)
>> +		return NULL;
>> +	size = PAGE_ALIGN(size);
>> +	if (size > MODULES_LEN)
>> +		return NULL;
>> +
>> +	area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
>> +	if (!area)
>> +		return NULL;
>> +
>> +	return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
>> +}
>> +#endif
>>     
>
> vmalloc_exec basically expands to the x86-64 version of that code, just
> using VMALLOC_START/VMALLOC_END instead of MODULES_VADDR/MODULES_END.
>
> So instead of having two variants it would be better to use the x86-64
> unconditionally and define MODULES_VADDR/MODULES_END to
> VMALLOC_START/VMALLOC_END to 32bit and uml.
>
> And that part should be a patch of it's own, not mixed with others.
>   

Thanks, it is a good idea!

But... vmalloc_exec() also sets __GFP_HIGHMEM, this is different from 
x86_64.
No? Or __GFP_HIGHMEM is meaningless on x86_64? :-)



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 4/4] module: trim exception table in module_free()
  2009-05-26  8:35 ` [Patch 4/4] module: trim exception table in module_free() Amerigo Wang
@ 2009-05-27  2:21   ` Rusty Russell
  2009-05-27  3:11     ` Amerigo Wang
  0 siblings, 1 reply; 15+ messages in thread
From: Rusty Russell @ 2009-05-27  2:21 UTC (permalink / raw)
  To: Amerigo Wang, linux-alpha
  Cc: linux-kernel, akpm, jdike, mingo, sparclinux, linux-ia64

On Tue, 26 May 2009 06:05:39 pm Amerigo Wang wrote:
>  void module_free(struct module *mod, void *module_region)
>  {
>  	vfree(module_region);
> -	/* FIXME: If module_region == mod->init_region, trim exception
> -	   table entries. */
> +	if (module_region == mod->module_init)
> +		mod->num_exentries = 0;
>  }

Hi Amerigo,

   This looks wrong.  The extable covers both init and core exception entries.   
We want to remove the ones in the module_init section.  The good news is that 
it's sorted, so they're either at the start or the end (except sparc 32).

  The bad news is that this is really a generic problem, and deserves a 
generic fix.  That's easy for archs which use the generic sort_extable(), but 
alpha, ia64 and sparc(32) will need to define their own trim_extable().

Thanks!
Rusty.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 4/4] module: trim exception table in module_free()
  2009-05-27  2:21   ` Rusty Russell
@ 2009-05-27  3:11     ` Amerigo Wang
  2009-05-27  5:23       ` Rusty Russell
  0 siblings, 1 reply; 15+ messages in thread
From: Amerigo Wang @ 2009-05-27  3:11 UTC (permalink / raw)
  To: Rusty Russell
  Cc: linux-alpha, linux-kernel, akpm, jdike, mingo, sparclinux, linux-ia64

Rusty Russell wrote:
> On Tue, 26 May 2009 06:05:39 pm Amerigo Wang wrote:
>   
>>  void module_free(struct module *mod, void *module_region)
>>  {
>>  	vfree(module_region);
>> -	/* FIXME: If module_region == mod->init_region, trim exception
>> -	   table entries. */
>> +	if (module_region == mod->module_init)
>> +		mod->num_exentries = 0;
>>  }
>>     
>
> Hi Amerigo,
>
>    This looks wrong.  The extable covers both init and core exception entries.   
> We want to remove the ones in the module_init section.  The good news is that 
> it's sorted, so they're either at the start or the end (except sparc 32).
>   

Hi, Rusty.

Yes? The extable of a module is in '__ex_table' section, and during the 
section transfer, one
section will be either in module_init or module_core, so its entries are 
only in one of them,
not both, right?

Thank you.





^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 4/4] module: trim exception table in module_free()
  2009-05-27  3:11     ` Amerigo Wang
@ 2009-05-27  5:23       ` Rusty Russell
  2009-05-27  5:48         ` Amerigo Wang
  2009-05-27  7:46         ` Amerigo Wang
  0 siblings, 2 replies; 15+ messages in thread
From: Rusty Russell @ 2009-05-27  5:23 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-alpha, linux-kernel, akpm, jdike, mingo, sparclinux, linux-ia64

On Wed, 27 May 2009 12:41:00 pm Amerigo Wang wrote:
> Rusty Russell wrote:
> > On Tue, 26 May 2009 06:05:39 pm Amerigo Wang wrote:
> >>  void module_free(struct module *mod, void *module_region)
> >>  {
> >>  	vfree(module_region);
> >> -	/* FIXME: If module_region == mod->init_region, trim exception
> >> -	   table entries. */
> >> +	if (module_region == mod->module_init)
> >> +		mod->num_exentries = 0;
> >>  }
> >
> > Hi Amerigo,
> >
> >    This looks wrong.  The extable covers both init and core exception
> > entries. We want to remove the ones in the module_init section.  The good
> > news is that it's sorted, so they're either at the start or the end
> > (except sparc 32).
>
> Hi, Rusty.
>
> Yes? The extable of a module is in '__ex_table' section, and during the
> section transfer, one
> section will be either in module_init or module_core, so its entries are
> only in one of them,
> not both, right?

32-bit example:

#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/moduleparam.h>

static unsigned long uaddr;
module_param(uaddr, ulong, 0600);

void extable_not_init(u64 val)
{
	__put_user(val, (u64 *)uaddr);
}

static int __init init(void)
{
	__put_user(0, (u64 *)uaddr);
	return 0;
}
module_init(init);

__ex_table ends up with two entries:

Contents of section __ex_table:
 0000 0c000000 00000000 0e000000 00000000  ................
 0010 10000000 0a000000 12000000 0a000000  ................

The first is for the __put_user in .text (extable_not_init()) and the second is 
for the one in .init.text (init()).

Depending on how the module gets allocated, the one referring to .init.text 
may be first or last.

(You can see here why we haven't fixed this: exceptions in __init in modules 
are rare, perhaps non-existent).

Hope that clarifies?
Rusty.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 4/4] module: trim exception table in module_free()
  2009-05-27  5:23       ` Rusty Russell
@ 2009-05-27  5:48         ` Amerigo Wang
  2009-05-27  7:46         ` Amerigo Wang
  1 sibling, 0 replies; 15+ messages in thread
From: Amerigo Wang @ 2009-05-27  5:48 UTC (permalink / raw)
  To: Rusty Russell
  Cc: linux-alpha, linux-kernel, akpm, jdike, mingo, sparclinux, linux-ia64

Rusty Russell wrote:
> __ex_table ends up with two entries:
>
> Contents of section __ex_table:
>  0000 0c000000 00000000 0e000000 00000000  ................
>  0010 10000000 0a000000 12000000 0a000000  ................
>
> The first is for the __put_user in .text (extable_not_init()) and the second is 
> for the one in .init.text (init()).
>
> Depending on how the module gets allocated, the one referring to .init.text 
> may be first or last.
>   

Hmm, I understand now. The problem is that we don't know which entries
are for __init, and which are not...

> (You can see here why we haven't fixed this: exceptions in __init in modules 
> are rare, perhaps non-existent).
>   
Agreed.
Is it possible to put extable for __init in a separate section?

Thanks for your explanation!


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 4/4] module: trim exception table in module_free()
  2009-05-27  5:23       ` Rusty Russell
  2009-05-27  5:48         ` Amerigo Wang
@ 2009-05-27  7:46         ` Amerigo Wang
  2009-05-28  6:55           ` Rusty Russell
  1 sibling, 1 reply; 15+ messages in thread
From: Amerigo Wang @ 2009-05-27  7:46 UTC (permalink / raw)
  To: Rusty Russell
  Cc: linux-alpha, linux-kernel, akpm, jdike, mingo, sparclinux, linux-ia64

Rusty Russell wrote:
> __ex_table ends up with two entries:
>
> Contents of section __ex_table:
>  0000 0c000000 00000000 0e000000 00000000  ................
>  0010 10000000 0a000000 12000000 0a000000  ................
>
> The first is for the __put_user in .text (extable_not_init()) and the second is 
> for the one in .init.text (init()).
>
> Depending on how the module gets allocated, the one referring to .init.text 
> may be first or last.
>   

Hmm, how about the following? :-)

struct exception_table_entry *p = mod->extable;

for (;p <= mod->extable+mod->num_exentries; p++ )
         if (with_in_module_init(p->insn, mod))
                   trim_it(p);




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 4/4] module: trim exception table in module_free()
  2009-05-27  7:46         ` Amerigo Wang
@ 2009-05-28  6:55           ` Rusty Russell
  2009-05-31  5:15             ` Amerigo Wang
  0 siblings, 1 reply; 15+ messages in thread
From: Rusty Russell @ 2009-05-28  6:55 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-alpha, linux-kernel, akpm, jdike, mingo, sparclinux, linux-ia64

On Wed, 27 May 2009 05:16:11 pm Amerigo Wang wrote:
> Rusty Russell wrote:
> > __ex_table ends up with two entries:
> >
> > Contents of section __ex_table:
> >  0000 0c000000 00000000 0e000000 00000000  ................
> >  0010 10000000 0a000000 12000000 0a000000  ................
> >
> > The first is for the __put_user in .text (extable_not_init()) and the
> > second is for the one in .init.text (init()).
> >
> > Depending on how the module gets allocated, the one referring to
> > .init.text may be first or last.
>
> Hmm, how about the following? :-)
>
> struct exception_table_entry *p = mod->extable;
>
> for (;p <= mod->extable+mod->num_exentries; p++ )
>          if (with_in_module_init(p->insn, mod))
>                    trim_it(p);

More like this:

void trim_init_extable(struct module *m)
{
	/* Since entries are sorted, init entries are at the start... */
	while (m->num_exentries && within_module_init(m->extable[0].insn)) {
		m->extable++;
		m->num_exentries--;
	}

	/* ... or the end. */
	while (m->num_exentries && within_module_init(m->extable[m->num_exentries-1].insn))
		m->num_exentries--;
}

Cheers,
Rusty.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 4/4] module: trim exception table in module_free()
  2009-05-28  6:55           ` Rusty Russell
@ 2009-05-31  5:15             ` Amerigo Wang
  2009-06-01 12:28               ` Rusty Russell
  0 siblings, 1 reply; 15+ messages in thread
From: Amerigo Wang @ 2009-05-31  5:15 UTC (permalink / raw)
  To: Rusty Russell
  Cc: linux-alpha, linux-kernel, akpm, jdike, mingo, sparclinux, linux-ia64

Rusty Russell wrote:
> On Wed, 27 May 2009 05:16:11 pm Amerigo Wang wrote:
>   
>> Rusty Russell wrote:
>>     
>>> __ex_table ends up with two entries:
>>>
>>> Contents of section __ex_table:
>>>  0000 0c000000 00000000 0e000000 00000000  ................
>>>  0010 10000000 0a000000 12000000 0a000000  ................
>>>
>>> The first is for the __put_user in .text (extable_not_init()) and the
>>> second is for the one in .init.text (init()).
>>>
>>> Depending on how the module gets allocated, the one referring to
>>> .init.text may be first or last.
>>>       
>> Hmm, how about the following? :-)
>>
>> struct exception_table_entry *p = mod->extable;
>>
>> for (;p <= mod->extable+mod->num_exentries; p++ )
>>          if (with_in_module_init(p->insn, mod))
>>                    trim_it(p);
>>     
>
> More like this:
>
> void trim_init_extable(struct module *m)
> {
> 	/* Since entries are sorted, init entries are at the start... */
> 	while (m->num_exentries && within_module_init(m->extable[0].insn)) {
> 		m->extable++;
> 		m->num_exentries--;
> 	}
>
> 	/* ... or the end. */
> 	while (m->num_exentries && within_module_init(m->extable[m->num_exentries-1].insn))
> 		m->num_exentries--;
> }
>   

Great! Thank you!
But does this works on all arch? Or only except sparc32?


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch 4/4] module: trim exception table in module_free()
  2009-05-31  5:15             ` Amerigo Wang
@ 2009-06-01 12:28               ` Rusty Russell
  0 siblings, 0 replies; 15+ messages in thread
From: Rusty Russell @ 2009-06-01 12:28 UTC (permalink / raw)
  To: Amerigo Wang
  Cc: linux-alpha, linux-kernel, akpm, jdike, mingo, sparclinux, linux-ia64

On Sun, 31 May 2009 02:45:44 pm Amerigo Wang wrote:
> Rusty Russell wrote:
> > On Wed, 27 May 2009 05:16:11 pm Amerigo Wang wrote:
> >> Rusty Russell wrote:
> >>> __ex_table ends up with two entries:
> >>>
> >>> Contents of section __ex_table:
> >>>  0000 0c000000 00000000 0e000000 00000000  ................
> >>>  0010 10000000 0a000000 12000000 0a000000  ................
> >>>
> >>> The first is for the __put_user in .text (extable_not_init()) and the
> >>> second is for the one in .init.text (init()).
> >>>
> >>> Depending on how the module gets allocated, the one referring to
> >>> .init.text may be first or last.
> >>
> >> Hmm, how about the following? :-)
> >>
> >> struct exception_table_entry *p = mod->extable;
> >>
> >> for (;p <= mod->extable+mod->num_exentries; p++ )
> >>          if (with_in_module_init(p->insn, mod))
> >>                    trim_it(p);
> >
> > More like this:
> >
> > void trim_init_extable(struct module *m)
> > {
> > 	/* Since entries are sorted, init entries are at the start... */
> > 	while (m->num_exentries && within_module_init(m->extable[0].insn)) {
> > 		m->extable++;
> > 		m->num_exentries--;
> > 	}
> >
> > 	/* ... or the end. */
> > 	while (m->num_exentries &&
> > within_module_init(m->extable[m->num_exentries-1].insn))
> > m->num_exentries--;
> > }
>
> Great! Thank you!
> But does this works on all arch? Or only except sparc32?

Variations will work on all archs.  sparc32 doesn't sort its exception table 
AFAICT, so it will need something more sophisticated (ISTR they have exception 
areas, so perhaps setting length to 0 would 'delete' them).

Hope that helps,
Rusty.


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2009-06-01 12:29 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-26  8:35 [Patch 0/4] module: merge module_32.c and module_64.c Amerigo Wang
2009-05-26  8:35 ` [Patch 1/4] x86 module: merge the same functions in " Amerigo Wang
2009-05-26  8:35 ` [Patch 2/4] x86 module: merge the rest functions with macros Amerigo Wang
2009-05-26  9:21   ` Christoph Hellwig
2009-05-26 10:02     ` Amerigo Wang
2009-05-26  8:35 ` [Patch 3/4] uml module: fix uml build process due to this merge Amerigo Wang
2009-05-26  8:35 ` [Patch 4/4] module: trim exception table in module_free() Amerigo Wang
2009-05-27  2:21   ` Rusty Russell
2009-05-27  3:11     ` Amerigo Wang
2009-05-27  5:23       ` Rusty Russell
2009-05-27  5:48         ` Amerigo Wang
2009-05-27  7:46         ` Amerigo Wang
2009-05-28  6:55           ` Rusty Russell
2009-05-31  5:15             ` Amerigo Wang
2009-06-01 12:28               ` Rusty Russell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).