1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21#include <linux/module.h>
22#include <linux/elf.h>
23#include <linux/moduleloader.h>
24#include <linux/err.h>
25#include <linux/vmalloc.h>
26#include <linux/ftrace.h>
27#include <linux/bug.h>
28#include <linux/uaccess.h>
29#include <asm/module.h>
30#include <asm/firmware.h>
31#include <asm/code-patching.h>
32#include <linux/sort.h>
33#include <asm/setup.h>
34#include <asm/sections.h>
35
36
37
38
39
40
41
42
43
44#if defined(_CALL_ELF) && _CALL_ELF == 2
45
46
47typedef unsigned long func_desc_t;
48
49static func_desc_t func_desc(unsigned long addr)
50{
51 return addr;
52}
53static unsigned long func_addr(unsigned long addr)
54{
55 return addr;
56}
57static unsigned long stub_func_addr(func_desc_t func)
58{
59 return func;
60}
61
62
63#define STO_PPC64_LOCAL_BIT 5
64#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
65#define PPC64_LOCAL_ENTRY_OFFSET(other) \
66 (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
67
68static unsigned int local_entry_offset(const Elf64_Sym *sym)
69{
70
71
72
73 return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
74}
75#else
76
77
78typedef struct ppc64_opd_entry func_desc_t;
79
80static func_desc_t func_desc(unsigned long addr)
81{
82 return *(struct ppc64_opd_entry *)addr;
83}
84static unsigned long func_addr(unsigned long addr)
85{
86 return func_desc(addr).funcaddr;
87}
88static unsigned long stub_func_addr(func_desc_t func)
89{
90 return func.funcaddr;
91}
92static unsigned int local_entry_offset(const Elf64_Sym *sym)
93{
94 return 0;
95}
96#endif
97
98#define STUB_MAGIC 0x73747562
99
100
101
102
103struct ppc64_stub_entry
104{
105
106
107
108 u32 jump[7];
109
110 u32 magic;
111
112 func_desc_t funcdata;
113};
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129static u32 ppc64_stub_insns[] = {
130 0x3d620000,
131 0x396b0000,
132
133 0xf8410000|R2_STACK_OFFSET,
134 0xe98b0020,
135#if !defined(_CALL_ELF) || _CALL_ELF != 2
136
137 0xe84b0028,
138#endif
139 0x7d8903a6,
140 0x4e800420
141};
142
143#ifdef CONFIG_DYNAMIC_FTRACE
144int module_trampoline_target(struct module *mod, unsigned long addr,
145 unsigned long *target)
146{
147 struct ppc64_stub_entry *stub;
148 func_desc_t funcdata;
149 u32 magic;
150
151 if (!within_module_core(addr, mod)) {
152 pr_err("%s: stub %lx not in module %s\n", __func__, addr, mod->name);
153 return -EFAULT;
154 }
155
156 stub = (struct ppc64_stub_entry *)addr;
157
158 if (probe_kernel_read(&magic, &stub->magic, sizeof(magic))) {
159 pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name);
160 return -EFAULT;
161 }
162
163 if (magic != STUB_MAGIC) {
164 pr_err("%s: bad magic for stub %lx for %s\n", __func__, addr, mod->name);
165 return -EFAULT;
166 }
167
168 if (probe_kernel_read(&funcdata, &stub->funcdata, sizeof(funcdata))) {
169 pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name);
170 return -EFAULT;
171 }
172
173 *target = stub_func_addr(funcdata);
174
175 return 0;
176}
177#endif
178
179
180
181static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num)
182{
183 unsigned int i, r_info, r_addend, _count_relocs;
184
185
186 _count_relocs = 0;
187 r_info = 0;
188 r_addend = 0;
189 for (i = 0; i < num; i++)
190
191 if (ELF64_R_TYPE(rela[i].r_info) == R_PPC_REL24 &&
192 (r_info != ELF64_R_SYM(rela[i].r_info) ||
193 r_addend != rela[i].r_addend)) {
194 _count_relocs++;
195 r_info = ELF64_R_SYM(rela[i].r_info);
196 r_addend = rela[i].r_addend;
197 }
198
199 return _count_relocs;
200}
201
202static int relacmp(const void *_x, const void *_y)
203{
204 const Elf64_Rela *x, *y;
205
206 y = (Elf64_Rela *)_x;
207 x = (Elf64_Rela *)_y;
208
209
210
211
212
213 if (x->r_info < y->r_info)
214 return -1;
215 else if (x->r_info > y->r_info)
216 return 1;
217 else if (x->r_addend < y->r_addend)
218 return -1;
219 else if (x->r_addend > y->r_addend)
220 return 1;
221 else
222 return 0;
223}
224
225static void relaswap(void *_x, void *_y, int size)
226{
227 uint64_t *x, *y, tmp;
228 int i;
229
230 y = (uint64_t *)_x;
231 x = (uint64_t *)_y;
232
233 for (i = 0; i < sizeof(Elf64_Rela) / sizeof(uint64_t); i++) {
234 tmp = x[i];
235 x[i] = y[i];
236 y[i] = tmp;
237 }
238}
239
240
241static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
242 const Elf64_Shdr *sechdrs)
243{
244
245 unsigned long relocs = 1;
246 unsigned i;
247
248
249 for (i = 1; i < hdr->e_shnum; i++) {
250 if (sechdrs[i].sh_type == SHT_RELA) {
251 pr_debug("Found relocations in section %u\n", i);
252 pr_debug("Ptr: %p. Number: %Lu\n",
253 (void *)sechdrs[i].sh_addr,
254 sechdrs[i].sh_size / sizeof(Elf64_Rela));
255
256
257
258
259
260
261 sort((void *)sechdrs[i].sh_addr,
262 sechdrs[i].sh_size / sizeof(Elf64_Rela),
263 sizeof(Elf64_Rela), relacmp, relaswap);
264
265 relocs += count_relocs((void *)sechdrs[i].sh_addr,
266 sechdrs[i].sh_size
267 / sizeof(Elf64_Rela));
268 }
269 }
270
271#ifdef CONFIG_DYNAMIC_FTRACE
272
273 relocs++;
274#endif
275
276 pr_debug("Looks like a total of %lu stubs, max\n", relocs);
277 return relocs * sizeof(struct ppc64_stub_entry);
278}
279
280
281static void dedotify_versions(struct modversion_info *vers,
282 unsigned long size)
283{
284 struct modversion_info *end;
285
286 for (end = (void *)vers + size; vers < end; vers++)
287 if (vers->name[0] == '.') {
288 memmove(vers->name, vers->name+1, strlen(vers->name));
289#ifdef ARCH_RELOCATES_KCRCTAB
290
291
292
293
294 if (!strcmp(vers->name, "TOC."))
295 vers->crc = -(unsigned long)reloc_start;
296#endif
297 }
298}
299
300
301
302
303
304static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab)
305{
306 unsigned int i;
307
308 for (i = 1; i < numsyms; i++) {
309 if (syms[i].st_shndx == SHN_UNDEF) {
310 char *name = strtab + syms[i].st_name;
311 if (name[0] == '.') {
312 if (strcmp(name+1, "TOC.") == 0)
313 syms[i].st_shndx = SHN_ABS;
314 syms[i].st_name++;
315 }
316 }
317 }
318}
319
320static Elf64_Sym *find_dot_toc(Elf64_Shdr *sechdrs,
321 const char *strtab,
322 unsigned int symindex)
323{
324 unsigned int i, numsyms;
325 Elf64_Sym *syms;
326
327 syms = (Elf64_Sym *)sechdrs[symindex].sh_addr;
328 numsyms = sechdrs[symindex].sh_size / sizeof(Elf64_Sym);
329
330 for (i = 1; i < numsyms; i++) {
331 if (syms[i].st_shndx == SHN_ABS
332 && strcmp(strtab + syms[i].st_name, "TOC.") == 0)
333 return &syms[i];
334 }
335 return NULL;
336}
337
338int module_frob_arch_sections(Elf64_Ehdr *hdr,
339 Elf64_Shdr *sechdrs,
340 char *secstrings,
341 struct module *me)
342{
343 unsigned int i;
344
345
346 for (i = 1; i < hdr->e_shnum; i++) {
347 char *p;
348 if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0)
349 me->arch.stubs_section = i;
350 else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0)
351 me->arch.toc_section = i;
352 else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
353 dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
354 sechdrs[i].sh_size);
355
356
357 while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))
358 p[0] = '_';
359
360 if (sechdrs[i].sh_type == SHT_SYMTAB)
361 dedotify((void *)hdr + sechdrs[i].sh_offset,
362 sechdrs[i].sh_size / sizeof(Elf64_Sym),
363 (void *)hdr
364 + sechdrs[sechdrs[i].sh_link].sh_offset);
365 }
366
367 if (!me->arch.stubs_section) {
368 pr_err("%s: doesn't contain .stubs.\n", me->name);
369 return -ENOEXEC;
370 }
371
372
373
374
375
376 if (!me->arch.toc_section)
377 me->arch.toc_section = me->arch.stubs_section;
378
379
380 sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
381 return 0;
382}
383
384
385
386
387static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me)
388{
389 return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
390}
391
392
393
394
395#define PPC_LO(v) ((v) & 0xffff)
396#define PPC_HI(v) (((v) >> 16) & 0xffff)
397#define PPC_HA(v) PPC_HI ((v) + 0x8000)
398
399
400static inline int create_stub(const Elf64_Shdr *sechdrs,
401 struct ppc64_stub_entry *entry,
402 unsigned long addr,
403 struct module *me)
404{
405 long reladdr;
406
407 memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns));
408
409
410 reladdr = (unsigned long)entry - my_r2(sechdrs, me);
411 if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
412 pr_err("%s: Address %p of stub out of range of %p.\n",
413 me->name, (void *)reladdr, (void *)my_r2);
414 return 0;
415 }
416 pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr);
417
418 entry->jump[0] |= PPC_HA(reladdr);
419 entry->jump[1] |= PPC_LO(reladdr);
420 entry->funcdata = func_desc(addr);
421 entry->magic = STUB_MAGIC;
422
423 return 1;
424}
425
426
427
428static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs,
429 unsigned long addr,
430 struct module *me)
431{
432 struct ppc64_stub_entry *stubs;
433 unsigned int i, num_stubs;
434
435 num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs);
436
437
438 stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
439 for (i = 0; stub_func_addr(stubs[i].funcdata); i++) {
440 BUG_ON(i >= num_stubs);
441
442 if (stub_func_addr(stubs[i].funcdata) == func_addr(addr))
443 return (unsigned long)&stubs[i];
444 }
445
446 if (!create_stub(sechdrs, &stubs[i], addr, me))
447 return 0;
448
449 return (unsigned long)&stubs[i];
450}
451
452#ifdef CC_USING_MPROFILE_KERNEL
453static bool is_early_mcount_callsite(u32 *instruction)
454{
455
456
457
458 if (instruction[-1] == PPC_INST_STD_LR &&
459 instruction[-2] == PPC_INST_MFLR)
460 return true;
461
462 if (instruction[-1] == PPC_INST_MFLR)
463 return true;
464
465 return false;
466}
467
468
469
470
471
472
473static void squash_toc_save_inst(const char *name, unsigned long addr)
474{
475 struct ppc64_stub_entry *stub = (struct ppc64_stub_entry *)addr;
476
477
478 if (strcmp("_mcount", name) != 0)
479 return;
480
481 stub->jump[2] = PPC_INST_NOP;
482}
483#else
484static void squash_toc_save_inst(const char *name, unsigned long addr) { }
485
486
487static bool is_early_mcount_callsite(u32 *instruction)
488{
489 return false;
490}
491#endif
492
493
494
495static int restore_r2(u32 *instruction, struct module *me)
496{
497 u32 *prev_insn = instruction - 1;
498
499 if (is_early_mcount_callsite(prev_insn))
500 return 1;
501
502
503
504
505
506
507 if (!instr_is_relative_link_branch(*prev_insn))
508 return 1;
509
510 if (*instruction != PPC_INST_NOP) {
511 pr_err("%s: Expected nop after call, got %08x at %pS\n",
512 me->name, *instruction, instruction);
513 return 0;
514 }
515
516 *instruction = PPC_INST_LD_TOC;
517 return 1;
518}
519
520int apply_relocate_add(Elf64_Shdr *sechdrs,
521 const char *strtab,
522 unsigned int symindex,
523 unsigned int relsec,
524 struct module *me)
525{
526 unsigned int i;
527 Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;
528 Elf64_Sym *sym;
529 unsigned long *location;
530 unsigned long value;
531
532 pr_debug("Applying ADD relocate section %u to %u\n", relsec,
533 sechdrs[relsec].sh_info);
534
535
536 if (!me->arch.toc_fixed) {
537 sym = find_dot_toc(sechdrs, strtab, symindex);
538
539
540 if (sym)
541 sym->st_value = my_r2(sechdrs, me);
542 me->arch.toc_fixed = true;
543 }
544
545 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
546
547 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
548 + rela[i].r_offset;
549
550 sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
551 + ELF64_R_SYM(rela[i].r_info);
552
553 pr_debug("RELOC at %p: %li-type as %s (0x%lx) + %li\n",
554 location, (long)ELF64_R_TYPE(rela[i].r_info),
555 strtab + sym->st_name, (unsigned long)sym->st_value,
556 (long)rela[i].r_addend);
557
558
559 value = sym->st_value + rela[i].r_addend;
560
561 switch (ELF64_R_TYPE(rela[i].r_info)) {
562 case R_PPC64_ADDR32:
563
564 *(u32 *)location = value;
565 break;
566
567 case R_PPC64_ADDR64:
568
569 *(unsigned long *)location = value;
570 break;
571
572 case R_PPC64_TOC:
573 *(unsigned long *)location = my_r2(sechdrs, me);
574 break;
575
576 case R_PPC64_TOC16:
577
578 value -= my_r2(sechdrs, me);
579 if (value + 0x8000 > 0xffff) {
580 pr_err("%s: bad TOC16 relocation (0x%lx)\n",
581 me->name, value);
582 return -ENOEXEC;
583 }
584 *((uint16_t *) location)
585 = (*((uint16_t *) location) & ~0xffff)
586 | (value & 0xffff);
587 break;
588
589 case R_PPC64_TOC16_LO:
590
591 value -= my_r2(sechdrs, me);
592 *((uint16_t *) location)
593 = (*((uint16_t *) location) & ~0xffff)
594 | (value & 0xffff);
595 break;
596
597 case R_PPC64_TOC16_DS:
598
599 value -= my_r2(sechdrs, me);
600 if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
601 pr_err("%s: bad TOC16_DS relocation (0x%lx)\n",
602 me->name, value);
603 return -ENOEXEC;
604 }
605 *((uint16_t *) location)
606 = (*((uint16_t *) location) & ~0xfffc)
607 | (value & 0xfffc);
608 break;
609
610 case R_PPC64_TOC16_LO_DS:
611
612 value -= my_r2(sechdrs, me);
613 if ((value & 3) != 0) {
614 pr_err("%s: bad TOC16_LO_DS relocation (0x%lx)\n",
615 me->name, value);
616 return -ENOEXEC;
617 }
618 *((uint16_t *) location)
619 = (*((uint16_t *) location) & ~0xfffc)
620 | (value & 0xfffc);
621 break;
622
623 case R_PPC64_TOC16_HA:
624
625 value -= my_r2(sechdrs, me);
626 value = ((value + 0x8000) >> 16);
627 *((uint16_t *) location)
628 = (*((uint16_t *) location) & ~0xffff)
629 | (value & 0xffff);
630 break;
631
632 case R_PPC_REL24:
633
634 if (sym->st_shndx == SHN_UNDEF ||
635 sym->st_shndx == SHN_LIVEPATCH) {
636
637 value = stub_for_addr(sechdrs, value, me);
638 if (!value)
639 return -ENOENT;
640 if (!restore_r2((u32 *)location + 1, me))
641 return -ENOEXEC;
642
643 squash_toc_save_inst(strtab + sym->st_name, value);
644 } else
645 value += local_entry_offset(sym);
646
647
648 value -= (unsigned long)location;
649 if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){
650 pr_err("%s: REL24 %li out of range!\n",
651 me->name, (long int)value);
652 return -ENOEXEC;
653 }
654
655
656 *(uint32_t *)location
657 = (*(uint32_t *)location & ~0x03fffffc)
658 | (value & 0x03fffffc);
659 break;
660
661 case R_PPC64_REL64:
662
663 *location = value - (unsigned long)location;
664 break;
665
666 case R_PPC64_TOCSAVE:
667
668
669
670
671
672 break;
673
674 case R_PPC64_REL16_HA:
675
676 value -= (unsigned long)location;
677 value = ((value + 0x8000) >> 16);
678 *((uint16_t *) location)
679 = (*((uint16_t *) location) & ~0xffff)
680 | (value & 0xffff);
681 break;
682
683 case R_PPC64_REL16_LO:
684
685 value -= (unsigned long)location;
686 *((uint16_t *) location)
687 = (*((uint16_t *) location) & ~0xffff)
688 | (value & 0xffff);
689 break;
690
691 default:
692 pr_err("%s: Unknown ADD relocation: %lu\n",
693 me->name,
694 (unsigned long)ELF64_R_TYPE(rela[i].r_info));
695 return -ENOEXEC;
696 }
697 }
698
699 return 0;
700}
701
702#ifdef CONFIG_DYNAMIC_FTRACE
703
704#ifdef CC_USING_MPROFILE_KERNEL
705
706#define PACATOC offsetof(struct paca_struct, kernel_toc)
707
708
709
710
711
712
713
714
715
716
717
718
719
720static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me)
721{
722 struct ppc64_stub_entry *entry;
723 unsigned int i, num_stubs;
724 static u32 stub_insns[] = {
725 0xe98d0000 | PACATOC,
726 0x3d8c0000,
727 0x398c0000,
728 0x7d8903a6,
729 0x4e800420,
730 };
731 long reladdr;
732
733 num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*entry);
734
735
736 entry = (void *)sechdrs[me->arch.stubs_section].sh_addr;
737 for (i = 0; i < num_stubs && stub_func_addr(entry->funcdata); i++, entry++);
738
739 if (i >= num_stubs) {
740 pr_err("%s: Unable to find a free slot for ftrace stub.\n", me->name);
741 return 0;
742 }
743
744 memcpy(entry->jump, stub_insns, sizeof(stub_insns));
745
746
747 reladdr = (unsigned long)ftrace_caller - kernel_toc_addr();
748 if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
749 pr_err("%s: Address of ftrace_caller out of range of kernel_toc.\n", me->name);
750 return 0;
751 }
752
753 entry->jump[1] |= PPC_HA(reladdr);
754 entry->jump[2] |= PPC_LO(reladdr);
755
756
757 entry->funcdata = func_desc((unsigned long)ftrace_caller);
758 entry->magic = STUB_MAGIC;
759
760 return (unsigned long)entry;
761}
762#else
763static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me)
764{
765 return stub_for_addr(sechdrs, (unsigned long)ftrace_caller, me);
766}
767#endif
768
769int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs)
770{
771 struct module_ext *mod_ext;
772
773 mutex_lock(&module_ext_mutex);
774 mod_ext = find_module_ext(mod);
775 mutex_unlock(&module_ext_mutex);
776
777 mod_ext->toc = my_r2(sechdrs, mod);
778 mod_ext->tramp = create_ftrace_stub(sechdrs, mod);
779
780 if (!mod_ext->tramp)
781 return -ENOENT;
782
783 return 0;
784}
785#endif
786