linux/tools/testing/selftests/powerpc/ptrace/ptrace-gpr.c
<<
>>
Prefs
   1/*
   2 * Ptrace test for GPR/FPR 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-gpr.h"
  13#include "reg.h"
  14
  15/* Tracer and Tracee Shared Data */
  16int shm_id;
  17int *cptr, *pptr;
  18
  19float a = FPR_1;
  20float b = FPR_2;
  21float c = FPR_3;
  22
  23void gpr(void)
  24{
  25        unsigned long gpr_buf[18];
  26        float fpr_buf[32];
  27
  28        cptr = (int *)shmat(shm_id, NULL, 0);
  29
  30        asm __volatile__(
  31                ASM_LOAD_GPR_IMMED(gpr_1)
  32                ASM_LOAD_FPR_SINGLE_PRECISION(flt_1)
  33                :
  34                : [gpr_1]"i"(GPR_1), [flt_1] "r" (&a)
  35                : "memory", "r6", "r7", "r8", "r9", "r10",
  36                "r11", "r12", "r13", "r14", "r15", "r16", "r17",
  37                "r18", "r19", "r20", "r21", "r22", "r23", "r24",
  38                "r25", "r26", "r27", "r28", "r29", "r30", "r31"
  39                );
  40
  41        cptr[1] = 1;
  42
  43        while (!cptr[0])
  44                asm volatile("" : : : "memory");
  45
  46        shmdt((void *)cptr);
  47        store_gpr(gpr_buf);
  48        store_fpr_single_precision(fpr_buf);
  49
  50        if (validate_gpr(gpr_buf, GPR_3))
  51                exit(1);
  52
  53        if (validate_fpr_float(fpr_buf, c))
  54                exit(1);
  55
  56        exit(0);
  57}
  58
  59int trace_gpr(pid_t child)
  60{
  61        unsigned long gpr[18];
  62        unsigned long fpr[32];
  63
  64        FAIL_IF(start_trace(child));
  65        FAIL_IF(show_gpr(child, gpr));
  66        FAIL_IF(validate_gpr(gpr, GPR_1));
  67        FAIL_IF(show_fpr(child, fpr));
  68        FAIL_IF(validate_fpr(fpr, FPR_1_REP));
  69        FAIL_IF(write_gpr(child, GPR_3));
  70        FAIL_IF(write_fpr(child, FPR_3_REP));
  71        FAIL_IF(stop_trace(child));
  72
  73        return TEST_PASS;
  74}
  75
  76int ptrace_gpr(void)
  77{
  78        pid_t pid;
  79        int ret, status;
  80
  81        shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
  82        pid = fork();
  83        if (pid < 0) {
  84                perror("fork() failed");
  85                return TEST_FAIL;
  86        }
  87        if (pid == 0)
  88                gpr();
  89
  90        if (pid) {
  91                pptr = (int *)shmat(shm_id, NULL, 0);
  92                while (!pptr[1])
  93                        asm volatile("" : : : "memory");
  94
  95                ret = trace_gpr(pid);
  96                if (ret) {
  97                        kill(pid, SIGTERM);
  98                        shmdt((void *)pptr);
  99                        shmctl(shm_id, IPC_RMID, NULL);
 100                        return TEST_FAIL;
 101                }
 102
 103                pptr[0] = 1;
 104                shmdt((void *)pptr);
 105
 106                ret = wait(&status);
 107                shmctl(shm_id, IPC_RMID, NULL);
 108                if (ret != pid) {
 109                        printf("Child's exit status not captured\n");
 110                        return TEST_FAIL;
 111                }
 112
 113                return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
 114                        TEST_PASS;
 115        }
 116
 117        return TEST_PASS;
 118}
 119
 120int main(int argc, char *argv[])
 121{
 122        return test_harness(ptrace_gpr, "ptrace_gpr");
 123}
 124