All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] m32r: module.c use kernel-provided unaligned helpers
@ 2008-05-28 23:30 Harvey Harrison
  0 siblings, 0 replies; only message in thread
From: Harvey Harrison @ 2008-05-28 23:30 UTC (permalink / raw)
  To: Hirokazu Takata; +Cc: LKML

Replace the hand-rolled COPY_UNALIGNED_WORD/HWORD

This also possibly fixes a bug in the R_M32R_16_RELA case as it was reading
2 bytes from hlocation, applying the relocation, but writing back 4 bytes
(perhaps it meant to use COPY_UNALIGNED_HWORD rather than _WORD) two bytes of
which were not calculated.  This patch writes back only two bytes as hvalue
is a short.

Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
---
 arch/m32r/kernel/module.c |  150 ++++++++++++++++-----------------------------
 1 files changed, 53 insertions(+), 97 deletions(-)

diff --git a/arch/m32r/kernel/module.c b/arch/m32r/kernel/module.c
index 8d42057..375ddf0 100644
--- a/arch/m32r/kernel/module.c
+++ b/arch/m32r/kernel/module.c
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <asm/unaligned.h>
 
 #if 0
 #define DEBUGP printk
@@ -57,46 +58,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
 	return 0;
 }
 
-#define COPY_UNALIGNED_WORD(sw, tw, align) \
-{ \
-	void *__s = &(sw), *__t = &(tw); \
-	unsigned short *__s2 = __s, *__t2 =__t; \
-	unsigned char *__s1 = __s, *__t1 =__t; \
-	switch ((align)) \
-	{ \
-	case 0: \
-		*(unsigned long *) __t = *(unsigned long *) __s; \
-		break; \
-	case 2: \
-		*__t2++ = *__s2++; \
-		*__t2 = *__s2; \
-		break; \
-	default: \
-		*__t1++ = *__s1++; \
-		*__t1++ = *__s1++; \
-		*__t1++ = *__s1++; \
-		*__t1 = *__s1; \
-		break; \
-	} \
-}
-
-#define COPY_UNALIGNED_HWORD(sw, tw, align) \
-  { \
-    void *__s = &(sw), *__t = &(tw); \
-    unsigned short *__s2 = __s, *__t2 =__t; \
-    unsigned char *__s1 = __s, *__t1 =__t; \
-    switch ((align)) \
-    { \
-    case 0: \
-      *__t2 = *__s2; \
-      break; \
-    default: \
-      *__t1++ = *__s1++; \
-      *__t1 = *__s1; \
-      break; \
-    } \
-  }
-
 int apply_relocate_add(Elf32_Shdr *sechdrs,
 		   const char *strtab,
 		   unsigned int symindex,
@@ -112,7 +73,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
 	unsigned short *hlocation;
 	unsigned short hvalue;
 	int svalue;
-	int align;
 
 	DEBUGP("Applying relocate section %u to %u\n", relsec,
 	       sechdrs[relsec].sh_info);
@@ -125,102 +85,98 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
 		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
 			+ ELF32_R_SYM(rel[i].r_info);
 		relocation = sym->st_value + rel[i].r_addend;
-		align = (int)location & 3;
 
 		switch (ELF32_R_TYPE(rel[i].r_info)) {
 		case R_M32R_32_RELA:
-	    		COPY_UNALIGNED_WORD (*location, value, align);
+			value = get_unaligned(location);
 			value += relocation;
-	    		COPY_UNALIGNED_WORD (value, *location, align);
+			put_unaligned(value, location);
 			break;
 		case R_M32R_HI16_ULO_RELA:
-	    		COPY_UNALIGNED_WORD (*location, value, align);
-                        relocation = (relocation >>16) & 0xffff;
+			value = get_unaligned(location);
+			relocation = (relocation >> 16) & 0xffff;
 			/* RELA must has 0 at relocation field. */
 			value += relocation;
-	    		COPY_UNALIGNED_WORD (value, *location, align);
+			put_unaligned(value, location);
 			break;
 		case R_M32R_HI16_SLO_RELA:
-	    		COPY_UNALIGNED_WORD (*location, value, align);
-			if (relocation & 0x8000) relocation += 0x10000;
-                        relocation = (relocation >>16) & 0xffff;
+			value = get_unaligned(location);
+			if (relocation & 0x8000)
+				relocation += 0x10000;
+			relocation = (relocation >> 16) & 0xffff;
 			/* RELA must has 0 at relocation field. */
 			value += relocation;
-	    		COPY_UNALIGNED_WORD (value, *location, align);
+			put_unaligned(value, location);
 			break;
 		case R_M32R_16_RELA:
 			hlocation = (unsigned short *)location;
-                        relocation = relocation & 0xffff;
+			relocation = relocation & 0xffff;
 			/* RELA must has 0 at relocation field. */
 			hvalue = relocation;
-	    		COPY_UNALIGNED_WORD (hvalue, *hlocation, align);
+			put_unaligned(hvalue, hlocation);
 			break;
 		case R_M32R_SDA16_RELA:
 		case R_M32R_LO16_RELA:
-	    		COPY_UNALIGNED_WORD (*location, value, align);
-                        relocation = relocation & 0xffff;
+			value = get_unaligned(location);
+			relocation = relocation & 0xffff;
 			/* RELA must has 0 at relocation field. */
 			value += relocation;
-	    		COPY_UNALIGNED_WORD (value, *location, align);
+			put_unaligned(value, location);
 			break;
 		case R_M32R_24_RELA:
-	    		COPY_UNALIGNED_WORD (*location, value, align);
-                        relocation = relocation & 0xffffff;
+			value = get_unaligned(location);
+			relocation = relocation & 0xffffff;
 			/* RELA must has 0 at relocation field. */
 			value += relocation;
-	    		COPY_UNALIGNED_WORD (value, *location, align);
+			put_unaligned(value, location);
 			break;
 		case R_M32R_18_PCREL_RELA:
-	  		relocation = (relocation - (Elf32_Addr) location);
-			if (relocation < -0x20000 || 0x1fffc < relocation)
-				{
-					printk(KERN_ERR "module %s: relocation overflow: %u\n",
-					me->name, relocation);
-					return -ENOEXEC;
-				}
-	    		COPY_UNALIGNED_WORD (*location, value, align);
-			if (value & 0xffff)
-				{
-					/* RELA must has 0 at relocation field. */
-					printk(KERN_ERR "module %s: illegal relocation field: %u\n",
-					me->name, value);
-					return -ENOEXEC;
-				}
-                        relocation = (relocation >> 2) & 0xffff;
+			relocation = (relocation - (Elf32_Addr) location);
+			if (relocation < -0x20000 || 0x1fffc < relocation) {
+				printk(KERN_ERR "module %s: relocation overflow: %u\n",
+				me->name, relocation);
+				return -ENOEXEC;
+			}
+			value = get_unaligned(location);
+			if (value & 0xffff) {
+				/* RELA must has 0 at relocation field. */
+				printk(KERN_ERR "module %s: illegal relocation field: %u\n",
+				me->name, value);
+				return -ENOEXEC;
+			}
+			relocation = (relocation >> 2) & 0xffff;
 			value += relocation;
-	    		COPY_UNALIGNED_WORD (value, *location, align);
+			put_unaligned(value, location);
 			break;
 		case R_M32R_10_PCREL_RELA:
 			hlocation = (unsigned short *)location;
-	  		relocation = (relocation - (Elf32_Addr) location);
-	    		COPY_UNALIGNED_HWORD (*hlocation, hvalue, align);
+			relocation = (relocation - (Elf32_Addr) location);
+			hvalue = get_unaligned(hlocation);
 			svalue = (int)hvalue;
 			svalue = (signed char)svalue << 2;
 			relocation += svalue;
-                        relocation = (relocation >> 2) & 0xff;
+			relocation = (relocation >> 2) & 0xff;
 			hvalue = hvalue & 0xff00;
 			hvalue += relocation;
-	    		COPY_UNALIGNED_HWORD (hvalue, *hlocation, align);
+			put_unaligned(hvalue, hlocation);
 			break;
 		case R_M32R_26_PCREL_RELA:
-	  		relocation = (relocation - (Elf32_Addr) location);
-			if (relocation < -0x2000000 || 0x1fffffc < relocation)
-				{
-					printk(KERN_ERR "module %s: relocation overflow: %u\n",
-					me->name, relocation);
-					return -ENOEXEC;
-				}
-	    		COPY_UNALIGNED_WORD (*location, value, align);
-			if (value & 0xffffff)
-				{
-					/* RELA must has 0 at relocation field. */
-					printk(KERN_ERR "module %s: illegal relocation field: %u\n",
-					me->name, value);
-					return -ENOEXEC;
-				}
-                        relocation = (relocation >> 2) & 0xffffff;
+			relocation = (relocation - (Elf32_Addr) location);
+			if (relocation < -0x2000000 || 0x1fffffc < relocation) {
+				printk(KERN_ERR "module %s: relocation overflow: %u\n",
+				me->name, relocation);
+				return -ENOEXEC;
+			}
+			value = get_unaligned(location);
+			if (value & 0xffffff) {
+				/* RELA must has 0 at relocation field. */
+				printk(KERN_ERR "module %s: illegal relocation field: %u\n",
+				me->name, value);
+				return -ENOEXEC;
+			}
+			relocation = (relocation >> 2) & 0xffffff;
 			value += relocation;
-	    		COPY_UNALIGNED_WORD (value, *location, align);
+			put_unaligned(value, location);
 			break;
 		default:
 			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
-- 
1.5.6.rc0.277.g804cf




^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-28 23:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-28 23:30 [PATCH] m32r: module.c use kernel-provided unaligned helpers Harvey Harrison

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.