vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 1 | /* |
| 2 | * make sure PEEKUSER matches GETREGS |
| 3 | * |
| 4 | * Copyright (c) 2008 Analog Devices Inc. |
| 5 | * |
| 6 | * Licensed under the GPL-2 or later |
| 7 | */ |
| 8 | |
vapier | 9a9a569 | 2008-12-11 09:56:27 +0000 | [diff] [blame] | 9 | #define _GNU_SOURCE |
| 10 | |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 11 | #include <errno.h> |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 12 | #include <stdbool.h> |
| 13 | #include <stdio.h> |
| 14 | #include <stdlib.h> |
| 15 | #include <unistd.h> |
vapier | 919dca8 | 2009-11-03 19:42:12 +0000 | [diff] [blame] | 16 | |
| 17 | #include <config.h> |
| 18 | #include "ptrace.h" |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 19 | |
| 20 | #include "test.h" |
subrata_modak | 90a8fb4 | 2008-10-15 14:38:51 +0000 | [diff] [blame] | 21 | #include "spawn_ptrace_child.h" |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 22 | |
| 23 | char *TCID = "ptrace04"; |
| 24 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 25 | static void cleanup(); |
yaberauneya | d283b3b | 2009-12-11 14:13:29 +0000 | [diff] [blame] | 26 | |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 27 | #define R(r) { .name = "PT_" #r, .off = PT_##r }, |
| 28 | static struct { |
| 29 | const char *name; |
| 30 | long off; |
| 31 | } regs[] = { |
| 32 | #ifdef __bfin__ |
| 33 | R(ORIG_R0) R(ORIG_P0) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 34 | R(R0) R(R1) R(R2) R(R3) R(R4) R(R5) R(R6) R(R7) |
| 35 | R(P0) R(P1) R(P2) R(P3) R(P4) R(P5) R(FP) R(USP) |
| 36 | R(I0) R(I1) R(I2) R(I3) |
| 37 | R(M0) R(M1) R(M2) R(M3) |
| 38 | R(L0) R(L1) R(L2) R(L3) |
| 39 | R(B0) R(B1) R(B2) R(B3) |
| 40 | R(A0X) R(A0W) R(A1X) R(A1W) |
| 41 | R(LC0) R(LC1) R(LT0) R(LT1) R(LB0) R(LB1) |
| 42 | R(ASTAT) |
| 43 | R(RETS) R(PC) R(RETX) R(RETN) R(RETE) |
| 44 | R(SEQSTAT) R(IPEND) R(SYSCFG) |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 45 | #endif |
| 46 | }; |
| 47 | |
| 48 | int TST_TOTAL = 2; |
| 49 | |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 50 | void compare_registers(unsigned char poison) |
| 51 | { |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 52 | #ifdef HAVE_STRUCT_PTRACE_REGS |
yaberauneya | 08984c5 | 2009-11-27 23:04:45 +0000 | [diff] [blame] | 53 | ptrace_regs _pt_regs; |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 54 | size_t i; |
| 55 | long ret; |
| 56 | bool failed = false; |
| 57 | |
yaberauneya | 08984c5 | 2009-11-27 23:04:45 +0000 | [diff] [blame] | 58 | memset(&_pt_regs, poison, sizeof(_pt_regs)); |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 59 | errno = 0; |
yaberauneya | 08984c5 | 2009-11-27 23:04:45 +0000 | [diff] [blame] | 60 | ret = ptrace(PTRACE_GETREGS, pid, NULL, &_pt_regs); |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 61 | if (ret && errno) { |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 62 | tst_resm(TFAIL | TERRNO, "PTRACE_GETREGS failed"); |
| 63 | } else { |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 64 | |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 65 | for (i = 0; i < ARRAY_SIZE(regs); ++i) { |
| 66 | errno = 0; |
| 67 | ret = ptrace(PTRACE_PEEKUSER, pid, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 68 | (void *)regs[i].off, NULL); |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 69 | if (ret && errno) { |
| 70 | tst_resm(TFAIL | TERRNO, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 71 | "PTRACE_PEEKUSER: register %s " |
| 72 | "(offset %li) failed", |
| 73 | regs[i].name, regs[i].off); |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 74 | failed = true; |
| 75 | continue; |
| 76 | } |
| 77 | |
yaberauneya | 08984c5 | 2009-11-27 23:04:45 +0000 | [diff] [blame] | 78 | long *pt_val = (void *)&_pt_regs + regs[i].off; |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 79 | if (*pt_val != ret) { |
| 80 | tst_resm(TFAIL, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 81 | "register %s (offset %li) did not " |
| 82 | "match\n\tGETREGS: 0x%08lx " |
| 83 | "PEEKUSER: 0x%08lx", |
| 84 | regs[i].name, regs[i].off, *pt_val, |
| 85 | ret); |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 86 | failed = true; |
| 87 | } |
| 88 | |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 89 | } |
| 90 | |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 91 | } |
| 92 | |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 93 | tst_resm((failed ? TFAIL : TPASS), |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 94 | "PTRACE PEEKUSER/GETREGS (poison 0x%02x)", poison); |
yaberauneya | a5dad42 | 2009-11-27 22:55:01 +0000 | [diff] [blame] | 95 | #else |
| 96 | tst_brkm(TCONF, cleanup, "System doesn't have ptrace_regs structure"); |
| 97 | #endif |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | int main(int argc, char *argv[]) |
| 101 | { |
Cyril Hrubis | 0b9589f | 2014-05-27 17:40:33 +0200 | [diff] [blame] | 102 | const char *msg; |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 103 | |
vapier | dcc74a4 | 2009-10-07 06:22:54 +0000 | [diff] [blame] | 104 | if (ARRAY_SIZE(regs) == 0) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 105 | tst_brkm(TCONF, NULL, "test not supported for your arch (yet)"); |
vapier | dcc74a4 | 2009-10-07 06:22:54 +0000 | [diff] [blame] | 106 | |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 107 | if ((msg = parse_opts(argc, argv, NULL, NULL))) |
Garrett Cooper | 60fa801 | 2010-11-22 13:50:58 -0800 | [diff] [blame] | 108 | tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 109 | |
| 110 | make_a_baby(argc, argv); |
| 111 | |
vapier | b6f710a | 2008-09-24 22:42:37 +0000 | [diff] [blame] | 112 | /* first compare register states when execl() syscall starts */ |
| 113 | tst_resm(TINFO, "Before exec() in child"); |
| 114 | compare_registers(0x00); |
| 115 | compare_registers(0xff); |
| 116 | |
| 117 | /* then compare register states after execl() syscall finishes */ |
| 118 | tst_resm(TINFO, "After exec() in child"); |
| 119 | errno = 0; |
| 120 | if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) && errno) { |
Cyril Hrubis | 526fdf8 | 2014-12-04 14:35:01 +0100 | [diff] [blame] | 121 | tst_brkm(TFAIL, NULL, "PTRACE_SYSCALL failed: %s", |
| 122 | strerror(errno)); |
vapier | b6f710a | 2008-09-24 22:42:37 +0000 | [diff] [blame] | 123 | } |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 124 | compare_registers(0x00); |
| 125 | compare_registers(0xff); |
| 126 | |
| 127 | /* hopefully this worked */ |
| 128 | ptrace(PTRACE_KILL, pid, NULL, NULL); |
| 129 | |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 130 | tst_exit(); |
vapier | 488d045 | 2008-09-23 19:19:31 +0000 | [diff] [blame] | 131 | } |
yaberauneya | d283b3b | 2009-12-11 14:13:29 +0000 | [diff] [blame] | 132 | |
Mike Frysinger | c57fba5 | 2014-04-09 18:56:30 -0400 | [diff] [blame] | 133 | static void cleanup(void) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 134 | { |
| 135 | } |