More updated translations
[binutils-gdb.git] / gdb / disasm-selftests.c
blob221b94f085135837510fa9062082702c76c5c802
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 "disasm.h"
21 #include "gdbsupport/selftest.h"
22 #include "selftest-arch.h"
23 #include "gdbarch.h"
25 namespace selftests {
27 /* Return a pointer to a buffer containing an instruction that can be
28 disassembled for architecture GDBARCH. *LEN will be set to the length
29 of the returned buffer.
31 If there's no known instruction to disassemble for GDBARCH (because we
32 haven't figured on out, not because no instructions exist) then nullptr
33 is returned, and *LEN is set to 0. */
35 static const gdb_byte *
36 get_test_insn (struct gdbarch *gdbarch, size_t *len)
38 *len = 0;
39 const gdb_byte *insn = nullptr;
41 switch (gdbarch_bfd_arch_info (gdbarch)->arch)
43 case bfd_arch_bfin:
44 /* M3.L = 0xe117 */
45 static const gdb_byte bfin_insn[] = {0x17, 0xe1, 0xff, 0xff};
47 insn = bfin_insn;
48 *len = sizeof (bfin_insn);
49 break;
50 case bfd_arch_arm:
51 /* mov r0, #0 */
52 static const gdb_byte arm_insn[] = {0x0, 0x0, 0xa0, 0xe3};
54 insn = arm_insn;
55 *len = sizeof (arm_insn);
56 break;
57 case bfd_arch_ia64:
58 /* We get:
59 internal-error: gdbarch_sw_breakpoint_from_kind:
60 Assertion `gdbarch->sw_breakpoint_from_kind != NULL' failed. */
61 return insn;
62 case bfd_arch_mep:
63 /* Disassembles as '*unknown*' insn, then len self-check fails. */
64 return insn;
65 case bfd_arch_mips:
66 if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mips16)
67 /* Disassembles insn, but len self-check fails. */
68 return insn;
69 goto generic_case;
70 case bfd_arch_tic6x:
71 /* Disassembles as '<undefined instruction 0x56454314>' insn, but len
72 self-check passes, so let's allow it. */
73 goto generic_case;
74 case bfd_arch_xtensa:
75 /* Disassembles insn, but len self-check fails. */
76 return insn;
77 case bfd_arch_or1k:
78 /* Disassembles as '*unknown*' insn, but len self-check passes, so let's
79 allow it. */
80 goto generic_case;
81 case bfd_arch_s390:
82 /* nopr %r7 */
83 static const gdb_byte s390_insn[] = {0x07, 0x07};
85 insn = s390_insn;
86 *len = sizeof (s390_insn);
87 break;
88 case bfd_arch_xstormy16:
89 /* nop */
90 static const gdb_byte xstormy16_insn[] = {0x0, 0x0};
92 insn = xstormy16_insn;
93 *len = sizeof (xstormy16_insn);
94 break;
95 case bfd_arch_score:
96 case bfd_arch_riscv:
97 /* riscv and score need to know the current instruction
98 to select breakpoint instruction. Give the breakpoint
99 instruction kind explicitly. */
101 int bplen;
102 insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &bplen);
103 *len = bplen;
105 break;
106 case bfd_arch_arc:
107 /* PR 21003 */
108 if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
109 return insn;
110 goto generic_case;
111 case bfd_arch_z80:
113 int bplen;
114 insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 0x0008, &bplen);
115 *len = bplen;
117 break;
118 case bfd_arch_i386:
120 const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
121 /* The disassembly tests will fail on x86-linux because
122 opcodes rejects an attempt to disassemble for an arch with
123 a 64-bit address size when bfd_vma is 32-bit. */
124 if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT)
125 return insn;
127 [[fallthrough]];
128 default:
129 generic_case:
131 /* Test disassemble breakpoint instruction. */
132 CORE_ADDR pc = 0;
133 int kind;
134 int bplen;
136 struct gdbarch_info info;
137 info.bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);
139 enum gdb_osabi it;
140 bool found = false;
141 for (it = GDB_OSABI_UNKNOWN; it != GDB_OSABI_INVALID;
142 it = static_cast<enum gdb_osabi>(static_cast<int>(it) + 1))
144 if (it == GDB_OSABI_UNKNOWN)
145 continue;
147 info.osabi = it;
149 if (it != GDB_OSABI_NONE)
151 if (!has_gdb_osabi_handler (info))
152 /* Unsupported. Skip to prevent warnings like:
153 A handler for the OS ABI <x> is not built into this
154 configuration of GDB. Attempting to continue with the
155 default <y> settings. */
156 continue;
159 gdbarch = gdbarch_find_by_info (info);
160 SELF_CHECK (gdbarch != NULL);
164 kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
165 insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen);
167 catch (const gdb_exception_error &)
169 continue;
171 found = true;
172 break;
175 /* Assert that we have found an instruction to disassemble. */
176 SELF_CHECK (found);
178 *len = bplen;
179 break;
182 SELF_CHECK (*len > 0);
184 return insn;
187 /* Test disassembly of one instruction. */
189 static void
190 print_one_insn_test (struct gdbarch *gdbarch)
192 size_t len;
193 const gdb_byte *insn = get_test_insn (gdbarch, &len);
195 if (insn == nullptr)
196 return;
198 /* Test gdb_disassembler for a given gdbarch by reading data from a
199 pre-allocated buffer. If you want to see the disassembled
200 instruction printed to gdb_stdout, use maint selftest -verbose. */
202 class gdb_disassembler_test : public gdb_disassembler
204 public:
206 explicit gdb_disassembler_test (struct gdbarch *gdbarch,
207 const gdb_byte *insn,
208 size_t len)
209 : gdb_disassembler (gdbarch,
210 (run_verbose () ? gdb_stdlog : &null_stream),
211 gdb_disassembler_test::read_memory),
212 m_insn (insn), m_len (len)
217 print_insn (CORE_ADDR memaddr)
219 int len = gdb_disassembler::print_insn (memaddr);
221 if (run_verbose ())
222 debug_printf ("\n");
224 return len;
227 private:
228 /* A buffer contain one instruction. */
229 const gdb_byte *m_insn;
231 /* Length of the buffer. */
232 size_t m_len;
234 static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
235 unsigned int len,
236 struct disassemble_info *info) noexcept
238 gdb_disassembler_test *self
239 = static_cast<gdb_disassembler_test *>(info->application_data);
241 /* The disassembler in opcodes may read more data than one
242 instruction. Supply infinite consecutive copies
243 of the same instruction. */
244 for (size_t i = 0; i < len; i++)
245 myaddr[i] = self->m_insn[(memaddr + i) % self->m_len];
247 return 0;
251 gdb_disassembler_test di (gdbarch, insn, len);
253 SELF_CHECK (di.print_insn (0) == len);
256 /* Test the gdb_buffered_insn_length function. */
258 static void
259 buffered_insn_length_test (struct gdbarch *gdbarch)
261 size_t buf_len;
262 const gdb_byte *insn = get_test_insn (gdbarch, &buf_len);
264 if (insn == nullptr)
265 return;
267 /* The tic6x architecture is VLIW. Disassembling requires that the
268 entire instruction bundle be available. However, the buffer we got
269 back from get_test_insn only contains a single instruction, which is
270 just part of an instruction bundle. As a result, the disassemble will
271 fail. To avoid this, skip tic6x tests now. */
272 if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_tic6x)
273 return;
275 CORE_ADDR insn_address = 0;
276 int calculated_len = gdb_buffered_insn_length (gdbarch, insn, buf_len,
277 insn_address);
279 SELF_CHECK (calculated_len == buf_len);
282 /* Test disassembly on memory error. */
284 static void
285 memory_error_test (struct gdbarch *gdbarch)
287 class gdb_disassembler_test : public gdb_disassembler
289 public:
290 gdb_disassembler_test (struct gdbarch *gdbarch)
291 : gdb_disassembler (gdbarch, &null_stream,
292 gdb_disassembler_test::read_memory)
296 static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
297 unsigned int len,
298 struct disassemble_info *info) noexcept
300 /* Always return an error. */
301 return -1;
305 if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_i386)
307 const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
308 /* This test will fail on x86-linux because opcodes rejects an
309 attempt to disassemble for an arch with a 64-bit address size
310 when bfd_vma is 32-bit. */
311 if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT)
312 return;
315 gdb_disassembler_test di (gdbarch);
316 bool saw_memory_error = false;
320 di.print_insn (0);
322 catch (const gdb_exception_error &ex)
324 if (ex.error == MEMORY_ERROR)
325 saw_memory_error = true;
328 /* Expect MEMORY_ERROR. */
329 SELF_CHECK (saw_memory_error);
332 } // namespace selftests
334 void _initialize_disasm_selftests ();
335 void
336 _initialize_disasm_selftests ()
338 selftests::register_test_foreach_arch ("print_one_insn",
339 selftests::print_one_insn_test);
340 selftests::register_test_foreach_arch ("memory_error",
341 selftests::memory_error_test);
342 selftests::register_test_foreach_arch ("buffered_insn_length",
343 selftests::buffered_insn_length_test);