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 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 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 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 116 int main(int argc, char *argv[]) 117 { 118 return test_harness(ptrace_gpr, "ptrace_gpr"); 119 } 120