Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Ptrace test for TAR, PPR, DSCR registers
0004  *
0005  * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
0006  */
0007 #include "ptrace.h"
0008 #include "ptrace-tar.h"
0009 
0010 /* Tracer and Tracee Shared Data */
0011 int shm_id;
0012 int *cptr;
0013 int *pptr;
0014 
0015 void tar(void)
0016 {
0017     unsigned long reg[3];
0018     int ret;
0019 
0020     cptr = (int *)shmat(shm_id, NULL, 0);
0021     printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
0022             user_write, TAR_1, PPR_1, DSCR_1);
0023 
0024     mtspr(SPRN_TAR, TAR_1);
0025     mtspr(SPRN_PPR, PPR_1);
0026     mtspr(SPRN_DSCR, DSCR_1);
0027 
0028     cptr[2] = 1;
0029 
0030     /* Wait on parent */
0031     while (!cptr[0])
0032         asm volatile("" : : : "memory");
0033 
0034     reg[0] = mfspr(SPRN_TAR);
0035     reg[1] = mfspr(SPRN_PPR);
0036     reg[2] = mfspr(SPRN_DSCR);
0037 
0038     printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0039             user_read, reg[0], reg[1], reg[2]);
0040 
0041     /* Unblock the parent now */
0042     cptr[1] = 1;
0043     shmdt((int *)cptr);
0044 
0045     ret = validate_tar_registers(reg, TAR_2, PPR_2, DSCR_2);
0046     if (ret)
0047         exit(1);
0048     exit(0);
0049 }
0050 
0051 int trace_tar(pid_t child)
0052 {
0053     unsigned long reg[3];
0054 
0055     FAIL_IF(start_trace(child));
0056     FAIL_IF(show_tar_registers(child, reg));
0057     printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0058             ptrace_read_running, reg[0], reg[1], reg[2]);
0059 
0060     FAIL_IF(validate_tar_registers(reg, TAR_1, PPR_1, DSCR_1));
0061     FAIL_IF(stop_trace(child));
0062     return TEST_PASS;
0063 }
0064 
0065 int trace_tar_write(pid_t child)
0066 {
0067     FAIL_IF(start_trace(child));
0068     FAIL_IF(write_tar_registers(child, TAR_2, PPR_2, DSCR_2));
0069     printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
0070             ptrace_write_running, TAR_2, PPR_2, DSCR_2);
0071 
0072     FAIL_IF(stop_trace(child));
0073     return TEST_PASS;
0074 }
0075 
0076 int ptrace_tar(void)
0077 {
0078     pid_t pid;
0079     int ret, status;
0080 
0081     // TAR was added in v2.07
0082     SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07));
0083 
0084     shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
0085     pid = fork();
0086     if (pid < 0) {
0087         perror("fork() failed");
0088         return TEST_FAIL;
0089     }
0090 
0091     if (pid == 0)
0092         tar();
0093 
0094     if (pid) {
0095         pptr = (int *)shmat(shm_id, NULL, 0);
0096         pptr[0] = 0;
0097         pptr[1] = 0;
0098 
0099         while (!pptr[2])
0100             asm volatile("" : : : "memory");
0101         ret = trace_tar(pid);
0102         if (ret)
0103             return ret;
0104 
0105         ret = trace_tar_write(pid);
0106         if (ret)
0107             return ret;
0108 
0109         /* Unblock the child now */
0110         pptr[0] = 1;
0111 
0112         /* Wait on child */
0113         while (!pptr[1])
0114             asm volatile("" : : : "memory");
0115 
0116         shmdt((int *)pptr);
0117 
0118         ret = wait(&status);
0119         shmctl(shm_id, IPC_RMID, NULL);
0120         if (ret != pid) {
0121             printf("Child's exit status not captured\n");
0122             return TEST_PASS;
0123         }
0124 
0125         return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0126             TEST_PASS;
0127     }
0128     return TEST_PASS;
0129 }
0130 
0131 int main(int argc, char *argv[])
0132 {
0133     return test_harness(ptrace_tar, "ptrace_tar");
0134 }