2 * Ptrace interface test helper functions
4 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
18 #include <sys/ptrace.h>
19 #include <sys/ioctl.h>
21 #include <sys/types.h>
23 #include <sys/signal.h>
27 #include <linux/elf.h>
28 #include <linux/types.h>
29 #include <linux/auxvec.h>
37 unsigned long fpr[32];
42 unsigned long tm_tfhar;
43 unsigned long tm_texasr;
44 unsigned long tm_tfiar;
48 #define NT_PPC_TAR 0x103
49 #define NT_PPC_PPR 0x104
50 #define NT_PPC_DSCR 0x105
51 #define NT_PPC_EBB 0x106
52 #define NT_PPC_PMU 0x107
53 #define NT_PPC_TM_CGPR 0x108
54 #define NT_PPC_TM_CFPR 0x109
55 #define NT_PPC_TM_CVMX 0x10a
56 #define NT_PPC_TM_CVSX 0x10b
57 #define NT_PPC_TM_SPR 0x10c
58 #define NT_PPC_TM_CTAR 0x10d
59 #define NT_PPC_TM_CPPR 0x10e
60 #define NT_PPC_TM_CDSCR 0x10f
63 /* Basic ptrace operations */
64 int start_trace(pid_t child)
68 ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
70 perror("ptrace(PTRACE_ATTACH) failed");
73 ret = waitpid(child, NULL, 0);
75 perror("waitpid() failed");
81 int stop_trace(pid_t child)
85 ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
87 perror("ptrace(PTRACE_DETACH) failed");
93 int cont_trace(pid_t child)
97 ret = ptrace(PTRACE_CONT, child, NULL, NULL);
99 perror("ptrace(PTRACE_CONT) failed");
106 int show_tar_registers(pid_t child, unsigned long *out)
112 reg = malloc(sizeof(unsigned long));
114 perror("malloc() failed");
117 iov.iov_base = (u64 *) reg;
118 iov.iov_len = sizeof(unsigned long);
120 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
122 perror("ptrace(PTRACE_GETREGSET) failed");
128 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
130 perror("ptrace(PTRACE_GETREGSET) failed");
136 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
138 perror("ptrace(PTRACE_GETREGSET) failed");
151 int write_tar_registers(pid_t child, unsigned long tar,
152 unsigned long ppr, unsigned long dscr)
158 reg = malloc(sizeof(unsigned long));
160 perror("malloc() failed");
164 iov.iov_base = (u64 *) reg;
165 iov.iov_len = sizeof(unsigned long);
168 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
170 perror("ptrace(PTRACE_SETREGSET) failed");
175 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
177 perror("ptrace(PTRACE_SETREGSET) failed");
182 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
184 perror("ptrace(PTRACE_SETREGSET) failed");
195 int show_tm_checkpointed_state(pid_t child, unsigned long *out)
201 reg = malloc(sizeof(unsigned long));
203 perror("malloc() failed");
207 iov.iov_base = (u64 *) reg;
208 iov.iov_len = sizeof(unsigned long);
210 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
212 perror("ptrace(PTRACE_GETREGSET) failed");
218 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
220 perror("ptrace(PTRACE_GETREGSET) failed");
226 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
228 perror("ptrace(PTRACE_GETREGSET) failed");
242 int write_ckpt_tar_registers(pid_t child, unsigned long tar,
243 unsigned long ppr, unsigned long dscr)
249 reg = malloc(sizeof(unsigned long));
251 perror("malloc() failed");
255 iov.iov_base = (u64 *) reg;
256 iov.iov_len = sizeof(unsigned long);
259 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
261 perror("ptrace(PTRACE_GETREGSET) failed");
266 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
268 perror("ptrace(PTRACE_GETREGSET) failed");
273 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
275 perror("ptrace(PTRACE_GETREGSET) failed");
287 int show_fpr(pid_t child, unsigned long *fpr)
289 struct fpr_regs *regs;
292 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
293 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
295 perror("ptrace(PTRACE_GETREGSET) failed");
300 for (i = 0; i < 32; i++)
301 fpr[i] = regs->fpr[i];
306 int write_fpr(pid_t child, unsigned long val)
308 struct fpr_regs *regs;
311 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
312 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
314 perror("ptrace(PTRACE_GETREGSET) failed");
318 for (i = 0; i < 32; i++)
321 ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
323 perror("ptrace(PTRACE_GETREGSET) failed");
329 int show_ckpt_fpr(pid_t child, unsigned long *fpr)
331 struct fpr_regs *regs;
335 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
337 iov.iov_len = sizeof(struct fpr_regs);
339 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
341 perror("ptrace(PTRACE_GETREGSET) failed");
346 for (i = 0; i < 32; i++)
347 fpr[i] = regs->fpr[i];
353 int write_ckpt_fpr(pid_t child, unsigned long val)
355 struct fpr_regs *regs;
359 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
361 iov.iov_len = sizeof(struct fpr_regs);
363 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
365 perror("ptrace(PTRACE_GETREGSET) failed");
369 for (i = 0; i < 32; i++)
372 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
374 perror("ptrace(PTRACE_GETREGSET) failed");
381 int show_gpr(pid_t child, unsigned long *gpr)
383 struct pt_regs *regs;
386 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
388 perror("malloc() failed");
392 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
394 perror("ptrace(PTRACE_GETREGSET) failed");
399 for (i = 14; i < 32; i++)
400 gpr[i-14] = regs->gpr[i];
406 int write_gpr(pid_t child, unsigned long val)
408 struct pt_regs *regs;
411 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
413 perror("malloc() failed");
417 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
419 perror("ptrace(PTRACE_GETREGSET) failed");
423 for (i = 14; i < 32; i++)
426 ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
428 perror("ptrace(PTRACE_GETREGSET) failed");
434 int show_ckpt_gpr(pid_t child, unsigned long *gpr)
436 struct pt_regs *regs;
440 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
442 perror("malloc() failed");
446 iov.iov_base = (u64 *) regs;
447 iov.iov_len = sizeof(struct pt_regs);
449 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
451 perror("ptrace(PTRACE_GETREGSET) failed");
456 for (i = 14; i < 32; i++)
457 gpr[i-14] = regs->gpr[i];
463 int write_ckpt_gpr(pid_t child, unsigned long val)
465 struct pt_regs *regs;
469 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
471 perror("malloc() failed\n");
474 iov.iov_base = (u64 *) regs;
475 iov.iov_len = sizeof(struct pt_regs);
477 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
479 perror("ptrace(PTRACE_GETREGSET) failed");
483 for (i = 14; i < 32; i++)
486 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
488 perror("ptrace(PTRACE_GETREGSET) failed");
495 int show_vmx(pid_t child, unsigned long vmx[][2])
499 ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
501 perror("ptrace(PTRACE_GETVRREGS) failed");
507 int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
509 unsigned long regs[34][2];
513 iov.iov_base = (u64 *) regs;
514 iov.iov_len = sizeof(regs);
515 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
517 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
520 memcpy(vmx, regs, sizeof(regs));
525 int write_vmx(pid_t child, unsigned long vmx[][2])
529 ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
531 perror("ptrace(PTRACE_SETVRREGS) failed");
537 int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
539 unsigned long regs[34][2];
543 memcpy(regs, vmx, sizeof(regs));
544 iov.iov_base = (u64 *) regs;
545 iov.iov_len = sizeof(regs);
546 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov);
548 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
555 int show_vsx(pid_t child, unsigned long *vsx)
559 ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
561 perror("ptrace(PTRACE_GETVSRREGS) failed");
567 int show_vsx_ckpt(pid_t child, unsigned long *vsx)
569 unsigned long regs[32];
573 iov.iov_base = (u64 *) regs;
574 iov.iov_len = sizeof(regs);
575 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
577 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
580 memcpy(vsx, regs, sizeof(regs));
584 int write_vsx(pid_t child, unsigned long *vsx)
588 ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
590 perror("ptrace(PTRACE_SETVSRREGS) failed");
596 int write_vsx_ckpt(pid_t child, unsigned long *vsx)
598 unsigned long regs[32];
602 memcpy(regs, vsx, sizeof(regs));
603 iov.iov_base = (u64 *) regs;
604 iov.iov_len = sizeof(regs);
605 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov);
607 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
614 int show_tm_spr(pid_t child, struct tm_spr_regs *out)
616 struct tm_spr_regs *regs;
620 regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
622 perror("malloc() failed");
626 iov.iov_base = (u64 *) regs;
627 iov.iov_len = sizeof(struct tm_spr_regs);
629 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
631 perror("ptrace(PTRACE_GETREGSET) failed");
636 memcpy(out, regs, sizeof(struct tm_spr_regs));
643 /* Analyse TEXASR after TM failure */
644 inline unsigned long get_tfiar(void)
648 asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR));
652 void analyse_texasr(unsigned long texasr)
654 printf("TEXASR: %16lx\t", texasr);
656 if (texasr & TEXASR_FP)
657 printf("TEXASR_FP ");
659 if (texasr & TEXASR_DA)
660 printf("TEXASR_DA ");
662 if (texasr & TEXASR_NO)
663 printf("TEXASR_NO ");
665 if (texasr & TEXASR_FO)
666 printf("TEXASR_FO ");
668 if (texasr & TEXASR_SIC)
669 printf("TEXASR_SIC ");
671 if (texasr & TEXASR_NTC)
672 printf("TEXASR_NTC ");
674 if (texasr & TEXASR_TC)
675 printf("TEXASR_TC ");
677 if (texasr & TEXASR_TIC)
678 printf("TEXASR_TIC ");
680 if (texasr & TEXASR_IC)
681 printf("TEXASR_IC ");
683 if (texasr & TEXASR_IFC)
684 printf("TEXASR_IFC ");
686 if (texasr & TEXASR_ABT)
687 printf("TEXASR_ABT ");
689 if (texasr & TEXASR_SPD)
690 printf("TEXASR_SPD ");
692 if (texasr & TEXASR_HV)
693 printf("TEXASR_HV ");
695 if (texasr & TEXASR_PR)
696 printf("TEXASR_PR ");
698 if (texasr & TEXASR_FS)
699 printf("TEXASR_FS ");
701 if (texasr & TEXASR_TE)
702 printf("TEXASR_TE ");
704 if (texasr & TEXASR_ROT)
705 printf("TEXASR_ROT ");
707 printf("TFIAR :%lx\n", get_tfiar());
710 void store_gpr(unsigned long *addr);
711 void store_fpr(float *addr);