xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/disasm-selftests.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1699b0f92Schristos /* Self tests for disassembler for GDB, the GNU debugger.
2699b0f92Schristos 
3*6881a400Schristos    Copyright (C) 2017-2023 Free Software Foundation, Inc.
4699b0f92Schristos 
5699b0f92Schristos    This file is part of GDB.
6699b0f92Schristos 
7699b0f92Schristos    This program is free software; you can redistribute it and/or modify
8699b0f92Schristos    it under the terms of the GNU General Public License as published by
9699b0f92Schristos    the Free Software Foundation; either version 3 of the License, or
10699b0f92Schristos    (at your option) any later version.
11699b0f92Schristos 
12699b0f92Schristos    This program is distributed in the hope that it will be useful,
13699b0f92Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
14699b0f92Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15699b0f92Schristos    GNU General Public License for more details.
16699b0f92Schristos 
17699b0f92Schristos    You should have received a copy of the GNU General Public License
18699b0f92Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19699b0f92Schristos 
20699b0f92Schristos #include "defs.h"
21699b0f92Schristos #include "disasm.h"
227d62b00eSchristos #include "gdbsupport/selftest.h"
23699b0f92Schristos #include "selftest-arch.h"
247d62b00eSchristos #include "gdbarch.h"
25699b0f92Schristos 
26699b0f92Schristos namespace selftests {
27699b0f92Schristos 
28*6881a400Schristos /* Return a pointer to a buffer containing an instruction that can be
29*6881a400Schristos    disassembled for architecture GDBARCH.  *LEN will be set to the length
30*6881a400Schristos    of the returned buffer.
31699b0f92Schristos 
32*6881a400Schristos    If there's no known instruction to disassemble for GDBARCH (because we
33*6881a400Schristos    haven't figured on out, not because no instructions exist) then nullptr
34*6881a400Schristos    is returned, and *LEN is set to 0.  */
35*6881a400Schristos 
36*6881a400Schristos static const gdb_byte *
37*6881a400Schristos get_test_insn (struct gdbarch *gdbarch, size_t *len)
38699b0f92Schristos {
39*6881a400Schristos   *len = 0;
40*6881a400Schristos   const gdb_byte *insn = nullptr;
41699b0f92Schristos 
42699b0f92Schristos   switch (gdbarch_bfd_arch_info (gdbarch)->arch)
43699b0f92Schristos     {
44699b0f92Schristos     case bfd_arch_bfin:
45699b0f92Schristos       /* M3.L = 0xe117 */
46699b0f92Schristos       static const gdb_byte bfin_insn[] = {0x17, 0xe1, 0xff, 0xff};
47699b0f92Schristos 
48699b0f92Schristos       insn = bfin_insn;
49*6881a400Schristos       *len = sizeof (bfin_insn);
50699b0f92Schristos       break;
51699b0f92Schristos     case bfd_arch_arm:
52699b0f92Schristos       /* mov     r0, #0 */
53699b0f92Schristos       static const gdb_byte arm_insn[] = {0x0, 0x0, 0xa0, 0xe3};
54699b0f92Schristos 
55699b0f92Schristos       insn = arm_insn;
56*6881a400Schristos       *len = sizeof (arm_insn);
57699b0f92Schristos       break;
58699b0f92Schristos     case bfd_arch_ia64:
59*6881a400Schristos       /* We get:
60*6881a400Schristos 	 internal-error: gdbarch_sw_breakpoint_from_kind:
61*6881a400Schristos 	 Assertion `gdbarch->sw_breakpoint_from_kind != NULL' failed.  */
62*6881a400Schristos       return insn;
63699b0f92Schristos     case bfd_arch_mep:
64*6881a400Schristos       /* Disassembles as '*unknown*' insn, then len self-check fails.  */
65*6881a400Schristos       return insn;
66699b0f92Schristos     case bfd_arch_mips:
67*6881a400Schristos       if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mips16)
68*6881a400Schristos 	/* Disassembles insn, but len self-check fails.  */
69*6881a400Schristos 	return insn;
70*6881a400Schristos       goto generic_case;
71699b0f92Schristos     case bfd_arch_tic6x:
72*6881a400Schristos       /* Disassembles as '<undefined instruction 0x56454314>' insn, but len
73*6881a400Schristos 	 self-check passes, so let's allow it.  */
74*6881a400Schristos       goto generic_case;
75699b0f92Schristos     case bfd_arch_xtensa:
76*6881a400Schristos       /* Disassembles insn, but len self-check fails.  */
77*6881a400Schristos       return insn;
78*6881a400Schristos     case bfd_arch_or1k:
79*6881a400Schristos       /* Disassembles as '*unknown*' insn, but len self-check passes, so let's
80*6881a400Schristos 	 allow it.  */
81*6881a400Schristos       goto generic_case;
82699b0f92Schristos     case bfd_arch_s390:
83699b0f92Schristos       /* nopr %r7 */
84699b0f92Schristos       static const gdb_byte s390_insn[] = {0x07, 0x07};
85699b0f92Schristos 
86699b0f92Schristos       insn = s390_insn;
87*6881a400Schristos       *len = sizeof (s390_insn);
88699b0f92Schristos       break;
89699b0f92Schristos     case bfd_arch_xstormy16:
90699b0f92Schristos       /* nop */
91699b0f92Schristos       static const gdb_byte xstormy16_insn[] = {0x0, 0x0};
92699b0f92Schristos 
93699b0f92Schristos       insn = xstormy16_insn;
94*6881a400Schristos       *len = sizeof (xstormy16_insn);
95699b0f92Schristos       break;
96699b0f92Schristos     case bfd_arch_nios2:
97699b0f92Schristos     case bfd_arch_score:
987f2ac410Schristos     case bfd_arch_riscv:
997f2ac410Schristos       /* nios2, riscv, and score need to know the current instruction
1007f2ac410Schristos 	 to select breakpoint instruction.  Give the breakpoint
1017f2ac410Schristos 	 instruction kind explicitly.  */
1027f2ac410Schristos       {
103699b0f92Schristos 	int bplen;
104699b0f92Schristos 	insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &bplen);
105*6881a400Schristos 	*len = bplen;
1067f2ac410Schristos       }
107699b0f92Schristos       break;
108*6881a400Schristos     case bfd_arch_arc:
109*6881a400Schristos       /* PR 21003 */
110*6881a400Schristos       if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
111*6881a400Schristos 	return insn;
112*6881a400Schristos       goto generic_case;
113*6881a400Schristos     case bfd_arch_z80:
114*6881a400Schristos       {
115*6881a400Schristos 	int bplen;
116*6881a400Schristos 	insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 0x0008, &bplen);
117*6881a400Schristos 	*len = bplen;
118*6881a400Schristos       }
119*6881a400Schristos       break;
120*6881a400Schristos     case bfd_arch_i386:
121*6881a400Schristos       {
122*6881a400Schristos 	const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
123*6881a400Schristos 	/* The disassembly tests will fail on x86-linux because
124*6881a400Schristos 	   opcodes rejects an attempt to disassemble for an arch with
125*6881a400Schristos 	   a 64-bit address size when bfd_vma is 32-bit.  */
126*6881a400Schristos 	if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT)
127*6881a400Schristos 	  return insn;
128*6881a400Schristos       }
129*6881a400Schristos       /* fall through */
130699b0f92Schristos     default:
131*6881a400Schristos     generic_case:
132699b0f92Schristos       {
133699b0f92Schristos 	/* Test disassemble breakpoint instruction.  */
134699b0f92Schristos 	CORE_ADDR pc = 0;
135*6881a400Schristos 	int kind;
136699b0f92Schristos 	int bplen;
137699b0f92Schristos 
138*6881a400Schristos 	struct gdbarch_info info;
139*6881a400Schristos 	info.bfd_arch_info = gdbarch_bfd_arch_info (gdbarch);
140699b0f92Schristos 
141*6881a400Schristos 	enum gdb_osabi it;
142*6881a400Schristos 	bool found = false;
143*6881a400Schristos 	for (it = GDB_OSABI_UNKNOWN; it != GDB_OSABI_INVALID;
144*6881a400Schristos 	     it = static_cast<enum gdb_osabi>(static_cast<int>(it) + 1))
145*6881a400Schristos 	  {
146*6881a400Schristos 	    if (it == GDB_OSABI_UNKNOWN)
147*6881a400Schristos 	      continue;
148*6881a400Schristos 
149*6881a400Schristos 	    info.osabi = it;
150*6881a400Schristos 
151*6881a400Schristos 	    if (it != GDB_OSABI_NONE)
152*6881a400Schristos 	      {
153*6881a400Schristos 		if (!has_gdb_osabi_handler (info))
154*6881a400Schristos 		  /* Unsupported.  Skip to prevent warnings like:
155*6881a400Schristos 		     A handler for the OS ABI <x> is not built into this
156*6881a400Schristos 		     configuration of GDB.  Attempting to continue with the
157*6881a400Schristos 		     default <y> settings.  */
158*6881a400Schristos 		  continue;
159*6881a400Schristos 	      }
160*6881a400Schristos 
161*6881a400Schristos 	    gdbarch = gdbarch_find_by_info (info);
162*6881a400Schristos 	    SELF_CHECK (gdbarch != NULL);
163*6881a400Schristos 
164*6881a400Schristos 	    try
165*6881a400Schristos 	      {
166*6881a400Schristos 		kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
167*6881a400Schristos 		insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen);
168*6881a400Schristos 	      }
169*6881a400Schristos 	    catch (...)
170*6881a400Schristos 	      {
171*6881a400Schristos 		continue;
172*6881a400Schristos 	      }
173*6881a400Schristos 	    found = true;
174*6881a400Schristos 	    break;
175*6881a400Schristos 	  }
176*6881a400Schristos 
177*6881a400Schristos 	/* Assert that we have found an instruction to disassemble.  */
178*6881a400Schristos 	SELF_CHECK (found);
179*6881a400Schristos 
180*6881a400Schristos 	*len = bplen;
181699b0f92Schristos 	break;
182699b0f92Schristos       }
183699b0f92Schristos     }
184*6881a400Schristos   SELF_CHECK (*len > 0);
185*6881a400Schristos 
186*6881a400Schristos   return insn;
187*6881a400Schristos }
188*6881a400Schristos 
189*6881a400Schristos /* Test disassembly of one instruction.  */
190*6881a400Schristos 
191*6881a400Schristos static void
192*6881a400Schristos print_one_insn_test (struct gdbarch *gdbarch)
193*6881a400Schristos {
194*6881a400Schristos   size_t len;
195*6881a400Schristos   const gdb_byte *insn = get_test_insn (gdbarch, &len);
196*6881a400Schristos 
197*6881a400Schristos   if (insn == nullptr)
198*6881a400Schristos     return;
199699b0f92Schristos 
200699b0f92Schristos   /* Test gdb_disassembler for a given gdbarch by reading data from a
201699b0f92Schristos      pre-allocated buffer.  If you want to see the disassembled
202*6881a400Schristos      instruction printed to gdb_stdout, use maint selftest -verbose.  */
203699b0f92Schristos 
204699b0f92Schristos   class gdb_disassembler_test : public gdb_disassembler
205699b0f92Schristos   {
206699b0f92Schristos   public:
207699b0f92Schristos 
208699b0f92Schristos     explicit gdb_disassembler_test (struct gdbarch *gdbarch,
209699b0f92Schristos 				    const gdb_byte *insn,
210699b0f92Schristos 				    size_t len)
211699b0f92Schristos       : gdb_disassembler (gdbarch,
212*6881a400Schristos 			  (run_verbose () ? gdb_stdlog : &null_stream),
213699b0f92Schristos 			  gdb_disassembler_test::read_memory),
214699b0f92Schristos 	m_insn (insn), m_len (len)
215699b0f92Schristos     {
216699b0f92Schristos     }
217699b0f92Schristos 
218699b0f92Schristos     int
219699b0f92Schristos     print_insn (CORE_ADDR memaddr)
220699b0f92Schristos     {
221699b0f92Schristos       int len = gdb_disassembler::print_insn (memaddr);
222699b0f92Schristos 
223*6881a400Schristos       if (run_verbose ())
224*6881a400Schristos 	debug_printf ("\n");
225699b0f92Schristos 
226699b0f92Schristos       return len;
227699b0f92Schristos     }
228699b0f92Schristos 
229699b0f92Schristos   private:
230699b0f92Schristos     /* A buffer contain one instruction.  */
231699b0f92Schristos     const gdb_byte *m_insn;
232699b0f92Schristos 
233699b0f92Schristos     /* Length of the buffer.  */
234699b0f92Schristos     size_t m_len;
235699b0f92Schristos 
236699b0f92Schristos     static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
237*6881a400Schristos 			    unsigned int len,
238*6881a400Schristos 			    struct disassemble_info *info) noexcept
239699b0f92Schristos     {
240699b0f92Schristos       gdb_disassembler_test *self
241699b0f92Schristos 	= static_cast<gdb_disassembler_test *>(info->application_data);
242699b0f92Schristos 
243699b0f92Schristos       /* The disassembler in opcodes may read more data than one
244699b0f92Schristos 	 instruction.  Supply infinite consecutive copies
245699b0f92Schristos 	 of the same instruction.  */
246699b0f92Schristos       for (size_t i = 0; i < len; i++)
247699b0f92Schristos 	myaddr[i] = self->m_insn[(memaddr + i) % self->m_len];
248699b0f92Schristos 
249699b0f92Schristos       return 0;
250699b0f92Schristos     }
251699b0f92Schristos   };
252699b0f92Schristos 
253699b0f92Schristos   gdb_disassembler_test di (gdbarch, insn, len);
254699b0f92Schristos 
255699b0f92Schristos   SELF_CHECK (di.print_insn (0) == len);
256699b0f92Schristos }
257699b0f92Schristos 
258*6881a400Schristos /* Test the gdb_buffered_insn_length function.  */
259*6881a400Schristos 
260*6881a400Schristos static void
261*6881a400Schristos buffered_insn_length_test (struct gdbarch *gdbarch)
262*6881a400Schristos {
263*6881a400Schristos   size_t buf_len;
264*6881a400Schristos   const gdb_byte *insn = get_test_insn (gdbarch, &buf_len);
265*6881a400Schristos 
266*6881a400Schristos   if (insn == nullptr)
267*6881a400Schristos     return;
268*6881a400Schristos 
269*6881a400Schristos   /* The tic6x architecture is VLIW.  Disassembling requires that the
270*6881a400Schristos      entire instruction bundle be available.  However, the buffer we got
271*6881a400Schristos      back from get_test_insn only contains a single instruction, which is
272*6881a400Schristos      just part of an instruction bundle.  As a result, the disassemble will
273*6881a400Schristos      fail.  To avoid this, skip tic6x tests now.  */
274*6881a400Schristos   if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_tic6x)
275*6881a400Schristos     return;
276*6881a400Schristos 
277*6881a400Schristos   CORE_ADDR insn_address = 0;
278*6881a400Schristos   int calculated_len = gdb_buffered_insn_length (gdbarch, insn, buf_len,
279*6881a400Schristos 						 insn_address);
280*6881a400Schristos 
281*6881a400Schristos   SELF_CHECK (calculated_len == buf_len);
282*6881a400Schristos }
283*6881a400Schristos 
284699b0f92Schristos /* Test disassembly on memory error.  */
285699b0f92Schristos 
286699b0f92Schristos static void
287699b0f92Schristos memory_error_test (struct gdbarch *gdbarch)
288699b0f92Schristos {
289699b0f92Schristos   class gdb_disassembler_test : public gdb_disassembler
290699b0f92Schristos   {
291699b0f92Schristos   public:
292699b0f92Schristos     gdb_disassembler_test (struct gdbarch *gdbarch)
293699b0f92Schristos       : gdb_disassembler (gdbarch, &null_stream,
294699b0f92Schristos 			  gdb_disassembler_test::read_memory)
295699b0f92Schristos     {
296699b0f92Schristos     }
297699b0f92Schristos 
298699b0f92Schristos     static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
299699b0f92Schristos 			    unsigned int len,
300*6881a400Schristos 			    struct disassemble_info *info) noexcept
301699b0f92Schristos     {
302699b0f92Schristos       /* Always return an error.  */
303699b0f92Schristos       return -1;
304699b0f92Schristos     }
305699b0f92Schristos   };
306699b0f92Schristos 
307*6881a400Schristos   if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_i386)
308*6881a400Schristos     {
309*6881a400Schristos       const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
310*6881a400Schristos       /* This test will fail on x86-linux because opcodes rejects an
311*6881a400Schristos 	 attempt to disassemble for an arch with a 64-bit address size
312*6881a400Schristos 	 when bfd_vma is 32-bit.  */
313*6881a400Schristos       if (info->bits_per_address > sizeof (bfd_vma) * CHAR_BIT)
314*6881a400Schristos 	return;
315*6881a400Schristos     }
316*6881a400Schristos 
317699b0f92Schristos   gdb_disassembler_test di (gdbarch);
318699b0f92Schristos   bool saw_memory_error = false;
319699b0f92Schristos 
3207d62b00eSchristos   try
321699b0f92Schristos     {
322699b0f92Schristos       di.print_insn (0);
323699b0f92Schristos     }
3247d62b00eSchristos   catch (const gdb_exception_error &ex)
325699b0f92Schristos     {
326699b0f92Schristos       if (ex.error == MEMORY_ERROR)
327699b0f92Schristos 	saw_memory_error = true;
328699b0f92Schristos     }
329699b0f92Schristos 
330699b0f92Schristos   /* Expect MEMORY_ERROR.  */
331699b0f92Schristos   SELF_CHECK (saw_memory_error);
332699b0f92Schristos }
333699b0f92Schristos 
334699b0f92Schristos } // namespace selftests
335699b0f92Schristos 
3367d62b00eSchristos void _initialize_disasm_selftests ();
337699b0f92Schristos void
3387d62b00eSchristos _initialize_disasm_selftests ()
339699b0f92Schristos {
3407f2ac410Schristos   selftests::register_test_foreach_arch ("print_one_insn",
3417f2ac410Schristos 					 selftests::print_one_insn_test);
3427f2ac410Schristos   selftests::register_test_foreach_arch ("memory_error",
3437f2ac410Schristos 					 selftests::memory_error_test);
344*6881a400Schristos   selftests::register_test_foreach_arch ("buffered_insn_length",
345*6881a400Schristos 					 selftests::buffered_insn_length_test);
346699b0f92Schristos }
347