disasm-selftests.c revision 1.1.1.6 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