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
35
36
37
38
39
40
41
42
43#if defined(_CALL_ELF) && _CALL_ELF == 2
44#define R2_STACK_OFFSET 24
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#define R2_STACK_OFFSET 40
77
78
79typedef struct ppc64_opd_entry func_desc_t;
80
81static func_desc_t func_desc(unsigned long addr)
82{
83 return *(struct ppc64_opd_entry *)addr;
84}
85static unsigned long func_addr(unsigned long addr)
86{
87 return func_desc(addr).funcaddr;
88}
89static unsigned long stub_func_addr(func_desc_t func)
90{
91 return func.funcaddr;
92}
93static unsigned int local_entry_offset(const Elf64_Sym *sym)
94{
95 return 0;
96}
97#endif
98
99
100
101
102struct ppc64_stub_entry
103{
104
105
106
107 u32 jump[7];
108 u32 unused;
109
110 func_desc_t funcdata;
111};
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127static u32 ppc64_stub_insns[] = {
128 0x3d620000,
129 0x396b0000,
130
131 0xf8410000|R2_STACK_OFFSET,
132 0xe98b0020,
133#if !defined(_CALL_ELF) || _CALL_ELF != 2
134
135 0xe84b0028,
136#endif
137 0x7d8903a6,
138 0x4e800420
139};
140
141#ifdef CONFIG_DYNAMIC_FTRACE
142
143static u32 ppc64_stub_mask[] = {
144 0xffff0000,
145 0xffff0000,
146 0xffffffff,
147 0xffffffff,
148#if !defined(_CALL_ELF) || _CALL_ELF != 2
149 0xffffffff,
150#endif
151 0xffffffff,
152 0xffffffff
153};
154
155bool is_module_trampoline(u32 *p)
156{
157 unsigned int i;
158 u32 insns[ARRAY_SIZE(ppc64_stub_insns)];
159
160 BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask));
161
162 if (probe_kernel_read(insns, p, sizeof(insns)))
163 return -EFAULT;
164
165 for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) {
166 u32 insna = insns[i];
167 u32 insnb = ppc64_stub_insns[i];
168 u32 mask = ppc64_stub_mask[i];
169
170 if ((insna & mask) != (insnb & mask))
171 return false;
172 }
173
174 return true;
175}
176
177int module_trampoline_target(struct module *mod, u32 *trampoline,
178 unsigned long *target)
179{
180 u32 buf[2];
181 u16 upper, lower;
182 long offset;
183 void *toc_entry;
184
185 if (probe_kernel_read(buf, trampoline, sizeof(buf)))
186 return -EFAULT;
187
188 upper = buf[0] & 0xffff;
189 lower = buf[1] & 0xffff;
190
191
192 offset = ((short)upper << 16) + (short)lower;
193
194
195
196
197
198 toc_entry = (void *)mod->arch.toc + offset + 32;
199
200 if (probe_kernel_read(target, toc_entry, sizeof(*target)))
201 return -EFAULT;
202
203 return 0;
204}
205
206#endif
207
208
209
210static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num)
211{
212 unsigned int i, r_info, r_addend, _count_relocs;
213
214
215 _count_relocs = 0;
216 r_info = 0;
217 r_addend = 0;
218 for (i = 0; i < num; i++)
219
220 if (ELF64_R_TYPE(rela[i].r_info) == R_PPC_REL24 &&
221 (r_info != ELF64_R_SYM(rela[i].r_info) ||
222 r_addend != rela[i].r_addend)) {
223 _count_relocs++;
224 r_info = ELF64_R_SYM(rela[i].r_info);
225 r_addend = rela[i].r_addend;
226 }
227
228 return _count_relocs;
229}
230
231static int relacmp(const void *_x, const void *_y)
232{
233 const Elf64_Rela *x, *y;
234
235 y = (Elf64_Rela *)_x;
236 x = (Elf64_Rela *)_y;
237
238
239
240
241
242 if (x->r_info < y->r_info)
243 return -1;
244 else if (x->r_info > y->r_info)
245 return 1;
246 else if (x->r_addend < y->r_addend)
247 return -1;
248 else if (x->r_addend > y->r_addend)
249 return 1;
250 else
251 return 0;
252}
253
254static void relaswap(void *_x, void *_y, int size)
255{
256 uint64_t *x, *y, tmp;
257 int i;
258
259 y = (uint64_t *)_x;
260 x = (uint64_t *)_y;
261
262 for (i = 0; i < sizeof(Elf64_Rela) / sizeof(uint64_t); i++) {
263 tmp = x[i];
264 x[i] = y[i];
265 y[i] = tmp;
266 }
267}
268
269
270static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
271 const Elf64_Shdr *sechdrs)
272{
273
274 unsigned long relocs = 1;
275 unsigned i;
276
277
278 for (i = 1; i < hdr->e_shnum; i++) {
279 if (sechdrs[i].sh_type == SHT_RELA) {
280 pr_debug("Found relocations in section %u\n", i);
281 pr_debug("Ptr: %p. Number: %Lu\n",
282 (void *)sechdrs[i].sh_addr,
283 sechdrs[i].sh_size / sizeof(Elf64_Rela));
284
285
286
287
288
289
290 sort((void *)sechdrs[i].sh_addr,
291 sechdrs[i].sh_size / sizeof(Elf64_Rela),
292 sizeof(Elf64_Rela), relacmp, relaswap);
293
294 relocs += count_relocs((void *)sechdrs[i].sh_addr,
295 sechdrs[i].sh_size
296 / sizeof(Elf64_Rela));
297 }
298 }
299
300#ifdef CONFIG_DYNAMIC_FTRACE
301
302 relocs++;
303#endif
304
305 pr_debug("Looks like a total of %lu stubs, max\n", relocs);
306 return relocs * sizeof(struct ppc64_stub_entry);
307}
308
309
310static void dedotify_versions(struct modversion_info *vers,
311 unsigned long size)
312{
313 struct modversion_info *end;
314
315 for (end = (void *)vers + size; vers < end; vers++)
316 if (vers->name[0] == '.') {
317 memmove(vers->name, vers->name+1, strlen(vers->name));
318#ifdef ARCH_RELOCATES_KCRCTAB
319
320
321
322
323 if (!strcmp(vers->name, "TOC."))
324 vers->crc = -(unsigned long)reloc_start;
325#endif
326 }
327}
328
329
330static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab)
331{
332 unsigned int i;
333
334 for (i = 1; i < numsyms; i++) {
335 if (syms[i].st_shndx == SHN_UNDEF) {
336 char *name = strtab + syms[i].st_name;
337 if (name[0] == '.')
338 memmove(name, name+1, strlen(name));
339 }
340 }
341}
342
343static Elf64_Sym *find_dot_toc(Elf64_Shdr *sechdrs,
344 const char *strtab,
345 unsigned int symindex)
346{
347 unsigned int i, numsyms;
348 Elf64_Sym *syms;
349
350 syms = (Elf64_Sym *)sechdrs[symindex].sh_addr;
351 numsyms = sechdrs[symindex].sh_size / sizeof(Elf64_Sym);
352
353 for (i = 1; i < numsyms; i++) {
354 if (syms[i].st_shndx == SHN_UNDEF
355 && strcmp(strtab + syms[i].st_name, "TOC.") == 0)
356 return &syms[i];
357 }
358 return NULL;
359}
360
361int module_frob_arch_sections(Elf64_Ehdr *hdr,
362 Elf64_Shdr *sechdrs,
363 char *secstrings,
364 struct module *me)
365{
366 unsigned int i;
367
368
369 for (i = 1; i < hdr->e_shnum; i++) {
370 char *p;
371 if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0)
372 me->arch.stubs_section = i;
373 else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0)
374 me->arch.toc_section = i;
375 else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
376 dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
377 sechdrs[i].sh_size);
378
379
380 while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))
381 p[0] = '_';
382
383 if (sechdrs[i].sh_type == SHT_SYMTAB)
384 dedotify((void *)hdr + sechdrs[i].sh_offset,
385 sechdrs[i].sh_size / sizeof(Elf64_Sym),
386 (void *)hdr
387 + sechdrs[sechdrs[i].sh_link].sh_offset);
388 }
389
390 if (!me->arch.stubs_section) {
391 pr_err("%s: doesn't contain .stubs.\n", me->name);
392 return -ENOEXEC;
393 }
394
395
396
397
398
399 if (!me->arch.toc_section)
400 me->arch.toc_section = me->arch.stubs_section;
401
402
403 sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
404 return 0;
405}
406
407
408
409
410static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
411{
412 return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
413}
414
415
416
417
418#define PPC_LO(v) ((v) & 0xffff)
419#define PPC_HI(v) (((v) >> 16) & 0xffff)
420#define PPC_HA(v) PPC_HI ((v) + 0x8000)
421
422
423static inline int create_stub(Elf64_Shdr *sechdrs,
424 struct ppc64_stub_entry *entry,
425 unsigned long addr,
426 struct module *me)
427{
428 long reladdr;
429
430 memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns));
431
432
433 reladdr = (unsigned long)entry - my_r2(sechdrs, me);
434 if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
435 pr_err("%s: Address %p of stub out of range of %p.\n",
436 me->name, (void *)reladdr, (void *)my_r2);
437 return 0;
438 }
439 pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr);
440
441 entry->jump[0] |= PPC_HA(reladdr);
442 entry->jump[1] |= PPC_LO(reladdr);
443 entry->funcdata = func_desc(addr);
444 return 1;
445}
446
447
448
449static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
450 unsigned long addr,
451 struct module *me)
452{
453 struct ppc64_stub_entry *stubs;
454 unsigned int i, num_stubs;
455
456 num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs);
457
458
459 stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
460 for (i = 0; stub_func_addr(stubs[i].funcdata); i++) {
461 BUG_ON(i >= num_stubs);
462
463 if (stub_func_addr(stubs[i].funcdata) == func_addr(addr))
464 return (unsigned long)&stubs[i];
465 }
466
467 if (!create_stub(sechdrs, &stubs[i], addr, me))
468 return 0;
469
470 return (unsigned long)&stubs[i];
471}
472
473
474
475static int restore_r2(u32 *instruction, struct module *me)
476{
477 if (*instruction != PPC_INST_NOP) {
478 pr_err("%s: Expect noop after relocate, got %08x\n",
479 me->name, *instruction);
480 return 0;
481 }
482
483 *instruction = 0xe8410000 | R2_STACK_OFFSET;
484 return 1;
485}
486
487int apply_relocate_add(Elf64_Shdr *sechdrs,
488 const char *strtab,
489 unsigned int symindex,
490 unsigned int relsec,
491 struct module *me)
492{
493 unsigned int i;
494 Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;
495 Elf64_Sym *sym;
496 unsigned long *location;
497 unsigned long value;
498
499 pr_debug("Applying ADD relocate section %u to %u\n", relsec,
500 sechdrs[relsec].sh_info);
501
502
503 if (!me->arch.toc_fixed) {
504 sym = find_dot_toc(sechdrs, strtab, symindex);
505
506
507 if (sym)
508 sym->st_value = my_r2(sechdrs, me);
509 me->arch.toc_fixed = true;
510 }
511
512 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
513
514 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
515 + rela[i].r_offset;
516
517 sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
518 + ELF64_R_SYM(rela[i].r_info);
519
520 pr_debug("RELOC at %p: %li-type as %s (0x%lx) + %li\n",
521 location, (long)ELF64_R_TYPE(rela[i].r_info),
522 strtab + sym->st_name, (unsigned long)sym->st_value,
523 (long)rela[i].r_addend);
524
525
526 value = sym->st_value + rela[i].r_addend;
527
528 switch (ELF64_R_TYPE(rela[i].r_info)) {
529 case R_PPC64_ADDR32:
530
531 *(u32 *)location = value;
532 break;
533
534 case R_PPC64_ADDR64:
535
536 *(unsigned long *)location = value;
537 break;
538
539 case R_PPC64_TOC:
540 *(unsigned long *)location = my_r2(sechdrs, me);
541 break;
542
543 case R_PPC64_TOC16:
544
545 value -= my_r2(sechdrs, me);
546 if (value + 0x8000 > 0xffff) {
547 pr_err("%s: bad TOC16 relocation (0x%lx)\n",
548 me->name, value);
549 return -ENOEXEC;
550 }
551 *((uint16_t *) location)
552 = (*((uint16_t *) location) & ~0xffff)
553 | (value & 0xffff);
554 break;
555
556 case R_PPC64_TOC16_LO:
557
558 value -= my_r2(sechdrs, me);
559 *((uint16_t *) location)
560 = (*((uint16_t *) location) & ~0xffff)
561 | (value & 0xffff);
562 break;
563
564 case R_PPC64_TOC16_DS:
565
566 value -= my_r2(sechdrs, me);
567 if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
568 pr_err("%s: bad TOC16_DS relocation (0x%lx)\n",
569 me->name, value);
570 return -ENOEXEC;
571 }
572 *((uint16_t *) location)
573 = (*((uint16_t *) location) & ~0xfffc)
574 | (value & 0xfffc);
575 break;
576
577 case R_PPC64_TOC16_LO_DS:
578
579 value -= my_r2(sechdrs, me);
580 if ((value & 3) != 0) {
581 pr_err("%s: bad TOC16_LO_DS relocation (0x%lx)\n",
582 me->name, value);
583 return -ENOEXEC;
584 }
585 *((uint16_t *) location)
586 = (*((uint16_t *) location) & ~0xfffc)
587 | (value & 0xfffc);
588 break;
589
590 case R_PPC64_TOC16_HA:
591
592 value -= my_r2(sechdrs, me);
593 value = ((value + 0x8000) >> 16);
594 *((uint16_t *) location)
595 = (*((uint16_t *) location) & ~0xffff)
596 | (value & 0xffff);
597 break;
598
599 case R_PPC_REL24:
600
601 if (sym->st_shndx == SHN_UNDEF) {
602
603 value = stub_for_addr(sechdrs, value, me);
604 if (!value)
605 return -ENOENT;
606 if (!restore_r2((u32 *)location + 1, me))
607 return -ENOEXEC;
608 } else
609 value += local_entry_offset(sym);
610
611
612 value -= (unsigned long)location;
613 if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){
614 pr_err("%s: REL24 %li out of range!\n",
615 me->name, (long int)value);
616 return -ENOEXEC;
617 }
618
619
620 *(uint32_t *)location
621 = (*(uint32_t *)location & ~0x03fffffc)
622 | (value & 0x03fffffc);
623 break;
624
625 case R_PPC64_REL64:
626
627 *location = value - (unsigned long)location;
628 break;
629
630 case R_PPC64_TOCSAVE:
631
632
633
634
635
636 break;
637
638 case R_PPC64_REL16_HA:
639
640 value -= (unsigned long)location;
641 value = ((value + 0x8000) >> 16);
642 *((uint16_t *) location)
643 = (*((uint16_t *) location) & ~0xffff)
644 | (value & 0xffff);
645 break;
646
647 case R_PPC64_REL16_LO:
648
649 value -= (unsigned long)location;
650 *((uint16_t *) location)
651 = (*((uint16_t *) location) & ~0xffff)
652 | (value & 0xffff);
653 break;
654
655 default:
656 pr_err("%s: Unknown ADD relocation: %lu\n",
657 me->name,
658 (unsigned long)ELF64_R_TYPE(rela[i].r_info));
659 return -ENOEXEC;
660 }
661 }
662
663#ifdef CONFIG_DYNAMIC_FTRACE
664 me->arch.toc = my_r2(sechdrs, me);
665 me->arch.tramp = stub_for_addr(sechdrs,
666 (unsigned long)ftrace_caller,
667 me);
668#endif
669
670 return 0;
671}
672