]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - tools/testing/selftests/powerpc/ptrace/ptrace.h
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");
105 int ptrace_read_regs(pid_t child
, unsigned long type
, unsigned long regs
[],
111 FAIL_IF(start_trace(child
));
114 iov
.iov_len
= n
* sizeof(unsigned long);
116 ret
= ptrace(PTRACE_GETREGSET
, child
, type
, &iov
);
120 FAIL_IF(stop_trace(child
));
125 long ptrace_write_regs(pid_t child
, unsigned long type
, unsigned long regs
[],
131 FAIL_IF(start_trace(child
));
134 iov
.iov_len
= n
* sizeof(unsigned long);
136 ret
= ptrace(PTRACE_SETREGSET
, child
, type
, &iov
);
138 FAIL_IF(stop_trace(child
));
144 int show_tar_registers(pid_t child
, unsigned long *out
)
150 reg
= malloc(sizeof(unsigned long));
152 perror("malloc() failed");
155 iov
.iov_base
= (u64
*) reg
;
156 iov
.iov_len
= sizeof(unsigned long);
158 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TAR
, &iov
);
160 perror("ptrace(PTRACE_GETREGSET) failed");
166 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_PPR
, &iov
);
168 perror("ptrace(PTRACE_GETREGSET) failed");
174 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_DSCR
, &iov
);
176 perror("ptrace(PTRACE_GETREGSET) failed");
189 int write_tar_registers(pid_t child
, unsigned long tar
,
190 unsigned long ppr
, unsigned long dscr
)
196 reg
= malloc(sizeof(unsigned long));
198 perror("malloc() failed");
202 iov
.iov_base
= (u64
*) reg
;
203 iov
.iov_len
= sizeof(unsigned long);
206 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TAR
, &iov
);
208 perror("ptrace(PTRACE_SETREGSET) failed");
213 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_PPR
, &iov
);
215 perror("ptrace(PTRACE_SETREGSET) failed");
220 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_DSCR
, &iov
);
222 perror("ptrace(PTRACE_SETREGSET) failed");
233 int show_tm_checkpointed_state(pid_t child
, unsigned long *out
)
239 reg
= malloc(sizeof(unsigned long));
241 perror("malloc() failed");
245 iov
.iov_base
= (u64
*) reg
;
246 iov
.iov_len
= sizeof(unsigned long);
248 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CTAR
, &iov
);
250 perror("ptrace(PTRACE_GETREGSET) failed");
256 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CPPR
, &iov
);
258 perror("ptrace(PTRACE_GETREGSET) failed");
264 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CDSCR
, &iov
);
266 perror("ptrace(PTRACE_GETREGSET) failed");
280 int write_ckpt_tar_registers(pid_t child
, unsigned long tar
,
281 unsigned long ppr
, unsigned long dscr
)
287 reg
= malloc(sizeof(unsigned long));
289 perror("malloc() failed");
293 iov
.iov_base
= (u64
*) reg
;
294 iov
.iov_len
= sizeof(unsigned long);
297 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CTAR
, &iov
);
299 perror("ptrace(PTRACE_GETREGSET) failed");
304 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CPPR
, &iov
);
306 perror("ptrace(PTRACE_GETREGSET) failed");
311 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CDSCR
, &iov
);
313 perror("ptrace(PTRACE_GETREGSET) failed");
325 int show_fpr(pid_t child
, unsigned long *fpr
)
327 struct fpr_regs
*regs
;
330 regs
= (struct fpr_regs
*) malloc(sizeof(struct fpr_regs
));
331 ret
= ptrace(PTRACE_GETFPREGS
, child
, NULL
, regs
);
333 perror("ptrace(PTRACE_GETREGSET) failed");
338 for (i
= 0; i
< 32; i
++)
339 fpr
[i
] = regs
->fpr
[i
];
344 int write_fpr(pid_t child
, unsigned long val
)
346 struct fpr_regs
*regs
;
349 regs
= (struct fpr_regs
*) malloc(sizeof(struct fpr_regs
));
350 ret
= ptrace(PTRACE_GETFPREGS
, child
, NULL
, regs
);
352 perror("ptrace(PTRACE_GETREGSET) failed");
356 for (i
= 0; i
< 32; i
++)
359 ret
= ptrace(PTRACE_SETFPREGS
, child
, NULL
, regs
);
361 perror("ptrace(PTRACE_GETREGSET) failed");
367 int show_ckpt_fpr(pid_t child
, unsigned long *fpr
)
369 struct fpr_regs
*regs
;
373 regs
= (struct fpr_regs
*) malloc(sizeof(struct fpr_regs
));
375 iov
.iov_len
= sizeof(struct fpr_regs
);
377 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CFPR
, &iov
);
379 perror("ptrace(PTRACE_GETREGSET) failed");
384 for (i
= 0; i
< 32; i
++)
385 fpr
[i
] = regs
->fpr
[i
];
391 int write_ckpt_fpr(pid_t child
, unsigned long val
)
393 struct fpr_regs
*regs
;
397 regs
= (struct fpr_regs
*) malloc(sizeof(struct fpr_regs
));
399 iov
.iov_len
= sizeof(struct fpr_regs
);
401 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CFPR
, &iov
);
403 perror("ptrace(PTRACE_GETREGSET) failed");
407 for (i
= 0; i
< 32; i
++)
410 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CFPR
, &iov
);
412 perror("ptrace(PTRACE_GETREGSET) failed");
419 int show_gpr(pid_t child
, unsigned long *gpr
)
421 struct pt_regs
*regs
;
424 regs
= (struct pt_regs
*) malloc(sizeof(struct pt_regs
));
426 perror("malloc() failed");
430 ret
= ptrace(PTRACE_GETREGS
, child
, NULL
, regs
);
432 perror("ptrace(PTRACE_GETREGSET) failed");
437 for (i
= 14; i
< 32; i
++)
438 gpr
[i
-14] = regs
->gpr
[i
];
444 int write_gpr(pid_t child
, unsigned long val
)
446 struct pt_regs
*regs
;
449 regs
= (struct pt_regs
*) malloc(sizeof(struct pt_regs
));
451 perror("malloc() failed");
455 ret
= ptrace(PTRACE_GETREGS
, child
, NULL
, regs
);
457 perror("ptrace(PTRACE_GETREGSET) failed");
461 for (i
= 14; i
< 32; i
++)
464 ret
= ptrace(PTRACE_SETREGS
, child
, NULL
, regs
);
466 perror("ptrace(PTRACE_GETREGSET) failed");
472 int show_ckpt_gpr(pid_t child
, unsigned long *gpr
)
474 struct pt_regs
*regs
;
478 regs
= (struct pt_regs
*) malloc(sizeof(struct pt_regs
));
480 perror("malloc() failed");
484 iov
.iov_base
= (u64
*) regs
;
485 iov
.iov_len
= sizeof(struct pt_regs
);
487 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CGPR
, &iov
);
489 perror("ptrace(PTRACE_GETREGSET) failed");
494 for (i
= 14; i
< 32; i
++)
495 gpr
[i
-14] = regs
->gpr
[i
];
501 int write_ckpt_gpr(pid_t child
, unsigned long val
)
503 struct pt_regs
*regs
;
507 regs
= (struct pt_regs
*) malloc(sizeof(struct pt_regs
));
509 perror("malloc() failed\n");
512 iov
.iov_base
= (u64
*) regs
;
513 iov
.iov_len
= sizeof(struct pt_regs
);
515 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CGPR
, &iov
);
517 perror("ptrace(PTRACE_GETREGSET) failed");
521 for (i
= 14; i
< 32; i
++)
524 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CGPR
, &iov
);
526 perror("ptrace(PTRACE_GETREGSET) failed");
533 int show_vmx(pid_t child
, unsigned long vmx
[][2])
537 ret
= ptrace(PTRACE_GETVRREGS
, child
, 0, vmx
);
539 perror("ptrace(PTRACE_GETVRREGS) failed");
545 int show_vmx_ckpt(pid_t child
, unsigned long vmx
[][2])
547 unsigned long regs
[34][2];
551 iov
.iov_base
= (u64
*) regs
;
552 iov
.iov_len
= sizeof(regs
);
553 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CVMX
, &iov
);
555 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
558 memcpy(vmx
, regs
, sizeof(regs
));
563 int write_vmx(pid_t child
, unsigned long vmx
[][2])
567 ret
= ptrace(PTRACE_SETVRREGS
, child
, 0, vmx
);
569 perror("ptrace(PTRACE_SETVRREGS) failed");
575 int write_vmx_ckpt(pid_t child
, unsigned long vmx
[][2])
577 unsigned long regs
[34][2];
581 memcpy(regs
, vmx
, sizeof(regs
));
582 iov
.iov_base
= (u64
*) regs
;
583 iov
.iov_len
= sizeof(regs
);
584 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CVMX
, &iov
);
586 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
593 int show_vsx(pid_t child
, unsigned long *vsx
)
597 ret
= ptrace(PTRACE_GETVSRREGS
, child
, 0, vsx
);
599 perror("ptrace(PTRACE_GETVSRREGS) failed");
605 int show_vsx_ckpt(pid_t child
, unsigned long *vsx
)
607 unsigned long regs
[32];
611 iov
.iov_base
= (u64
*) regs
;
612 iov
.iov_len
= sizeof(regs
);
613 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CVSX
, &iov
);
615 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
618 memcpy(vsx
, regs
, sizeof(regs
));
622 int write_vsx(pid_t child
, unsigned long *vsx
)
626 ret
= ptrace(PTRACE_SETVSRREGS
, child
, 0, vsx
);
628 perror("ptrace(PTRACE_SETVSRREGS) failed");
634 int write_vsx_ckpt(pid_t child
, unsigned long *vsx
)
636 unsigned long regs
[32];
640 memcpy(regs
, vsx
, sizeof(regs
));
641 iov
.iov_base
= (u64
*) regs
;
642 iov
.iov_len
= sizeof(regs
);
643 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CVSX
, &iov
);
645 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
652 int show_tm_spr(pid_t child
, struct tm_spr_regs
*out
)
654 struct tm_spr_regs
*regs
;
658 regs
= (struct tm_spr_regs
*) malloc(sizeof(struct tm_spr_regs
));
660 perror("malloc() failed");
664 iov
.iov_base
= (u64
*) regs
;
665 iov
.iov_len
= sizeof(struct tm_spr_regs
);
667 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_SPR
, &iov
);
669 perror("ptrace(PTRACE_GETREGSET) failed");
674 memcpy(out
, regs
, sizeof(struct tm_spr_regs
));
681 /* Analyse TEXASR after TM failure */
682 inline unsigned long get_tfiar(void)
686 asm volatile("mfspr %0,%1" : "=r" (ret
) : "i" (SPRN_TFIAR
));
690 void analyse_texasr(unsigned long texasr
)
692 printf("TEXASR: %16lx\t", texasr
);
694 if (texasr
& TEXASR_FP
)
695 printf("TEXASR_FP ");
697 if (texasr
& TEXASR_DA
)
698 printf("TEXASR_DA ");
700 if (texasr
& TEXASR_NO
)
701 printf("TEXASR_NO ");
703 if (texasr
& TEXASR_FO
)
704 printf("TEXASR_FO ");
706 if (texasr
& TEXASR_SIC
)
707 printf("TEXASR_SIC ");
709 if (texasr
& TEXASR_NTC
)
710 printf("TEXASR_NTC ");
712 if (texasr
& TEXASR_TC
)
713 printf("TEXASR_TC ");
715 if (texasr
& TEXASR_TIC
)
716 printf("TEXASR_TIC ");
718 if (texasr
& TEXASR_IC
)
719 printf("TEXASR_IC ");
721 if (texasr
& TEXASR_IFC
)
722 printf("TEXASR_IFC ");
724 if (texasr
& TEXASR_ABT
)
725 printf("TEXASR_ABT ");
727 if (texasr
& TEXASR_SPD
)
728 printf("TEXASR_SPD ");
730 if (texasr
& TEXASR_HV
)
731 printf("TEXASR_HV ");
733 if (texasr
& TEXASR_PR
)
734 printf("TEXASR_PR ");
736 if (texasr
& TEXASR_FS
)
737 printf("TEXASR_FS ");
739 if (texasr
& TEXASR_TE
)
740 printf("TEXASR_TE ");
742 if (texasr
& TEXASR_ROT
)
743 printf("TEXASR_ROT ");
745 printf("TFIAR :%lx\n", get_tfiar());
748 void store_gpr(unsigned long *addr
);
749 void store_fpr(float *addr
);