module_64.c (7e3a68be42e10f5fa5890e97afc0afd992355bc3) | module_64.c (77e69ee7ce0715c39b9a0cde68ff44fe467435ef) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* Kernel module help for PPC64. 3 Copyright (C) 2001, 2003 Rusty Russell IBM Corporation. 4 5*/ 6 7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 --- 100 unchanged lines hidden (view full) --- 109 */ 110 u32 jump[7]; 111 /* Used by ftrace to identify stubs */ 112 u32 magic; 113 /* Data for the above code */ 114 func_desc_t funcdata; 115} __aligned(8); 116 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* Kernel module help for PPC64. 3 Copyright (C) 2001, 2003 Rusty Russell IBM Corporation. 4 5*/ 6 7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 --- 100 unchanged lines hidden (view full) --- 109 */ 110 u32 jump[7]; 111 /* Used by ftrace to identify stubs */ 112 u32 magic; 113 /* Data for the above code */ 114 func_desc_t funcdata; 115} __aligned(8); 116 |
117struct ppc64_got_entry { 118 u64 addr; 119}; 120 |
|
117/* 118 * PPC64 uses 24 bit jumps, but we need to jump into other modules or 119 * the kernel which may be further. So we jump to a stub. 120 * | 121/* 122 * PPC64 uses 24 bit jumps, but we need to jump into other modules or 123 * the kernel which may be further. So we jump to a stub. 124 * |
121 * For ELFv1 we need to use this to set up the new r2 value (aka TOC 122 * pointer). For ELFv2 it's the callee's responsibility to set up the 123 * new r2, but for both we need to save the old r2. | 125 * Target address and TOC are loaded from function descriptor in the 126 * ppc64_stub_entry. |
124 * | 127 * |
125 * We could simply patch the new r2 value and function pointer into 126 * the stub, but it's significantly shorter to put these values at the 127 * end of the stub code, and patch the stub address (32-bits relative 128 * to the TOC ptr, r2) into the stub. | 128 * r12 is used to generate the target address, which is required for the 129 * ELFv2 global entry point calling convention. 130 * 131 * TOC handling: 132 * - PCREL does not have a TOC. 133 * - ELFv2 non-PCREL just has to save r2, the callee is responsible for 134 * setting its own TOC pointer at the global entry address. 135 * - ELFv1 must load the new TOC pointer from the function descriptor. |
129 */ 130static u32 ppc64_stub_insns[] = { | 136 */ 137static u32 ppc64_stub_insns[] = { |
138#ifdef CONFIG_PPC_KERNEL_PCREL 139 /* pld r12,addr */ 140 PPC_PREFIX_8LS | __PPC_PRFX_R(1), 141 PPC_INST_PLD | ___PPC_RT(_R12), 142#else |
|
131 PPC_RAW_ADDIS(_R11, _R2, 0), 132 PPC_RAW_ADDI(_R11, _R11, 0), 133 /* Save current r2 value in magic place on the stack. */ 134 PPC_RAW_STD(_R2, _R1, R2_STACK_OFFSET), 135 PPC_RAW_LD(_R12, _R11, 32), 136#ifdef CONFIG_PPC64_ELF_ABI_V1 137 /* Set up new r2 from function descriptor */ 138 PPC_RAW_LD(_R2, _R11, 40), 139#endif | 143 PPC_RAW_ADDIS(_R11, _R2, 0), 144 PPC_RAW_ADDI(_R11, _R11, 0), 145 /* Save current r2 value in magic place on the stack. */ 146 PPC_RAW_STD(_R2, _R1, R2_STACK_OFFSET), 147 PPC_RAW_LD(_R12, _R11, 32), 148#ifdef CONFIG_PPC64_ELF_ABI_V1 149 /* Set up new r2 from function descriptor */ 150 PPC_RAW_LD(_R2, _R11, 40), 151#endif |
152#endif |
|
140 PPC_RAW_MTCTR(_R12), 141 PPC_RAW_BCTR(), 142}; 143 | 153 PPC_RAW_MTCTR(_R12), 154 PPC_RAW_BCTR(), 155}; 156 |
144/* Count how many different 24-bit relocations (different symbol, 145 different addend) */ 146static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num) | 157/* 158 * Count how many different r_type relocations (different symbol, 159 * different addend). 160 */ 161static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num, 162 unsigned long r_type) |
147{ 148 unsigned int i, r_info, r_addend, _count_relocs; 149 150 /* FIXME: Only count external ones --RR */ 151 _count_relocs = 0; 152 r_info = 0; 153 r_addend = 0; 154 for (i = 0; i < num; i++) | 163{ 164 unsigned int i, r_info, r_addend, _count_relocs; 165 166 /* FIXME: Only count external ones --RR */ 167 _count_relocs = 0; 168 r_info = 0; 169 r_addend = 0; 170 for (i = 0; i < num; i++) |
155 /* Only count 24-bit relocs, others don't need stubs */ 156 if (ELF64_R_TYPE(rela[i].r_info) == R_PPC_REL24 && | 171 /* Only count r_type relocs, others don't need stubs */ 172 if (ELF64_R_TYPE(rela[i].r_info) == r_type && |
157 (r_info != ELF64_R_SYM(rela[i].r_info) || 158 r_addend != rela[i].r_addend)) { 159 _count_relocs++; 160 r_info = ELF64_R_SYM(rela[i].r_info); 161 r_addend = rela[i].r_addend; 162 } 163 164 return _count_relocs; --- 44 unchanged lines hidden (view full) --- 209 * count_relocs() to linear complexity O(n) 210 */ 211 sort((void *)sechdrs[i].sh_addr, 212 sechdrs[i].sh_size / sizeof(Elf64_Rela), 213 sizeof(Elf64_Rela), relacmp, NULL); 214 215 relocs += count_relocs((void *)sechdrs[i].sh_addr, 216 sechdrs[i].sh_size | 173 (r_info != ELF64_R_SYM(rela[i].r_info) || 174 r_addend != rela[i].r_addend)) { 175 _count_relocs++; 176 r_info = ELF64_R_SYM(rela[i].r_info); 177 r_addend = rela[i].r_addend; 178 } 179 180 return _count_relocs; --- 44 unchanged lines hidden (view full) --- 225 * count_relocs() to linear complexity O(n) 226 */ 227 sort((void *)sechdrs[i].sh_addr, 228 sechdrs[i].sh_size / sizeof(Elf64_Rela), 229 sizeof(Elf64_Rela), relacmp, NULL); 230 231 relocs += count_relocs((void *)sechdrs[i].sh_addr, 232 sechdrs[i].sh_size |
217 / sizeof(Elf64_Rela)); | 233 / sizeof(Elf64_Rela), 234 R_PPC_REL24); 235#ifdef CONFIG_PPC_KERNEL_PCREL 236 relocs += count_relocs((void *)sechdrs[i].sh_addr, 237 sechdrs[i].sh_size 238 / sizeof(Elf64_Rela), 239 R_PPC64_REL24_NOTOC); 240#endif |
218 } 219 } 220 221#ifdef CONFIG_DYNAMIC_FTRACE 222 /* make the trampoline to the ftrace_caller */ 223 relocs++; 224#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 225 /* an additional one for ftrace_regs_caller */ 226 relocs++; 227#endif 228#endif 229 230 pr_debug("Looks like a total of %lu stubs, max\n", relocs); 231 return relocs * sizeof(struct ppc64_stub_entry); 232} 233 | 241 } 242 } 243 244#ifdef CONFIG_DYNAMIC_FTRACE 245 /* make the trampoline to the ftrace_caller */ 246 relocs++; 247#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS 248 /* an additional one for ftrace_regs_caller */ 249 relocs++; 250#endif 251#endif 252 253 pr_debug("Looks like a total of %lu stubs, max\n", relocs); 254 return relocs * sizeof(struct ppc64_stub_entry); 255} 256 |
257#ifdef CONFIG_PPC_KERNEL_PCREL 258static int count_pcpu_relocs(const Elf64_Shdr *sechdrs, 259 const Elf64_Rela *rela, unsigned int num, 260 unsigned int symindex, unsigned int pcpu) 261{ 262 unsigned int i, r_info, r_addend, _count_relocs; 263 264 _count_relocs = 0; 265 r_info = 0; 266 r_addend = 0; 267 268 for (i = 0; i < num; i++) { 269 Elf64_Sym *sym; 270 271 /* This is the symbol it is referring to */ 272 sym = (Elf64_Sym *)sechdrs[symindex].sh_addr 273 + ELF64_R_SYM(rela[i].r_info); 274 275 if (sym->st_shndx == pcpu && 276 (r_info != ELF64_R_SYM(rela[i].r_info) || 277 r_addend != rela[i].r_addend)) { 278 _count_relocs++; 279 r_info = ELF64_R_SYM(rela[i].r_info); 280 r_addend = rela[i].r_addend; 281 } 282 } 283 284 return _count_relocs; 285} 286 287/* Get size of potential GOT required. */ 288static unsigned long get_got_size(const Elf64_Ehdr *hdr, 289 const Elf64_Shdr *sechdrs, 290 struct module *me) 291{ 292 /* One extra reloc so it's always 0-addr terminated */ 293 unsigned long relocs = 1; 294 unsigned int i, symindex = 0; 295 296 for (i = 1; i < hdr->e_shnum; i++) { 297 if (sechdrs[i].sh_type == SHT_SYMTAB) { 298 symindex = i; 299 break; 300 } 301 } 302 WARN_ON_ONCE(!symindex); 303 304 /* Every relocated section... */ 305 for (i = 1; i < hdr->e_shnum; i++) { 306 if (sechdrs[i].sh_type == SHT_RELA) { 307 pr_debug("Found relocations in section %u\n", i); 308 pr_debug("Ptr: %p. Number: %llu\n", (void *)sechdrs[i].sh_addr, 309 sechdrs[i].sh_size / sizeof(Elf64_Rela)); 310 311 /* 312 * Sort the relocation information based on a symbol and 313 * addend key. This is a stable O(n*log n) complexity 314 * algorithm but it will reduce the complexity of 315 * count_relocs() to linear complexity O(n) 316 */ 317 sort((void *)sechdrs[i].sh_addr, 318 sechdrs[i].sh_size / sizeof(Elf64_Rela), 319 sizeof(Elf64_Rela), relacmp, NULL); 320 321 relocs += count_relocs((void *)sechdrs[i].sh_addr, 322 sechdrs[i].sh_size 323 / sizeof(Elf64_Rela), 324 R_PPC64_GOT_PCREL34); 325 326 /* 327 * Percpu data access typically gets linked with 328 * REL34 relocations, but the percpu section gets 329 * moved at load time and requires that to be 330 * converted to GOT linkage. 331 */ 332 if (IS_ENABLED(CONFIG_SMP) && symindex) 333 relocs += count_pcpu_relocs(sechdrs, 334 (void *)sechdrs[i].sh_addr, 335 sechdrs[i].sh_size 336 / sizeof(Elf64_Rela), 337 symindex, me->arch.pcpu_section); 338 } 339 } 340 341 pr_debug("Looks like a total of %lu GOT entries, max\n", relocs); 342 return relocs * sizeof(struct ppc64_got_entry); 343} 344#else /* CONFIG_PPC_KERNEL_PCREL */ 345 |
|
234/* Still needed for ELFv2, for .TOC. */ 235static void dedotify_versions(struct modversion_info *vers, 236 unsigned long size) 237{ 238 struct modversion_info *end; 239 240 for (end = (void *)vers + size; vers < end; vers++) 241 if (vers->name[0] == '.') { --- 33 unchanged lines hidden (view full) --- 275 276 for (i = 1; i < numsyms; i++) { 277 if (syms[i].st_shndx == SHN_ABS 278 && strcmp(strtab + syms[i].st_name, "TOC.") == 0) 279 return &syms[i]; 280 } 281 return NULL; 282} | 346/* Still needed for ELFv2, for .TOC. */ 347static void dedotify_versions(struct modversion_info *vers, 348 unsigned long size) 349{ 350 struct modversion_info *end; 351 352 for (end = (void *)vers + size; vers < end; vers++) 353 if (vers->name[0] == '.') { --- 33 unchanged lines hidden (view full) --- 387 388 for (i = 1; i < numsyms; i++) { 389 if (syms[i].st_shndx == SHN_ABS 390 && strcmp(strtab + syms[i].st_name, "TOC.") == 0) 391 return &syms[i]; 392 } 393 return NULL; 394} |
395#endif /* CONFIG_PPC_KERNEL_PCREL */ |
|
283 284bool module_init_section(const char *name) 285{ 286 /* We don't handle .init for the moment: always return false. */ 287 return false; 288} 289 290int module_frob_arch_sections(Elf64_Ehdr *hdr, 291 Elf64_Shdr *sechdrs, 292 char *secstrings, 293 struct module *me) 294{ 295 unsigned int i; 296 297 /* Find .toc and .stubs sections, symtab and strtab */ 298 for (i = 1; i < hdr->e_shnum; i++) { 299 if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0) 300 me->arch.stubs_section = i; | 396 397bool module_init_section(const char *name) 398{ 399 /* We don't handle .init for the moment: always return false. */ 400 return false; 401} 402 403int module_frob_arch_sections(Elf64_Ehdr *hdr, 404 Elf64_Shdr *sechdrs, 405 char *secstrings, 406 struct module *me) 407{ 408 unsigned int i; 409 410 /* Find .toc and .stubs sections, symtab and strtab */ 411 for (i = 1; i < hdr->e_shnum; i++) { 412 if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0) 413 me->arch.stubs_section = i; |
414#ifdef CONFIG_PPC_KERNEL_PCREL 415 else if (strcmp(secstrings + sechdrs[i].sh_name, ".data..percpu") == 0) 416 me->arch.pcpu_section = i; 417 else if (strcmp(secstrings + sechdrs[i].sh_name, ".mygot") == 0) { 418 me->arch.got_section = i; 419 if (sechdrs[i].sh_addralign < 8) 420 sechdrs[i].sh_addralign = 8; 421 } 422#else |
|
301 else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0) { 302 me->arch.toc_section = i; 303 if (sechdrs[i].sh_addralign < 8) 304 sechdrs[i].sh_addralign = 8; 305 } 306 else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0) 307 dedotify_versions((void *)hdr + sechdrs[i].sh_offset, 308 sechdrs[i].sh_size); 309 310 if (sechdrs[i].sh_type == SHT_SYMTAB) 311 dedotify((void *)hdr + sechdrs[i].sh_offset, 312 sechdrs[i].sh_size / sizeof(Elf64_Sym), 313 (void *)hdr 314 + sechdrs[sechdrs[i].sh_link].sh_offset); | 423 else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0) { 424 me->arch.toc_section = i; 425 if (sechdrs[i].sh_addralign < 8) 426 sechdrs[i].sh_addralign = 8; 427 } 428 else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0) 429 dedotify_versions((void *)hdr + sechdrs[i].sh_offset, 430 sechdrs[i].sh_size); 431 432 if (sechdrs[i].sh_type == SHT_SYMTAB) 433 dedotify((void *)hdr + sechdrs[i].sh_offset, 434 sechdrs[i].sh_size / sizeof(Elf64_Sym), 435 (void *)hdr 436 + sechdrs[sechdrs[i].sh_link].sh_offset); |
437#endif |
|
315 } 316 317 if (!me->arch.stubs_section) { 318 pr_err("%s: doesn't contain .stubs.\n", me->name); 319 return -ENOEXEC; 320 } 321 | 438 } 439 440 if (!me->arch.stubs_section) { 441 pr_err("%s: doesn't contain .stubs.\n", me->name); 442 return -ENOEXEC; 443 } 444 |
445#ifdef CONFIG_PPC_KERNEL_PCREL 446 if (!me->arch.got_section) { 447 pr_err("%s: doesn't contain .mygot.\n", me->name); 448 return -ENOEXEC; 449 } 450 451 /* Override the got size */ 452 sechdrs[me->arch.got_section].sh_size = get_got_size(hdr, sechdrs, me); 453#else |
|
322 /* If we don't have a .toc, just use .stubs. We need to set r2 323 to some reasonable value in case the module calls out to 324 other functions via a stub, or if a function pointer escapes 325 the module by some means. */ 326 if (!me->arch.toc_section) 327 me->arch.toc_section = me->arch.stubs_section; | 454 /* If we don't have a .toc, just use .stubs. We need to set r2 455 to some reasonable value in case the module calls out to 456 other functions via a stub, or if a function pointer escapes 457 the module by some means. */ 458 if (!me->arch.toc_section) 459 me->arch.toc_section = me->arch.stubs_section; |
460#endif |
|
328 329 /* Override the stubs size */ 330 sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs); | 461 462 /* Override the stubs size */ 463 sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs); |
464 |
|
331 return 0; 332} 333 334#ifdef CONFIG_MPROFILE_KERNEL 335 336static u32 stub_insns[] = { 337#ifdef CONFIG_PPC_KERNEL_PCREL 338 PPC_RAW_LD(_R12, _R13, offsetof(struct paca_struct, kernelbase)), --- 101 unchanged lines hidden (view full) --- 440/* 441 * r2 is the TOC pointer: it actually points 0x8000 into the TOC (this gives the 442 * value maximum span in an instruction which uses a signed offset). Round down 443 * to a 256 byte boundary for the odd case where we are setting up r2 without a 444 * .toc section. 445 */ 446static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me) 447{ | 465 return 0; 466} 467 468#ifdef CONFIG_MPROFILE_KERNEL 469 470static u32 stub_insns[] = { 471#ifdef CONFIG_PPC_KERNEL_PCREL 472 PPC_RAW_LD(_R12, _R13, offsetof(struct paca_struct, kernelbase)), --- 101 unchanged lines hidden (view full) --- 574/* 575 * r2 is the TOC pointer: it actually points 0x8000 into the TOC (this gives the 576 * value maximum span in an instruction which uses a signed offset). Round down 577 * to a 256 byte boundary for the odd case where we are setting up r2 without a 578 * .toc section. 579 */ 580static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me) 581{ |
582#ifndef CONFIG_PPC_KERNEL_PCREL |
|
448 return (sechdrs[me->arch.toc_section].sh_addr & ~0xfful) + 0x8000; | 583 return (sechdrs[me->arch.toc_section].sh_addr & ~0xfful) + 0x8000; |
584#else 585 return -1; 586#endif |
|
449} 450 451/* Patch stub to reference function and correct r2 value. */ 452static inline int create_stub(const Elf64_Shdr *sechdrs, 453 struct ppc64_stub_entry *entry, 454 unsigned long addr, 455 struct module *me, 456 const char *name) 457{ 458 long reladdr; 459 func_desc_t desc; 460 int i; 461 462 if (is_mprofile_ftrace_call(name)) 463 return create_ftrace_stub(entry, addr, me); 464 | 587} 588 589/* Patch stub to reference function and correct r2 value. */ 590static inline int create_stub(const Elf64_Shdr *sechdrs, 591 struct ppc64_stub_entry *entry, 592 unsigned long addr, 593 struct module *me, 594 const char *name) 595{ 596 long reladdr; 597 func_desc_t desc; 598 int i; 599 600 if (is_mprofile_ftrace_call(name)) 601 return create_ftrace_stub(entry, addr, me); 602 |
603 if ((unsigned long)entry->jump % 8 != 0) { 604 pr_err("%s: Address of stub entry is not 8-byte aligned\n", me->name); 605 return 0; 606 } 607 608 BUILD_BUG_ON(sizeof(ppc64_stub_insns) > sizeof(entry->jump)); |
|
465 for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) { 466 if (patch_instruction(&entry->jump[i], 467 ppc_inst(ppc64_stub_insns[i]))) 468 return 0; 469 } 470 | 609 for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) { 610 if (patch_instruction(&entry->jump[i], 611 ppc_inst(ppc64_stub_insns[i]))) 612 return 0; 613 } 614 |
471 /* Stub uses address relative to r2. */ 472 reladdr = (unsigned long)entry - my_r2(sechdrs, me); 473 if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { 474 pr_err("%s: Address %p of stub out of range of %p.\n", 475 me->name, (void *)reladdr, (void *)my_r2); 476 return 0; 477 } 478 pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr); | 615 if (IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) { 616 /* Stub uses address relative to itself! */ 617 reladdr = 0 + offsetof(struct ppc64_stub_entry, funcdata); 618 BUILD_BUG_ON(reladdr != 32); 619 if (reladdr > 0x1FFFFFFFFL || reladdr < -0x200000000L) { 620 pr_err("%s: Address of %p out of range of 34-bit relative address.\n", 621 me->name, (void *)reladdr); 622 return 0; 623 } 624 pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr); |
479 | 625 |
480 if (patch_instruction(&entry->jump[0], 481 ppc_inst(entry->jump[0] | PPC_HA(reladdr)))) 482 return 0; | 626 /* May not even need this if we're relative to 0 */ 627 if (patch_instruction(&entry->jump[0], 628 ppc_inst_prefix(entry->jump[0] | IMM_H18(reladdr), 629 entry->jump[1] | IMM_L(reladdr)))) 630 return 0; |
483 | 631 |
484 if (patch_instruction(&entry->jump[1], 485 ppc_inst(entry->jump[1] | PPC_LO(reladdr)))) 486 return 0; | 632 } else { 633 /* Stub uses address relative to r2. */ 634 reladdr = (unsigned long)entry - my_r2(sechdrs, me); 635 if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { 636 pr_err("%s: Address %p of stub out of range of %p.\n", 637 me->name, (void *)reladdr, (void *)my_r2); 638 return 0; 639 } 640 pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr); |
487 | 641 |
642 if (patch_instruction(&entry->jump[0], 643 ppc_inst(entry->jump[0] | PPC_HA(reladdr)))) 644 return 0; 645 646 if (patch_instruction(&entry->jump[1], 647 ppc_inst(entry->jump[1] | PPC_LO(reladdr)))) 648 return 0; 649 } 650 |
|
488 // func_desc_t is 8 bytes if ABIv2, else 16 bytes 489 desc = func_desc(addr); 490 for (i = 0; i < sizeof(func_desc_t) / sizeof(u32); i++) { 491 if (patch_instruction(((u32 *)&entry->funcdata) + i, 492 ppc_inst(((u32 *)(&desc))[i]))) 493 return 0; 494 } 495 --- 26 unchanged lines hidden (view full) --- 522 } 523 524 if (!create_stub(sechdrs, &stubs[i], addr, me, name)) 525 return 0; 526 527 return (unsigned long)&stubs[i]; 528} 529 | 651 // func_desc_t is 8 bytes if ABIv2, else 16 bytes 652 desc = func_desc(addr); 653 for (i = 0; i < sizeof(func_desc_t) / sizeof(u32); i++) { 654 if (patch_instruction(((u32 *)&entry->funcdata) + i, 655 ppc_inst(((u32 *)(&desc))[i]))) 656 return 0; 657 } 658 --- 26 unchanged lines hidden (view full) --- 685 } 686 687 if (!create_stub(sechdrs, &stubs[i], addr, me, name)) 688 return 0; 689 690 return (unsigned long)&stubs[i]; 691} 692 |
693#ifdef CONFIG_PPC_KERNEL_PCREL 694/* Create GOT to load the location described in this ptr */ 695static unsigned long got_for_addr(const Elf64_Shdr *sechdrs, 696 unsigned long addr, 697 struct module *me, 698 const char *name) 699{ 700 struct ppc64_got_entry *got; 701 unsigned int i, num_got; 702 703 if (!IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) 704 return addr; 705 706 num_got = sechdrs[me->arch.got_section].sh_size / sizeof(*got); 707 708 /* Find this stub, or if that fails, the next avail. entry */ 709 got = (void *)sechdrs[me->arch.got_section].sh_addr; 710 for (i = 0; got[i].addr; i++) { 711 if (WARN_ON(i >= num_got)) 712 return 0; 713 714 if (got[i].addr == addr) 715 return (unsigned long)&got[i]; 716 } 717 718 got[i].addr = addr; 719 720 return (unsigned long)&got[i]; 721} 722#endif 723 |
|
530/* We expect a noop next: if it is, replace it with instruction to 531 restore r2. */ 532static int restore_r2(const char *name, u32 *instruction, struct module *me) 533{ 534 u32 *prev_insn = instruction - 1; 535 u32 insn_val = *instruction; 536 | 724/* We expect a noop next: if it is, replace it with instruction to 725 restore r2. */ 726static int restore_r2(const char *name, u32 *instruction, struct module *me) 727{ 728 u32 *prev_insn = instruction - 1; 729 u32 insn_val = *instruction; 730 |
731 if (IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) 732 return 0; 733 |
|
537 if (is_mprofile_ftrace_call(name)) 538 return 0; 539 540 /* 541 * Make sure the branch isn't a sibling call. Sibling calls aren't 542 * "link" branches and they don't return, so they don't need the r2 543 * restore afterwards. 544 */ --- 29 unchanged lines hidden (view full) --- 574 Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr; 575 Elf64_Sym *sym; 576 unsigned long *location; 577 unsigned long value; 578 579 pr_debug("Applying ADD relocate section %u to %u\n", relsec, 580 sechdrs[relsec].sh_info); 581 | 734 if (is_mprofile_ftrace_call(name)) 735 return 0; 736 737 /* 738 * Make sure the branch isn't a sibling call. Sibling calls aren't 739 * "link" branches and they don't return, so they don't need the r2 740 * restore afterwards. 741 */ --- 29 unchanged lines hidden (view full) --- 771 Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr; 772 Elf64_Sym *sym; 773 unsigned long *location; 774 unsigned long value; 775 776 pr_debug("Applying ADD relocate section %u to %u\n", relsec, 777 sechdrs[relsec].sh_info); 778 |
779#ifndef CONFIG_PPC_KERNEL_PCREL |
|
582 /* First time we're called, we can fix up .TOC. */ 583 if (!me->arch.toc_fixed) { 584 sym = find_dot_toc(sechdrs, strtab, symindex); 585 /* It's theoretically possible that a module doesn't want a 586 * .TOC. so don't fail it just for that. */ 587 if (sym) 588 sym->st_value = my_r2(sechdrs, me); 589 me->arch.toc_fixed = true; 590 } | 780 /* First time we're called, we can fix up .TOC. */ 781 if (!me->arch.toc_fixed) { 782 sym = find_dot_toc(sechdrs, strtab, symindex); 783 /* It's theoretically possible that a module doesn't want a 784 * .TOC. so don't fail it just for that. */ 785 if (sym) 786 sym->st_value = my_r2(sechdrs, me); 787 me->arch.toc_fixed = true; 788 } |
591 | 789#endif |
592 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { 593 /* This is where to make the change */ 594 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 595 + rela[i].r_offset; 596 /* This is the symbol it is referring to */ 597 sym = (Elf64_Sym *)sechdrs[symindex].sh_addr 598 + ELF64_R_SYM(rela[i].r_info); 599 --- 11 unchanged lines hidden (view full) --- 611 *(u32 *)location = value; 612 break; 613 614 case R_PPC64_ADDR64: 615 /* Simply set it */ 616 *(unsigned long *)location = value; 617 break; 618 | 790 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { 791 /* This is where to make the change */ 792 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 793 + rela[i].r_offset; 794 /* This is the symbol it is referring to */ 795 sym = (Elf64_Sym *)sechdrs[symindex].sh_addr 796 + ELF64_R_SYM(rela[i].r_info); 797 --- 11 unchanged lines hidden (view full) --- 809 *(u32 *)location = value; 810 break; 811 812 case R_PPC64_ADDR64: 813 /* Simply set it */ 814 *(unsigned long *)location = value; 815 break; 816 |
817#ifndef CONFIG_PPC_KERNEL_PCREL |
|
619 case R_PPC64_TOC: 620 *(unsigned long *)location = my_r2(sechdrs, me); 621 break; 622 623 case R_PPC64_TOC16: 624 /* Subtract TOC pointer */ 625 value -= my_r2(sechdrs, me); 626 if (value + 0x8000 > 0xffff) { --- 43 unchanged lines hidden (view full) --- 670 case R_PPC64_TOC16_HA: 671 /* Subtract TOC pointer */ 672 value -= my_r2(sechdrs, me); 673 value = ((value + 0x8000) >> 16); 674 *((uint16_t *) location) 675 = (*((uint16_t *) location) & ~0xffff) 676 | (value & 0xffff); 677 break; | 818 case R_PPC64_TOC: 819 *(unsigned long *)location = my_r2(sechdrs, me); 820 break; 821 822 case R_PPC64_TOC16: 823 /* Subtract TOC pointer */ 824 value -= my_r2(sechdrs, me); 825 if (value + 0x8000 > 0xffff) { --- 43 unchanged lines hidden (view full) --- 869 case R_PPC64_TOC16_HA: 870 /* Subtract TOC pointer */ 871 value -= my_r2(sechdrs, me); 872 value = ((value + 0x8000) >> 16); 873 *((uint16_t *) location) 874 = (*((uint16_t *) location) & ~0xffff) 875 | (value & 0xffff); 876 break; |
877#endif |
|
678 679 case R_PPC_REL24: | 878 879 case R_PPC_REL24: |
880#ifdef CONFIG_PPC_KERNEL_PCREL 881 /* PCREL still generates REL24 for mcount */ 882 case R_PPC64_REL24_NOTOC: 883#endif |
|
680 /* FIXME: Handle weak symbols here --RR */ 681 if (sym->st_shndx == SHN_UNDEF || 682 sym->st_shndx == SHN_LIVEPATCH) { 683 /* External: go via stub */ 684 value = stub_for_addr(sechdrs, value, me, 685 strtab + sym->st_name); 686 if (!value) 687 return -ENOENT; --- 31 unchanged lines hidden (view full) --- 719 if (value + 0x80000000 > 0xffffffff) { 720 pr_err("%s: REL32 %li out of range!\n", 721 me->name, (long int)value); 722 return -ENOEXEC; 723 } 724 *(u32 *)location = value; 725 break; 726 | 884 /* FIXME: Handle weak symbols here --RR */ 885 if (sym->st_shndx == SHN_UNDEF || 886 sym->st_shndx == SHN_LIVEPATCH) { 887 /* External: go via stub */ 888 value = stub_for_addr(sechdrs, value, me, 889 strtab + sym->st_name); 890 if (!value) 891 return -ENOENT; --- 31 unchanged lines hidden (view full) --- 923 if (value + 0x80000000 > 0xffffffff) { 924 pr_err("%s: REL32 %li out of range!\n", 925 me->name, (long int)value); 926 return -ENOEXEC; 927 } 928 *(u32 *)location = value; 929 break; 930 |
931#ifdef CONFIG_PPC_KERNEL_PCREL 932 case R_PPC64_PCREL34: { 933 unsigned long absvalue = value; 934 935 /* Convert value to relative */ 936 value -= (unsigned long)location; 937 938 if (value + 0x200000000 > 0x3ffffffff) { 939 if (sym->st_shndx != me->arch.pcpu_section) { 940 pr_err("%s: REL34 %li out of range!\n", 941 me->name, (long)value); 942 return -ENOEXEC; 943 } 944 945 /* 946 * per-cpu section is special cased because 947 * it is moved during loading, so has to be 948 * converted to use GOT. 949 */ 950 value = got_for_addr(sechdrs, absvalue, me, 951 strtab + sym->st_name); 952 if (!value) 953 return -ENOENT; 954 value -= (unsigned long)location; 955 956 /* Turn pla into pld */ 957 if (patch_instruction((u32 *)location, 958 ppc_inst_prefix((*(u32 *)location & ~0x02000000), 959 (*((u32 *)location + 1) & ~0xf8000000) | 0xe4000000))) 960 return -EFAULT; 961 } 962 963 if (patch_instruction((u32 *)location, 964 ppc_inst_prefix((*(u32 *)location & ~0x3ffff) | IMM_H18(value), 965 (*((u32 *)location + 1) & ~0xffff) | IMM_L(value)))) 966 return -EFAULT; 967 968 break; 969 } 970 971#else |
|
727 case R_PPC64_TOCSAVE: 728 /* 729 * Marker reloc indicates we don't have to save r2. 730 * That would only save us one instruction, so ignore 731 * it. 732 */ 733 break; | 972 case R_PPC64_TOCSAVE: 973 /* 974 * Marker reloc indicates we don't have to save r2. 975 * That would only save us one instruction, so ignore 976 * it. 977 */ 978 break; |
979#endif |
|
734 735 case R_PPC64_ENTRY: | 980 981 case R_PPC64_ENTRY: |
982 if (IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) 983 break; 984 |
|
736 /* 737 * Optimize ELFv2 large code model entry point if 738 * the TOC is within 2GB range of current location. 739 */ 740 value = my_r2(sechdrs, me) - (unsigned long)location; 741 if (value + 0x80008000 > 0xffffffff) 742 break; 743 /* --- 26 unchanged lines hidden (view full) --- 770 case R_PPC64_REL16_LO: 771 /* Subtract location pointer */ 772 value -= (unsigned long)location; 773 *((uint16_t *) location) 774 = (*((uint16_t *) location) & ~0xffff) 775 | (value & 0xffff); 776 break; 777 | 985 /* 986 * Optimize ELFv2 large code model entry point if 987 * the TOC is within 2GB range of current location. 988 */ 989 value = my_r2(sechdrs, me) - (unsigned long)location; 990 if (value + 0x80008000 > 0xffffffff) 991 break; 992 /* --- 26 unchanged lines hidden (view full) --- 1019 case R_PPC64_REL16_LO: 1020 /* Subtract location pointer */ 1021 value -= (unsigned long)location; 1022 *((uint16_t *) location) 1023 = (*((uint16_t *) location) & ~0xffff) 1024 | (value & 0xffff); 1025 break; 1026 |
1027#ifdef CONFIG_PPC_KERNEL_PCREL 1028 case R_PPC64_GOT_PCREL34: 1029 value = got_for_addr(sechdrs, value, me, 1030 strtab + sym->st_name); 1031 if (!value) 1032 return -ENOENT; 1033 value -= (unsigned long)location; 1034 ((uint32_t *)location)[0] = (((uint32_t *)location)[0] & ~0x3ffff) | 1035 ((value >> 16) & 0x3ffff); 1036 ((uint32_t *)location)[1] = (((uint32_t *)location)[1] & ~0xffff) | 1037 (value & 0xffff); 1038 break; 1039#endif 1040 |
|
778 default: 779 pr_err("%s: Unknown ADD relocation: %lu\n", 780 me->name, 781 (unsigned long)ELF64_R_TYPE(rela[i].r_info)); 782 return -ENOEXEC; 783 } 784 } 785 --- 61 unchanged lines hidden --- | 1041 default: 1042 pr_err("%s: Unknown ADD relocation: %lu\n", 1043 me->name, 1044 (unsigned long)ELF64_R_TYPE(rela[i].r_info)); 1045 return -ENOEXEC; 1046 } 1047 } 1048 --- 61 unchanged lines hidden --- |