1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Ptrace interface test helper functions
5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
14 #include <sys/ptrace.h>
15 #include <sys/ioctl.h>
17 #include <sys/types.h>
19 #include <sys/signal.h>
23 #include <linux/elf.h>
24 #include <linux/types.h>
25 #include <linux/auxvec.h>
33 unsigned long fpr[32];
38 unsigned long tm_tfhar;
39 unsigned long tm_texasr;
40 unsigned long tm_tfiar;
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
59 /* Basic ptrace operations */
60 int start_trace(pid_t child)
64 ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
66 perror("ptrace(PTRACE_ATTACH) failed");
69 ret = waitpid(child, NULL, 0);
71 perror("waitpid() failed");
77 int stop_trace(pid_t child)
81 ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
83 perror("ptrace(PTRACE_DETACH) failed");
89 int cont_trace(pid_t child)
93 ret = ptrace(PTRACE_CONT, child, NULL, NULL);
95 perror("ptrace(PTRACE_CONT) failed");
101 int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[],
107 FAIL_IF(start_trace(child));
110 iov.iov_len = n * sizeof(unsigned long);
112 ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
116 FAIL_IF(stop_trace(child));
121 long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[],
127 FAIL_IF(start_trace(child));
130 iov.iov_len = n * sizeof(unsigned long);
132 ret = ptrace(PTRACE_SETREGSET, child, type, &iov);
134 FAIL_IF(stop_trace(child));
140 int show_tar_registers(pid_t child, unsigned long *out)
146 reg = malloc(sizeof(unsigned long));
148 perror("malloc() failed");
151 iov.iov_base = (u64 *) reg;
152 iov.iov_len = sizeof(unsigned long);
154 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
156 perror("ptrace(PTRACE_GETREGSET) failed");
162 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
164 perror("ptrace(PTRACE_GETREGSET) failed");
170 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
172 perror("ptrace(PTRACE_GETREGSET) failed");
185 int write_tar_registers(pid_t child, unsigned long tar,
186 unsigned long ppr, unsigned long dscr)
192 reg = malloc(sizeof(unsigned long));
194 perror("malloc() failed");
198 iov.iov_base = (u64 *) reg;
199 iov.iov_len = sizeof(unsigned long);
202 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
204 perror("ptrace(PTRACE_SETREGSET) failed");
209 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
211 perror("ptrace(PTRACE_SETREGSET) failed");
216 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
218 perror("ptrace(PTRACE_SETREGSET) failed");
229 int show_tm_checkpointed_state(pid_t child, unsigned long *out)
235 reg = malloc(sizeof(unsigned long));
237 perror("malloc() failed");
241 iov.iov_base = (u64 *) reg;
242 iov.iov_len = sizeof(unsigned long);
244 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
246 perror("ptrace(PTRACE_GETREGSET) failed");
252 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
254 perror("ptrace(PTRACE_GETREGSET) failed");
260 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
262 perror("ptrace(PTRACE_GETREGSET) failed");
276 int write_ckpt_tar_registers(pid_t child, unsigned long tar,
277 unsigned long ppr, unsigned long dscr)
283 reg = malloc(sizeof(unsigned long));
285 perror("malloc() failed");
289 iov.iov_base = (u64 *) reg;
290 iov.iov_len = sizeof(unsigned long);
293 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
295 perror("ptrace(PTRACE_GETREGSET) failed");
300 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
302 perror("ptrace(PTRACE_GETREGSET) failed");
307 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
309 perror("ptrace(PTRACE_GETREGSET) failed");
321 int show_fpr(pid_t child, unsigned long *fpr)
323 struct fpr_regs *regs;
326 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
327 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
329 perror("ptrace(PTRACE_GETREGSET) failed");
334 for (i = 0; i < 32; i++)
335 fpr[i] = regs->fpr[i];
340 int write_fpr(pid_t child, unsigned long val)
342 struct fpr_regs *regs;
345 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
346 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
348 perror("ptrace(PTRACE_GETREGSET) failed");
352 for (i = 0; i < 32; i++)
355 ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
357 perror("ptrace(PTRACE_GETREGSET) failed");
363 int show_ckpt_fpr(pid_t child, unsigned long *fpr)
365 struct fpr_regs *regs;
369 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
371 iov.iov_len = sizeof(struct fpr_regs);
373 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
375 perror("ptrace(PTRACE_GETREGSET) failed");
380 for (i = 0; i < 32; i++)
381 fpr[i] = regs->fpr[i];
387 int write_ckpt_fpr(pid_t child, unsigned long val)
389 struct fpr_regs *regs;
393 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
395 iov.iov_len = sizeof(struct fpr_regs);
397 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
399 perror("ptrace(PTRACE_GETREGSET) failed");
403 for (i = 0; i < 32; i++)
406 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
408 perror("ptrace(PTRACE_GETREGSET) failed");
415 int show_gpr(pid_t child, unsigned long *gpr)
417 struct pt_regs *regs;
420 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
422 perror("malloc() failed");
426 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
428 perror("ptrace(PTRACE_GETREGSET) failed");
433 for (i = 14; i < 32; i++)
434 gpr[i-14] = regs->gpr[i];
440 int write_gpr(pid_t child, unsigned long val)
442 struct pt_regs *regs;
445 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
447 perror("malloc() failed");
451 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
453 perror("ptrace(PTRACE_GETREGSET) failed");
457 for (i = 14; i < 32; i++)
460 ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
462 perror("ptrace(PTRACE_GETREGSET) failed");
468 int show_ckpt_gpr(pid_t child, unsigned long *gpr)
470 struct pt_regs *regs;
474 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
476 perror("malloc() failed");
480 iov.iov_base = (u64 *) regs;
481 iov.iov_len = sizeof(struct pt_regs);
483 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
485 perror("ptrace(PTRACE_GETREGSET) failed");
490 for (i = 14; i < 32; i++)
491 gpr[i-14] = regs->gpr[i];
497 int write_ckpt_gpr(pid_t child, unsigned long val)
499 struct pt_regs *regs;
503 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
505 perror("malloc() failed\n");
508 iov.iov_base = (u64 *) regs;
509 iov.iov_len = sizeof(struct pt_regs);
511 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
513 perror("ptrace(PTRACE_GETREGSET) failed");
517 for (i = 14; i < 32; i++)
520 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
522 perror("ptrace(PTRACE_GETREGSET) failed");
529 int show_vmx(pid_t child, unsigned long vmx[][2])
533 ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
535 perror("ptrace(PTRACE_GETVRREGS) failed");
541 int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
543 unsigned long regs[34][2];
547 iov.iov_base = (u64 *) regs;
548 iov.iov_len = sizeof(regs);
549 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
551 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
554 memcpy(vmx, regs, sizeof(regs));
559 int write_vmx(pid_t child, unsigned long vmx[][2])
563 ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
565 perror("ptrace(PTRACE_SETVRREGS) failed");
571 int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
573 unsigned long regs[34][2];
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);
582 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
589 int show_vsx(pid_t child, unsigned long *vsx)
593 ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
595 perror("ptrace(PTRACE_GETVSRREGS) failed");
601 int show_vsx_ckpt(pid_t child, unsigned long *vsx)
603 unsigned long regs[32];
607 iov.iov_base = (u64 *) regs;
608 iov.iov_len = sizeof(regs);
609 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
611 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
614 memcpy(vsx, regs, sizeof(regs));
618 int write_vsx(pid_t child, unsigned long *vsx)
622 ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
624 perror("ptrace(PTRACE_SETVSRREGS) failed");
630 int write_vsx_ckpt(pid_t child, unsigned long *vsx)
632 unsigned long regs[32];
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);
641 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
648 int show_tm_spr(pid_t child, struct tm_spr_regs *out)
650 struct tm_spr_regs *regs;
654 regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
656 perror("malloc() failed");
660 iov.iov_base = (u64 *) regs;
661 iov.iov_len = sizeof(struct tm_spr_regs);
663 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
665 perror("ptrace(PTRACE_GETREGSET) failed");
670 memcpy(out, regs, sizeof(struct tm_spr_regs));
677 /* Analyse TEXASR after TM failure */
678 inline unsigned long get_tfiar(void)
682 asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR));
686 void analyse_texasr(unsigned long texasr)
688 printf("TEXASR: %16lx\t", texasr);
690 if (texasr & TEXASR_FP)
691 printf("TEXASR_FP ");
693 if (texasr & TEXASR_DA)
694 printf("TEXASR_DA ");
696 if (texasr & TEXASR_NO)
697 printf("TEXASR_NO ");
699 if (texasr & TEXASR_FO)
700 printf("TEXASR_FO ");
702 if (texasr & TEXASR_SIC)
703 printf("TEXASR_SIC ");
705 if (texasr & TEXASR_NTC)
706 printf("TEXASR_NTC ");
708 if (texasr & TEXASR_TC)
709 printf("TEXASR_TC ");
711 if (texasr & TEXASR_TIC)
712 printf("TEXASR_TIC ");
714 if (texasr & TEXASR_IC)
715 printf("TEXASR_IC ");
717 if (texasr & TEXASR_IFC)
718 printf("TEXASR_IFC ");
720 if (texasr & TEXASR_ABT)
721 printf("TEXASR_ABT ");
723 if (texasr & TEXASR_SPD)
724 printf("TEXASR_SPD ");
726 if (texasr & TEXASR_HV)
727 printf("TEXASR_HV ");
729 if (texasr & TEXASR_PR)
730 printf("TEXASR_PR ");
732 if (texasr & TEXASR_FS)
733 printf("TEXASR_FS ");
735 if (texasr & TEXASR_TE)
736 printf("TEXASR_TE ");
738 if (texasr & TEXASR_ROT)
739 printf("TEXASR_ROT ");
741 printf("TFIAR :%lx\n", get_tfiar());
744 void store_gpr(unsigned long *addr);
745 void store_fpr(float *addr);