blob: b29e3da4ee6154e0f2dd809d83d93f120beea4e6 [file] [log] [blame]
vapier488d0452008-09-23 19:19:31 +00001/*
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
vapier9a9a5692008-12-11 09:56:27 +00009#define _GNU_SOURCE
10
vapier488d0452008-09-23 19:19:31 +000011#include <errno.h>
vapier488d0452008-09-23 19:19:31 +000012#include <stdbool.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
vapier919dca82009-11-03 19:42:12 +000016
17#include <config.h>
18#include "ptrace.h"
vapier488d0452008-09-23 19:19:31 +000019
20#include "test.h"
subrata_modak90a8fb42008-10-15 14:38:51 +000021#include "spawn_ptrace_child.h"
vapier488d0452008-09-23 19:19:31 +000022
23char *TCID = "ptrace04";
24
Wanlong Gao354ebb42012-12-07 10:10:04 +080025static void cleanup();
yaberauneyad283b3b2009-12-11 14:13:29 +000026
vapier488d0452008-09-23 19:19:31 +000027#define R(r) { .name = "PT_" #r, .off = PT_##r },
28static struct {
29 const char *name;
30 long off;
31} regs[] = {
32#ifdef __bfin__
33 R(ORIG_R0) R(ORIG_P0)
Wanlong Gao354ebb42012-12-07 10:10:04 +080034 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)
vapier488d0452008-09-23 19:19:31 +000045#endif
46};
47
48int TST_TOTAL = 2;
49
vapier488d0452008-09-23 19:19:31 +000050void compare_registers(unsigned char poison)
51{
yaberauneyaa5dad422009-11-27 22:55:01 +000052#ifdef HAVE_STRUCT_PTRACE_REGS
yaberauneya08984c52009-11-27 23:04:45 +000053 ptrace_regs _pt_regs;
vapier488d0452008-09-23 19:19:31 +000054 size_t i;
55 long ret;
56 bool failed = false;
57
yaberauneya08984c52009-11-27 23:04:45 +000058 memset(&_pt_regs, poison, sizeof(_pt_regs));
vapier488d0452008-09-23 19:19:31 +000059 errno = 0;
yaberauneya08984c52009-11-27 23:04:45 +000060 ret = ptrace(PTRACE_GETREGS, pid, NULL, &_pt_regs);
vapier488d0452008-09-23 19:19:31 +000061 if (ret && errno) {
yaberauneyaa5dad422009-11-27 22:55:01 +000062 tst_resm(TFAIL | TERRNO, "PTRACE_GETREGS failed");
63 } else {
vapier488d0452008-09-23 19:19:31 +000064
yaberauneyaa5dad422009-11-27 22:55:01 +000065 for (i = 0; i < ARRAY_SIZE(regs); ++i) {
66 errno = 0;
67 ret = ptrace(PTRACE_PEEKUSER, pid,
Wanlong Gao354ebb42012-12-07 10:10:04 +080068 (void *)regs[i].off, NULL);
yaberauneyaa5dad422009-11-27 22:55:01 +000069 if (ret && errno) {
70 tst_resm(TFAIL | TERRNO,
Wanlong Gao354ebb42012-12-07 10:10:04 +080071 "PTRACE_PEEKUSER: register %s "
72 "(offset %li) failed",
73 regs[i].name, regs[i].off);
yaberauneyaa5dad422009-11-27 22:55:01 +000074 failed = true;
75 continue;
76 }
77
yaberauneya08984c52009-11-27 23:04:45 +000078 long *pt_val = (void *)&_pt_regs + regs[i].off;
yaberauneyaa5dad422009-11-27 22:55:01 +000079 if (*pt_val != ret) {
80 tst_resm(TFAIL,
Wanlong Gao354ebb42012-12-07 10:10:04 +080081 "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);
yaberauneyaa5dad422009-11-27 22:55:01 +000086 failed = true;
87 }
88
vapier488d0452008-09-23 19:19:31 +000089 }
90
vapier488d0452008-09-23 19:19:31 +000091 }
92
yaberauneyaa5dad422009-11-27 22:55:01 +000093 tst_resm((failed ? TFAIL : TPASS),
Wanlong Gao354ebb42012-12-07 10:10:04 +080094 "PTRACE PEEKUSER/GETREGS (poison 0x%02x)", poison);
yaberauneyaa5dad422009-11-27 22:55:01 +000095#else
96 tst_brkm(TCONF, cleanup, "System doesn't have ptrace_regs structure");
97#endif
vapier488d0452008-09-23 19:19:31 +000098}
99
100int main(int argc, char *argv[])
101{
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200102 const char *msg;
vapier488d0452008-09-23 19:19:31 +0000103
vapierdcc74a42009-10-07 06:22:54 +0000104 if (ARRAY_SIZE(regs) == 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800105 tst_brkm(TCONF, NULL, "test not supported for your arch (yet)");
vapierdcc74a42009-10-07 06:22:54 +0000106
vapier488d0452008-09-23 19:19:31 +0000107 if ((msg = parse_opts(argc, argv, NULL, NULL)))
Garrett Cooper60fa8012010-11-22 13:50:58 -0800108 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
vapier488d0452008-09-23 19:19:31 +0000109
110 make_a_baby(argc, argv);
111
vapierb6f710a2008-09-24 22:42:37 +0000112 /* 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 Hrubis526fdf82014-12-04 14:35:01 +0100121 tst_brkm(TFAIL, NULL, "PTRACE_SYSCALL failed: %s",
122 strerror(errno));
vapierb6f710a2008-09-24 22:42:37 +0000123 }
vapier488d0452008-09-23 19:19:31 +0000124 compare_registers(0x00);
125 compare_registers(0xff);
126
127 /* hopefully this worked */
128 ptrace(PTRACE_KILL, pid, NULL, NULL);
129
Garrett Cooper2c282152010-12-16 00:55:50 -0800130 tst_exit();
vapier488d0452008-09-23 19:19:31 +0000131}
yaberauneyad283b3b2009-12-11 14:13:29 +0000132
Mike Frysingerc57fba52014-04-09 18:56:30 -0400133static void cleanup(void)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800134{
135}