This source file includes following definitions.
- start_trace
- stop_trace
- cont_trace
- ptrace_read_regs
- ptrace_write_regs
- show_tar_registers
- write_tar_registers
- show_tm_checkpointed_state
- write_ckpt_tar_registers
- show_fpr
- write_fpr
- show_ckpt_fpr
- write_ckpt_fpr
- show_gpr
- write_gpr
- show_ckpt_gpr
- write_ckpt_gpr
- show_vmx
- show_vmx_ckpt
- write_vmx
- write_vmx_ckpt
- show_vsx
- show_vsx_ckpt
- write_vsx
- write_vsx_ckpt
- show_tm_spr
- get_tfiar
- analyse_texasr
1
2
3
4
5
6
7 #include <inttypes.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <malloc.h>
12 #include <errno.h>
13 #include <time.h>
14 #include <sys/ptrace.h>
15 #include <sys/ioctl.h>
16 #include <sys/uio.h>
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <sys/signal.h>
20 #include <sys/ipc.h>
21 #include <sys/shm.h>
22 #include <sys/user.h>
23 #include <linux/elf.h>
24 #include <linux/types.h>
25 #include <linux/auxvec.h>
26 #include "reg.h"
27 #include "utils.h"
28
29 #define TEST_PASS 0
30 #define TEST_FAIL 1
31
32 struct fpr_regs {
33 unsigned long fpr[32];
34 unsigned long fpscr;
35 };
36
37 struct tm_spr_regs {
38 unsigned long tm_tfhar;
39 unsigned long tm_texasr;
40 unsigned long tm_tfiar;
41 };
42
43 #ifndef NT_PPC_TAR
44 #define NT_PPC_TAR 0x103
45 #define NT_PPC_PPR 0x104
46 #define NT_PPC_DSCR 0x105
47 #define NT_PPC_EBB 0x106
48 #define NT_PPC_PMU 0x107
49 #define NT_PPC_TM_CGPR 0x108
50 #define NT_PPC_TM_CFPR 0x109
51 #define NT_PPC_TM_CVMX 0x10a
52 #define NT_PPC_TM_CVSX 0x10b
53 #define NT_PPC_TM_SPR 0x10c
54 #define NT_PPC_TM_CTAR 0x10d
55 #define NT_PPC_TM_CPPR 0x10e
56 #define NT_PPC_TM_CDSCR 0x10f
57 #endif
58
59
60 int start_trace(pid_t child)
61 {
62 int ret;
63
64 ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
65 if (ret) {
66 perror("ptrace(PTRACE_ATTACH) failed");
67 return TEST_FAIL;
68 }
69 ret = waitpid(child, NULL, 0);
70 if (ret != child) {
71 perror("waitpid() failed");
72 return TEST_FAIL;
73 }
74 return TEST_PASS;
75 }
76
77 int stop_trace(pid_t child)
78 {
79 int ret;
80
81 ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
82 if (ret) {
83 perror("ptrace(PTRACE_DETACH) failed");
84 return TEST_FAIL;
85 }
86 return TEST_PASS;
87 }
88
89 int cont_trace(pid_t child)
90 {
91 int ret;
92
93 ret = ptrace(PTRACE_CONT, child, NULL, NULL);
94 if (ret) {
95 perror("ptrace(PTRACE_CONT) failed");
96 return TEST_FAIL;
97 }
98 return TEST_PASS;
99 }
100
101 int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[],
102 int n)
103 {
104 struct iovec iov;
105 long ret;
106
107 FAIL_IF(start_trace(child));
108
109 iov.iov_base = regs;
110 iov.iov_len = n * sizeof(unsigned long);
111
112 ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
113 if (ret)
114 return ret;
115
116 FAIL_IF(stop_trace(child));
117
118 return TEST_PASS;
119 }
120
121 long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[],
122 int n)
123 {
124 struct iovec iov;
125 long ret;
126
127 FAIL_IF(start_trace(child));
128
129 iov.iov_base = regs;
130 iov.iov_len = n * sizeof(unsigned long);
131
132 ret = ptrace(PTRACE_SETREGSET, child, type, &iov);
133
134 FAIL_IF(stop_trace(child));
135
136 return ret;
137 }
138
139
140 int show_tar_registers(pid_t child, unsigned long *out)
141 {
142 struct iovec iov;
143 unsigned long *reg;
144 int ret;
145
146 reg = malloc(sizeof(unsigned long));
147 if (!reg) {
148 perror("malloc() failed");
149 return TEST_FAIL;
150 }
151 iov.iov_base = (u64 *) reg;
152 iov.iov_len = sizeof(unsigned long);
153
154 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
155 if (ret) {
156 perror("ptrace(PTRACE_GETREGSET) failed");
157 goto fail;
158 }
159 if (out)
160 out[0] = *reg;
161
162 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
163 if (ret) {
164 perror("ptrace(PTRACE_GETREGSET) failed");
165 goto fail;
166 }
167 if (out)
168 out[1] = *reg;
169
170 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
171 if (ret) {
172 perror("ptrace(PTRACE_GETREGSET) failed");
173 goto fail;
174 }
175 if (out)
176 out[2] = *reg;
177
178 free(reg);
179 return TEST_PASS;
180 fail:
181 free(reg);
182 return TEST_FAIL;
183 }
184
185 int write_tar_registers(pid_t child, unsigned long tar,
186 unsigned long ppr, unsigned long dscr)
187 {
188 struct iovec iov;
189 unsigned long *reg;
190 int ret;
191
192 reg = malloc(sizeof(unsigned long));
193 if (!reg) {
194 perror("malloc() failed");
195 return TEST_FAIL;
196 }
197
198 iov.iov_base = (u64 *) reg;
199 iov.iov_len = sizeof(unsigned long);
200
201 *reg = tar;
202 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
203 if (ret) {
204 perror("ptrace(PTRACE_SETREGSET) failed");
205 goto fail;
206 }
207
208 *reg = ppr;
209 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
210 if (ret) {
211 perror("ptrace(PTRACE_SETREGSET) failed");
212 goto fail;
213 }
214
215 *reg = dscr;
216 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
217 if (ret) {
218 perror("ptrace(PTRACE_SETREGSET) failed");
219 goto fail;
220 }
221
222 free(reg);
223 return TEST_PASS;
224 fail:
225 free(reg);
226 return TEST_FAIL;
227 }
228
229 int show_tm_checkpointed_state(pid_t child, unsigned long *out)
230 {
231 struct iovec iov;
232 unsigned long *reg;
233 int ret;
234
235 reg = malloc(sizeof(unsigned long));
236 if (!reg) {
237 perror("malloc() failed");
238 return TEST_FAIL;
239 }
240
241 iov.iov_base = (u64 *) reg;
242 iov.iov_len = sizeof(unsigned long);
243
244 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
245 if (ret) {
246 perror("ptrace(PTRACE_GETREGSET) failed");
247 goto fail;
248 }
249 if (out)
250 out[0] = *reg;
251
252 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
253 if (ret) {
254 perror("ptrace(PTRACE_GETREGSET) failed");
255 goto fail;
256 }
257 if (out)
258 out[1] = *reg;
259
260 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
261 if (ret) {
262 perror("ptrace(PTRACE_GETREGSET) failed");
263 goto fail;
264 }
265 if (out)
266 out[2] = *reg;
267
268 free(reg);
269 return TEST_PASS;
270
271 fail:
272 free(reg);
273 return TEST_FAIL;
274 }
275
276 int write_ckpt_tar_registers(pid_t child, unsigned long tar,
277 unsigned long ppr, unsigned long dscr)
278 {
279 struct iovec iov;
280 unsigned long *reg;
281 int ret;
282
283 reg = malloc(sizeof(unsigned long));
284 if (!reg) {
285 perror("malloc() failed");
286 return TEST_FAIL;
287 }
288
289 iov.iov_base = (u64 *) reg;
290 iov.iov_len = sizeof(unsigned long);
291
292 *reg = tar;
293 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
294 if (ret) {
295 perror("ptrace(PTRACE_GETREGSET) failed");
296 goto fail;
297 }
298
299 *reg = ppr;
300 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
301 if (ret) {
302 perror("ptrace(PTRACE_GETREGSET) failed");
303 goto fail;
304 }
305
306 *reg = dscr;
307 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
308 if (ret) {
309 perror("ptrace(PTRACE_GETREGSET) failed");
310 goto fail;
311 }
312
313 free(reg);
314 return TEST_PASS;
315 fail:
316 free(reg);
317 return TEST_FAIL;
318 }
319
320
321 int show_fpr(pid_t child, unsigned long *fpr)
322 {
323 struct fpr_regs *regs;
324 int ret, i;
325
326 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
327 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
328 if (ret) {
329 perror("ptrace(PTRACE_GETREGSET) failed");
330 return TEST_FAIL;
331 }
332
333 if (fpr) {
334 for (i = 0; i < 32; i++)
335 fpr[i] = regs->fpr[i];
336 }
337 return TEST_PASS;
338 }
339
340 int write_fpr(pid_t child, unsigned long val)
341 {
342 struct fpr_regs *regs;
343 int ret, i;
344
345 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
346 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
347 if (ret) {
348 perror("ptrace(PTRACE_GETREGSET) failed");
349 return TEST_FAIL;
350 }
351
352 for (i = 0; i < 32; i++)
353 regs->fpr[i] = val;
354
355 ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
356 if (ret) {
357 perror("ptrace(PTRACE_GETREGSET) failed");
358 return TEST_FAIL;
359 }
360 return TEST_PASS;
361 }
362
363 int show_ckpt_fpr(pid_t child, unsigned long *fpr)
364 {
365 struct fpr_regs *regs;
366 struct iovec iov;
367 int ret, i;
368
369 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
370 iov.iov_base = regs;
371 iov.iov_len = sizeof(struct fpr_regs);
372
373 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
374 if (ret) {
375 perror("ptrace(PTRACE_GETREGSET) failed");
376 return TEST_FAIL;
377 }
378
379 if (fpr) {
380 for (i = 0; i < 32; i++)
381 fpr[i] = regs->fpr[i];
382 }
383
384 return TEST_PASS;
385 }
386
387 int write_ckpt_fpr(pid_t child, unsigned long val)
388 {
389 struct fpr_regs *regs;
390 struct iovec iov;
391 int ret, i;
392
393 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
394 iov.iov_base = regs;
395 iov.iov_len = sizeof(struct fpr_regs);
396
397 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
398 if (ret) {
399 perror("ptrace(PTRACE_GETREGSET) failed");
400 return TEST_FAIL;
401 }
402
403 for (i = 0; i < 32; i++)
404 regs->fpr[i] = val;
405
406 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
407 if (ret) {
408 perror("ptrace(PTRACE_GETREGSET) failed");
409 return TEST_FAIL;
410 }
411 return TEST_PASS;
412 }
413
414
415 int show_gpr(pid_t child, unsigned long *gpr)
416 {
417 struct pt_regs *regs;
418 int ret, i;
419
420 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
421 if (!regs) {
422 perror("malloc() failed");
423 return TEST_FAIL;
424 }
425
426 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
427 if (ret) {
428 perror("ptrace(PTRACE_GETREGSET) failed");
429 return TEST_FAIL;
430 }
431
432 if (gpr) {
433 for (i = 14; i < 32; i++)
434 gpr[i-14] = regs->gpr[i];
435 }
436
437 return TEST_PASS;
438 }
439
440 int write_gpr(pid_t child, unsigned long val)
441 {
442 struct pt_regs *regs;
443 int i, ret;
444
445 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
446 if (!regs) {
447 perror("malloc() failed");
448 return TEST_FAIL;
449 }
450
451 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
452 if (ret) {
453 perror("ptrace(PTRACE_GETREGSET) failed");
454 return TEST_FAIL;
455 }
456
457 for (i = 14; i < 32; i++)
458 regs->gpr[i] = val;
459
460 ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
461 if (ret) {
462 perror("ptrace(PTRACE_GETREGSET) failed");
463 return TEST_FAIL;
464 }
465 return TEST_PASS;
466 }
467
468 int show_ckpt_gpr(pid_t child, unsigned long *gpr)
469 {
470 struct pt_regs *regs;
471 struct iovec iov;
472 int ret, i;
473
474 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
475 if (!regs) {
476 perror("malloc() failed");
477 return TEST_FAIL;
478 }
479
480 iov.iov_base = (u64 *) regs;
481 iov.iov_len = sizeof(struct pt_regs);
482
483 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
484 if (ret) {
485 perror("ptrace(PTRACE_GETREGSET) failed");
486 return TEST_FAIL;
487 }
488
489 if (gpr) {
490 for (i = 14; i < 32; i++)
491 gpr[i-14] = regs->gpr[i];
492 }
493
494 return TEST_PASS;
495 }
496
497 int write_ckpt_gpr(pid_t child, unsigned long val)
498 {
499 struct pt_regs *regs;
500 struct iovec iov;
501 int ret, i;
502
503 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
504 if (!regs) {
505 perror("malloc() failed\n");
506 return TEST_FAIL;
507 }
508 iov.iov_base = (u64 *) regs;
509 iov.iov_len = sizeof(struct pt_regs);
510
511 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
512 if (ret) {
513 perror("ptrace(PTRACE_GETREGSET) failed");
514 return TEST_FAIL;
515 }
516
517 for (i = 14; i < 32; i++)
518 regs->gpr[i] = val;
519
520 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
521 if (ret) {
522 perror("ptrace(PTRACE_GETREGSET) failed");
523 return TEST_FAIL;
524 }
525 return TEST_PASS;
526 }
527
528
529 int show_vmx(pid_t child, unsigned long vmx[][2])
530 {
531 int ret;
532
533 ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
534 if (ret) {
535 perror("ptrace(PTRACE_GETVRREGS) failed");
536 return TEST_FAIL;
537 }
538 return TEST_PASS;
539 }
540
541 int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
542 {
543 unsigned long regs[34][2];
544 struct iovec iov;
545 int ret;
546
547 iov.iov_base = (u64 *) regs;
548 iov.iov_len = sizeof(regs);
549 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
550 if (ret) {
551 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
552 return TEST_FAIL;
553 }
554 memcpy(vmx, regs, sizeof(regs));
555 return TEST_PASS;
556 }
557
558
559 int write_vmx(pid_t child, unsigned long vmx[][2])
560 {
561 int ret;
562
563 ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
564 if (ret) {
565 perror("ptrace(PTRACE_SETVRREGS) failed");
566 return TEST_FAIL;
567 }
568 return TEST_PASS;
569 }
570
571 int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
572 {
573 unsigned long regs[34][2];
574 struct iovec iov;
575 int ret;
576
577 memcpy(regs, vmx, sizeof(regs));
578 iov.iov_base = (u64 *) regs;
579 iov.iov_len = sizeof(regs);
580 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov);
581 if (ret) {
582 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
583 return TEST_FAIL;
584 }
585 return TEST_PASS;
586 }
587
588
589 int show_vsx(pid_t child, unsigned long *vsx)
590 {
591 int ret;
592
593 ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
594 if (ret) {
595 perror("ptrace(PTRACE_GETVSRREGS) failed");
596 return TEST_FAIL;
597 }
598 return TEST_PASS;
599 }
600
601 int show_vsx_ckpt(pid_t child, unsigned long *vsx)
602 {
603 unsigned long regs[32];
604 struct iovec iov;
605 int ret;
606
607 iov.iov_base = (u64 *) regs;
608 iov.iov_len = sizeof(regs);
609 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
610 if (ret) {
611 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
612 return TEST_FAIL;
613 }
614 memcpy(vsx, regs, sizeof(regs));
615 return TEST_PASS;
616 }
617
618 int write_vsx(pid_t child, unsigned long *vsx)
619 {
620 int ret;
621
622 ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
623 if (ret) {
624 perror("ptrace(PTRACE_SETVSRREGS) failed");
625 return TEST_FAIL;
626 }
627 return TEST_PASS;
628 }
629
630 int write_vsx_ckpt(pid_t child, unsigned long *vsx)
631 {
632 unsigned long regs[32];
633 struct iovec iov;
634 int ret;
635
636 memcpy(regs, vsx, sizeof(regs));
637 iov.iov_base = (u64 *) regs;
638 iov.iov_len = sizeof(regs);
639 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov);
640 if (ret) {
641 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
642 return TEST_FAIL;
643 }
644 return TEST_PASS;
645 }
646
647
648 int show_tm_spr(pid_t child, struct tm_spr_regs *out)
649 {
650 struct tm_spr_regs *regs;
651 struct iovec iov;
652 int ret;
653
654 regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
655 if (!regs) {
656 perror("malloc() failed");
657 return TEST_FAIL;
658 }
659
660 iov.iov_base = (u64 *) regs;
661 iov.iov_len = sizeof(struct tm_spr_regs);
662
663 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
664 if (ret) {
665 perror("ptrace(PTRACE_GETREGSET) failed");
666 return TEST_FAIL;
667 }
668
669 if (out)
670 memcpy(out, regs, sizeof(struct tm_spr_regs));
671
672 return TEST_PASS;
673 }
674
675
676
677
678 inline unsigned long get_tfiar(void)
679 {
680 unsigned long ret;
681
682 asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR));
683 return ret;
684 }
685
686 void analyse_texasr(unsigned long texasr)
687 {
688 printf("TEXASR: %16lx\t", texasr);
689
690 if (texasr & TEXASR_FP)
691 printf("TEXASR_FP ");
692
693 if (texasr & TEXASR_DA)
694 printf("TEXASR_DA ");
695
696 if (texasr & TEXASR_NO)
697 printf("TEXASR_NO ");
698
699 if (texasr & TEXASR_FO)
700 printf("TEXASR_FO ");
701
702 if (texasr & TEXASR_SIC)
703 printf("TEXASR_SIC ");
704
705 if (texasr & TEXASR_NTC)
706 printf("TEXASR_NTC ");
707
708 if (texasr & TEXASR_TC)
709 printf("TEXASR_TC ");
710
711 if (texasr & TEXASR_TIC)
712 printf("TEXASR_TIC ");
713
714 if (texasr & TEXASR_IC)
715 printf("TEXASR_IC ");
716
717 if (texasr & TEXASR_IFC)
718 printf("TEXASR_IFC ");
719
720 if (texasr & TEXASR_ABT)
721 printf("TEXASR_ABT ");
722
723 if (texasr & TEXASR_SPD)
724 printf("TEXASR_SPD ");
725
726 if (texasr & TEXASR_HV)
727 printf("TEXASR_HV ");
728
729 if (texasr & TEXASR_PR)
730 printf("TEXASR_PR ");
731
732 if (texasr & TEXASR_FS)
733 printf("TEXASR_FS ");
734
735 if (texasr & TEXASR_TE)
736 printf("TEXASR_TE ");
737
738 if (texasr & TEXASR_ROT)
739 printf("TEXASR_ROT ");
740
741 printf("TFIAR :%lx\n", get_tfiar());
742 }
743
744 void store_gpr(unsigned long *addr);
745 void store_fpr(float *addr);