1 /* 2 * Ptrace test for TAR, PPR, DSCR registers 3 * 4 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation. 5 * 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. 10 */ 11 #include "ptrace.h" 12 #include "ptrace-tar.h" 13 14 /* Tracer and Tracee Shared Data */ 15 int shm_id; 16 int *cptr; 17 int *pptr; 18 19 void tar(void) 20 { 21 unsigned long reg[3]; 22 int ret; 23 24 cptr = (int *)shmat(shm_id, NULL, 0); 25 printf("%-30s TAR: %u PPR: %lx DSCR: %u\n", 26 user_write, TAR_1, PPR_1, DSCR_1); 27 28 mtspr(SPRN_TAR, TAR_1); 29 mtspr(SPRN_PPR, PPR_1); 30 mtspr(SPRN_DSCR, DSCR_1); 31 32 cptr[2] = 1; 33 34 /* Wait on parent */ 35 while (!cptr[0]) 36 asm volatile("" : : : "memory"); 37 38 reg[0] = mfspr(SPRN_TAR); 39 reg[1] = mfspr(SPRN_PPR); 40 reg[2] = mfspr(SPRN_DSCR); 41 42 printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", 43 user_read, reg[0], reg[1], reg[2]); 44 45 /* Unblock the parent now */ 46 cptr[1] = 1; 47 shmdt((int *)cptr); 48 49 ret = validate_tar_registers(reg, TAR_2, PPR_2, DSCR_2); 50 if (ret) 51 exit(1); 52 exit(0); 53 } 54 55 int trace_tar(pid_t child) 56 { 57 unsigned long reg[3]; 58 59 FAIL_IF(start_trace(child)); 60 FAIL_IF(show_tar_registers(child, reg)); 61 printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", 62 ptrace_read_running, reg[0], reg[1], reg[2]); 63 64 FAIL_IF(validate_tar_registers(reg, TAR_1, PPR_1, DSCR_1)); 65 FAIL_IF(stop_trace(child)); 66 return TEST_PASS; 67 } 68 69 int trace_tar_write(pid_t child) 70 { 71 FAIL_IF(start_trace(child)); 72 FAIL_IF(write_tar_registers(child, TAR_2, PPR_2, DSCR_2)); 73 printf("%-30s TAR: %u PPR: %lx DSCR: %u\n", 74 ptrace_write_running, TAR_2, PPR_2, DSCR_2); 75 76 FAIL_IF(stop_trace(child)); 77 return TEST_PASS; 78 } 79 80 int ptrace_tar(void) 81 { 82 pid_t pid; 83 int ret, status; 84 85 shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT); 86 pid = fork(); 87 if (pid < 0) { 88 perror("fork() failed"); 89 return TEST_FAIL; 90 } 91 92 if (pid == 0) 93 tar(); 94 95 if (pid) { 96 pptr = (int *)shmat(shm_id, NULL, 0); 97 pptr[0] = 0; 98 pptr[1] = 0; 99 100 while (!pptr[2]) 101 asm volatile("" : : : "memory"); 102 ret = trace_tar(pid); 103 if (ret) 104 return ret; 105 106 ret = trace_tar_write(pid); 107 if (ret) 108 return ret; 109 110 /* Unblock the child now */ 111 pptr[0] = 1; 112 113 /* Wait on child */ 114 while (!pptr[1]) 115 asm volatile("" : : : "memory"); 116 117 shmdt((int *)pptr); 118 119 ret = wait(&status); 120 shmctl(shm_id, IPC_RMID, NULL); 121 if (ret != pid) { 122 printf("Child's exit status not captured\n"); 123 return TEST_PASS; 124 } 125 126 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL : 127 TEST_PASS; 128 } 129 return TEST_PASS; 130 } 131 132 int main(int argc, char *argv[]) 133 { 134 return test_harness(ptrace_tar, "ptrace_tar"); 135 } 136