1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Ptrace test for GPR/FPR registers
4 *
5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
6 */
7 #include "ptrace.h"
8 #include "ptrace-gpr.h"
9 #include "reg.h"
10
11 /* Tracer and Tracee Shared Data */
12 int shm_id;
13 int *cptr, *pptr;
14
15 float a = FPR_1;
16 float b = FPR_2;
17 float c = FPR_3;
18
gpr(void)19 void gpr(void)
20 {
21 unsigned long gpr_buf[18];
22 float fpr_buf[32];
23
24 cptr = (int *)shmat(shm_id, NULL, 0);
25
26 asm __volatile__(
27 ASM_LOAD_GPR_IMMED(gpr_1)
28 ASM_LOAD_FPR_SINGLE_PRECISION(flt_1)
29 :
30 : [gpr_1]"i"(GPR_1), [flt_1] "b" (&a)
31 : "memory", "r6", "r7", "r8", "r9", "r10",
32 "r11", "r12", "r13", "r14", "r15", "r16", "r17",
33 "r18", "r19", "r20", "r21", "r22", "r23", "r24",
34 "r25", "r26", "r27", "r28", "r29", "r30", "r31"
35 );
36
37 cptr[1] = 1;
38
39 while (!cptr[0])
40 asm volatile("" : : : "memory");
41
42 shmdt((void *)cptr);
43 store_gpr(gpr_buf);
44 store_fpr_single_precision(fpr_buf);
45
46 if (validate_gpr(gpr_buf, GPR_3))
47 exit(1);
48
49 if (validate_fpr_float(fpr_buf, c))
50 exit(1);
51
52 exit(0);
53 }
54
trace_gpr(pid_t child)55 int trace_gpr(pid_t child)
56 {
57 unsigned long gpr[18];
58 unsigned long fpr[32];
59
60 FAIL_IF(start_trace(child));
61 FAIL_IF(show_gpr(child, gpr));
62 FAIL_IF(validate_gpr(gpr, GPR_1));
63 FAIL_IF(show_fpr(child, fpr));
64 FAIL_IF(validate_fpr(fpr, FPR_1_REP));
65 FAIL_IF(write_gpr(child, GPR_3));
66 FAIL_IF(write_fpr(child, FPR_3_REP));
67 FAIL_IF(stop_trace(child));
68
69 return TEST_PASS;
70 }
71
ptrace_gpr(void)72 int ptrace_gpr(void)
73 {
74 pid_t pid;
75 int ret, status;
76
77 shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
78 pid = fork();
79 if (pid < 0) {
80 perror("fork() failed");
81 return TEST_FAIL;
82 }
83 if (pid == 0)
84 gpr();
85
86 if (pid) {
87 pptr = (int *)shmat(shm_id, NULL, 0);
88 while (!pptr[1])
89 asm volatile("" : : : "memory");
90
91 ret = trace_gpr(pid);
92 if (ret) {
93 kill(pid, SIGTERM);
94 shmdt((void *)pptr);
95 shmctl(shm_id, IPC_RMID, NULL);
96 return TEST_FAIL;
97 }
98
99 pptr[0] = 1;
100 shmdt((void *)pptr);
101
102 ret = wait(&status);
103 shmctl(shm_id, IPC_RMID, NULL);
104 if (ret != pid) {
105 printf("Child's exit status not captured\n");
106 return TEST_FAIL;
107 }
108
109 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
110 TEST_PASS;
111 }
112
113 return TEST_PASS;
114 }
115
main(int argc,char * argv[])116 int main(int argc, char *argv[])
117 {
118 return test_harness(ptrace_gpr, "ptrace_gpr");
119 }
120