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