1// Copyright 2023, VIXL authors 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are met: 6// 7// * Redistributions of source code must retain the above copyright notice, 8// this list of conditions and the following disclaimer. 9// * Redistributions in binary form must reproduce the above copyright notice, 10// this list of conditions and the following disclaimer in the documentation 11// and/or other materials provided with the distribution. 12// * Neither the name of ARM Limited nor the names of its contributors may be 13// used to endorse or promote products derived from this software without 14// specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27#include "test-debugger-aarch64.h" 28 29namespace vixl { 30namespace aarch64 { 31 32#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 33// The debugger is only available to be tested in simulator builds. 34 35TEST(breakpoints_invalid) { 36 SETUP(); 37 38 // Test invalid strings instead of numbers. 39 SETUP_CMD("break a", "Error: Use `break <address>` to set a breakpoint"); 40 SETUP_CMD("break abcdef", "Error: Use `break <address>` to set a breakpoint"); 41 SETUP_CMD("break A", "Error: Use `break <address>` to set a breakpoint"); 42 SETUP_CMD("break ABCDEF", "Error: Use `break <address>` to set a breakpoint"); 43 SETUP_CMD("break 0x", "Error: Use `break <address>` to set a breakpoint"); 44 SETUP_CMD("break 0xg", "Error: Use `break <address>` to set a breakpoint"); 45 46 // Test different amounts of parameters. 47 SETUP_CMD("break", "Error: Use `break <address>` to set a breakpoint"); 48 SETUP_CMD("break 42 52", "Error: Use `break <address>` to set a breakpoint"); 49 50 // Test out of range addresses. 51 SETUP_CMD("break 0xFFFFFFFFFFFFFFFF1", 52 "Error: Use `break <address>` to set a breakpoint"); 53 SETUP_CMD("break 18446744073709551616", 54 "Error: Use `break <address>` to set a breakpoint"); 55 56 // Continue to exit the debugger. 57 SETUP_CMD("continue", "Continuing..."); 58 RUN(); 59 60 CHECK_OUTPUT(); 61} 62 63TEST(breakpoints_valid) { 64 SETUP(); 65 66 // Test bottom boundary of addresses. 67 SETUP_CMD("break 0x0", "Breakpoint successfully added at: 0x0"); 68 SETUP_CMD("break 0", "Breakpoint successfully removed at: 0x0"); 69 SETUP_CMD("break 0x1", "Breakpoint successfully added at: 0x1"); 70 SETUP_CMD("break 1", "Breakpoint successfully removed at: 0x1"); 71 72 // Test top boundary of addresses. 73 SETUP_CMD("break 0xFFFFFFFFFFFFFFFF", 74 "Breakpoint successfully added at: 0xffffffffffffffff"); 75 SETUP_CMD("break 18446744073709551615", 76 "Breakpoint successfully removed at: 0xffffffffffffffff"); 77 78 // Continue to exit the debugger. 79 SETUP_CMD("continue", "Continuing..."); 80 RUN(); 81 82 CHECK_OUTPUT(); 83} 84 85TEST(breakpoints_hit) { 86 SETUP(); 87 88 // Test hitting a breakpoint. 89 std::string mov_addr = GET_INSTRUCTION_ADDRESS("mov x2, #0x2"); 90 std::string break_cmd = "break "; 91 break_cmd += mov_addr; 92 std::string expected_trace = "Breakpoint successfully added at: "; 93 expected_trace += mov_addr; 94 SETUP_CMD(break_cmd, expected_trace); 95 SETUP_CMD("continue", 96 "Continuing...\n" 97 "Debugger hit breakpoint, breaking..."); 98 99 // Continue to exit the debugger. 100 SETUP_CMD("continue", "Continuing..."); 101 RUN(); 102 103 CHECK_OUTPUT(); 104} 105 106TEST(cmd_aliases) { 107 SETUP(); 108 109 // Test all short form commands, to ensure they correctly run their long form 110 // counterparts. 111 SETUP_CMD("b", "Error: Use `break <address>` to set a breakpoint"); 112 SETUP_CMD("s x", 113 "Error: use `step \\[number\\]` to step an optional number of" 114 " instructions"); 115 SETUP_CMD("p", 116 "Error: use `print <register|all>` to print the contents of a" 117 " specific register or all registers."); 118 SETUP_CMD("t 1", "Error: use `trace` to toggle tracing of registers."); 119 SETUP_CMD("g 1", 120 "Error: use `gdb` to enter GDB from the simulator debugger."); 121 122 // Continue to exit the debugger. 123 SETUP_CMD("c", "Continuing..."); 124 RUN(); 125 126 CHECK_OUTPUT(); 127} 128 129TEST(stepping_single) { 130 SETUP(); 131 132 // Test single stepping through the whole program. 133 SETUP_CMD("step", ".*mov x2, #0x2"); 134 SETUP_CMD("step", ".*sub x3, x1, x2"); 135 SETUP_CMD("step", ".*ret"); 136 SETUP_CMD("step", 137 ".*Debugger at the end of simulation, leaving simulator..."); 138 139 RUN(); 140 141 CHECK_OUTPUT(); 142} 143 144TEST(stepping_single_and_continue) { 145 SETUP(); 146 147 // Test single stepping and then continuing. 148 SETUP_CMD("step", ".*mov x2, #0x2"); 149 SETUP_CMD("continue", "Continuing..."); 150 151 RUN(); 152 153 CHECK_OUTPUT(); 154} 155 156TEST(stepping_multi_1) { 157 SETUP(); 158 159 // Test multi stepping a single instruction. 160 SETUP_CMD("step 1", ".*mov x2, #0x2"); 161 162 // Continue to exit the debugger. 163 SETUP_CMD("continue", "Continuing..."); 164 RUN(); 165 166 CHECK_OUTPUT(); 167} 168 169TEST(stepping_multi_2) { 170 SETUP(); 171 172 // Test multi stepping two instructions. 173 SETUP_CMD("step 2", 174 ".*mov x2, #0x2\n" 175 ".*sub x3, x1, x2"); 176 177 // Continue to exit the debugger. 178 SETUP_CMD("continue", "Continuing..."); 179 RUN(); 180 181 CHECK_OUTPUT(); 182} 183 184TEST(stepping_multi_3) { 185 SETUP(); 186 187 // Test multi stepping three instructions. 188 SETUP_CMD("step 3", 189 ".*mov x2, #0x2\n" 190 ".*sub x3, x1, x2\n" 191 ".*ret"); 192 193 // Continue to exit the debugger. 194 SETUP_CMD("continue", "Continuing..."); 195 RUN(); 196 197 CHECK_OUTPUT(); 198} 199 200TEST(stepping_multi_4) { 201 SETUP(); 202 203 // Test stepping through the whole program in one go. 204 SETUP_CMD("step 4", 205 ".*mov x2, #0x2\n" 206 ".*sub x3, x1, x2\n" 207 ".*ret\n" 208 "Debugger at the end of simulation, leaving simulator..."); 209 210 RUN(); 211 212 CHECK_OUTPUT(); 213} 214 215TEST(stepping_multi_5) { 216 SETUP(); 217 218 // Test multi stepping past the end of the program. 219 SETUP_CMD("step 5", 220 ".*mov x2, #0x2\n" 221 ".*sub x3, x1, x2\n" 222 ".*ret\n" 223 "Debugger at the end of simulation, leaving simulator..."); 224 225 RUN(); 226 227 CHECK_OUTPUT(); 228} 229 230TEST(stepping_invalid) { 231 SETUP(); 232 233 // Test invalid arguments to step command. 234 SETUP_CMD("step 1 2", 235 "Error: use `step \\[number\\]` to step an optional number of" 236 " instructions"); 237 238 // Continue to exit the debugger. 239 SETUP_CMD("continue", "Continuing..."); 240 RUN(); 241 242 CHECK_OUTPUT(); 243} 244 245TEST(print_invalid) { 246 SETUP(); 247 248 // Test invalid amounts of arguments to the print command. 249 SETUP_CMD("print", 250 "Error: use `print <register|all>` to print the contents of a" 251 " specific register or all registers."); 252 SETUP_CMD("print all all", 253 "Error: use `print <register|all>` to print the contents of a" 254 " specific register or all registers."); 255 256 // Test invalid types of registers. 257 SETUP_CMD("print alls", 258 "Error: incorrect register format, use e.g: X0, x0, etc..."); 259 SETUP_CMD("print a", 260 "Error: incorrect register format, use e.g: X0, x0, etc..."); 261 SETUP_CMD("print x", 262 "Error: incorrect register format, use e.g: X0, x0, etc..."); 263 SETUP_CMD("print 0", 264 "Error: incorrect register format, use e.g: X0, x0, etc..."); 265 266 // Test registers that don't exist on AARCH64. 267 SETUP_CMD("print w32", 268 "Error: incorrect register format, use e.g: X0, x0, etc..."); 269 SETUP_CMD("print W32", 270 "Error: incorrect register format, use e.g: X0, x0, etc..."); 271 SETUP_CMD("print x32", 272 "Error: incorrect register format, use e.g: X0, x0, etc..."); 273 SETUP_CMD("print X32", 274 "Error: incorrect register format, use e.g: X0, x0, etc..."); 275 SETUP_CMD("print v32", 276 "Error: incorrect register format, use e.g: X0, x0, etc..."); 277 SETUP_CMD("print V32", 278 "Error: incorrect register format, use e.g: X0, x0, etc..."); 279 280 // Continue to exit the debugger. 281 SETUP_CMD("continue", "Continuing..."); 282 RUN(); 283 284 CHECK_OUTPUT(); 285} 286 287TEST(trace_invalid) { 288 SETUP(); 289 290 // Test invalid arguments to trace command. 291 SETUP_CMD("trace 1 2", "Error: use `trace` to toggle tracing of registers."); 292 293 // Continue to exit the debugger. 294 SETUP_CMD("continue", "Continuing..."); 295 RUN(); 296 297 CHECK_OUTPUT(); 298} 299 300TEST(trace_toggling) { 301 SETUP(); 302 303 // Test toggling tracing. 304 SETUP_CMD("trace", 305 "Enabling disassembly, registers and memory write tracing"); 306 SETUP_CMD("trace", 307 "Disabling disassembly, registers and memory write tracing"); 308 SETUP_CMD("trace", 309 "Enabling disassembly, registers and memory write tracing"); 310 SETUP_CMD("trace", 311 "Disabling disassembly, registers and memory write tracing"); 312 313 // Continue to exit the debugger. 314 SETUP_CMD("continue", "Continuing..."); 315 RUN(); 316 317 CHECK_OUTPUT(); 318} 319 320TEST(trace_full) { 321 SETUP(); 322 323 // Test tracing the whole program. 324 SETUP_CMD("trace", 325 "Enabling disassembly, registers and memory write tracing"); 326 327 std::string expected_trace = "Continuing...\n"; 328 expected_trace += ".*add x1, x0, #0x5 \\(5\\)\n"; 329 expected_trace += "(" + x_register_trace + "\\n){32}"; 330 expected_trace += "(" + v_register_trace + "\\n){32}"; 331 expected_trace += ".*mov x2, #0x2\n"; 332 expected_trace += x_register_trace + "\n"; 333 expected_trace += ".*sub x3, x1, x2\n"; 334 expected_trace += x_register_trace + "\n"; 335 expected_trace += ".*ret\n"; 336 expected_trace += "# Branch to 0x0000000000000000."; 337 SETUP_CMD("continue", expected_trace); 338 339 RUN(); 340 341 CHECK_OUTPUT(); 342} 343 344TEST(trace_partial) { 345 SETUP(); 346 347 // Test tracing a single line. 348 SETUP_CMD("trace", 349 "Enabling disassembly, registers and memory write tracing"); 350 351 std::string expected_trace = ".*add x1, x0, #0x5 \\(5\\)\n"; 352 expected_trace += "(" + x_register_trace + "\\n){32}"; 353 expected_trace += "(" + v_register_trace + "\\n){32}"; 354 expected_trace += ".*mov x2, #0x2\n"; 355 SETUP_CMD("step", expected_trace); 356 SETUP_CMD("trace", 357 "Disabling disassembly, registers and memory write tracing"); 358 SETUP_CMD("continue", "Continuing...\n"); 359 360 RUN(); 361 362 CHECK_OUTPUT(); 363} 364 365#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 366 367} // namespace aarch64 368} // namespace vixl 369