summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@lsi.nec.co.jp>2003-01-10 04:42:21 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2003-01-10 04:42:21 -0800
commit9f7470bf90a908c6f1b908eeaa014f2b3cc4da28 (patch)
treefc3f4a2d7dfa0a4f4addb36e003b805f773c3bdd
parent63986a43f9687d4afeedc698d9902700f8d1eb48 (diff)
[PATCH] Update v850 module support for 2.5.55
-rw-r--r--arch/v850/kernel/module.c50
-rw-r--r--include/asm-v850/module.h30
2 files changed, 53 insertions, 27 deletions
diff --git a/arch/v850/kernel/module.c b/arch/v850/kernel/module.c
index 437b31f989fb..e2a272433f7e 100644
--- a/arch/v850/kernel/module.c
+++ b/arch/v850/kernel/module.c
@@ -1,9 +1,9 @@
/*
* arch/v850/kernel/module.c -- Architecture-specific module functions
*
- * Copyright (C) 2002 NEC Corporation
- * Copyright (C) 2002 Miles Bader <miles@gnu.org>
- * Copyright (C) 2001 Rusty Russell
+ * Copyright (C) 2002,03 NEC Electronics Corporation
+ * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
+ * Copyright (C) 2001,03 Rusty Russell
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file COPYING in the main directory of this
@@ -100,18 +100,31 @@ static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
return ret;
}
-long module_core_size (const Elf32_Ehdr *hdr, const Elf32_Shdr *sechdrs,
- const char *secstrings, struct module *mod)
+int module_frob_arch_sections(Elf32_Ehdr *hdr,
+ Elf32_Shdr *sechdrs,
+ char *secstrings,
+ struct module *me)
{
- mod->arch.core_plt_offset = (mod->core_size + 3) & ~3;
- return mod->core_size + get_plt_size (hdr, sechdrs, secstrings, 1);
-}
+ unsigned int i;
-long module_init_size (const Elf32_Ehdr *hdr, const Elf32_Shdr *sechdrs,
- const char *secstrings, struct module *mod)
-{
- mod->arch.init_plt_offset = (mod->init_size + 3) & ~3;
- return mod->init_size + get_plt_size (hdr, sechdrs, secstrings, 1);
+ /* Find .plt and .pltinit sections */
+ for (i = 0; i < hdr->e_shnum; i++) {
+ if (strcmp(secstrings + sechdrs[i].sh_name, ".init.plt") == 0)
+ me->arch.init_plt_section = i;
+ else if (strcmp(secstrings + sechdrs[i].sh_name, ".plt") == 0)
+ me->arch.core_plt_section = i;
+ }
+ if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
+ printk("Module doesn't contain .plt or .plt.init sections.\n");
+ return -ENOEXEC;
+ }
+
+ /* Override their sizes */
+ sechdrs[me->arch.core_plt_section].sh_size
+ = get_plt_size(hdr, sechdrs, secstrings, 0);
+ sechdrs[me->arch.init_plt_section].sh_size
+ = get_plt_size(hdr, sechdrs, secstrings, 1);
+ return 0;
}
int apply_relocate (Elf32_Shdr *sechdrs, const char *strtab,
@@ -123,7 +136,8 @@ int apply_relocate (Elf32_Shdr *sechdrs, const char *strtab,
}
/* Set up a trampoline in the PLT to bounce us to the distant function */
-static uint32_t do_plt_call(void *location, Elf32_Addr val, struct module *mod)
+static uint32_t do_plt_call (void *location, Elf32_Addr val,
+ Elf32_Shdr *sechdrs, struct module *mod)
{
struct v850_plt_entry *entry;
/* Instructions used to do the indirect jump. */
@@ -137,10 +151,10 @@ static uint32_t do_plt_call(void *location, Elf32_Addr val, struct module *mod)
/* Init, or core PLT? */
if (location >= mod->module_core
- && location < mod->module_core + mod->arch.core_plt_offset)
- entry = mod->module_core + mod->arch.core_plt_offset;
+ && location < mod->module_core + mod->core_size)
+ entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
else
- entry = mod->module_init + mod->arch.init_plt_offset;
+ entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
/* Find this entry, or if that fails, the next avail. entry */
while (entry->tramp[0])
@@ -199,7 +213,7 @@ int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab,
/* Maybe jump indirectly via a PLT table entry. */
if ((int32_t)(val - (uint32_t)loc) > 0x1fffff
|| (int32_t)(val - (uint32_t)loc) < -0x200000)
- val = do_plt_call (loc, val, mod);
+ val = do_plt_call (loc, val, sechdrs, mod);
val -= (uint32_t)loc;
diff --git a/include/asm-v850/module.h b/include/asm-v850/module.h
index 3067eb592f5b..9b2e1e30033a 100644
--- a/include/asm-v850/module.h
+++ b/include/asm-v850/module.h
@@ -1,9 +1,9 @@
/*
* include/asm-v850/module.h -- Architecture-specific module hooks
*
- * Copyright (C) 2001,02 NEC Corporation
- * Copyright (C) 2001,02 Miles Bader <miles@gnu.org>
- * Copyright (C) 2001 Rusty Russell
+ * Copyright (C) 2001,02,03 NEC Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ * Copyright (C) 2001,03 Rusty Russell
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file COPYING in the main directory of this
@@ -27,16 +27,28 @@ struct v850_plt_entry
struct mod_arch_specific
{
- /* How much of the core is actually taken up with core (then
- we know the rest is for the PLT). */
- unsigned int core_plt_offset;
-
- /* Same for init. */
- unsigned int init_plt_offset;
+ /* Indices of PLT sections within module. */
+ unsigned int core_plt_section, init_plt_section;
};
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+/* Make empty sections for module_frob_arch_sections to expand. */
+#ifdef MODULE
+asm(".section .plt,\"ax\",@nobits; .align 3; .previous");
+asm(".section .init.plt,\"ax\",@nobits; .align 3; .previous");
+#endif
+
+/* We don't do exception tables. */
+struct exception_table_entry;
+static inline const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value)
+{
+ return 0;
+}
+
#endif /* __V850_MODULE_H__ */