From: Harvey Harrison <harvey.harrison@gmail.com>
To: Hirokazu Takata <takata@linux-m32r.org>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: [PATCH] m32r: module.c use kernel-provided unaligned helpers
Date: Wed, 28 May 2008 16:30:47 -0700 [thread overview]
Message-ID: <1212017447.20781.4.camel@brick> (raw)
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
reply other threads:[~2008-05-28 23:30 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1212017447.20781.4.camel@brick \
--to=harvey.harrison@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=takata@linux-m32r.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.