gdb: move displaced stepping logic to gdbarch, allow starting concurrent displaced...
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.arch / aarch64-dbreg-contents.c
CommitLineData
01c7ae81
WP
1/* Test case for setting a memory-write unaligned watchpoint on aarch64.
2
3 This software is provided 'as-is', without any express or implied
4 warranty. In no event will the authors be held liable for any damages
5 arising from the use of this software.
6
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it
9 freely. */
10
11#define _GNU_SOURCE 1
718e0816
LM
12#include <stdlib.h>
13#include <unistd.h>
01c7ae81 14#include <sys/ptrace.h>
718e0816 15#include <asm/ptrace.h>
01c7ae81
WP
16#include <assert.h>
17#include <sys/wait.h>
18#include <stddef.h>
19#include <errno.h>
20#include <sys/uio.h>
21#include <elf.h>
718e0816 22#include <error.h>
01c7ae81
WP
23
24static pid_t child;
25
26static void
27cleanup (void)
28{
29 if (child > 0)
30 kill (child, SIGKILL);
31 child = 0;
32}
33
01c7ae81
WP
34/* Macros to extract fields from the hardware debug information word. */
35#define AARCH64_DEBUG_NUM_SLOTS(x) ((x) & 0xff)
36#define AARCH64_DEBUG_ARCH(x) (((x) >> 8) & 0xff)
37/* Macro for the expected version of the ARMv8-A debug architecture. */
38#define AARCH64_DEBUG_ARCH_V8 0x6
39#define DR_CONTROL_ENABLED(ctrl) (((ctrl) & 0x1) == 1)
40#define DR_CONTROL_LENGTH(ctrl) (((ctrl) >> 5) & 0xff)
41
42static void
43set_watchpoint (pid_t pid, volatile void *addr, unsigned len_mask)
44{
45 struct user_hwdebug_state dreg_state;
46 struct iovec iov;
47 long l;
48
49 assert (len_mask >= 0x01);
50 assert (len_mask <= 0xff);
51
52 iov.iov_base = &dreg_state;
53 iov.iov_len = sizeof (dreg_state);
54 errno = 0;
55 l = ptrace (PTRACE_GETREGSET, pid, NT_ARM_HW_WATCH, &iov);
56 assert (l == 0);
57 assert (AARCH64_DEBUG_ARCH (dreg_state.dbg_info) == AARCH64_DEBUG_ARCH_V8);
58 assert (AARCH64_DEBUG_NUM_SLOTS (dreg_state.dbg_info) >= 1);
59
60 assert (!DR_CONTROL_ENABLED (dreg_state.dbg_regs[0].ctrl));
61 dreg_state.dbg_regs[0].ctrl |= 1;
62 assert ( DR_CONTROL_ENABLED (dreg_state.dbg_regs[0].ctrl));
63
64 assert (DR_CONTROL_LENGTH (dreg_state.dbg_regs[0].ctrl) == 0);
65 dreg_state.dbg_regs[0].ctrl |= len_mask << 5;
66 assert (DR_CONTROL_LENGTH (dreg_state.dbg_regs[0].ctrl) == len_mask);
67
68 dreg_state.dbg_regs[0].ctrl |= 2 << 3; // write
9d70ffbc 69 dreg_state.dbg_regs[0].ctrl |= 2 << 1; // enabled at el0
01c7ae81
WP
70 dreg_state.dbg_regs[0].addr = (uintptr_t) addr;
71
72 iov.iov_base = &dreg_state;
73 iov.iov_len = (offsetof (struct user_hwdebug_state, dbg_regs)
74 + sizeof (dreg_state.dbg_regs[0]));
75 errno = 0;
76 l = ptrace (PTRACE_SETREGSET, pid, NT_ARM_HW_WATCH, &iov);
77 if (errno != 0)
78 error (1, errno, "PTRACE_SETREGSET: NT_ARM_HW_WATCH");
79 assert (l == 0);
80}
81
82static volatile long long check;
83
84int
85main (void)
86{
87 pid_t got_pid;
88 int i, status;
89 long l;
90
91 atexit (cleanup);
92
93 child = fork ();
94 assert (child >= 0);
95 if (child == 0)
96 {
97 l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
98 assert (l == 0);
99 i = raise (SIGUSR1);
100 assert (i == 0);
101 check = -1;
102 i = raise (SIGUSR2);
103 /* NOTREACHED */
104 assert (0);
105 }
106
107 got_pid = waitpid (child, &status, 0);
108 assert (got_pid == child);
109 assert (WIFSTOPPED (status));
110 assert (WSTOPSIG (status) == SIGUSR1);
111
112 /* Add a watchpoint to check.
113 Restart the child. It will write to check.
114 Check child has stopped on the watchpoint. */
9d70ffbc 115 set_watchpoint (child, &check, 0x02);
01c7ae81
WP
116
117 errno = 0;
118 l = ptrace (PTRACE_CONT, child, 0l, 0l);
119 assert_perror (errno);
120 assert (l == 0);
121
122 got_pid = waitpid (child, &status, 0);
123 assert (got_pid == child);
124 assert (WIFSTOPPED (status));
125 if (WSTOPSIG (status) == SIGUSR2)
126 {
127 /* We missed the watchpoint - unsupported by hardware? */
128 cleanup ();
129 return 2;
130 }
131 assert (WSTOPSIG (status) == SIGTRAP);
132
01c7ae81
WP
133 return 0;
134}
This page took 0.214003 seconds and 4 git commands to generate.