• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/h8300/kernel/
1#include <linux/moduleloader.h>
2#include <linux/elf.h>
3#include <linux/vmalloc.h>
4#include <linux/fs.h>
5#include <linux/string.h>
6#include <linux/kernel.h>
7
8#define DEBUGP(fmt...)
9
10void *module_alloc(unsigned long size)
11{
12	if (size == 0)
13		return NULL;
14	return vmalloc(size);
15}
16
17
18/* Free memory returned from module_alloc */
19void module_free(struct module *mod, void *module_region)
20{
21	vfree(module_region);
22}
23
24/* We don't need anything special. */
25int module_frob_arch_sections(Elf_Ehdr *hdr,
26			      Elf_Shdr *sechdrs,
27			      char *secstrings,
28			      struct module *mod)
29{
30	return 0;
31}
32
33int apply_relocate(Elf32_Shdr *sechdrs,
34		   const char *strtab,
35		   unsigned int symindex,
36		   unsigned int relsec,
37		   struct module *me)
38{
39	printk(KERN_ERR "module %s: RELOCATION unsupported\n",
40	       me->name);
41	return -ENOEXEC;
42}
43
44int apply_relocate_add(Elf32_Shdr *sechdrs,
45		       const char *strtab,
46		       unsigned int symindex,
47		       unsigned int relsec,
48		       struct module *me)
49{
50	unsigned int i;
51	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
52
53	DEBUGP("Applying relocate section %u to %u\n", relsec,
54	       sechdrs[relsec].sh_info);
55	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
56		/* This is where to make the change */
57		uint32_t *loc = (uint32_t *)(sechdrs[sechdrs[relsec].sh_info].sh_addr
58					     + rela[i].r_offset);
59		/* This is the symbol it is referring to.  Note that all
60		   undefined symbols have been resolved.  */
61		Elf32_Sym *sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
62			+ ELF32_R_SYM(rela[i].r_info);
63		uint32_t v = sym->st_value + rela[i].r_addend;
64
65		switch (ELF32_R_TYPE(rela[i].r_info)) {
66		case R_H8_DIR24R8:
67			loc = (uint32_t *)((uint32_t)loc - 1);
68			*loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
69			break;
70		case R_H8_DIR24A8:
71			if (ELF32_R_SYM(rela[i].r_info))
72				*loc += v;
73			break;
74		case R_H8_DIR32:
75		case R_H8_DIR32A16:
76			*loc += v;
77			break;
78		case R_H8_PCREL16:
79			v -= (unsigned long)loc + 2;
80			if ((Elf32_Sword)v > 0x7fff ||
81			    (Elf32_Sword)v < -(Elf32_Sword)0x8000)
82				goto overflow;
83			else
84				*(unsigned short *)loc = v;
85			break;
86		case R_H8_PCREL8:
87			v -= (unsigned long)loc + 1;
88			if ((Elf32_Sword)v > 0x7f ||
89			    (Elf32_Sword)v < -(Elf32_Sword)0x80)
90				goto overflow;
91			else
92				*(unsigned char *)loc = v;
93			break;
94		default:
95			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
96			       me->name, ELF32_R_TYPE(rela[i].r_info));
97			return -ENOEXEC;
98		}
99	}
100	return 0;
101 overflow:
102	printk(KERN_ERR "module %s: relocation offset overflow: %08x\n",
103	       me->name, rela[i].r_offset);
104	return -ENOEXEC;
105}
106
107int module_finalize(const Elf_Ehdr *hdr,
108		    const Elf_Shdr *sechdrs,
109		    struct module *me)
110{
111	return 0;
112}
113
114void module_arch_cleanup(struct module *mod)
115{
116}
117