0001
0002
0003
0004
0005
0006
0007 #include "ptrace.h"
0008 #include "ptrace-gpr.h"
0009 #include "tm.h"
0010
0011
0012 int shm_id;
0013 unsigned long *cptr, *pptr;
0014
0015 double a = FPR_1;
0016 double b = FPR_2;
0017 double c = FPR_3;
0018
0019 void tm_gpr(void)
0020 {
0021 unsigned long gpr_buf[18];
0022 unsigned long result, texasr;
0023 double fpr_buf[32];
0024
0025 printf("Starting the child\n");
0026 cptr = (unsigned long *)shmat(shm_id, NULL, 0);
0027
0028 trans:
0029 cptr[1] = 0;
0030 asm __volatile__(
0031 ASM_LOAD_GPR_IMMED(gpr_1)
0032 ASM_LOAD_FPR(flt_1)
0033 "1: ;"
0034 "tbegin.;"
0035 "beq 2f;"
0036 ASM_LOAD_GPR_IMMED(gpr_2)
0037 ASM_LOAD_FPR(flt_2)
0038 "tsuspend.;"
0039 "li 7, 1;"
0040 "stw 7, 0(%[cptr1]);"
0041 "tresume.;"
0042 "b .;"
0043
0044 "tend.;"
0045 "li 0, 0;"
0046 "ori %[res], 0, 0;"
0047 "b 3f;"
0048
0049
0050 "2: ;"
0051 "li 0, 1;"
0052 "ori %[res], 0, 0;"
0053 "mfspr %[texasr], %[sprn_texasr];"
0054
0055 "3: ;"
0056 : [res] "=r" (result), [texasr] "=r" (texasr)
0057 : [gpr_1]"i"(GPR_1), [gpr_2]"i"(GPR_2),
0058 [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "b" (&a),
0059 [flt_2] "b" (&b), [cptr1] "b" (&cptr[1])
0060 : "memory", "r0", "r7", "r8", "r9", "r10",
0061 "r11", "r12", "r13", "r14", "r15", "r16",
0062 "r17", "r18", "r19", "r20", "r21", "r22",
0063 "r23", "r24", "r25", "r26", "r27", "r28",
0064 "r29", "r30", "r31"
0065 );
0066
0067 if (result) {
0068 if (!cptr[0])
0069 goto trans;
0070
0071 shmdt((void *)cptr);
0072 store_gpr(gpr_buf);
0073 store_fpr(fpr_buf);
0074
0075 if (validate_gpr(gpr_buf, GPR_3))
0076 exit(1);
0077
0078 if (validate_fpr_double(fpr_buf, c))
0079 exit(1);
0080
0081 exit(0);
0082 }
0083 shmdt((void *)cptr);
0084 exit(1);
0085 }
0086
0087 int trace_tm_gpr(pid_t child)
0088 {
0089 unsigned long gpr[18];
0090 __u64 fpr[32];
0091
0092 FAIL_IF(start_trace(child));
0093 FAIL_IF(show_gpr(child, gpr));
0094 FAIL_IF(validate_gpr(gpr, GPR_2));
0095 FAIL_IF(show_fpr(child, fpr));
0096 FAIL_IF(validate_fpr(fpr, FPR_2_REP));
0097 FAIL_IF(show_ckpt_fpr(child, fpr));
0098 FAIL_IF(validate_fpr(fpr, FPR_1_REP));
0099 FAIL_IF(show_ckpt_gpr(child, gpr));
0100 FAIL_IF(validate_gpr(gpr, GPR_1));
0101 FAIL_IF(write_ckpt_gpr(child, GPR_3));
0102 FAIL_IF(write_ckpt_fpr(child, FPR_3_REP));
0103
0104 pptr[0] = 1;
0105 FAIL_IF(stop_trace(child));
0106
0107 return TEST_PASS;
0108 }
0109
0110 int ptrace_tm_gpr(void)
0111 {
0112 pid_t pid;
0113 int ret, status;
0114
0115 SKIP_IF(!have_htm());
0116 SKIP_IF(htm_is_synthetic());
0117 shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
0118 pid = fork();
0119 if (pid < 0) {
0120 perror("fork() failed");
0121 return TEST_FAIL;
0122 }
0123 if (pid == 0)
0124 tm_gpr();
0125
0126 if (pid) {
0127 pptr = (unsigned long *)shmat(shm_id, NULL, 0);
0128
0129 while (!pptr[1])
0130 asm volatile("" : : : "memory");
0131 ret = trace_tm_gpr(pid);
0132 if (ret) {
0133 kill(pid, SIGTERM);
0134 return TEST_FAIL;
0135 }
0136
0137 shmdt((void *)pptr);
0138
0139 ret = wait(&status);
0140 shmctl(shm_id, IPC_RMID, NULL);
0141 if (ret != pid) {
0142 printf("Child's exit status not captured\n");
0143 return TEST_FAIL;
0144 }
0145
0146 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0147 TEST_PASS;
0148 }
0149 return TEST_PASS;
0150 }
0151
0152 int main(int argc, char *argv[])
0153 {
0154 return test_harness(ptrace_tm_gpr, "ptrace_tm_gpr");
0155 }