0001
0002
0003
0004
0005
0006
0007 #include "ptrace.h"
0008 #include "ptrace-gpr.h"
0009 #include "reg.h"
0010 #include <time.h>
0011
0012
0013 int shm_id;
0014 int *cptr, *pptr;
0015
0016 extern void gpr_child_loop(int *read_flag, int *write_flag,
0017 unsigned long *gpr_buf, double *fpr_buf);
0018
0019 unsigned long child_gpr_val, parent_gpr_val;
0020 double child_fpr_val, parent_fpr_val;
0021
0022 static int child(void)
0023 {
0024 unsigned long gpr_buf[32];
0025 double fpr_buf[32];
0026 int i;
0027
0028 cptr = (int *)shmat(shm_id, NULL, 0);
0029 memset(gpr_buf, 0, sizeof(gpr_buf));
0030 memset(fpr_buf, 0, sizeof(fpr_buf));
0031
0032 for (i = 0; i < 32; i++) {
0033 gpr_buf[i] = child_gpr_val;
0034 fpr_buf[i] = child_fpr_val;
0035 }
0036
0037 gpr_child_loop(&cptr[0], &cptr[1], gpr_buf, fpr_buf);
0038
0039 shmdt((void *)cptr);
0040
0041 FAIL_IF(validate_gpr(gpr_buf, parent_gpr_val));
0042 FAIL_IF(validate_fpr_double(fpr_buf, parent_fpr_val));
0043
0044 return 0;
0045 }
0046
0047 int trace_gpr(pid_t child)
0048 {
0049 __u64 tmp, fpr[32], *peeked_fprs;
0050 unsigned long gpr[18];
0051
0052 FAIL_IF(start_trace(child));
0053
0054
0055 FAIL_IF(show_gpr(child, gpr));
0056 FAIL_IF(validate_gpr(gpr, child_gpr_val));
0057
0058
0059 FAIL_IF(show_fpr(child, fpr));
0060 memcpy(&tmp, &child_fpr_val, sizeof(tmp));
0061 FAIL_IF(validate_fpr(fpr, tmp));
0062
0063
0064 peeked_fprs = peek_fprs(child);
0065 FAIL_IF(!peeked_fprs);
0066 FAIL_IF(validate_fpr(peeked_fprs, tmp));
0067 free(peeked_fprs);
0068
0069
0070 FAIL_IF(write_gpr(child, parent_gpr_val));
0071
0072
0073 memcpy(&tmp, &parent_fpr_val, sizeof(tmp));
0074 FAIL_IF(write_fpr(child, tmp));
0075
0076
0077 peeked_fprs = peek_fprs(child);
0078 FAIL_IF(!peeked_fprs);
0079 FAIL_IF(validate_fpr(peeked_fprs, tmp));
0080
0081
0082 FAIL_IF(poke_fprs(child, (unsigned long *)peeked_fprs));
0083
0084
0085 FAIL_IF(stop_trace(child));
0086
0087 return TEST_PASS;
0088 }
0089
0090 #ifndef __LONG_WIDTH__
0091 #define __LONG_WIDTH__ (sizeof(long) * 8)
0092 #endif
0093
0094 static uint64_t rand_reg(void)
0095 {
0096 uint64_t result;
0097 long r;
0098
0099 r = random();
0100
0101
0102 result = r & 0xffff;
0103 if (r & 0x10000)
0104 return result;
0105
0106
0107 result |= random() << (__LONG_WIDTH__ - 31);
0108 if (r & 0x100000)
0109 return result;
0110
0111
0112 result ^= random() << 16;
0113
0114 return result;
0115 }
0116
0117 int ptrace_gpr(void)
0118 {
0119 unsigned long seed;
0120 int ret, status;
0121 pid_t pid;
0122
0123 seed = getpid() ^ time(NULL);
0124 printf("srand(%lu)\n", seed);
0125 srand(seed);
0126
0127 child_gpr_val = rand_reg();
0128 child_fpr_val = rand_reg();
0129 parent_gpr_val = rand_reg();
0130 parent_fpr_val = rand_reg();
0131
0132 shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
0133 pid = fork();
0134 if (pid < 0) {
0135 perror("fork() failed");
0136 return TEST_FAIL;
0137 }
0138 if (pid == 0)
0139 exit(child());
0140
0141 if (pid) {
0142 pptr = (int *)shmat(shm_id, NULL, 0);
0143 while (!pptr[1])
0144 asm volatile("" : : : "memory");
0145
0146 ret = trace_gpr(pid);
0147 if (ret) {
0148 kill(pid, SIGTERM);
0149 shmdt((void *)pptr);
0150 shmctl(shm_id, IPC_RMID, NULL);
0151 return TEST_FAIL;
0152 }
0153
0154 pptr[0] = 1;
0155 shmdt((void *)pptr);
0156
0157 ret = wait(&status);
0158 shmctl(shm_id, IPC_RMID, NULL);
0159 if (ret != pid) {
0160 printf("Child's exit status not captured\n");
0161 return TEST_FAIL;
0162 }
0163
0164 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0165 TEST_PASS;
0166 }
0167
0168 return TEST_PASS;
0169 }
0170
0171 int main(int argc, char *argv[])
0172 {
0173 return test_harness(ptrace_gpr, "ptrace_gpr");
0174 }