Home | History | Annotate | Line # | Download | only in gdb
disasm-selftests.c revision 1.1
      1  1.1  christos /* Self tests for disassembler for GDB, the GNU debugger.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2017 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  christos 
     23  1.1  christos #if GDB_SELF_TEST
     24  1.1  christos #include "selftest.h"
     25  1.1  christos #include "selftest-arch.h"
     26  1.1  christos 
     27  1.1  christos namespace selftests {
     28  1.1  christos 
     29  1.1  christos /* Test disassembly of one instruction.  */
     30  1.1  christos 
     31  1.1  christos static void
     32  1.1  christos print_one_insn_test (struct gdbarch *gdbarch)
     33  1.1  christos {
     34  1.1  christos   size_t len = 0;
     35  1.1  christos   const gdb_byte *insn = NULL;
     36  1.1  christos 
     37  1.1  christos   switch (gdbarch_bfd_arch_info (gdbarch)->arch)
     38  1.1  christos     {
     39  1.1  christos     case bfd_arch_bfin:
     40  1.1  christos       /* M3.L = 0xe117 */
     41  1.1  christos       static const gdb_byte bfin_insn[] = {0x17, 0xe1, 0xff, 0xff};
     42  1.1  christos 
     43  1.1  christos       insn = bfin_insn;
     44  1.1  christos       len = sizeof (bfin_insn);
     45  1.1  christos       break;
     46  1.1  christos     case bfd_arch_arm:
     47  1.1  christos       /* mov     r0, #0 */
     48  1.1  christos       static const gdb_byte arm_insn[] = {0x0, 0x0, 0xa0, 0xe3};
     49  1.1  christos 
     50  1.1  christos       insn = arm_insn;
     51  1.1  christos       len = sizeof (arm_insn);
     52  1.1  christos       break;
     53  1.1  christos     case bfd_arch_ia64:
     54  1.1  christos     case bfd_arch_mep:
     55  1.1  christos     case bfd_arch_mips:
     56  1.1  christos     case bfd_arch_tic6x:
     57  1.1  christos     case bfd_arch_xtensa:
     58  1.1  christos       return;
     59  1.1  christos     case bfd_arch_s390:
     60  1.1  christos       /* nopr %r7 */
     61  1.1  christos       static const gdb_byte s390_insn[] = {0x07, 0x07};
     62  1.1  christos 
     63  1.1  christos       insn = s390_insn;
     64  1.1  christos       len = sizeof (s390_insn);
     65  1.1  christos       break;
     66  1.1  christos     case bfd_arch_xstormy16:
     67  1.1  christos       /* nop */
     68  1.1  christos       static const gdb_byte xstormy16_insn[] = {0x0, 0x0};
     69  1.1  christos 
     70  1.1  christos       insn = xstormy16_insn;
     71  1.1  christos       len = sizeof (xstormy16_insn);
     72  1.1  christos       break;
     73  1.1  christos     case bfd_arch_arc:
     74  1.1  christos       /* PR 21003 */
     75  1.1  christos       if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
     76  1.1  christos 	return;
     77  1.1  christos       /* fall through */
     78  1.1  christos     case bfd_arch_nios2:
     79  1.1  christos     case bfd_arch_score:
     80  1.1  christos       /* nios2 and score need to know the current instruction to select
     81  1.1  christos 	 breakpoint instruction.  Give the breakpoint instruction kind
     82  1.1  christos 	 explicitly.  */
     83  1.1  christos       int bplen;
     84  1.1  christos       insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &bplen);
     85  1.1  christos       len = bplen;
     86  1.1  christos       break;
     87  1.1  christos     default:
     88  1.1  christos       {
     89  1.1  christos 	/* Test disassemble breakpoint instruction.  */
     90  1.1  christos 	CORE_ADDR pc = 0;
     91  1.1  christos 	int kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
     92  1.1  christos 	int bplen;
     93  1.1  christos 
     94  1.1  christos 	insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen);
     95  1.1  christos 	len = bplen;
     96  1.1  christos 
     97  1.1  christos 	break;
     98  1.1  christos       }
     99  1.1  christos     }
    100  1.1  christos   SELF_CHECK (len > 0);
    101  1.1  christos 
    102  1.1  christos   /* Test gdb_disassembler for a given gdbarch by reading data from a
    103  1.1  christos      pre-allocated buffer.  If you want to see the disassembled
    104  1.1  christos      instruction printed to gdb_stdout, set verbose to true.  */
    105  1.1  christos   static const bool verbose = false;
    106  1.1  christos 
    107  1.1  christos   class gdb_disassembler_test : public gdb_disassembler
    108  1.1  christos   {
    109  1.1  christos   public:
    110  1.1  christos 
    111  1.1  christos     explicit gdb_disassembler_test (struct gdbarch *gdbarch,
    112  1.1  christos 				    const gdb_byte *insn,
    113  1.1  christos 				    size_t len)
    114  1.1  christos       : gdb_disassembler (gdbarch,
    115  1.1  christos 			  (verbose ? gdb_stdout : &null_stream),
    116  1.1  christos 			  gdb_disassembler_test::read_memory),
    117  1.1  christos 	m_insn (insn), m_len (len)
    118  1.1  christos     {
    119  1.1  christos     }
    120  1.1  christos 
    121  1.1  christos     int
    122  1.1  christos     print_insn (CORE_ADDR memaddr)
    123  1.1  christos     {
    124  1.1  christos       if (verbose)
    125  1.1  christos 	{
    126  1.1  christos 	  fprintf_unfiltered (stream (), "%s ",
    127  1.1  christos 			      gdbarch_bfd_arch_info (arch ())->arch_name);
    128  1.1  christos 	}
    129  1.1  christos 
    130  1.1  christos       int len = gdb_disassembler::print_insn (memaddr);
    131  1.1  christos 
    132  1.1  christos       if (verbose)
    133  1.1  christos 	fprintf_unfiltered (stream (), "\n");
    134  1.1  christos 
    135  1.1  christos       return len;
    136  1.1  christos     }
    137  1.1  christos 
    138  1.1  christos   private:
    139  1.1  christos     /* A buffer contain one instruction.  */
    140  1.1  christos     const gdb_byte *m_insn;
    141  1.1  christos 
    142  1.1  christos     /* Length of the buffer.  */
    143  1.1  christos     size_t m_len;
    144  1.1  christos 
    145  1.1  christos     static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
    146  1.1  christos 			    unsigned int len, struct disassemble_info *info)
    147  1.1  christos     {
    148  1.1  christos       gdb_disassembler_test *self
    149  1.1  christos 	= static_cast<gdb_disassembler_test *>(info->application_data);
    150  1.1  christos 
    151  1.1  christos       /* The disassembler in opcodes may read more data than one
    152  1.1  christos 	 instruction.  Supply infinite consecutive copies
    153  1.1  christos 	 of the same instruction.  */
    154  1.1  christos       for (size_t i = 0; i < len; i++)
    155  1.1  christos 	myaddr[i] = self->m_insn[(memaddr + i) % self->m_len];
    156  1.1  christos 
    157  1.1  christos       return 0;
    158  1.1  christos     }
    159  1.1  christos   };
    160  1.1  christos 
    161  1.1  christos   gdb_disassembler_test di (gdbarch, insn, len);
    162  1.1  christos 
    163  1.1  christos   SELF_CHECK (di.print_insn (0) == len);
    164  1.1  christos }
    165  1.1  christos 
    166  1.1  christos /* Test disassembly on memory error.  */
    167  1.1  christos 
    168  1.1  christos static void
    169  1.1  christos memory_error_test (struct gdbarch *gdbarch)
    170  1.1  christos {
    171  1.1  christos   class gdb_disassembler_test : public gdb_disassembler
    172  1.1  christos   {
    173  1.1  christos   public:
    174  1.1  christos     gdb_disassembler_test (struct gdbarch *gdbarch)
    175  1.1  christos       : gdb_disassembler (gdbarch, &null_stream,
    176  1.1  christos 			  gdb_disassembler_test::read_memory)
    177  1.1  christos     {
    178  1.1  christos     }
    179  1.1  christos 
    180  1.1  christos     static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
    181  1.1  christos 			    unsigned int len,
    182  1.1  christos 			    struct disassemble_info *info)
    183  1.1  christos     {
    184  1.1  christos       /* Always return an error.  */
    185  1.1  christos       return -1;
    186  1.1  christos     }
    187  1.1  christos   };
    188  1.1  christos 
    189  1.1  christos   gdb_disassembler_test di (gdbarch);
    190  1.1  christos   bool saw_memory_error = false;
    191  1.1  christos 
    192  1.1  christos   TRY
    193  1.1  christos     {
    194  1.1  christos       di.print_insn (0);
    195  1.1  christos     }
    196  1.1  christos   CATCH (ex, RETURN_MASK_ERROR)
    197  1.1  christos     {
    198  1.1  christos       if (ex.error == MEMORY_ERROR)
    199  1.1  christos 	saw_memory_error = true;
    200  1.1  christos     }
    201  1.1  christos   END_CATCH
    202  1.1  christos 
    203  1.1  christos   /* Expect MEMORY_ERROR.  */
    204  1.1  christos   SELF_CHECK (saw_memory_error);
    205  1.1  christos }
    206  1.1  christos 
    207  1.1  christos } // namespace selftests
    208  1.1  christos #endif /* GDB_SELF_TEST */
    209  1.1  christos 
    210  1.1  christos /* Suppress warning from -Wmissing-prototypes.  */
    211  1.1  christos extern initialize_file_ftype _initialize_disasm_selftests;
    212  1.1  christos 
    213  1.1  christos void
    214  1.1  christos _initialize_disasm_selftests (void)
    215  1.1  christos {
    216  1.1  christos #if GDB_SELF_TEST
    217  1.1  christos   register_self_test_foreach_arch (selftests::print_one_insn_test);
    218  1.1  christos   register_self_test_foreach_arch (selftests::memory_error_test);
    219  1.1  christos #endif
    220  1.1  christos }
    221