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