niu: panic on reset
[pandora-kernel.git] / arch / parisc / kernel / module.c
1 /*    Kernel dynamically loadable module help for PARISC.
2  *
3  *    The best reference for this stuff is probably the Processor-
4  *    Specific ELF Supplement for PA-RISC:
5  *        http://ftp.parisc-linux.org/docs/arch/elf-pa-hp.pdf
6  *
7  *    Linux/PA-RISC Project (http://www.parisc-linux.org/)
8  *    Copyright (C) 2003 Randolph Chung <tausq at debian . org>
9  *
10  *
11  *    This program is free software; you can redistribute it and/or modify
12  *    it under the terms of the GNU General Public License as published by
13  *    the Free Software Foundation; either version 2 of the License, or
14  *    (at your option) any later version.
15  *
16  *    This program is distributed in the hope that it will be useful,
17  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *    GNU General Public License for more details.
20  *
21  *    You should have received a copy of the GNU General Public License
22  *    along with this program; if not, write to the Free Software
23  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  *
25  *
26  *    Notes:
27  *    - SEGREL32 handling
28  *      We are not doing SEGREL32 handling correctly. According to the ABI, we
29  *      should do a value offset, like this:
30  *                      if (in_init(me, (void *)val))
31  *                              val -= (uint32_t)me->module_init;
32  *                      else
33  *                              val -= (uint32_t)me->module_core;
34  *      However, SEGREL32 is used only for PARISC unwind entries, and we want
35  *      those entries to have an absolute address, and not just an offset.
36  *
37  *      The unwind table mechanism has the ability to specify an offset for 
38  *      the unwind table; however, because we split off the init functions into
39  *      a different piece of memory, it is not possible to do this using a 
40  *      single offset. Instead, we use the above hack for now.
41  */
42
43 #include <linux/moduleloader.h>
44 #include <linux/elf.h>
45 #include <linux/vmalloc.h>
46 #include <linux/fs.h>
47 #include <linux/string.h>
48 #include <linux/kernel.h>
49 #include <linux/bug.h>
50
51 #include <asm/unwind.h>
52
53 #if 0
54 #define DEBUGP printk
55 #else
56 #define DEBUGP(fmt...)
57 #endif
58
59 #define CHECK_RELOC(val, bits) \
60         if ( ( !((val) & (1<<((bits)-1))) && ((val)>>(bits)) != 0 )  || \
61              ( ((val) & (1<<((bits)-1))) && ((val)>>(bits)) != (((__typeof__(val))(~0))>>((bits)+2)))) { \
62                 printk(KERN_ERR "module %s relocation of symbol %s is out of range (0x%lx in %d bits)\n", \
63                 me->name, strtab + sym->st_name, (unsigned long)val, bits); \
64                 return -ENOEXEC;                        \
65         }
66
67 /* Maximum number of GOT entries. We use a long displacement ldd from
68  * the bottom of the table, which has a maximum signed displacement of
69  * 0x3fff; however, since we're only going forward, this becomes
70  * 0x1fff, and thus, since each GOT entry is 8 bytes long we can have
71  * at most 1023 entries */
72 #define MAX_GOTS        1023
73
74 /* three functions to determine where in the module core
75  * or init pieces the location is */
76 static inline int in_init(struct module *me, void *loc)
77 {
78         return (loc >= me->module_init &&
79                 loc <= (me->module_init + me->init_size));
80 }
81
82 static inline int in_core(struct module *me, void *loc)
83 {
84         return (loc >= me->module_core &&
85                 loc <= (me->module_core + me->core_size));
86 }
87
88 static inline int in_local(struct module *me, void *loc)
89 {
90         return in_init(me, loc) || in_core(me, loc);
91 }
92
93 static inline int in_local_section(struct module *me, void *loc, void *dot)
94 {
95         return (in_init(me, loc) && in_init(me, dot)) ||
96                 (in_core(me, loc) && in_core(me, dot));
97 }
98
99
100 #ifndef CONFIG_64BIT
101 struct got_entry {
102         Elf32_Addr addr;
103 };
104
105 #define Elf_Fdesc       Elf32_Fdesc
106
107 struct stub_entry {
108         Elf32_Word insns[2]; /* each stub entry has two insns */
109 };
110 #else
111 struct got_entry {
112         Elf64_Addr addr;
113 };
114
115 #define Elf_Fdesc       Elf64_Fdesc
116
117 struct stub_entry {
118         Elf64_Word insns[4]; /* each stub entry has four insns */
119 };
120 #endif
121
122 /* Field selection types defined by hppa */
123 #define rnd(x)                  (((x)+0x1000)&~0x1fff)
124 /* fsel: full 32 bits */
125 #define fsel(v,a)               ((v)+(a))
126 /* lsel: select left 21 bits */
127 #define lsel(v,a)               (((v)+(a))>>11)
128 /* rsel: select right 11 bits */
129 #define rsel(v,a)               (((v)+(a))&0x7ff)
130 /* lrsel with rounding of addend to nearest 8k */
131 #define lrsel(v,a)              (((v)+rnd(a))>>11)
132 /* rrsel with rounding of addend to nearest 8k */
133 #define rrsel(v,a)              ((((v)+rnd(a))&0x7ff)+((a)-rnd(a)))
134
135 #define mask(x,sz)              ((x) & ~((1<<(sz))-1))
136
137
138 /* The reassemble_* functions prepare an immediate value for
139    insertion into an opcode. pa-risc uses all sorts of weird bitfields
140    in the instruction to hold the value.  */
141 static inline int reassemble_14(int as14)
142 {
143         return (((as14 & 0x1fff) << 1) |
144                 ((as14 & 0x2000) >> 13));
145 }
146
147 static inline int reassemble_17(int as17)
148 {
149         return (((as17 & 0x10000) >> 16) |
150                 ((as17 & 0x0f800) << 5) |
151                 ((as17 & 0x00400) >> 8) |
152                 ((as17 & 0x003ff) << 3));
153 }
154
155 static inline int reassemble_21(int as21)
156 {
157         return (((as21 & 0x100000) >> 20) |
158                 ((as21 & 0x0ffe00) >> 8) |
159                 ((as21 & 0x000180) << 7) |
160                 ((as21 & 0x00007c) << 14) |
161                 ((as21 & 0x000003) << 12));
162 }
163
164 static inline int reassemble_22(int as22)
165 {
166         return (((as22 & 0x200000) >> 21) |
167                 ((as22 & 0x1f0000) << 5) |
168                 ((as22 & 0x00f800) << 5) |
169                 ((as22 & 0x000400) >> 8) |
170                 ((as22 & 0x0003ff) << 3));
171 }
172
173 void *module_alloc(unsigned long size)
174 {
175         if (size == 0)
176                 return NULL;
177         return vmalloc(size);
178 }
179
180 #ifndef CONFIG_64BIT
181 static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
182 {
183         return 0;
184 }
185
186 static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
187 {
188         return 0;
189 }
190
191 static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
192 {
193         unsigned long cnt = 0;
194
195         for (; n > 0; n--, rela++)
196         {
197                 switch (ELF32_R_TYPE(rela->r_info)) {
198                         case R_PARISC_PCREL17F:
199                         case R_PARISC_PCREL22F:
200                                 cnt++;
201                 }
202         }
203
204         return cnt;
205 }
206 #else
207 static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
208 {
209         unsigned long cnt = 0;
210
211         for (; n > 0; n--, rela++)
212         {
213                 switch (ELF64_R_TYPE(rela->r_info)) {
214                         case R_PARISC_LTOFF21L:
215                         case R_PARISC_LTOFF14R:
216                         case R_PARISC_PCREL22F:
217                                 cnt++;
218                 }
219         }
220
221         return cnt;
222 }
223
224 static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
225 {
226         unsigned long cnt = 0;
227
228         for (; n > 0; n--, rela++)
229         {
230                 switch (ELF64_R_TYPE(rela->r_info)) {
231                         case R_PARISC_FPTR64:
232                                 cnt++;
233                 }
234         }
235
236         return cnt;
237 }
238
239 static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
240 {
241         unsigned long cnt = 0;
242
243         for (; n > 0; n--, rela++)
244         {
245                 switch (ELF64_R_TYPE(rela->r_info)) {
246                         case R_PARISC_PCREL22F:
247                                 cnt++;
248                 }
249         }
250
251         return cnt;
252 }
253 #endif
254
255
256 /* Free memory returned from module_alloc */
257 void module_free(struct module *mod, void *module_region)
258 {
259         vfree(module_region);
260         /* FIXME: If module_region == mod->init_region, trim exception
261            table entries. */
262 }
263
264 #define CONST 
265 int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
266                               CONST Elf_Shdr *sechdrs,
267                               CONST char *secstrings,
268                               struct module *me)
269 {
270         unsigned long gots = 0, fdescs = 0, stubs = 0, init_stubs = 0;
271         unsigned int i;
272
273         for (i = 1; i < hdr->e_shnum; i++) {
274                 const Elf_Rela *rels = (void *)hdr + sechdrs[i].sh_offset;
275                 unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels);
276
277                 if (strncmp(secstrings + sechdrs[i].sh_name,
278                             ".PARISC.unwind", 14) == 0)
279                         me->arch.unwind_section = i;
280
281                 if (sechdrs[i].sh_type != SHT_RELA)
282                         continue;
283
284                 /* some of these are not relevant for 32-bit/64-bit
285                  * we leave them here to make the code common. the
286                  * compiler will do its thing and optimize out the
287                  * stuff we don't need
288                  */
289                 gots += count_gots(rels, nrels);
290                 fdescs += count_fdescs(rels, nrels);
291                 if(strncmp(secstrings + sechdrs[i].sh_name,
292                            ".rela.init", 10) == 0)
293                         init_stubs += count_stubs(rels, nrels);
294                 else
295                         stubs += count_stubs(rels, nrels);
296         }
297
298         /* align things a bit */
299         me->core_size = ALIGN(me->core_size, 16);
300         me->arch.got_offset = me->core_size;
301         me->core_size += gots * sizeof(struct got_entry);
302
303         me->core_size = ALIGN(me->core_size, 16);
304         me->arch.fdesc_offset = me->core_size;
305         me->core_size += fdescs * sizeof(Elf_Fdesc);
306
307         me->core_size = ALIGN(me->core_size, 16);
308         me->arch.stub_offset = me->core_size;
309         me->core_size += stubs * sizeof(struct stub_entry);
310
311         me->init_size = ALIGN(me->init_size, 16);
312         me->arch.init_stub_offset = me->init_size;
313         me->init_size += init_stubs * sizeof(struct stub_entry);
314
315         me->arch.got_max = gots;
316         me->arch.fdesc_max = fdescs;
317         me->arch.stub_max = stubs;
318         me->arch.init_stub_max = init_stubs;
319
320         return 0;
321 }
322
323 #ifdef CONFIG_64BIT
324 static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
325 {
326         unsigned int i;
327         struct got_entry *got;
328
329         value += addend;
330
331         BUG_ON(value == 0);
332
333         got = me->module_core + me->arch.got_offset;
334         for (i = 0; got[i].addr; i++)
335                 if (got[i].addr == value)
336                         goto out;
337
338         BUG_ON(++me->arch.got_count > me->arch.got_max);
339
340         got[i].addr = value;
341  out:
342         DEBUGP("GOT ENTRY %d[%x] val %lx\n", i, i*sizeof(struct got_entry),
343                value);
344         return i * sizeof(struct got_entry);
345 }
346 #endif /* CONFIG_64BIT */
347
348 #ifdef CONFIG_64BIT
349 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
350 {
351         Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
352
353         if (!value) {
354                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
355                 return 0;
356         }
357
358         /* Look for existing fdesc entry. */
359         while (fdesc->addr) {
360                 if (fdesc->addr == value)
361                         return (Elf_Addr)fdesc;
362                 fdesc++;
363         }
364
365         BUG_ON(++me->arch.fdesc_count > me->arch.fdesc_max);
366
367         /* Create new one */
368         fdesc->addr = value;
369         fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
370         return (Elf_Addr)fdesc;
371 }
372 #endif /* CONFIG_64BIT */
373
374 enum elf_stub_type {
375         ELF_STUB_GOT,
376         ELF_STUB_MILLI,
377         ELF_STUB_DIRECT,
378 };
379
380 static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
381         enum elf_stub_type stub_type, int init_section)
382 {
383         unsigned long i;
384         struct stub_entry *stub;
385
386         if(init_section) {
387                 i = me->arch.init_stub_count++;
388                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
389                 stub = me->module_init + me->arch.init_stub_offset + 
390                         i * sizeof(struct stub_entry);
391         } else {
392                 i = me->arch.stub_count++;
393                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
394                 stub = me->module_core + me->arch.stub_offset + 
395                         i * sizeof(struct stub_entry);
396         }
397
398 #ifndef CONFIG_64BIT
399 /* for 32-bit the stub looks like this:
400  *      ldil L'XXX,%r1
401  *      be,n R'XXX(%sr4,%r1)
402  */
403         //value = *(unsigned long *)((value + addend) & ~3); /* why? */
404
405         stub->insns[0] = 0x20200000;    /* ldil L'XXX,%r1       */
406         stub->insns[1] = 0xe0202002;    /* be,n R'XXX(%sr4,%r1) */
407
408         stub->insns[0] |= reassemble_21(lrsel(value, addend));
409         stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4);
410
411 #else
412 /* for 64-bit we have three kinds of stubs:
413  * for normal function calls:
414  *      ldd 0(%dp),%dp
415  *      ldd 10(%dp), %r1
416  *      bve (%r1)
417  *      ldd 18(%dp), %dp
418  *
419  * for millicode:
420  *      ldil 0, %r1
421  *      ldo 0(%r1), %r1
422  *      ldd 10(%r1), %r1
423  *      bve,n (%r1)
424  *
425  * for direct branches (jumps between different section of the
426  * same module):
427  *      ldil 0, %r1
428  *      ldo 0(%r1), %r1
429  *      bve,n (%r1)
430  */
431         switch (stub_type) {
432         case ELF_STUB_GOT:
433                 stub->insns[0] = 0x537b0000;    /* ldd 0(%dp),%dp       */
434                 stub->insns[1] = 0x53610020;    /* ldd 10(%dp),%r1      */
435                 stub->insns[2] = 0xe820d000;    /* bve (%r1)            */
436                 stub->insns[3] = 0x537b0030;    /* ldd 18(%dp),%dp      */
437
438                 stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff);
439                 break;
440         case ELF_STUB_MILLI:
441                 stub->insns[0] = 0x20200000;    /* ldil 0,%r1           */
442                 stub->insns[1] = 0x34210000;    /* ldo 0(%r1), %r1      */
443                 stub->insns[2] = 0x50210020;    /* ldd 10(%r1),%r1      */
444                 stub->insns[3] = 0xe820d002;    /* bve,n (%r1)          */
445
446                 stub->insns[0] |= reassemble_21(lrsel(value, addend));
447                 stub->insns[1] |= reassemble_14(rrsel(value, addend));
448                 break;
449         case ELF_STUB_DIRECT:
450                 stub->insns[0] = 0x20200000;    /* ldil 0,%r1           */
451                 stub->insns[1] = 0x34210000;    /* ldo 0(%r1), %r1      */
452                 stub->insns[2] = 0xe820d002;    /* bve,n (%r1)          */
453
454                 stub->insns[0] |= reassemble_21(lrsel(value, addend));
455                 stub->insns[1] |= reassemble_14(rrsel(value, addend));
456                 break;
457         }
458
459 #endif
460
461         return (Elf_Addr)stub;
462 }
463
464 int apply_relocate(Elf_Shdr *sechdrs,
465                    const char *strtab,
466                    unsigned int symindex,
467                    unsigned int relsec,
468                    struct module *me)
469 {
470         /* parisc should not need this ... */
471         printk(KERN_ERR "module %s: RELOCATION unsupported\n",
472                me->name);
473         return -ENOEXEC;
474 }
475
476 #ifndef CONFIG_64BIT
477 int apply_relocate_add(Elf_Shdr *sechdrs,
478                        const char *strtab,
479                        unsigned int symindex,
480                        unsigned int relsec,
481                        struct module *me)
482 {
483         int i;
484         Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
485         Elf32_Sym *sym;
486         Elf32_Word *loc;
487         Elf32_Addr val;
488         Elf32_Sword addend;
489         Elf32_Addr dot;
490         //unsigned long dp = (unsigned long)$global$;
491         register unsigned long dp asm ("r27");
492
493         DEBUGP("Applying relocate section %u to %u\n", relsec,
494                sechdrs[relsec].sh_info);
495         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
496                 /* This is where to make the change */
497                 loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
498                       + rel[i].r_offset;
499                 /* This is the symbol it is referring to */
500                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
501                         + ELF32_R_SYM(rel[i].r_info);
502                 if (!sym->st_value) {
503                         printk(KERN_WARNING "%s: Unknown symbol %s\n",
504                                me->name, strtab + sym->st_name);
505                         return -ENOENT;
506                 }
507                 //dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
508                 dot =  (Elf32_Addr)loc & ~0x03;
509
510                 val = sym->st_value;
511                 addend = rel[i].r_addend;
512
513 #if 0
514 #define r(t) ELF32_R_TYPE(rel[i].r_info)==t ? #t :
515                 DEBUGP("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n",
516                         strtab + sym->st_name,
517                         (uint32_t)loc, val, addend,
518                         r(R_PARISC_PLABEL32)
519                         r(R_PARISC_DIR32)
520                         r(R_PARISC_DIR21L)
521                         r(R_PARISC_DIR14R)
522                         r(R_PARISC_SEGREL32)
523                         r(R_PARISC_DPREL21L)
524                         r(R_PARISC_DPREL14R)
525                         r(R_PARISC_PCREL17F)
526                         r(R_PARISC_PCREL22F)
527                         "UNKNOWN");
528 #undef r
529 #endif
530
531                 switch (ELF32_R_TYPE(rel[i].r_info)) {
532                 case R_PARISC_PLABEL32:
533                         /* 32-bit function address */
534                         /* no function descriptors... */
535                         *loc = fsel(val, addend);
536                         break;
537                 case R_PARISC_DIR32:
538                         /* direct 32-bit ref */
539                         *loc = fsel(val, addend);
540                         break;
541                 case R_PARISC_DIR21L:
542                         /* left 21 bits of effective address */
543                         val = lrsel(val, addend);
544                         *loc = mask(*loc, 21) | reassemble_21(val);
545                         break;
546                 case R_PARISC_DIR14R:
547                         /* right 14 bits of effective address */
548                         val = rrsel(val, addend);
549                         *loc = mask(*loc, 14) | reassemble_14(val);
550                         break;
551                 case R_PARISC_SEGREL32:
552                         /* 32-bit segment relative address */
553                         /* See note about special handling of SEGREL32 at
554                          * the beginning of this file.
555                          */
556                         *loc = fsel(val, addend); 
557                         break;
558                 case R_PARISC_DPREL21L:
559                         /* left 21 bit of relative address */
560                         val = lrsel(val - dp, addend);
561                         *loc = mask(*loc, 21) | reassemble_21(val);
562                         break;
563                 case R_PARISC_DPREL14R:
564                         /* right 14 bit of relative address */
565                         val = rrsel(val - dp, addend);
566                         *loc = mask(*loc, 14) | reassemble_14(val);
567                         break;
568                 case R_PARISC_PCREL17F:
569                         /* 17-bit PC relative address */
570                         val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc));
571                         val = (val - dot - 8)/4;
572                         CHECK_RELOC(val, 17)
573                         *loc = (*loc & ~0x1f1ffd) | reassemble_17(val);
574                         break;
575                 case R_PARISC_PCREL22F:
576                         /* 22-bit PC relative address; only defined for pa20 */
577                         val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc));
578                         DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", 
579                                strtab + sym->st_name, (unsigned long)loc, addend, 
580                                val)
581                         val = (val - dot - 8)/4;
582                         CHECK_RELOC(val, 22);
583                         *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
584                         break;
585
586                 default:
587                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
588                                me->name, ELF32_R_TYPE(rel[i].r_info));
589                         return -ENOEXEC;
590                 }
591         }
592
593         return 0;
594 }
595
596 #else
597 int apply_relocate_add(Elf_Shdr *sechdrs,
598                        const char *strtab,
599                        unsigned int symindex,
600                        unsigned int relsec,
601                        struct module *me)
602 {
603         int i;
604         Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
605         Elf64_Sym *sym;
606         Elf64_Word *loc;
607         Elf64_Xword *loc64;
608         Elf64_Addr val;
609         Elf64_Sxword addend;
610         Elf64_Addr dot;
611
612         DEBUGP("Applying relocate section %u to %u\n", relsec,
613                sechdrs[relsec].sh_info);
614         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
615                 /* This is where to make the change */
616                 loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
617                       + rel[i].r_offset;
618                 /* This is the symbol it is referring to */
619                 sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
620                         + ELF64_R_SYM(rel[i].r_info);
621                 if (!sym->st_value) {
622                         printk(KERN_WARNING "%s: Unknown symbol %s\n",
623                                me->name, strtab + sym->st_name);
624                         return -ENOENT;
625                 }
626                 //dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
627                 dot = (Elf64_Addr)loc & ~0x03;
628                 loc64 = (Elf64_Xword *)loc;
629
630                 val = sym->st_value;
631                 addend = rel[i].r_addend;
632
633 #if 0
634 #define r(t) ELF64_R_TYPE(rel[i].r_info)==t ? #t :
635                 printk("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n",
636                         strtab + sym->st_name,
637                         loc, val, addend,
638                         r(R_PARISC_LTOFF14R)
639                         r(R_PARISC_LTOFF21L)
640                         r(R_PARISC_PCREL22F)
641                         r(R_PARISC_DIR64)
642                         r(R_PARISC_SEGREL32)
643                         r(R_PARISC_FPTR64)
644                         "UNKNOWN");
645 #undef r
646 #endif
647
648                 switch (ELF64_R_TYPE(rel[i].r_info)) {
649                 case R_PARISC_LTOFF21L:
650                         /* LT-relative; left 21 bits */
651                         val = get_got(me, val, addend);
652                         DEBUGP("LTOFF21L Symbol %s loc %p val %lx\n",
653                                strtab + sym->st_name,
654                                loc, val);
655                         val = lrsel(val, 0);
656                         *loc = mask(*loc, 21) | reassemble_21(val);
657                         break;
658                 case R_PARISC_LTOFF14R:
659                         /* L(ltoff(val+addend)) */
660                         /* LT-relative; right 14 bits */
661                         val = get_got(me, val, addend);
662                         val = rrsel(val, 0);
663                         DEBUGP("LTOFF14R Symbol %s loc %p val %lx\n",
664                                strtab + sym->st_name,
665                                loc, val);
666                         *loc = mask(*loc, 14) | reassemble_14(val);
667                         break;
668                 case R_PARISC_PCREL22F:
669                         /* PC-relative; 22 bits */
670                         DEBUGP("PCREL22F Symbol %s loc %p val %lx\n",
671                                strtab + sym->st_name,
672                                loc, val);
673                         /* can we reach it locally? */
674                         if(!in_local_section(me, (void *)val, (void *)dot)) {
675
676                                 if (in_local(me, (void *)val))
677                                         /* this is the case where the
678                                          * symbol is local to the
679                                          * module, but in a different
680                                          * section, so stub the jump
681                                          * in case it's more than 22
682                                          * bits away */
683                                         val = get_stub(me, val, addend, ELF_STUB_DIRECT,
684                                                        in_init(me, loc));
685                                 else if (strncmp(strtab + sym->st_name, "$$", 2)
686                                     == 0)
687                                         val = get_stub(me, val, addend, ELF_STUB_MILLI,
688                                                        in_init(me, loc));
689                                 else
690                                         val = get_stub(me, val, addend, ELF_STUB_GOT,
691                                                        in_init(me, loc));
692                         }
693                         DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", 
694                                strtab + sym->st_name, loc, sym->st_value,
695                                addend, val);
696                         /* FIXME: local symbols work as long as the
697                          * core and init pieces aren't separated too
698                          * far.  If this is ever broken, you will trip
699                          * the check below.  The way to fix it would
700                          * be to generate local stubs to go between init
701                          * and core */
702                         if((Elf64_Sxword)(val - dot - 8) > 0x800000 -1 ||
703                            (Elf64_Sxword)(val - dot - 8) < -0x800000) {
704                                 printk(KERN_ERR "Module %s, symbol %s is out of range for PCREL22F relocation\n",
705                                        me->name, strtab + sym->st_name);
706                                 return -ENOEXEC;
707                         }
708                         val = (val - dot - 8)/4;
709                         *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
710                         break;
711                 case R_PARISC_DIR64:
712                         /* 64-bit effective address */
713                         *loc64 = val + addend;
714                         break;
715                 case R_PARISC_SEGREL32:
716                         /* 32-bit segment relative address */
717                         /* See note about special handling of SEGREL32 at
718                          * the beginning of this file.
719                          */
720                         *loc = fsel(val, addend); 
721                         break;
722                 case R_PARISC_FPTR64:
723                         /* 64-bit function address */
724                         if(in_local(me, (void *)(val + addend))) {
725                                 *loc64 = get_fdesc(me, val+addend);
726                                 DEBUGP("FDESC for %s at %p points to %lx\n",
727                                        strtab + sym->st_name, *loc64,
728                                        ((Elf_Fdesc *)*loc64)->addr);
729                         } else {
730                                 /* if the symbol is not local to this
731                                  * module then val+addend is a pointer
732                                  * to the function descriptor */
733                                 DEBUGP("Non local FPTR64 Symbol %s loc %p val %lx\n",
734                                        strtab + sym->st_name,
735                                        loc, val);
736                                 *loc64 = val + addend;
737                         }
738                         break;
739
740                 default:
741                         printk(KERN_ERR "module %s: Unknown relocation: %Lu\n",
742                                me->name, ELF64_R_TYPE(rel[i].r_info));
743                         return -ENOEXEC;
744                 }
745         }
746         return 0;
747 }
748 #endif
749
750 static void
751 register_unwind_table(struct module *me,
752                       const Elf_Shdr *sechdrs)
753 {
754         unsigned char *table, *end;
755         unsigned long gp;
756
757         if (!me->arch.unwind_section)
758                 return;
759
760         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
761         end = table + sechdrs[me->arch.unwind_section].sh_size;
762         gp = (Elf_Addr)me->module_core + me->arch.got_offset;
763
764         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
765                me->arch.unwind_section, table, end, gp);
766         me->arch.unwind = unwind_table_add(me->name, 0, gp, table, end);
767 }
768
769 static void
770 deregister_unwind_table(struct module *me)
771 {
772         if (me->arch.unwind)
773                 unwind_table_remove(me->arch.unwind);
774 }
775
776 int module_finalize(const Elf_Ehdr *hdr,
777                     const Elf_Shdr *sechdrs,
778                     struct module *me)
779 {
780         int i;
781         unsigned long nsyms;
782         const char *strtab = NULL;
783         Elf_Sym *newptr, *oldptr;
784         Elf_Shdr *symhdr = NULL;
785 #ifdef DEBUG
786         Elf_Fdesc *entry;
787         u32 *addr;
788
789         entry = (Elf_Fdesc *)me->init;
790         printk("FINALIZE, ->init FPTR is %p, GP %lx ADDR %lx\n", entry,
791                entry->gp, entry->addr);
792         addr = (u32 *)entry->addr;
793         printk("INSNS: %x %x %x %x\n",
794                addr[0], addr[1], addr[2], addr[3]);
795         printk("stubs used %ld, stubs max %ld\n"
796                "init_stubs used %ld, init stubs max %ld\n"
797                "got entries used %ld, gots max %ld\n"
798                "fdescs used %ld, fdescs max %ld\n",
799                me->arch.stub_count, me->arch.stub_max,
800                me->arch.init_stub_count, me->arch.init_stub_max,
801                me->arch.got_count, me->arch.got_max,
802                me->arch.fdesc_count, me->arch.fdesc_max);
803 #endif
804
805         register_unwind_table(me, sechdrs);
806
807         /* haven't filled in me->symtab yet, so have to find it
808          * ourselves */
809         for (i = 1; i < hdr->e_shnum; i++) {
810                 if(sechdrs[i].sh_type == SHT_SYMTAB
811                    && (sechdrs[i].sh_type & SHF_ALLOC)) {
812                         int strindex = sechdrs[i].sh_link;
813                         /* FIXME: AWFUL HACK
814                          * The cast is to drop the const from
815                          * the sechdrs pointer */
816                         symhdr = (Elf_Shdr *)&sechdrs[i];
817                         strtab = (char *)sechdrs[strindex].sh_addr;
818                         break;
819                 }
820         }
821
822         DEBUGP("module %s: strtab %p, symhdr %p\n",
823                me->name, strtab, symhdr);
824
825         if(me->arch.got_count > MAX_GOTS) {
826                 printk(KERN_ERR "%s: Global Offset Table overflow (used %ld, allowed %d)\n",
827                                 me->name, me->arch.got_count, MAX_GOTS);
828                 return -EINVAL;
829         }
830         
831         /* no symbol table */
832         if(symhdr == NULL)
833                 return 0;
834
835         oldptr = (void *)symhdr->sh_addr;
836         newptr = oldptr + 1;    /* we start counting at 1 */
837         nsyms = symhdr->sh_size / sizeof(Elf_Sym);
838         DEBUGP("OLD num_symtab %lu\n", nsyms);
839
840         for (i = 1; i < nsyms; i++) {
841                 oldptr++;       /* note, count starts at 1 so preincrement */
842                 if(strncmp(strtab + oldptr->st_name,
843                               ".L", 2) == 0)
844                         continue;
845
846                 if(newptr != oldptr)
847                         *newptr++ = *oldptr;
848                 else
849                         newptr++;
850
851         }
852         nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
853         DEBUGP("NEW num_symtab %lu\n", nsyms);
854         symhdr->sh_size = nsyms * sizeof(Elf_Sym);
855         return module_bug_finalize(hdr, sechdrs, me);
856 }
857
858 void module_arch_cleanup(struct module *mod)
859 {
860         deregister_unwind_table(mod);
861         module_bug_cleanup(mod);
862 }