1 1.1 christos /* Self tests for disassembler for GDB, the GNU debugger. 2 1.1 christos 3 1.1.1.5 christos Copyright (C) 2017-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos #include "disasm.h" 21 1.1.1.3 christos #include "gdbsupport/selftest.h" 22 1.1 christos #include "selftest-arch.h" 23 1.1.1.3 christos #include "gdbarch.h" 24 1.1 christos 25 1.1 christos namespace selftests { 26 1.1 christos 27 1.1.1.4 christos /* Return a pointer to a buffer containing an instruction that can be 28 1.1.1.4 christos disassembled for architecture GDBARCH. *LEN will be set to the length 29 1.1.1.4 christos of the returned buffer. 30 1.1.1.4 christos 31 1.1.1.4 christos If there's no known instruction to disassemble for GDBARCH (because we 32 1.1.1.4 christos haven't figured on out, not because no instructions exist) then nullptr 33 1.1.1.4 christos is returned, and *LEN is set to 0. */ 34 1.1 christos 35 1.1.1.4 christos static const gdb_byte * 36 1.1.1.4 christos get_test_insn (struct gdbarch *gdbarch, size_t *len) 37 1.1 christos { 38 1.1.1.4 christos *len = 0; 39 1.1.1.4 christos const gdb_byte *insn = nullptr; 40 1.1 christos 41 1.1 christos switch (gdbarch_bfd_arch_info (gdbarch)->arch) 42 1.1 christos { 43 1.1 christos case bfd_arch_bfin: 44 1.1 christos /* M3.L = 0xe117 */ 45 1.1 christos static const gdb_byte bfin_insn[] = {0x17, 0xe1, 0xff, 0xff}; 46 1.1 christos 47 1.1 christos insn = bfin_insn; 48 1.1.1.4 christos *len = sizeof (bfin_insn); 49 1.1 christos break; 50 1.1 christos case bfd_arch_arm: 51 1.1 christos /* mov r0, #0 */ 52 1.1 christos static const gdb_byte arm_insn[] = {0x0, 0x0, 0xa0, 0xe3}; 53 1.1 christos 54 1.1 christos insn = arm_insn; 55 1.1.1.4 christos *len = sizeof (arm_insn); 56 1.1 christos break; 57 1.1 christos case bfd_arch_ia64: 58 1.1.1.4 christos /* We get: 59 1.1.1.4 christos internal-error: gdbarch_sw_breakpoint_from_kind: 60 1.1.1.4 christos Assertion `gdbarch->sw_breakpoint_from_kind != NULL' failed. */ 61 1.1.1.4 christos return insn; 62 1.1 christos case bfd_arch_mep: 63 1.1.1.4 christos /* Disassembles as '*unknown*' insn, then len self-check fails. */ 64 1.1.1.4 christos return insn; 65 1.1 christos case bfd_arch_mips: 66 1.1.1.4 christos if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mips16) 67 1.1.1.4 christos /* Disassembles insn, but len self-check fails. */ 68 1.1.1.4 christos return insn; 69 1.1.1.4 christos goto generic_case; 70 1.1 christos case bfd_arch_tic6x: 71 1.1.1.4 christos /* Disassembles as '<undefined instruction 0x56454314>' insn, but len 72 1.1.1.4 christos self-check passes, so let's allow it. */ 73 1.1.1.4 christos goto generic_case; 74 1.1 christos case bfd_arch_xtensa: 75 1.1.1.4 christos /* Disassembles insn, but len self-check fails. */ 76 1.1.1.4 christos return insn; 77 1.1.1.4 christos case bfd_arch_or1k: 78 1.1.1.4 christos /* Disassembles as '*unknown*' insn, but len self-check passes, so let's 79 1.1.1.4 christos allow it. */ 80 1.1.1.4 christos goto generic_case; 81 1.1 christos case bfd_arch_s390: 82 1.1 christos /* nopr %r7 */ 83 1.1 christos static const gdb_byte s390_insn[] = {0x07, 0x07}; 84 1.1 christos 85 1.1 christos insn = s390_insn; 86 1.1.1.4 christos *len = sizeof (s390_insn); 87 1.1 christos break; 88 1.1 christos case bfd_arch_xstormy16: 89 1.1 christos /* nop */ 90 1.1 christos static const gdb_byte xstormy16_insn[] = {0x0, 0x0}; 91 1.1 christos 92 1.1 christos insn = xstormy16_insn; 93 1.1.1.4 christos *len = sizeof (xstormy16_insn); 94 1.1 christos break; 95 1.1 christos case bfd_arch_score: 96 1.1.1.2 christos case bfd_arch_riscv: 97 1.1.1.6 christos /* riscv and score need to know the current instruction 98 1.1.1.2 christos to select breakpoint instruction. Give the breakpoint 99 1.1.1.2 christos instruction kind explicitly. */ 100 1.1.1.2 christos { 101 1.1.1.2 christos int bplen; 102 1.1.1.2 christos insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &bplen); 103 1.1.1.4 christos *len = bplen; 104 1.1.1.4 christos } 105 1.1.1.4 christos break; 106 1.1.1.4 christos case bfd_arch_arc: 107 1.1.1.4 christos /* PR 21003 */ 108 1.1.1.4 christos if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601) 109 1.1.1.4 christos return insn; 110 1.1.1.4 christos goto generic_case; 111 1.1.1.4 christos case bfd_arch_z80: 112 1.1.1.4 christos { 113 1.1.1.4 christos int bplen; 114 1.1.1.4 christos insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 0x0008, &bplen); 115 1.1.1.4 christos *len = bplen; 116 1.1.1.2 christos } 117 1.1 christos break; 118 1.1.1.4 christos case bfd_arch_i386: 119 1.1.1.4 christos { 120 1.1.1.4 christos const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch); 121 1.1.1.4 christos /* The disassembly tests will fail on x86-linux because 122 1.1.1.4 christos opcodes rejects an attempt to disassemble for an arch with 123 1.1.1.4 christos a 64-bit address size when bfd_vma is 32-bit. */ 124 1.1.1.4 christos if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT) 125 1.1.1.4 christos return insn; 126 1.1.1.4 christos } 127 1.1.1.5 christos [[fallthrough]]; 128 1.1 christos default: 129 1.1.1.4 christos generic_case: 130 1.1 christos { 131 1.1 christos /* Test disassemble breakpoint instruction. */ 132 1.1 christos CORE_ADDR pc = 0; 133 1.1.1.4 christos int kind; 134 1.1 christos int bplen; 135 1.1 christos 136 1.1.1.4 christos struct gdbarch_info info; 137 1.1.1.4 christos info.bfd_arch_info = gdbarch_bfd_arch_info (gdbarch); 138 1.1.1.4 christos 139 1.1.1.4 christos enum gdb_osabi it; 140 1.1.1.4 christos bool found = false; 141 1.1.1.4 christos for (it = GDB_OSABI_UNKNOWN; it != GDB_OSABI_INVALID; 142 1.1.1.4 christos it = static_cast<enum gdb_osabi>(static_cast<int>(it) + 1)) 143 1.1.1.4 christos { 144 1.1.1.4 christos if (it == GDB_OSABI_UNKNOWN) 145 1.1.1.4 christos continue; 146 1.1.1.4 christos 147 1.1.1.4 christos info.osabi = it; 148 1.1.1.4 christos 149 1.1.1.4 christos if (it != GDB_OSABI_NONE) 150 1.1.1.4 christos { 151 1.1.1.4 christos if (!has_gdb_osabi_handler (info)) 152 1.1.1.4 christos /* Unsupported. Skip to prevent warnings like: 153 1.1.1.4 christos A handler for the OS ABI <x> is not built into this 154 1.1.1.4 christos configuration of GDB. Attempting to continue with the 155 1.1.1.4 christos default <y> settings. */ 156 1.1.1.4 christos continue; 157 1.1.1.4 christos } 158 1.1.1.4 christos 159 1.1.1.4 christos gdbarch = gdbarch_find_by_info (info); 160 1.1.1.4 christos SELF_CHECK (gdbarch != NULL); 161 1.1.1.4 christos 162 1.1.1.4 christos try 163 1.1.1.4 christos { 164 1.1.1.4 christos kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc); 165 1.1.1.4 christos insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen); 166 1.1.1.4 christos } 167 1.1.1.6 christos catch (const gdb_exception_error &) 168 1.1.1.4 christos { 169 1.1.1.4 christos continue; 170 1.1.1.4 christos } 171 1.1.1.4 christos found = true; 172 1.1.1.4 christos break; 173 1.1.1.4 christos } 174 1.1.1.4 christos 175 1.1.1.4 christos /* Assert that we have found an instruction to disassemble. */ 176 1.1.1.4 christos SELF_CHECK (found); 177 1.1 christos 178 1.1.1.4 christos *len = bplen; 179 1.1 christos break; 180 1.1 christos } 181 1.1 christos } 182 1.1.1.4 christos SELF_CHECK (*len > 0); 183 1.1.1.4 christos 184 1.1.1.4 christos return insn; 185 1.1.1.4 christos } 186 1.1.1.4 christos 187 1.1.1.4 christos /* Test disassembly of one instruction. */ 188 1.1.1.4 christos 189 1.1.1.4 christos static void 190 1.1.1.4 christos print_one_insn_test (struct gdbarch *gdbarch) 191 1.1.1.4 christos { 192 1.1.1.4 christos size_t len; 193 1.1.1.4 christos const gdb_byte *insn = get_test_insn (gdbarch, &len); 194 1.1.1.4 christos 195 1.1.1.4 christos if (insn == nullptr) 196 1.1.1.4 christos return; 197 1.1 christos 198 1.1 christos /* Test gdb_disassembler for a given gdbarch by reading data from a 199 1.1 christos pre-allocated buffer. If you want to see the disassembled 200 1.1.1.4 christos instruction printed to gdb_stdout, use maint selftest -verbose. */ 201 1.1 christos 202 1.1 christos class gdb_disassembler_test : public gdb_disassembler 203 1.1 christos { 204 1.1 christos public: 205 1.1 christos 206 1.1 christos explicit gdb_disassembler_test (struct gdbarch *gdbarch, 207 1.1 christos const gdb_byte *insn, 208 1.1 christos size_t len) 209 1.1 christos : gdb_disassembler (gdbarch, 210 1.1.1.4 christos (run_verbose () ? gdb_stdlog : &null_stream), 211 1.1 christos gdb_disassembler_test::read_memory), 212 1.1 christos m_insn (insn), m_len (len) 213 1.1 christos { 214 1.1 christos } 215 1.1 christos 216 1.1 christos int 217 1.1 christos print_insn (CORE_ADDR memaddr) 218 1.1 christos { 219 1.1 christos int len = gdb_disassembler::print_insn (memaddr); 220 1.1 christos 221 1.1.1.4 christos if (run_verbose ()) 222 1.1.1.4 christos debug_printf ("\n"); 223 1.1 christos 224 1.1 christos return len; 225 1.1 christos } 226 1.1 christos 227 1.1 christos private: 228 1.1 christos /* A buffer contain one instruction. */ 229 1.1 christos const gdb_byte *m_insn; 230 1.1 christos 231 1.1 christos /* Length of the buffer. */ 232 1.1 christos size_t m_len; 233 1.1 christos 234 1.1 christos static int read_memory (bfd_vma memaddr, gdb_byte *myaddr, 235 1.1.1.4 christos unsigned int len, 236 1.1.1.4 christos struct disassemble_info *info) noexcept 237 1.1 christos { 238 1.1 christos gdb_disassembler_test *self 239 1.1 christos = static_cast<gdb_disassembler_test *>(info->application_data); 240 1.1 christos 241 1.1 christos /* The disassembler in opcodes may read more data than one 242 1.1 christos instruction. Supply infinite consecutive copies 243 1.1 christos of the same instruction. */ 244 1.1 christos for (size_t i = 0; i < len; i++) 245 1.1 christos myaddr[i] = self->m_insn[(memaddr + i) % self->m_len]; 246 1.1 christos 247 1.1 christos return 0; 248 1.1 christos } 249 1.1 christos }; 250 1.1 christos 251 1.1 christos gdb_disassembler_test di (gdbarch, insn, len); 252 1.1 christos 253 1.1 christos SELF_CHECK (di.print_insn (0) == len); 254 1.1 christos } 255 1.1 christos 256 1.1.1.4 christos /* Test the gdb_buffered_insn_length function. */ 257 1.1.1.4 christos 258 1.1.1.4 christos static void 259 1.1.1.4 christos buffered_insn_length_test (struct gdbarch *gdbarch) 260 1.1.1.4 christos { 261 1.1.1.4 christos size_t buf_len; 262 1.1.1.4 christos const gdb_byte *insn = get_test_insn (gdbarch, &buf_len); 263 1.1.1.4 christos 264 1.1.1.4 christos if (insn == nullptr) 265 1.1.1.4 christos return; 266 1.1.1.4 christos 267 1.1.1.4 christos /* The tic6x architecture is VLIW. Disassembling requires that the 268 1.1.1.4 christos entire instruction bundle be available. However, the buffer we got 269 1.1.1.4 christos back from get_test_insn only contains a single instruction, which is 270 1.1.1.4 christos just part of an instruction bundle. As a result, the disassemble will 271 1.1.1.4 christos fail. To avoid this, skip tic6x tests now. */ 272 1.1.1.4 christos if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_tic6x) 273 1.1.1.4 christos return; 274 1.1.1.4 christos 275 1.1.1.4 christos CORE_ADDR insn_address = 0; 276 1.1.1.4 christos int calculated_len = gdb_buffered_insn_length (gdbarch, insn, buf_len, 277 1.1.1.4 christos insn_address); 278 1.1.1.4 christos 279 1.1.1.4 christos SELF_CHECK (calculated_len == buf_len); 280 1.1.1.4 christos } 281 1.1.1.4 christos 282 1.1 christos /* Test disassembly on memory error. */ 283 1.1 christos 284 1.1 christos static void 285 1.1 christos memory_error_test (struct gdbarch *gdbarch) 286 1.1 christos { 287 1.1 christos class gdb_disassembler_test : public gdb_disassembler 288 1.1 christos { 289 1.1 christos public: 290 1.1 christos gdb_disassembler_test (struct gdbarch *gdbarch) 291 1.1 christos : gdb_disassembler (gdbarch, &null_stream, 292 1.1 christos gdb_disassembler_test::read_memory) 293 1.1 christos { 294 1.1 christos } 295 1.1 christos 296 1.1 christos static int read_memory (bfd_vma memaddr, gdb_byte *myaddr, 297 1.1 christos unsigned int len, 298 1.1.1.4 christos struct disassemble_info *info) noexcept 299 1.1 christos { 300 1.1 christos /* Always return an error. */ 301 1.1 christos return -1; 302 1.1 christos } 303 1.1 christos }; 304 1.1 christos 305 1.1.1.4 christos if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_i386) 306 1.1.1.4 christos { 307 1.1.1.4 christos const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch); 308 1.1.1.4 christos /* This test will fail on x86-linux because opcodes rejects an 309 1.1.1.4 christos attempt to disassemble for an arch with a 64-bit address size 310 1.1.1.4 christos when bfd_vma is 32-bit. */ 311 1.1.1.4 christos if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT) 312 1.1.1.4 christos return; 313 1.1.1.4 christos } 314 1.1.1.4 christos 315 1.1 christos gdb_disassembler_test di (gdbarch); 316 1.1 christos bool saw_memory_error = false; 317 1.1 christos 318 1.1.1.3 christos try 319 1.1 christos { 320 1.1 christos di.print_insn (0); 321 1.1 christos } 322 1.1.1.3 christos catch (const gdb_exception_error &ex) 323 1.1 christos { 324 1.1 christos if (ex.error == MEMORY_ERROR) 325 1.1 christos saw_memory_error = true; 326 1.1 christos } 327 1.1 christos 328 1.1 christos /* Expect MEMORY_ERROR. */ 329 1.1 christos SELF_CHECK (saw_memory_error); 330 1.1 christos } 331 1.1 christos 332 1.1 christos } // namespace selftests 333 1.1 christos 334 1.1.1.3 christos void _initialize_disasm_selftests (); 335 1.1 christos void 336 1.1.1.3 christos _initialize_disasm_selftests () 337 1.1 christos { 338 1.1.1.2 christos selftests::register_test_foreach_arch ("print_one_insn", 339 1.1.1.2 christos selftests::print_one_insn_test); 340 1.1.1.2 christos selftests::register_test_foreach_arch ("memory_error", 341 1.1.1.2 christos selftests::memory_error_test); 342 1.1.1.4 christos selftests::register_test_foreach_arch ("buffered_insn_length", 343 1.1.1.4 christos selftests::buffered_insn_length_test); 344 1.1 christos } 345