[PATCH 7/57][Arm][GAS] Add support for MVE instructions: vstr/vldr
[binutils-gdb.git] / gdb / testsuite / gdb.arch / aarch64-dbreg-contents.c
blob66ca76f847729d398cfbbdad408b5c105be480dc
1 /* Test case for setting a memory-write unaligned watchpoint on aarch64.
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.
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. */
11 #define _GNU_SOURCE 1
12 #include <sys/ptrace.h>
13 #include <assert.h>
14 #include <sys/wait.h>
15 #include <stddef.h>
16 #include <errno.h>
17 #include <sys/uio.h>
18 #include <elf.h>
20 static pid_t child;
22 static void
23 cleanup (void)
25 if (child > 0)
26 kill (child, SIGKILL);
27 child = 0;
30 /* Macros to extract fields from the hardware debug information word. */
31 #define AARCH64_DEBUG_NUM_SLOTS(x) ((x) & 0xff)
32 #define AARCH64_DEBUG_ARCH(x) (((x) >> 8) & 0xff)
33 /* Macro for the expected version of the ARMv8-A debug architecture. */
34 #define AARCH64_DEBUG_ARCH_V8 0x6
35 #define DR_CONTROL_ENABLED(ctrl) (((ctrl) & 0x1) == 1)
36 #define DR_CONTROL_LENGTH(ctrl) (((ctrl) >> 5) & 0xff)
38 static void
39 set_watchpoint (pid_t pid, volatile void *addr, unsigned len_mask)
41 struct user_hwdebug_state dreg_state;
42 struct iovec iov;
43 long l;
45 assert (len_mask >= 0x01);
46 assert (len_mask <= 0xff);
48 iov.iov_base = &dreg_state;
49 iov.iov_len = sizeof (dreg_state);
50 errno = 0;
51 l = ptrace (PTRACE_GETREGSET, pid, NT_ARM_HW_WATCH, &iov);
52 assert (l == 0);
53 assert (AARCH64_DEBUG_ARCH (dreg_state.dbg_info) == AARCH64_DEBUG_ARCH_V8);
54 assert (AARCH64_DEBUG_NUM_SLOTS (dreg_state.dbg_info) >= 1);
56 assert (!DR_CONTROL_ENABLED (dreg_state.dbg_regs[0].ctrl));
57 dreg_state.dbg_regs[0].ctrl |= 1;
58 assert ( DR_CONTROL_ENABLED (dreg_state.dbg_regs[0].ctrl));
60 assert (DR_CONTROL_LENGTH (dreg_state.dbg_regs[0].ctrl) == 0);
61 dreg_state.dbg_regs[0].ctrl |= len_mask << 5;
62 assert (DR_CONTROL_LENGTH (dreg_state.dbg_regs[0].ctrl) == len_mask);
64 dreg_state.dbg_regs[0].ctrl |= 2 << 3; // write
65 dreg_state.dbg_regs[0].ctrl |= 2 << 1; // enabled at el0
66 dreg_state.dbg_regs[0].addr = (uintptr_t) addr;
68 iov.iov_base = &dreg_state;
69 iov.iov_len = (offsetof (struct user_hwdebug_state, dbg_regs)
70 + sizeof (dreg_state.dbg_regs[0]));
71 errno = 0;
72 l = ptrace (PTRACE_SETREGSET, pid, NT_ARM_HW_WATCH, &iov);
73 if (errno != 0)
74 error (1, errno, "PTRACE_SETREGSET: NT_ARM_HW_WATCH");
75 assert (l == 0);
78 static volatile long long check;
80 int
81 main (void)
83 pid_t got_pid;
84 int i, status;
85 long l;
87 atexit (cleanup);
89 child = fork ();
90 assert (child >= 0);
91 if (child == 0)
93 l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
94 assert (l == 0);
95 i = raise (SIGUSR1);
96 assert (i == 0);
97 check = -1;
98 i = raise (SIGUSR2);
99 /* NOTREACHED */
100 assert (0);
103 got_pid = waitpid (child, &status, 0);
104 assert (got_pid == child);
105 assert (WIFSTOPPED (status));
106 assert (WSTOPSIG (status) == SIGUSR1);
108 /* Add a watchpoint to check.
109 Restart the child. It will write to check.
110 Check child has stopped on the watchpoint. */
111 set_watchpoint (child, &check, 0x02);
113 errno = 0;
114 l = ptrace (PTRACE_CONT, child, 0l, 0l);
115 assert_perror (errno);
116 assert (l == 0);
118 got_pid = waitpid (child, &status, 0);
119 assert (got_pid == child);
120 assert (WIFSTOPPED (status));
121 if (WSTOPSIG (status) == SIGUSR2)
123 /* We missed the watchpoint - unsupported by hardware? */
124 cleanup ();
125 return 2;
127 assert (WSTOPSIG (status) == SIGTRAP);
129 return 0;