Home | History | Annotate | Download | only in ptrace
      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