]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/disasm-selftests.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / disasm-selftests.c
CommitLineData
79843d45
YQ
1/* Self tests for disassembler for GDB, the GNU debugger.
2
213516ef 3 Copyright (C) 2017-2023 Free Software Foundation, Inc.
79843d45
YQ
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20#include "defs.h"
21#include "disasm.h"
268a13a5 22#include "gdbsupport/selftest.h"
79843d45 23#include "selftest-arch.h"
0d12e84c 24#include "gdbarch.h"
79843d45
YQ
25
26namespace selftests {
27
8b39b1e7
AB
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.
79843d45 31
8b39b1e7
AB
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. */
35
36static const gdb_byte *
37get_test_insn (struct gdbarch *gdbarch, size_t *len)
79843d45 38{
8b39b1e7
AB
39 *len = 0;
40 const gdb_byte *insn = nullptr;
79843d45
YQ
41
42 switch (gdbarch_bfd_arch_info (gdbarch)->arch)
43 {
44 case bfd_arch_bfin:
45 /* M3.L = 0xe117 */
46 static const gdb_byte bfin_insn[] = {0x17, 0xe1, 0xff, 0xff};
47
48 insn = bfin_insn;
8b39b1e7 49 *len = sizeof (bfin_insn);
79843d45
YQ
50 break;
51 case bfd_arch_arm:
52 /* mov r0, #0 */
53 static const gdb_byte arm_insn[] = {0x0, 0x0, 0xa0, 0xe3};
54
55 insn = arm_insn;
8b39b1e7 56 *len = sizeof (arm_insn);
79843d45
YQ
57 break;
58 case bfd_arch_ia64:
4ab19f4c
TV
59 /* We get:
60 internal-error: gdbarch_sw_breakpoint_from_kind:
61 Assertion `gdbarch->sw_breakpoint_from_kind != NULL' failed. */
8b39b1e7 62 return insn;
79843d45 63 case bfd_arch_mep:
4ab19f4c 64 /* Disassembles as '*unknown*' insn, then len self-check fails. */
8b39b1e7 65 return insn;
79843d45 66 case bfd_arch_mips:
4ab19f4c
TV
67 if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mips16)
68 /* Disassembles insn, but len self-check fails. */
8b39b1e7 69 return insn;
4ab19f4c 70 goto generic_case;
79843d45 71 case bfd_arch_tic6x:
4ab19f4c
TV
72 /* Disassembles as '<undefined instruction 0x56454314>' insn, but len
73 self-check passes, so let's allow it. */
74 goto generic_case;
79843d45 75 case bfd_arch_xtensa:
4ab19f4c 76 /* Disassembles insn, but len self-check fails. */
8b39b1e7 77 return insn;
4ab19f4c
TV
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;
79843d45
YQ
82 case bfd_arch_s390:
83 /* nopr %r7 */
84 static const gdb_byte s390_insn[] = {0x07, 0x07};
85
86 insn = s390_insn;
8b39b1e7 87 *len = sizeof (s390_insn);
79843d45
YQ
88 break;
89 case bfd_arch_xstormy16:
90 /* nop */
91 static const gdb_byte xstormy16_insn[] = {0x0, 0x0};
92
93 insn = xstormy16_insn;
8b39b1e7 94 *len = sizeof (xstormy16_insn);
79843d45 95 break;
79843d45
YQ
96 case bfd_arch_nios2:
97 case bfd_arch_score:
f37bc8b1
JB
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. */
b926417a
TT
102 {
103 int bplen;
104 insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &bplen);
8b39b1e7 105 *len = bplen;
b926417a 106 }
79843d45 107 break;
6f2643db
AB
108 case bfd_arch_arc:
109 /* PR 21003 */
110 if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
8b39b1e7 111 return insn;
9e697875 112 goto generic_case;
98c17098
TV
113 case bfd_arch_z80:
114 {
115 int bplen;
116 insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 0x0008, &bplen);
8b39b1e7 117 *len = bplen;
98c17098
TV
118 }
119 break;
9e697875
TT
120 case bfd_arch_i386:
121 {
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)
8b39b1e7 127 return insn;
9e697875 128 }
6f2643db 129 /* fall through */
79843d45 130 default:
9e697875 131 generic_case:
79843d45
YQ
132 {
133 /* Test disassemble breakpoint instruction. */
134 CORE_ADDR pc = 0;
450afa94 135 int kind;
79843d45
YQ
136 int bplen;
137
450afa94
TV
138 struct gdbarch_info info;
139 info.bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);
140
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))
145 {
146 if (it == GDB_OSABI_UNKNOWN)
147 continue;
148
149 info.osabi = it;
150
151 if (it != GDB_OSABI_NONE)
152 {
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;
159 }
160
161 gdbarch = gdbarch_find_by_info (info);
162 SELF_CHECK (gdbarch != NULL);
163
164 try
165 {
166 kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
167 insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen);
168 }
169 catch (...)
170 {
171 continue;
172 }
173 found = true;
174 break;
175 }
176
177 /* Assert that we have found an instruction to disassemble. */
178 SELF_CHECK (found);
79843d45 179
8b39b1e7 180 *len = bplen;
79843d45
YQ
181 break;
182 }
183 }
8b39b1e7
AB
184 SELF_CHECK (*len > 0);
185
186 return insn;
187}
188
189/* Test disassembly of one instruction. */
190
191static void
192print_one_insn_test (struct gdbarch *gdbarch)
193{
194 size_t len;
195 const gdb_byte *insn = get_test_insn (gdbarch, &len);
196
197 if (insn == nullptr)
198 return;
79843d45
YQ
199
200 /* Test gdb_disassembler for a given gdbarch by reading data from a
201 pre-allocated buffer. If you want to see the disassembled
479209dd 202 instruction printed to gdb_stdout, use maint selftest -verbose. */
79843d45
YQ
203
204 class gdb_disassembler_test : public gdb_disassembler
205 {
206 public:
207
79843d45
YQ
208 explicit gdb_disassembler_test (struct gdbarch *gdbarch,
209 const gdb_byte *insn,
210 size_t len)
211 : gdb_disassembler (gdbarch,
faec7017 212 (run_verbose () ? gdb_stdlog : &null_stream),
79843d45
YQ
213 gdb_disassembler_test::read_memory),
214 m_insn (insn), m_len (len)
215 {
216 }
217
218 int
219 print_insn (CORE_ADDR memaddr)
220 {
79843d45
YQ
221 int len = gdb_disassembler::print_insn (memaddr);
222
479209dd 223 if (run_verbose ())
faec7017 224 debug_printf ("\n");
79843d45
YQ
225
226 return len;
227 }
228
229 private:
230 /* A buffer contain one instruction. */
231 const gdb_byte *m_insn;
232
233 /* Length of the buffer. */
234 size_t m_len;
235
236 static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
8eb7d135
AB
237 unsigned int len,
238 struct disassemble_info *info) noexcept
79843d45
YQ
239 {
240 gdb_disassembler_test *self
241 = static_cast<gdb_disassembler_test *>(info->application_data);
242
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];
248
249 return 0;
250 }
251 };
252
253 gdb_disassembler_test di (gdbarch, insn, len);
254
255 SELF_CHECK (di.print_insn (0) == len);
256}
257
8b39b1e7
AB
258/* Test the gdb_buffered_insn_length function. */
259
260static void
261buffered_insn_length_test (struct gdbarch *gdbarch)
262{
263 size_t buf_len;
264 const gdb_byte *insn = get_test_insn (gdbarch, &buf_len);
265
266 if (insn == nullptr)
267 return;
268
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;
276
277 CORE_ADDR insn_address = 0;
278 int calculated_len = gdb_buffered_insn_length (gdbarch, insn, buf_len,
279 insn_address);
280
281 SELF_CHECK (calculated_len == buf_len);
282}
283
658ca58c
YQ
284/* Test disassembly on memory error. */
285
286static void
287memory_error_test (struct gdbarch *gdbarch)
288{
289 class gdb_disassembler_test : public gdb_disassembler
290 {
291 public:
292 gdb_disassembler_test (struct gdbarch *gdbarch)
d7e74731 293 : gdb_disassembler (gdbarch, &null_stream,
658ca58c
YQ
294 gdb_disassembler_test::read_memory)
295 {
296 }
297
298 static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
299 unsigned int len,
8eb7d135 300 struct disassemble_info *info) noexcept
658ca58c
YQ
301 {
302 /* Always return an error. */
303 return -1;
304 }
305 };
306
9e697875
TT
307 if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_i386)
308 {
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;
315 }
316
658ca58c
YQ
317 gdb_disassembler_test di (gdbarch);
318 bool saw_memory_error = false;
319
a70b8144 320 try
658ca58c
YQ
321 {
322 di.print_insn (0);
323 }
230d2906 324 catch (const gdb_exception_error &ex)
658ca58c
YQ
325 {
326 if (ex.error == MEMORY_ERROR)
327 saw_memory_error = true;
328 }
658ca58c
YQ
329
330 /* Expect MEMORY_ERROR. */
331 SELF_CHECK (saw_memory_error);
332}
333
79843d45 334} // namespace selftests
79843d45 335
6c265988 336void _initialize_disasm_selftests ();
79843d45 337void
6c265988 338_initialize_disasm_selftests ()
79843d45 339{
1526853e
SM
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);
8b39b1e7
AB
344 selftests::register_test_foreach_arch ("buffered_insn_length",
345 selftests::buffered_insn_length_test);
79843d45 346}