Home | History | Annotate | Line # | Download | only in gdb
      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