block: fix warning with calling smp_processor_id() in preemptible section
[pandora-kernel.git] / arch / m68k / kernel / module_mm.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file COPYING in the main directory of this archive
4  * for more details.
5  */
6
7 #include <linux/moduleloader.h>
8 #include <linux/elf.h>
9 #include <linux/vmalloc.h>
10 #include <linux/fs.h>
11 #include <linux/string.h>
12 #include <linux/kernel.h>
13
14 #if 0
15 #define DEBUGP printk
16 #else
17 #define DEBUGP(fmt...)
18 #endif
19
20 #ifdef CONFIG_MODULES
21
22 int apply_relocate(Elf32_Shdr *sechdrs,
23                    const char *strtab,
24                    unsigned int symindex,
25                    unsigned int relsec,
26                    struct module *me)
27 {
28         unsigned int i;
29         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
30         Elf32_Sym *sym;
31         uint32_t *location;
32
33         DEBUGP("Applying relocate section %u to %u\n", relsec,
34                sechdrs[relsec].sh_info);
35         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
36                 /* This is where to make the change */
37                 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
38                         + rel[i].r_offset;
39                 /* This is the symbol it is referring to.  Note that all
40                    undefined symbols have been resolved.  */
41                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
42                         + ELF32_R_SYM(rel[i].r_info);
43
44                 switch (ELF32_R_TYPE(rel[i].r_info)) {
45                 case R_68K_32:
46                         /* We add the value into the location given */
47                         *location += sym->st_value;
48                         break;
49                 case R_68K_PC32:
50                         /* Add the value, subtract its postition */
51                         *location += sym->st_value - (uint32_t)location;
52                         break;
53                 default:
54                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
55                                me->name, ELF32_R_TYPE(rel[i].r_info));
56                         return -ENOEXEC;
57                 }
58         }
59         return 0;
60 }
61
62 int apply_relocate_add(Elf32_Shdr *sechdrs,
63                        const char *strtab,
64                        unsigned int symindex,
65                        unsigned int relsec,
66                        struct module *me)
67 {
68         unsigned int i;
69         Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
70         Elf32_Sym *sym;
71         uint32_t *location;
72
73         DEBUGP("Applying relocate_add section %u to %u\n", relsec,
74                sechdrs[relsec].sh_info);
75         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
76                 /* This is where to make the change */
77                 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
78                         + rel[i].r_offset;
79                 /* This is the symbol it is referring to.  Note that all
80                    undefined symbols have been resolved.  */
81                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
82                         + ELF32_R_SYM(rel[i].r_info);
83
84                 switch (ELF32_R_TYPE(rel[i].r_info)) {
85                 case R_68K_32:
86                         /* We add the value into the location given */
87                         *location = rel[i].r_addend + sym->st_value;
88                         break;
89                 case R_68K_PC32:
90                         /* Add the value, subtract its postition */
91                         *location = rel[i].r_addend + sym->st_value - (uint32_t)location;
92                         break;
93                 default:
94                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
95                                me->name, ELF32_R_TYPE(rel[i].r_info));
96                         return -ENOEXEC;
97                 }
98         }
99         return 0;
100 }
101
102 int module_finalize(const Elf_Ehdr *hdr,
103                     const Elf_Shdr *sechdrs,
104                     struct module *mod)
105 {
106         module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
107
108         return 0;
109 }
110
111 #endif /* CONFIG_MODULES */
112
113 void module_fixup(struct module *mod, struct m68k_fixup_info *start,
114                   struct m68k_fixup_info *end)
115 {
116         struct m68k_fixup_info *fixup;
117
118         for (fixup = start; fixup < end; fixup++) {
119                 switch (fixup->type) {
120                 case m68k_fixup_memoffset:
121                         *(u32 *)fixup->addr = m68k_memoffset;
122                         break;
123                 case m68k_fixup_vnode_shift:
124                         *(u16 *)fixup->addr += m68k_virt_to_node_shift;
125                         break;
126                 }
127         }
128 }