linux/tools/testing/selftests/powerpc/ptrace/ptrace-tar.c
<<
>>
Prefs
   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 */
  15int shm_id;
  16int *cptr;
  17int *pptr;
  18
  19void 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
  55int 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
  69int 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
  80int 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
 132int main(int argc, char *argv[])
 133{
 134        return test_harness(ptrace_tar, "ptrace_tar");
 135}
 136