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
);