Root/target/linux/cobalt/patches-2.6.39/001-no_module_reloc.patch

1--- a/arch/mips/include/asm/module.h
2+++ b/arch/mips/include/asm/module.h
3@@ -9,11 +9,6 @@ struct mod_arch_specific {
4     struct list_head dbe_list;
5     const struct exception_table_entry *dbe_start;
6     const struct exception_table_entry *dbe_end;
7-
8- void *phys_plt_tbl;
9- void *virt_plt_tbl;
10- unsigned int phys_plt_offset;
11- unsigned int virt_plt_offset;
12 };
13 
14 typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
15--- a/arch/mips/kernel/module.c
16+++ b/arch/mips/kernel/module.c
17@@ -45,117 +45,6 @@ static struct mips_hi16 *mips_hi16_list;
18 static LIST_HEAD(dbe_list);
19 static DEFINE_SPINLOCK(dbe_lock);
20 
21-/*
22- * Get the potential max trampolines size required of the init and
23- * non-init sections. Only used if we cannot find enough contiguous
24- * physically mapped memory to put the module into.
25- */
26-static unsigned int
27-get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
28- const char *secstrings, unsigned int symindex, bool is_init)
29-{
30- unsigned long ret = 0;
31- unsigned int i, j;
32- Elf_Sym *syms;
33-
34- /* Everything marked ALLOC (this includes the exported symbols) */
35- for (i = 1; i < hdr->e_shnum; ++i) {
36- unsigned int info = sechdrs[i].sh_info;
37-
38- if (sechdrs[i].sh_type != SHT_REL
39- && sechdrs[i].sh_type != SHT_RELA)
40- continue;
41-
42- /* Not a valid relocation section? */
43- if (info >= hdr->e_shnum)
44- continue;
45-
46- /* Don't bother with non-allocated sections */
47- if (!(sechdrs[info].sh_flags & SHF_ALLOC))
48- continue;
49-
50- /* If it's called *.init*, and we're not init, we're
51- not interested */
52- if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
53- != is_init)
54- continue;
55-
56- syms = (Elf_Sym *) sechdrs[symindex].sh_addr;
57- if (sechdrs[i].sh_type == SHT_REL) {
58- Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr;
59- unsigned int size = sechdrs[i].sh_size / sizeof(*rel);
60-
61- for (j = 0; j < size; ++j) {
62- Elf_Sym *sym;
63-
64- if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26)
65- continue;
66-
67- sym = syms + ELF_MIPS_R_SYM(rel[j]);
68- if (!is_init && sym->st_shndx != SHN_UNDEF)
69- continue;
70-
71- ret += 4 * sizeof(int);
72- }
73- } else {
74- Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr;
75- unsigned int size = sechdrs[i].sh_size / sizeof(*rela);
76-
77- for (j = 0; j < size; ++j) {
78- Elf_Sym *sym;
79-
80- if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26)
81- continue;
82-
83- sym = syms + ELF_MIPS_R_SYM(rela[j]);
84- if (!is_init && sym->st_shndx != SHN_UNDEF)
85- continue;
86-
87- ret += 4 * sizeof(int);
88- }
89- }
90- }
91-
92- return ret;
93-}
94-
95-#ifndef MODULE_START
96-static void *alloc_phys(unsigned long size)
97-{
98- unsigned order;
99- struct page *page;
100- struct page *p;
101-
102- size = PAGE_ALIGN(size);
103- order = get_order(size);
104-
105- page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN |
106- __GFP_THISNODE, order);
107- if (!page)
108- return NULL;
109-
110- split_page(page, order);
111-
112- for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p)
113- __free_page(p);
114-
115- return page_address(page);
116-}
117-#endif
118-
119-static void free_phys(void *ptr, unsigned long size)
120-{
121- struct page *page;
122- struct page *end;
123-
124- page = virt_to_page(ptr);
125- end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT);
126-
127- for (; page < end; ++page)
128- __free_page(page);
129-}
130-
131-
132 void *module_alloc(unsigned long size)
133 {
134 #ifdef MODULE_START
135@@ -163,99 +52,21 @@ void *module_alloc(unsigned long size)
136                 GFP_KERNEL, PAGE_KERNEL, -1,
137                 __builtin_return_address(0));
138 #else
139- void *ptr;
140-
141     if (size == 0)
142         return NULL;
143-
144- ptr = alloc_phys(size);
145-
146- /* If we failed to allocate physically contiguous memory,
147- * fall back to regular vmalloc. The module loader code will
148- * create jump tables to handle long jumps */
149- if (!ptr)
150- return vmalloc(size);
151-
152- return ptr;
153-#endif
154-}
155-
156-static inline bool is_phys_addr(void *ptr)
157-{
158-#ifdef CONFIG_64BIT
159- return (KSEGX((unsigned long)ptr) == CKSEG0);
160-#else
161- return (KSEGX(ptr) == KSEG0);
162+ return vmalloc(size);
163 #endif
164 }
165 
166 /* Free memory returned from module_alloc */
167 void module_free(struct module *mod, void *module_region)
168 {
169- if (is_phys_addr(module_region)) {
170- if (mod->module_init == module_region)
171- free_phys(module_region, mod->init_size);
172- else if (mod->module_core == module_region)
173- free_phys(module_region, mod->core_size);
174- else
175- BUG();
176- } else {
177- vfree(module_region);
178- }
179-}
180-
181-static void *__module_alloc(int size, bool phys)
182-{
183- void *ptr;
184-
185- if (phys)
186- ptr = kmalloc(size, GFP_KERNEL);
187- else
188- ptr = vmalloc(size);
189- return ptr;
190-}
191-
192-static void __module_free(void *ptr)
193-{
194- if (is_phys_addr(ptr))
195- kfree(ptr);
196- else
197- vfree(ptr);
198+ vfree(module_region);
199 }
200 
201 int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
202                   char *secstrings, struct module *mod)
203 {
204- unsigned int symindex = 0;
205- unsigned int core_size, init_size;
206- int i;
207-
208- for (i = 1; i < hdr->e_shnum; i++)
209- if (sechdrs[i].sh_type == SHT_SYMTAB)
210- symindex = i;
211-
212- core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false);
213- init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true);
214-
215- mod->arch.phys_plt_offset = 0;
216- mod->arch.virt_plt_offset = 0;
217- mod->arch.phys_plt_tbl = NULL;
218- mod->arch.virt_plt_tbl = NULL;
219-
220- if ((core_size + init_size) == 0)
221- return 0;
222-
223- mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1);
224- if (!mod->arch.phys_plt_tbl)
225- return -ENOMEM;
226-
227- mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0);
228- if (!mod->arch.virt_plt_tbl) {
229- __module_free(mod->arch.phys_plt_tbl);
230- mod->arch.phys_plt_tbl = NULL;
231- return -ENOMEM;
232- }
233-
234     return 0;
235 }
236 
237@@ -278,36 +89,28 @@ static int apply_r_mips_32_rela(struct m
238     return 0;
239 }
240 
241-static Elf_Addr add_plt_entry_to(unsigned *plt_offset,
242- void *start, Elf_Addr v)
243+static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
244 {
245- unsigned *tramp = start + *plt_offset;
246- *plt_offset += 4 * sizeof(int);
247-
248- /* adjust carry for addiu */
249- if (v & 0x00008000)
250- v += 0x10000;
251-
252- tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */
253- tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */
254- tramp[2] = 0x03200008; /* jr t9 */
255- tramp[3] = 0x00000000; /* nop */
256+ if (v % 4) {
257+ pr_err("module %s: dangerous R_MIPS_26 REL relocation\n",
258+ me->name);
259+ return -ENOEXEC;
260+ }
261 
262- return (Elf_Addr) tramp;
263-}
264+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
265+ printk(KERN_ERR
266+ "module %s: relocation overflow\n",
267+ me->name);
268+ return -ENOEXEC;
269+ }
270 
271-static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v)
272-{
273- if (is_phys_addr(location))
274- return add_plt_entry_to(&me->arch.phys_plt_offset,
275- me->arch.phys_plt_tbl, v);
276- else
277- return add_plt_entry_to(&me->arch.virt_plt_offset,
278- me->arch.virt_plt_tbl, v);
279+ *location = (*location & ~0x03ffffff) |
280+ ((*location + (v >> 2)) & 0x03ffffff);
281 
282+ return 0;
283 }
284 
285-static int set_r_mips_26(struct module *me, u32 *location, u32 ofs, Elf_Addr v)
286+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
287 {
288     if (v % 4) {
289         pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
290@@ -316,31 +119,17 @@ static int set_r_mips_26(struct module *
291     }
292 
293     if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
294- v = add_plt_entry(me, location, v + (ofs << 2));
295- if (!v) {
296- printk(KERN_ERR
297+ printk(KERN_ERR
298                "module %s: relocation overflow\n",
299                me->name);
300- return -ENOEXEC;
301- }
302- ofs = 0;
303+ return -ENOEXEC;
304     }
305 
306- *location = (*location & ~0x03ffffff) | ((ofs + (v >> 2)) & 0x03ffffff);
307+ *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
308 
309     return 0;
310 }
311 
312-static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
313-{
314- return set_r_mips_26(me, location, *location & 0x03ffffff, v);
315-}
316-
317-static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
318-{
319- return set_r_mips_26(me, location, 0, v);
320-}
321-
322 static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
323 {
324     struct mips_hi16 *n;
325@@ -608,32 +397,11 @@ int module_finalize(const Elf_Ehdr *hdr,
326         list_add(&me->arch.dbe_list, &dbe_list);
327         spin_unlock_irq(&dbe_lock);
328     }
329-
330- /* Get rid of the fixup trampoline if we're running the module
331- * from physically mapped address space */
332- if (me->arch.phys_plt_offset == 0) {
333- __module_free(me->arch.phys_plt_tbl);
334- me->arch.phys_plt_tbl = NULL;
335- }
336- if (me->arch.virt_plt_offset == 0) {
337- __module_free(me->arch.virt_plt_tbl);
338- me->arch.virt_plt_tbl = NULL;
339- }
340-
341     return 0;
342 }
343 
344 void module_arch_cleanup(struct module *mod)
345 {
346- if (mod->arch.phys_plt_tbl) {
347- __module_free(mod->arch.phys_plt_tbl);
348- mod->arch.phys_plt_tbl = NULL;
349- }
350- if (mod->arch.virt_plt_tbl) {
351- __module_free(mod->arch.virt_plt_tbl);
352- mod->arch.virt_plt_tbl = NULL;
353- }
354-
355     spin_lock_irq(&dbe_lock);
356     list_del(&mod->arch.dbe_list);
357     spin_unlock_irq(&dbe_lock);
358--- a/arch/mips/Makefile
359+++ b/arch/mips/Makefile
360@@ -90,8 +90,8 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
361 cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
362 cflags-y += -msoft-float
363 LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
364-KBUILD_AFLAGS_MODULE += -mno-long-calls
365-KBUILD_CFLAGS_MODULE += -mno-long-calls
366+KBUILD_AFLAGS_MODULE += -mlong-calls
367+KBUILD_CFLAGS_MODULE += -mlong-calls
368 
369 cflags-y += -ffreestanding
370 
371

Archive Download this file



interactive