1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Author: Hanlu Li <lihanlu@loongson.cn> 4 * Huacai Chen <chenhuacai@loongson.cn> 5 * 6 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 7 */ 8 9 #define pr_fmt(fmt) "kmod: " fmt 10 11 #include <linux/moduleloader.h> 12 #include <linux/elf.h> 13 #include <linux/mm.h> 14 #include <linux/numa.h> 15 #include <linux/vmalloc.h> 16 #include <linux/slab.h> 17 #include <linux/fs.h> 18 #include <linux/ftrace.h> 19 #include <linux/string.h> 20 #include <linux/kernel.h> 21 #include <asm/alternative.h> 22 #include <asm/inst.h> 23 #include <asm/unwind.h> 24 25 /* 26 * reloc_rela_handler() - Apply a particular relocation to a module 27 * @mod: the module to apply the reloc to 28 * @location: the address at which the reloc is to be applied 29 * @v: the value of the reloc, with addend for RELA-style 30 * @rela_stack: the stack used for store relocation info, LOCAL to THIS module 31 * @rela_stac_top: where the stack operation(pop/push) applies to 32 * 33 * Return: 0 upon success, else -ERRNO 34 */ 35 typedef int (*reloc_rela_handler)(struct module *mod, u32 *location, Elf_Addr v, 36 long *rela_stack, size_t *rela_stack_top, unsigned int type); 37 38 static int rela_stack_push(long stack_value, long *rela_stack, size_t *rela_stack_top) 39 { 40 if (*rela_stack_top >= RELA_STACK_DEPTH) 41 return -ENOEXEC; 42 43 rela_stack[(*rela_stack_top)++] = stack_value; 44 pr_debug("%s stack_value = 0x%lx\n", __func__, stack_value); 45 46 return 0; 47 } 48 49 static int rela_stack_pop(long *stack_value, long *rela_stack, size_t *rela_stack_top) 50 { 51 if (*rela_stack_top == 0) 52 return -ENOEXEC; 53 54 *stack_value = rela_stack[--(*rela_stack_top)]; 55 pr_debug("%s stack_value = 0x%lx\n", __func__, *stack_value); 56 57 return 0; 58 } 59 60 static int apply_r_larch_none(struct module *mod, u32 *location, Elf_Addr v, 61 long *rela_stack, size_t *rela_stack_top, unsigned int type) 62 { 63 return 0; 64 } 65 66 static int apply_r_larch_error(struct module *me, u32 *location, Elf_Addr v, 67 long *rela_stack, size_t *rela_stack_top, unsigned int type) 68 { 69 pr_err("%s: Unsupport relocation type %u, please add its support.\n", me->name, type); 70 return -EINVAL; 71 } 72 73 static int apply_r_larch_32(struct module *mod, u32 *location, Elf_Addr v, 74 long *rela_stack, size_t *rela_stack_top, unsigned int type) 75 { 76 *location = v; 77 return 0; 78 } 79 80 #ifdef CONFIG_32BIT 81 #define apply_r_larch_64 apply_r_larch_error 82 #else 83 static int apply_r_larch_64(struct module *mod, u32 *location, Elf_Addr v, 84 long *rela_stack, size_t *rela_stack_top, unsigned int type) 85 { 86 *(Elf_Addr *)location = v; 87 return 0; 88 } 89 #endif 90 91 static int apply_r_larch_sop_push_pcrel(struct module *mod, u32 *location, Elf_Addr v, 92 long *rela_stack, size_t *rela_stack_top, unsigned int type) 93 { 94 return rela_stack_push(v - (unsigned long)location, rela_stack, rela_stack_top); 95 } 96 97 static int apply_r_larch_sop_push_absolute(struct module *mod, u32 *location, Elf_Addr v, 98 long *rela_stack, size_t *rela_stack_top, unsigned int type) 99 { 100 return rela_stack_push(v, rela_stack, rela_stack_top); 101 } 102 103 static int apply_r_larch_sop_push_dup(struct module *mod, u32 *location, Elf_Addr v, 104 long *rela_stack, size_t *rela_stack_top, unsigned int type) 105 { 106 int err = 0; 107 long opr1; 108 109 err = rela_stack_pop(&opr1, rela_stack, rela_stack_top); 110 if (err) 111 return err; 112 err = rela_stack_push(opr1, rela_stack, rela_stack_top); 113 if (err) 114 return err; 115 err = rela_stack_push(opr1, rela_stack, rela_stack_top); 116 if (err) 117 return err; 118 119 return 0; 120 } 121 122 static int apply_r_larch_sop_push_plt_pcrel(struct module *mod, 123 Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, 124 long *rela_stack, size_t *rela_stack_top, unsigned int type) 125 { 126 ptrdiff_t offset = (void *)v - (void *)location; 127 128 if (offset >= SZ_128M) 129 v = module_emit_plt_entry(mod, sechdrs, v); 130 131 if (offset < -SZ_128M) 132 v = module_emit_plt_entry(mod, sechdrs, v); 133 134 return apply_r_larch_sop_push_pcrel(mod, location, v, rela_stack, rela_stack_top, type); 135 } 136 137 static int apply_r_larch_sop(struct module *mod, u32 *location, Elf_Addr v, 138 long *rela_stack, size_t *rela_stack_top, unsigned int type) 139 { 140 int err = 0; 141 long opr1, opr2, opr3; 142 143 if (type == R_LARCH_SOP_IF_ELSE) { 144 err = rela_stack_pop(&opr3, rela_stack, rela_stack_top); 145 if (err) 146 return err; 147 } 148 149 err = rela_stack_pop(&opr2, rela_stack, rela_stack_top); 150 if (err) 151 return err; 152 err = rela_stack_pop(&opr1, rela_stack, rela_stack_top); 153 if (err) 154 return err; 155 156 switch (type) { 157 case R_LARCH_SOP_AND: 158 err = rela_stack_push(opr1 & opr2, rela_stack, rela_stack_top); 159 break; 160 case R_LARCH_SOP_ADD: 161 err = rela_stack_push(opr1 + opr2, rela_stack, rela_stack_top); 162 break; 163 case R_LARCH_SOP_SUB: 164 err = rela_stack_push(opr1 - opr2, rela_stack, rela_stack_top); 165 break; 166 case R_LARCH_SOP_SL: 167 err = rela_stack_push(opr1 << opr2, rela_stack, rela_stack_top); 168 break; 169 case R_LARCH_SOP_SR: 170 err = rela_stack_push(opr1 >> opr2, rela_stack, rela_stack_top); 171 break; 172 case R_LARCH_SOP_IF_ELSE: 173 err = rela_stack_push(opr1 ? opr2 : opr3, rela_stack, rela_stack_top); 174 break; 175 default: 176 pr_err("%s: Unsupport relocation type %u\n", mod->name, type); 177 return -EINVAL; 178 } 179 180 return err; 181 } 182 183 static int apply_r_larch_sop_imm_field(struct module *mod, u32 *location, Elf_Addr v, 184 long *rela_stack, size_t *rela_stack_top, unsigned int type) 185 { 186 int err = 0; 187 long opr1; 188 union loongarch_instruction *insn = (union loongarch_instruction *)location; 189 190 err = rela_stack_pop(&opr1, rela_stack, rela_stack_top); 191 if (err) 192 return err; 193 194 switch (type) { 195 case R_LARCH_SOP_POP_32_U_10_12: 196 if (!unsigned_imm_check(opr1, 12)) 197 goto overflow; 198 199 /* (*(uint32_t *) PC) [21 ... 10] = opr [11 ... 0] */ 200 insn->reg2i12_format.immediate = opr1 & 0xfff; 201 return 0; 202 case R_LARCH_SOP_POP_32_S_10_12: 203 if (!signed_imm_check(opr1, 12)) 204 goto overflow; 205 206 insn->reg2i12_format.immediate = opr1 & 0xfff; 207 return 0; 208 case R_LARCH_SOP_POP_32_S_10_16: 209 if (!signed_imm_check(opr1, 16)) 210 goto overflow; 211 212 insn->reg2i16_format.immediate = opr1 & 0xffff; 213 return 0; 214 case R_LARCH_SOP_POP_32_S_10_16_S2: 215 if (opr1 % 4) 216 goto unaligned; 217 218 if (!signed_imm_check(opr1, 18)) 219 goto overflow; 220 221 insn->reg2i16_format.immediate = (opr1 >> 2) & 0xffff; 222 return 0; 223 case R_LARCH_SOP_POP_32_S_5_20: 224 if (!signed_imm_check(opr1, 20)) 225 goto overflow; 226 227 insn->reg1i20_format.immediate = (opr1) & 0xfffff; 228 return 0; 229 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: 230 if (opr1 % 4) 231 goto unaligned; 232 233 if (!signed_imm_check(opr1, 23)) 234 goto overflow; 235 236 opr1 >>= 2; 237 insn->reg1i21_format.immediate_l = opr1 & 0xffff; 238 insn->reg1i21_format.immediate_h = (opr1 >> 16) & 0x1f; 239 return 0; 240 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: 241 if (opr1 % 4) 242 goto unaligned; 243 244 if (!signed_imm_check(opr1, 28)) 245 goto overflow; 246 247 opr1 >>= 2; 248 insn->reg0i26_format.immediate_l = opr1 & 0xffff; 249 insn->reg0i26_format.immediate_h = (opr1 >> 16) & 0x3ff; 250 return 0; 251 case R_LARCH_SOP_POP_32_U: 252 if (!unsigned_imm_check(opr1, 32)) 253 goto overflow; 254 255 /* (*(uint32_t *) PC) = opr */ 256 *location = (u32)opr1; 257 return 0; 258 default: 259 pr_err("%s: Unsupport relocation type %u\n", mod->name, type); 260 return -EINVAL; 261 } 262 263 overflow: 264 pr_err("module %s: opr1 = 0x%lx overflow! dangerous %s (%u) relocation\n", 265 mod->name, opr1, __func__, type); 266 return -ENOEXEC; 267 268 unaligned: 269 pr_err("module %s: opr1 = 0x%lx unaligned! dangerous %s (%u) relocation\n", 270 mod->name, opr1, __func__, type); 271 return -ENOEXEC; 272 } 273 274 static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Addr v, 275 long *rela_stack, size_t *rela_stack_top, unsigned int type) 276 { 277 switch (type) { 278 case R_LARCH_ADD32: 279 *(s32 *)location += v; 280 return 0; 281 case R_LARCH_SUB32: 282 *(s32 *)location -= v; 283 return 0; 284 #ifdef CONFIG_64BIT 285 case R_LARCH_ADD64: 286 *(s64 *)location += v; 287 return 0; 288 case R_LARCH_SUB64: 289 *(s64 *)location -= v; 290 #endif 291 return 0; 292 default: 293 pr_err("%s: Unsupport relocation type %u\n", mod->name, type); 294 return -EINVAL; 295 } 296 } 297 298 static int apply_r_larch_b26(struct module *mod, 299 Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, 300 long *rela_stack, size_t *rela_stack_top, unsigned int type) 301 { 302 ptrdiff_t offset = (void *)v - (void *)location; 303 union loongarch_instruction *insn = (union loongarch_instruction *)location; 304 305 if (offset >= SZ_128M) 306 v = module_emit_plt_entry(mod, sechdrs, v); 307 308 if (offset < -SZ_128M) 309 v = module_emit_plt_entry(mod, sechdrs, v); 310 311 offset = (void *)v - (void *)location; 312 313 if (offset & 3) { 314 pr_err("module %s: jump offset = 0x%llx unaligned! dangerous R_LARCH_B26 (%u) relocation\n", 315 mod->name, (long long)offset, type); 316 return -ENOEXEC; 317 } 318 319 if (!signed_imm_check(offset, 28)) { 320 pr_err("module %s: jump offset = 0x%llx overflow! dangerous R_LARCH_B26 (%u) relocation\n", 321 mod->name, (long long)offset, type); 322 return -ENOEXEC; 323 } 324 325 offset >>= 2; 326 insn->reg0i26_format.immediate_l = offset & 0xffff; 327 insn->reg0i26_format.immediate_h = (offset >> 16) & 0x3ff; 328 329 return 0; 330 } 331 332 static int apply_r_larch_pcadd(struct module *mod, u32 *location, Elf_Addr v, 333 long *rela_stack, size_t *rela_stack_top, unsigned int type) 334 { 335 union loongarch_instruction *insn = (union loongarch_instruction *)location; 336 /* Use s32 for a sign-extension deliberately. */ 337 s32 offset_hi20 = (void *)((v + 0x800)) - (void *)((Elf_Addr)location); 338 339 switch (type) { 340 case R_LARCH_PCADD_LO12: 341 insn->reg2i12_format.immediate = v & 0xfff; 342 break; 343 case R_LARCH_PCADD_HI20: 344 v = offset_hi20 >> 12; 345 insn->reg1i20_format.immediate = v & 0xfffff; 346 break; 347 default: 348 pr_err("%s: Unsupport relocation type %u\n", mod->name, type); 349 return -EINVAL; 350 } 351 352 return 0; 353 } 354 355 static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v, 356 long *rela_stack, size_t *rela_stack_top, unsigned int type) 357 { 358 union loongarch_instruction *insn = (union loongarch_instruction *)location; 359 /* Use s32 for a sign-extension deliberately. */ 360 s32 offset_hi20 = (void *)((v + 0x800) & ~0xfff) - 361 (void *)((Elf_Addr)location & ~0xfff); 362 #ifdef CONFIG_64BIT 363 Elf_Addr anchor = (((Elf_Addr)location) & ~0xfff) + offset_hi20; 364 ptrdiff_t offset_rem = (void *)v - (void *)anchor; 365 #endif 366 367 switch (type) { 368 case R_LARCH_PCALA_LO12: 369 insn->reg2i12_format.immediate = v & 0xfff; 370 break; 371 case R_LARCH_PCALA_HI20: 372 v = offset_hi20 >> 12; 373 insn->reg1i20_format.immediate = v & 0xfffff; 374 break; 375 #ifdef CONFIG_64BIT 376 case R_LARCH_PCALA64_LO20: 377 v = offset_rem >> 32; 378 insn->reg1i20_format.immediate = v & 0xfffff; 379 break; 380 case R_LARCH_PCALA64_HI12: 381 v = offset_rem >> 52; 382 insn->reg2i12_format.immediate = v & 0xfff; 383 break; 384 #endif 385 default: 386 pr_err("%s: Unsupport relocation type %u\n", mod->name, type); 387 return -EINVAL; 388 } 389 390 return 0; 391 } 392 393 static int apply_r_larch_got_pc(struct module *mod, 394 Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, 395 long *rela_stack, size_t *rela_stack_top, unsigned int type) 396 { 397 reloc_rela_handler got_handler; 398 399 if (type != R_LARCH_GOT_PCADD_LO12) { 400 v = module_emit_got_entry(mod, sechdrs, v); 401 if (!v) 402 return -EINVAL; 403 } 404 405 switch (type) { 406 case R_LARCH_GOT_PC_LO12: 407 type = R_LARCH_PCALA_LO12; 408 got_handler = apply_r_larch_pcala; 409 break; 410 case R_LARCH_GOT_PC_HI20: 411 type = R_LARCH_PCALA_HI20; 412 got_handler = apply_r_larch_pcala; 413 break; 414 case R_LARCH_GOT_PCADD_LO12: 415 type = R_LARCH_PCADD_LO12; 416 got_handler = apply_r_larch_pcadd; 417 break; 418 case R_LARCH_GOT_PCADD_HI20: 419 type = R_LARCH_PCADD_HI20; 420 got_handler = apply_r_larch_pcadd; 421 break; 422 default: 423 pr_err("%s: Unsupport relocation type %u\n", mod->name, type); 424 return -EINVAL; 425 } 426 427 return got_handler(mod, location, v, rela_stack, rela_stack_top, type); 428 } 429 430 static int apply_r_larch_32_pcrel(struct module *mod, u32 *location, Elf_Addr v, 431 long *rela_stack, size_t *rela_stack_top, unsigned int type) 432 { 433 ptrdiff_t offset = (void *)v - (void *)location; 434 435 *(u32 *)location = offset; 436 return 0; 437 } 438 439 #ifdef CONFIG_32BIT 440 #define apply_r_larch_64_pcrel apply_r_larch_error 441 #else 442 static int apply_r_larch_64_pcrel(struct module *mod, u32 *location, Elf_Addr v, 443 long *rela_stack, size_t *rela_stack_top, unsigned int type) 444 { 445 ptrdiff_t offset = (void *)v - (void *)location; 446 447 *(u64 *)location = offset; 448 return 0; 449 } 450 #endif 451 452 /* The handlers for known reloc types */ 453 static reloc_rela_handler reloc_rela_handlers[] = { 454 [R_LARCH_NONE ... R_LARCH_TLS_DESC_PCADD_LO12] = apply_r_larch_error, 455 456 [R_LARCH_NONE] = apply_r_larch_none, 457 [R_LARCH_32] = apply_r_larch_32, 458 [R_LARCH_64] = apply_r_larch_64, 459 [R_LARCH_MARK_LA] = apply_r_larch_none, 460 [R_LARCH_MARK_PCREL] = apply_r_larch_none, 461 [R_LARCH_SOP_PUSH_PCREL] = apply_r_larch_sop_push_pcrel, 462 [R_LARCH_SOP_PUSH_ABSOLUTE] = apply_r_larch_sop_push_absolute, 463 [R_LARCH_SOP_PUSH_DUP] = apply_r_larch_sop_push_dup, 464 [R_LARCH_SOP_SUB ... R_LARCH_SOP_IF_ELSE] = apply_r_larch_sop, 465 [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field, 466 [R_LARCH_ADD32 ... R_LARCH_SUB64] = apply_r_larch_add_sub, 467 [R_LARCH_PCADD_HI20 ... R_LARCH_PCADD_LO12] = apply_r_larch_pcadd, 468 [R_LARCH_PCALA_HI20 ... R_LARCH_PCALA64_HI12] = apply_r_larch_pcala, 469 [R_LARCH_32_PCREL] = apply_r_larch_32_pcrel, 470 [R_LARCH_64_PCREL] = apply_r_larch_64_pcrel, 471 }; 472 473 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, 474 unsigned int symindex, unsigned int relsec, 475 struct module *mod) 476 { 477 int err; 478 unsigned int i, idx, type; 479 unsigned int num_relocations; 480 long rela_stack[RELA_STACK_DEPTH]; 481 size_t rela_stack_top = 0; 482 reloc_rela_handler handler; 483 void *location; 484 Elf_Addr v; 485 Elf_Sym *sym; 486 Elf_Rela *rel = (void *) sechdrs[relsec].sh_addr; 487 488 pr_debug("%s: Applying relocate section %u to %u\n", __func__, relsec, 489 sechdrs[relsec].sh_info); 490 491 idx = 0; 492 rela_stack_top = 0; 493 num_relocations = sechdrs[relsec].sh_size / sizeof(*rel); 494 for (i = 0; i < num_relocations; i++) { 495 /* This is where to make the change */ 496 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset; 497 /* This is the symbol it is referring to */ 498 sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_R_SYM(rel[i].r_info); 499 if (IS_ERR_VALUE(sym->st_value)) { 500 /* Ignore unresolved weak symbol */ 501 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) 502 continue; 503 pr_warn("%s: Unknown symbol %s\n", mod->name, strtab + sym->st_name); 504 return -ENOENT; 505 } 506 507 type = ELF_R_TYPE(rel[i].r_info); 508 509 if (type < ARRAY_SIZE(reloc_rela_handlers)) 510 handler = reloc_rela_handlers[type]; 511 else 512 handler = NULL; 513 514 if (!handler) { 515 pr_err("%s: Unknown relocation type %u\n", mod->name, type); 516 return -EINVAL; 517 } 518 519 pr_debug("type %d st_value %lx r_addend %lx loc %lx\n", 520 (int)ELF_R_TYPE(rel[i].r_info), 521 (unsigned long)sym->st_value, (unsigned long)rel[i].r_addend, (unsigned long)location); 522 523 v = sym->st_value + rel[i].r_addend; 524 525 if (type == R_LARCH_PCADD_LO12 || type == R_LARCH_GOT_PCADD_LO12) { 526 bool found = false; 527 unsigned int j = idx; 528 529 do { 530 u32 hi20_type = ELF_R_TYPE(rel[j].r_info); 531 unsigned long hi20_location = 532 sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[j].r_offset; 533 534 /* Find the corresponding HI20 relocation entry */ 535 if ((hi20_location == sym->st_value) && (hi20_type == type - 1)) { 536 s32 hi20, lo12; 537 Elf_Sym *hi20_sym = 538 (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_R_SYM(rel[j].r_info); 539 unsigned long hi20_sym_val = hi20_sym->st_value + rel[j].r_addend; 540 541 /* Calculate LO12 offset */ 542 size_t offset = hi20_sym_val - hi20_location; 543 if (hi20_type == R_LARCH_GOT_PCADD_HI20) { 544 offset = module_emit_got_entry(mod, sechdrs, hi20_sym_val); 545 offset = offset - hi20_location; 546 } 547 hi20 = (offset + 0x800) & 0xfffff000; 548 v = lo12 = offset - hi20; 549 found = true; 550 break; 551 } 552 553 j = (j + 1) % num_relocations; 554 555 } while (idx != j); 556 557 if (!found) { 558 pr_err("%s: Can not find HI20 relocation information\n", mod->name); 559 return -EINVAL; 560 } 561 562 idx = j; /* Record the previous j-loop end index */ 563 } 564 565 switch (type) { 566 case R_LARCH_B26: 567 err = apply_r_larch_b26(mod, sechdrs, location, 568 v, rela_stack, &rela_stack_top, type); 569 break; 570 case R_LARCH_GOT_PC_HI20...R_LARCH_GOT_PC_LO12: 571 case R_LARCH_GOT_PCADD_HI20...R_LARCH_GOT_PCADD_LO12: 572 err = apply_r_larch_got_pc(mod, sechdrs, location, 573 v, rela_stack, &rela_stack_top, type); 574 break; 575 case R_LARCH_SOP_PUSH_PLT_PCREL: 576 err = apply_r_larch_sop_push_plt_pcrel(mod, sechdrs, location, 577 v, rela_stack, &rela_stack_top, type); 578 break; 579 default: 580 err = handler(mod, location, v, rela_stack, &rela_stack_top, type); 581 } 582 if (err) 583 return err; 584 } 585 586 return 0; 587 } 588 589 static void module_init_ftrace_plt(const Elf_Ehdr *hdr, 590 const Elf_Shdr *sechdrs, struct module *mod) 591 { 592 #ifdef CONFIG_DYNAMIC_FTRACE 593 struct plt_entry *ftrace_plts; 594 595 ftrace_plts = (void *)sechdrs->sh_addr; 596 597 ftrace_plts[FTRACE_PLT_IDX] = emit_plt_entry(FTRACE_ADDR); 598 599 if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS)) 600 ftrace_plts[FTRACE_REGS_PLT_IDX] = emit_plt_entry(FTRACE_REGS_ADDR); 601 602 mod->arch.ftrace_trampolines = ftrace_plts; 603 #endif 604 } 605 606 int module_finalize(const Elf_Ehdr *hdr, 607 const Elf_Shdr *sechdrs, struct module *mod) 608 { 609 const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; 610 const Elf_Shdr *s, *alt = NULL, *orc = NULL, *orc_ip = NULL, *ftrace = NULL; 611 612 for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { 613 if (!strcmp(".altinstructions", secstrs + s->sh_name)) 614 alt = s; 615 if (!strcmp(".orc_unwind", secstrs + s->sh_name)) 616 orc = s; 617 if (!strcmp(".orc_unwind_ip", secstrs + s->sh_name)) 618 orc_ip = s; 619 if (!strcmp(".ftrace_trampoline", secstrs + s->sh_name)) 620 ftrace = s; 621 } 622 623 if (alt) 624 apply_alternatives((void *)alt->sh_addr, (void *)alt->sh_addr + alt->sh_size); 625 626 if (orc && orc_ip) 627 unwind_module_init(mod, (void *)orc_ip->sh_addr, orc_ip->sh_size, (void *)orc->sh_addr, orc->sh_size); 628 629 if (ftrace) 630 module_init_ftrace_plt(hdr, ftrace, mod); 631 632 return 0; 633 } 634