aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/module.c')
-rw-r--r--arch/sh/kernel/module.c88
1 files changed, 16 insertions, 72 deletions
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index b3d0a03b4c7..1b525dedd29 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -27,62 +27,12 @@
#include <linux/moduleloader.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
+#include <linux/bug.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
-
-void *module_alloc(unsigned long size)
-{
- if (size == 0)
- return NULL;
- return vmalloc(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;
-}
-
-#ifdef CONFIG_SUPERH32
-#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; \
- } \
-}
-#else
-/* One thing SHmedia doesn't screw up! */
-#define COPY_UNALIGNED_WORD(sw, tw, align) { (tw) = (sw); }
-#endif
+#include <asm/unaligned.h>
+#include <asm/dwarf.h>
int apply_relocate_add(Elf32_Shdr *sechdrs,
const char *strtab,
@@ -96,7 +46,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
Elf32_Addr relocation;
uint32_t *location;
uint32_t value;
- int align;
pr_debug("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
@@ -109,7 +58,6 @@ 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;
#ifdef CONFIG_SUPERH64
/* For text addresses, bit2 of the st_other field indicates
@@ -117,20 +65,22 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
* SHmedia, the LSB of the symbol needs to be asserted
* for the CPU to be in SHmedia mode when it starts executing
* the branch target. */
- relocation |= (sym->st_other & 4);
+ relocation |= !!(sym->st_other & 4);
#endif
switch (ELF32_R_TYPE(rel[i].r_info)) {
+ case R_SH_NONE:
+ break;
case R_SH_DIR32:
- 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_SH_REL32:
relocation = (relocation - (Elf32_Addr) location);
- 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_SH_IMM_LOW16:
*location = (*location & ~0x3fffc00) |
@@ -159,24 +109,18 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
return 0;
}
-int apply_relocate(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- printk(KERN_ERR "module %s: REL RELOCATION unsupported\n",
- me->name);
- return -ENOEXEC;
-}
-
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
- return 0;
+ int ret = 0;
+
+ ret |= module_dwarf_finalize(hdr, sechdrs, me);
+
+ return ret;
}
void module_arch_cleanup(struct module *mod)
{
+ module_dwarf_cleanup(mod);
}