~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/powerpc/ptrace/ptrace-gpr.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 #include <time.h>
 11 
 12 /* Tracer and Tracee Shared Data */
 13 int shm_id;
 14 int *cptr, *pptr;
 15 
 16 extern void gpr_child_loop(int *read_flag, int *write_flag,
 17                            unsigned long *gpr_buf, double *fpr_buf);
 18 
 19 unsigned long child_gpr_val, parent_gpr_val;
 20 double child_fpr_val, parent_fpr_val;
 21 
 22 static int child(void)
 23 {
 24         unsigned long gpr_buf[32];
 25         double fpr_buf[32];
 26         int i;
 27 
 28         cptr = (int *)shmat(shm_id, NULL, 0);
 29         memset(gpr_buf, 0, sizeof(gpr_buf));
 30         memset(fpr_buf, 0, sizeof(fpr_buf));
 31 
 32         for (i = 0; i < 32; i++) {
 33                 gpr_buf[i] = child_gpr_val;
 34                 fpr_buf[i] = child_fpr_val;
 35         }
 36 
 37         gpr_child_loop(&cptr[0], &cptr[1], gpr_buf, fpr_buf);
 38 
 39         shmdt((void *)cptr);
 40 
 41         FAIL_IF(validate_gpr(gpr_buf, parent_gpr_val));
 42         FAIL_IF(validate_fpr_double(fpr_buf, parent_fpr_val));
 43 
 44         return 0;
 45 }
 46 
 47 int trace_gpr(pid_t child)
 48 {
 49         __u64 tmp, fpr[32], *peeked_fprs;
 50         unsigned long gpr[18];
 51 
 52         FAIL_IF(start_trace(child));
 53 
 54         // Check child GPRs match what we expect using GETREGS
 55         FAIL_IF(show_gpr(child, gpr));
 56         FAIL_IF(validate_gpr(gpr, child_gpr_val));
 57 
 58         // Check child FPRs match what we expect using GETFPREGS
 59         FAIL_IF(show_fpr(child, fpr));
 60         memcpy(&tmp, &child_fpr_val, sizeof(tmp));
 61         FAIL_IF(validate_fpr(fpr, tmp));
 62 
 63         // Check child FPRs match what we expect using PEEKUSR
 64         peeked_fprs = peek_fprs(child);
 65         FAIL_IF(!peeked_fprs);
 66         FAIL_IF(validate_fpr(peeked_fprs, tmp));
 67         free(peeked_fprs);
 68 
 69         // Write child GPRs using SETREGS
 70         FAIL_IF(write_gpr(child, parent_gpr_val));
 71 
 72         // Write child FPRs using SETFPREGS
 73         memcpy(&tmp, &parent_fpr_val, sizeof(tmp));
 74         FAIL_IF(write_fpr(child, tmp));
 75 
 76         // Check child FPRs match what we just set, using PEEKUSR
 77         peeked_fprs = peek_fprs(child);
 78         FAIL_IF(!peeked_fprs);
 79         FAIL_IF(validate_fpr(peeked_fprs, tmp));
 80 
 81         // Write child FPRs using POKEUSR
 82         FAIL_IF(poke_fprs(child, (unsigned long *)peeked_fprs));
 83 
 84         // Child will check its FPRs match before exiting
 85         FAIL_IF(stop_trace(child));
 86 
 87         return TEST_PASS;
 88 }
 89 
 90 #ifndef __LONG_WIDTH__
 91 #define __LONG_WIDTH__ (sizeof(long) * 8)
 92 #endif
 93 
 94 static uint64_t rand_reg(void)
 95 {
 96         uint64_t result;
 97         long r;
 98 
 99         r = random();
100 
101         // Small values are typical
102         result = r & 0xffff;
103         if (r & 0x10000)
104                 return result;
105 
106         // Pointers tend to have high bits set
107         result |= random() << (__LONG_WIDTH__ - 31);
108         if (r & 0x100000)
109                 return result;
110 
111         // And sometimes we want a full 64-bit value
112         result ^= random() << 16;
113 
114         return result;
115 }
116 
117 int ptrace_gpr(void)
118 {
119         unsigned long seed;
120         int ret, status;
121         pid_t pid;
122 
123         seed = getpid() ^ time(NULL);
124         printf("srand(%lu)\n", seed);
125         srand(seed);
126 
127         child_gpr_val = rand_reg();
128         child_fpr_val = rand_reg();
129         parent_gpr_val = rand_reg();
130         parent_fpr_val = rand_reg();
131 
132         shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
133         pid = fork();
134         if (pid < 0) {
135                 perror("fork() failed");
136                 return TEST_FAIL;
137         }
138         if (pid == 0)
139                 exit(child());
140 
141         if (pid) {
142                 pptr = (int *)shmat(shm_id, NULL, 0);
143                 while (!pptr[1])
144                         asm volatile("" : : : "memory");
145 
146                 ret = trace_gpr(pid);
147                 if (ret) {
148                         kill(pid, SIGTERM);
149                         shmdt((void *)pptr);
150                         shmctl(shm_id, IPC_RMID, NULL);
151                         return TEST_FAIL;
152                 }
153 
154                 pptr[0] = 1;
155                 shmdt((void *)pptr);
156 
157                 ret = wait(&status);
158                 shmctl(shm_id, IPC_RMID, NULL);
159                 if (ret != pid) {
160                         printf("Child's exit status not captured\n");
161                         return TEST_FAIL;
162                 }
163 
164                 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
165                         TEST_PASS;
166         }
167 
168         return TEST_PASS;
169 }
170 
171 int main(int argc, char *argv[])
172 {
173         return test_harness(ptrace_gpr, "ptrace_gpr");
174 }
175 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php