Commit 9f7470bf authored by Miles Bader's avatar Miles Bader Committed by Linus Torvalds

[PATCH] Update v850 module support for 2.5.55

parent 63986a43
/* /*
* arch/v850/kernel/module.c -- Architecture-specific module functions * arch/v850/kernel/module.c -- Architecture-specific module functions
* *
* Copyright (C) 2002 NEC Corporation * Copyright (C) 2002,03 NEC Electronics Corporation
* Copyright (C) 2002 Miles Bader <miles@gnu.org> * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
* Copyright (C) 2001 Rusty Russell * Copyright (C) 2001,03 Rusty Russell
* *
* This file is subject to the terms and conditions of the GNU General * 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 * 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, ...@@ -100,18 +100,31 @@ static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
return ret; return ret;
} }
long module_core_size (const Elf32_Ehdr *hdr, const Elf32_Shdr *sechdrs, int module_frob_arch_sections(Elf32_Ehdr *hdr,
const char *secstrings, struct module *mod) Elf32_Shdr *sechdrs,
char *secstrings,
struct module *me)
{ {
mod->arch.core_plt_offset = (mod->core_size + 3) & ~3; unsigned int i;
return mod->core_size + get_plt_size (hdr, sechdrs, secstrings, 1);
}
long module_init_size (const Elf32_Ehdr *hdr, const Elf32_Shdr *sechdrs, /* Find .plt and .pltinit sections */
const char *secstrings, struct module *mod) for (i = 0; i < hdr->e_shnum; i++) {
{ if (strcmp(secstrings + sechdrs[i].sh_name, ".init.plt") == 0)
mod->arch.init_plt_offset = (mod->init_size + 3) & ~3; me->arch.init_plt_section = i;
return mod->init_size + get_plt_size (hdr, sechdrs, secstrings, 1); 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, int apply_relocate (Elf32_Shdr *sechdrs, const char *strtab,
...@@ -123,7 +136,8 @@ 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 */ /* 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; struct v850_plt_entry *entry;
/* Instructions used to do the indirect jump. */ /* 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) ...@@ -137,10 +151,10 @@ static uint32_t do_plt_call(void *location, Elf32_Addr val, struct module *mod)
/* Init, or core PLT? */ /* Init, or core PLT? */
if (location >= mod->module_core if (location >= mod->module_core
&& location < mod->module_core + mod->arch.core_plt_offset) && location < mod->module_core + mod->core_size)
entry = mod->module_core + mod->arch.core_plt_offset; entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
else 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 */ /* Find this entry, or if that fails, the next avail. entry */
while (entry->tramp[0]) while (entry->tramp[0])
...@@ -199,7 +213,7 @@ int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab, ...@@ -199,7 +213,7 @@ int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab,
/* Maybe jump indirectly via a PLT table entry. */ /* Maybe jump indirectly via a PLT table entry. */
if ((int32_t)(val - (uint32_t)loc) > 0x1fffff if ((int32_t)(val - (uint32_t)loc) > 0x1fffff
|| (int32_t)(val - (uint32_t)loc) < -0x200000) || (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; val -= (uint32_t)loc;
......
/* /*
* include/asm-v850/module.h -- Architecture-specific module hooks * include/asm-v850/module.h -- Architecture-specific module hooks
* *
* Copyright (C) 2001,02 NEC Corporation * Copyright (C) 2001,02,03 NEC Corporation
* Copyright (C) 2001,02 Miles Bader <miles@gnu.org> * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
* Copyright (C) 2001 Rusty Russell * Copyright (C) 2001,03 Rusty Russell
* *
* This file is subject to the terms and conditions of the GNU General * 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 * Public License. See the file COPYING in the main directory of this
...@@ -27,16 +27,28 @@ struct v850_plt_entry ...@@ -27,16 +27,28 @@ struct v850_plt_entry
struct mod_arch_specific struct mod_arch_specific
{ {
/* How much of the core is actually taken up with core (then /* Indices of PLT sections within module. */
we know the rest is for the PLT). */ unsigned int core_plt_section, init_plt_section;
unsigned int core_plt_offset;
/* Same for init. */
unsigned int init_plt_offset;
}; };
#define Elf_Shdr Elf32_Shdr #define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym #define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr #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__ */ #endif /* __V850_MODULE_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment