Merge tag 'xtensa-20180225' of git://github.com/jcmvbkbc/linux-xtensa
[cris-mirror.git] / tools / testing / selftests / powerpc / ptrace / ptrace.h
blob19fb825270a186d3958784ea73bd82a2e71e2b89
1 /*
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.
11 #include <inttypes.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <malloc.h>
16 #include <errno.h>
17 #include <time.h>
18 #include <sys/ptrace.h>
19 #include <sys/ioctl.h>
20 #include <sys/uio.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <sys/signal.h>
24 #include <sys/ipc.h>
25 #include <sys/shm.h>
26 #include <sys/user.h>
27 #include <linux/elf.h>
28 #include <linux/types.h>
29 #include <linux/auxvec.h>
30 #include "reg.h"
31 #include "utils.h"
33 #define TEST_PASS 0
34 #define TEST_FAIL 1
36 struct fpr_regs {
37 unsigned long fpr[32];
38 unsigned long fpscr;
41 struct tm_spr_regs {
42 unsigned long tm_tfhar;
43 unsigned long tm_texasr;
44 unsigned long tm_tfiar;
47 #ifndef NT_PPC_TAR
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
61 #endif
63 /* Basic ptrace operations */
64 int start_trace(pid_t child)
66 int ret;
68 ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
69 if (ret) {
70 perror("ptrace(PTRACE_ATTACH) failed");
71 return TEST_FAIL;
73 ret = waitpid(child, NULL, 0);
74 if (ret != child) {
75 perror("waitpid() failed");
76 return TEST_FAIL;
78 return TEST_PASS;
81 int stop_trace(pid_t child)
83 int ret;
85 ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
86 if (ret) {
87 perror("ptrace(PTRACE_DETACH) failed");
88 return TEST_FAIL;
90 return TEST_PASS;
93 int cont_trace(pid_t child)
95 int ret;
97 ret = ptrace(PTRACE_CONT, child, NULL, NULL);
98 if (ret) {
99 perror("ptrace(PTRACE_CONT) failed");
100 return TEST_FAIL;
102 return TEST_PASS;
105 /* TAR, PPR, DSCR */
106 int show_tar_registers(pid_t child, unsigned long *out)
108 struct iovec iov;
109 unsigned long *reg;
110 int ret;
112 reg = malloc(sizeof(unsigned long));
113 if (!reg) {
114 perror("malloc() failed");
115 return TEST_FAIL;
117 iov.iov_base = (u64 *) reg;
118 iov.iov_len = sizeof(unsigned long);
120 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
121 if (ret) {
122 perror("ptrace(PTRACE_GETREGSET) failed");
123 goto fail;
125 if (out)
126 out[0] = *reg;
128 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
129 if (ret) {
130 perror("ptrace(PTRACE_GETREGSET) failed");
131 goto fail;
133 if (out)
134 out[1] = *reg;
136 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
137 if (ret) {
138 perror("ptrace(PTRACE_GETREGSET) failed");
139 goto fail;
141 if (out)
142 out[2] = *reg;
144 free(reg);
145 return TEST_PASS;
146 fail:
147 free(reg);
148 return TEST_FAIL;
151 int write_tar_registers(pid_t child, unsigned long tar,
152 unsigned long ppr, unsigned long dscr)
154 struct iovec iov;
155 unsigned long *reg;
156 int ret;
158 reg = malloc(sizeof(unsigned long));
159 if (!reg) {
160 perror("malloc() failed");
161 return TEST_FAIL;
164 iov.iov_base = (u64 *) reg;
165 iov.iov_len = sizeof(unsigned long);
167 *reg = tar;
168 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
169 if (ret) {
170 perror("ptrace(PTRACE_SETREGSET) failed");
171 goto fail;
174 *reg = ppr;
175 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
176 if (ret) {
177 perror("ptrace(PTRACE_SETREGSET) failed");
178 goto fail;
181 *reg = dscr;
182 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
183 if (ret) {
184 perror("ptrace(PTRACE_SETREGSET) failed");
185 goto fail;
188 free(reg);
189 return TEST_PASS;
190 fail:
191 free(reg);
192 return TEST_FAIL;
195 int show_tm_checkpointed_state(pid_t child, unsigned long *out)
197 struct iovec iov;
198 unsigned long *reg;
199 int ret;
201 reg = malloc(sizeof(unsigned long));
202 if (!reg) {
203 perror("malloc() failed");
204 return TEST_FAIL;
207 iov.iov_base = (u64 *) reg;
208 iov.iov_len = sizeof(unsigned long);
210 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
211 if (ret) {
212 perror("ptrace(PTRACE_GETREGSET) failed");
213 goto fail;
215 if (out)
216 out[0] = *reg;
218 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
219 if (ret) {
220 perror("ptrace(PTRACE_GETREGSET) failed");
221 goto fail;
223 if (out)
224 out[1] = *reg;
226 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
227 if (ret) {
228 perror("ptrace(PTRACE_GETREGSET) failed");
229 goto fail;
231 if (out)
232 out[2] = *reg;
234 free(reg);
235 return TEST_PASS;
237 fail:
238 free(reg);
239 return TEST_FAIL;
242 int write_ckpt_tar_registers(pid_t child, unsigned long tar,
243 unsigned long ppr, unsigned long dscr)
245 struct iovec iov;
246 unsigned long *reg;
247 int ret;
249 reg = malloc(sizeof(unsigned long));
250 if (!reg) {
251 perror("malloc() failed");
252 return TEST_FAIL;
255 iov.iov_base = (u64 *) reg;
256 iov.iov_len = sizeof(unsigned long);
258 *reg = tar;
259 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
260 if (ret) {
261 perror("ptrace(PTRACE_GETREGSET) failed");
262 goto fail;
265 *reg = ppr;
266 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
267 if (ret) {
268 perror("ptrace(PTRACE_GETREGSET) failed");
269 goto fail;
272 *reg = dscr;
273 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
274 if (ret) {
275 perror("ptrace(PTRACE_GETREGSET) failed");
276 goto fail;
279 free(reg);
280 return TEST_PASS;
281 fail:
282 free(reg);
283 return TEST_FAIL;
286 /* FPR */
287 int show_fpr(pid_t child, unsigned long *fpr)
289 struct fpr_regs *regs;
290 int ret, i;
292 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
293 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
294 if (ret) {
295 perror("ptrace(PTRACE_GETREGSET) failed");
296 return TEST_FAIL;
299 if (fpr) {
300 for (i = 0; i < 32; i++)
301 fpr[i] = regs->fpr[i];
303 return TEST_PASS;
306 int write_fpr(pid_t child, unsigned long val)
308 struct fpr_regs *regs;
309 int ret, i;
311 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
312 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
313 if (ret) {
314 perror("ptrace(PTRACE_GETREGSET) failed");
315 return TEST_FAIL;
318 for (i = 0; i < 32; i++)
319 regs->fpr[i] = val;
321 ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
322 if (ret) {
323 perror("ptrace(PTRACE_GETREGSET) failed");
324 return TEST_FAIL;
326 return TEST_PASS;
329 int show_ckpt_fpr(pid_t child, unsigned long *fpr)
331 struct fpr_regs *regs;
332 struct iovec iov;
333 int ret, i;
335 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
336 iov.iov_base = regs;
337 iov.iov_len = sizeof(struct fpr_regs);
339 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
340 if (ret) {
341 perror("ptrace(PTRACE_GETREGSET) failed");
342 return TEST_FAIL;
345 if (fpr) {
346 for (i = 0; i < 32; i++)
347 fpr[i] = regs->fpr[i];
350 return TEST_PASS;
353 int write_ckpt_fpr(pid_t child, unsigned long val)
355 struct fpr_regs *regs;
356 struct iovec iov;
357 int ret, i;
359 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
360 iov.iov_base = regs;
361 iov.iov_len = sizeof(struct fpr_regs);
363 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
364 if (ret) {
365 perror("ptrace(PTRACE_GETREGSET) failed");
366 return TEST_FAIL;
369 for (i = 0; i < 32; i++)
370 regs->fpr[i] = val;
372 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
373 if (ret) {
374 perror("ptrace(PTRACE_GETREGSET) failed");
375 return TEST_FAIL;
377 return TEST_PASS;
380 /* GPR */
381 int show_gpr(pid_t child, unsigned long *gpr)
383 struct pt_regs *regs;
384 int ret, i;
386 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
387 if (!regs) {
388 perror("malloc() failed");
389 return TEST_FAIL;
392 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
393 if (ret) {
394 perror("ptrace(PTRACE_GETREGSET) failed");
395 return TEST_FAIL;
398 if (gpr) {
399 for (i = 14; i < 32; i++)
400 gpr[i-14] = regs->gpr[i];
403 return TEST_PASS;
406 int write_gpr(pid_t child, unsigned long val)
408 struct pt_regs *regs;
409 int i, ret;
411 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
412 if (!regs) {
413 perror("malloc() failed");
414 return TEST_FAIL;
417 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
418 if (ret) {
419 perror("ptrace(PTRACE_GETREGSET) failed");
420 return TEST_FAIL;
423 for (i = 14; i < 32; i++)
424 regs->gpr[i] = val;
426 ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
427 if (ret) {
428 perror("ptrace(PTRACE_GETREGSET) failed");
429 return TEST_FAIL;
431 return TEST_PASS;
434 int show_ckpt_gpr(pid_t child, unsigned long *gpr)
436 struct pt_regs *regs;
437 struct iovec iov;
438 int ret, i;
440 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
441 if (!regs) {
442 perror("malloc() failed");
443 return TEST_FAIL;
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);
450 if (ret) {
451 perror("ptrace(PTRACE_GETREGSET) failed");
452 return TEST_FAIL;
455 if (gpr) {
456 for (i = 14; i < 32; i++)
457 gpr[i-14] = regs->gpr[i];
460 return TEST_PASS;
463 int write_ckpt_gpr(pid_t child, unsigned long val)
465 struct pt_regs *regs;
466 struct iovec iov;
467 int ret, i;
469 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
470 if (!regs) {
471 perror("malloc() failed\n");
472 return TEST_FAIL;
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);
478 if (ret) {
479 perror("ptrace(PTRACE_GETREGSET) failed");
480 return TEST_FAIL;
483 for (i = 14; i < 32; i++)
484 regs->gpr[i] = val;
486 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
487 if (ret) {
488 perror("ptrace(PTRACE_GETREGSET) failed");
489 return TEST_FAIL;
491 return TEST_PASS;
494 /* VMX */
495 int show_vmx(pid_t child, unsigned long vmx[][2])
497 int ret;
499 ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
500 if (ret) {
501 perror("ptrace(PTRACE_GETVRREGS) failed");
502 return TEST_FAIL;
504 return TEST_PASS;
507 int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
509 unsigned long regs[34][2];
510 struct iovec iov;
511 int ret;
513 iov.iov_base = (u64 *) regs;
514 iov.iov_len = sizeof(regs);
515 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
516 if (ret) {
517 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
518 return TEST_FAIL;
520 memcpy(vmx, regs, sizeof(regs));
521 return TEST_PASS;
525 int write_vmx(pid_t child, unsigned long vmx[][2])
527 int ret;
529 ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
530 if (ret) {
531 perror("ptrace(PTRACE_SETVRREGS) failed");
532 return TEST_FAIL;
534 return TEST_PASS;
537 int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
539 unsigned long regs[34][2];
540 struct iovec iov;
541 int ret;
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);
547 if (ret) {
548 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
549 return TEST_FAIL;
551 return TEST_PASS;
554 /* VSX */
555 int show_vsx(pid_t child, unsigned long *vsx)
557 int ret;
559 ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
560 if (ret) {
561 perror("ptrace(PTRACE_GETVSRREGS) failed");
562 return TEST_FAIL;
564 return TEST_PASS;
567 int show_vsx_ckpt(pid_t child, unsigned long *vsx)
569 unsigned long regs[32];
570 struct iovec iov;
571 int ret;
573 iov.iov_base = (u64 *) regs;
574 iov.iov_len = sizeof(regs);
575 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
576 if (ret) {
577 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
578 return TEST_FAIL;
580 memcpy(vsx, regs, sizeof(regs));
581 return TEST_PASS;
584 int write_vsx(pid_t child, unsigned long *vsx)
586 int ret;
588 ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
589 if (ret) {
590 perror("ptrace(PTRACE_SETVSRREGS) failed");
591 return TEST_FAIL;
593 return TEST_PASS;
596 int write_vsx_ckpt(pid_t child, unsigned long *vsx)
598 unsigned long regs[32];
599 struct iovec iov;
600 int ret;
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);
606 if (ret) {
607 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
608 return TEST_FAIL;
610 return TEST_PASS;
613 /* TM SPR */
614 int show_tm_spr(pid_t child, struct tm_spr_regs *out)
616 struct tm_spr_regs *regs;
617 struct iovec iov;
618 int ret;
620 regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
621 if (!regs) {
622 perror("malloc() failed");
623 return TEST_FAIL;
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);
630 if (ret) {
631 perror("ptrace(PTRACE_GETREGSET) failed");
632 return TEST_FAIL;
635 if (out)
636 memcpy(out, regs, sizeof(struct tm_spr_regs));
638 return TEST_PASS;
643 /* Analyse TEXASR after TM failure */
644 inline unsigned long get_tfiar(void)
646 unsigned long ret;
648 asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR));
649 return ret;
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);