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