GDB (xrefs)
/tmp/gdb-8.1/gdb/disasm-selftests.c
Go to the documentation of this file.
1 /* Self tests for disassembler for GDB, the GNU debugger.
2 
3  Copyright (C) 2017-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "disasm.h"
22 
23 #if GDB_SELF_TEST
24 #include "selftest.h"
25 #include "selftest-arch.h"
26 
27 namespace selftests {
28 
29 /* Test disassembly of one instruction. */
30 
31 static void
32 print_one_insn_test (struct gdbarch *gdbarch)
33 {
34  size_t len = 0;
35  const gdb_byte *insn = NULL;
36 
37  switch (gdbarch_bfd_arch_info (gdbarch)->arch)
38  {
39  case bfd_arch_bfin:
40  /* M3.L = 0xe117 */
41  static const gdb_byte bfin_insn[] = {0x17, 0xe1, 0xff, 0xff};
42 
43  insn = bfin_insn;
44  len = sizeof (bfin_insn);
45  break;
46  case bfd_arch_arm:
47  /* mov r0, #0 */
48  static const gdb_byte arm_insn[] = {0x0, 0x0, 0xa0, 0xe3};
49 
50  insn = arm_insn;
51  len = sizeof (arm_insn);
52  break;
53  case bfd_arch_ia64:
54  case bfd_arch_mep:
55  case bfd_arch_mips:
56  case bfd_arch_tic6x:
57  case bfd_arch_xtensa:
58  return;
59  case bfd_arch_s390:
60  /* nopr %r7 */
61  static const gdb_byte s390_insn[] = {0x07, 0x07};
62 
63  insn = s390_insn;
64  len = sizeof (s390_insn);
65  break;
66  case bfd_arch_xstormy16:
67  /* nop */
68  static const gdb_byte xstormy16_insn[] = {0x0, 0x0};
69 
70  insn = xstormy16_insn;
71  len = sizeof (xstormy16_insn);
72  break;
73  case bfd_arch_arc:
74  /* PR 21003 */
75  if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
76  return;
77  /* fall through */
78  case bfd_arch_nios2:
79  case bfd_arch_score:
80  /* nios2 and score need to know the current instruction to select
81  breakpoint instruction. Give the breakpoint instruction kind
82  explicitly. */
83  int bplen;
84  insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &bplen);
85  len = bplen;
86  break;
87  default:
88  {
89  /* Test disassemble breakpoint instruction. */
90  CORE_ADDR pc = 0;
91  int kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
92  int bplen;
93 
94  insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen);
95  len = bplen;
96 
97  break;
98  }
99  }
100  SELF_CHECK (len > 0);
101 
102  /* Test gdb_disassembler for a given gdbarch by reading data from a
103  pre-allocated buffer. If you want to see the disassembled
104  instruction printed to gdb_stdout, set verbose to true. */
105  static const bool verbose = false;
106 
107  class gdb_disassembler_test : public gdb_disassembler
108  {
109  public:
110 
111  explicit gdb_disassembler_test (struct gdbarch *gdbarch,
112  const gdb_byte *insn,
113  size_t len)
115  (verbose ? gdb_stdout : &null_stream),
116  gdb_disassembler_test::read_memory),
117  m_insn (insn), m_len (len)
118  {
119  }
120 
121  int
122  print_insn (CORE_ADDR memaddr)
123  {
124  if (verbose)
125  {
126  fprintf_unfiltered (stream (), "%s ",
127  gdbarch_bfd_arch_info (arch ())->arch_name);
128  }
129 
130  int len = gdb_disassembler::print_insn (memaddr);
131 
132  if (verbose)
133  fprintf_unfiltered (stream (), "\n");
134 
135  return len;
136  }
137 
138  private:
139  /* A buffer contain one instruction. */
140  const gdb_byte *m_insn;
141 
142  /* Length of the buffer. */
143  size_t m_len;
144 
145  static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
146  unsigned int len, struct disassemble_info *info)
147  {
148  gdb_disassembler_test *self
149  = static_cast<gdb_disassembler_test *>(info->application_data);
150 
151  /* The disassembler in opcodes may read more data than one
152  instruction. Supply infinite consecutive copies
153  of the same instruction. */
154  for (size_t i = 0; i < len; i++)
155  myaddr[i] = self->m_insn[(memaddr + i) % self->m_len];
156 
157  return 0;
158  }
159  };
160 
161  gdb_disassembler_test di (gdbarch, insn, len);
162 
163  SELF_CHECK (di.print_insn (0) == len);
164 }
165 
166 /* Test disassembly on memory error. */
167 
168 static void
169 memory_error_test (struct gdbarch *gdbarch)
170 {
171  class gdb_disassembler_test : public gdb_disassembler
172  {
173  public:
174  gdb_disassembler_test (struct gdbarch *gdbarch)
176  gdb_disassembler_test::read_memory)
177  {
178  }
179 
180  static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
181  unsigned int len,
182  struct disassemble_info *info)
183  {
184  /* Always return an error. */
185  return -1;
186  }
187  };
188 
189  gdb_disassembler_test di (gdbarch);
190  bool saw_memory_error = false;
191 
192  TRY
193  {
194  di.print_insn (0);
195  }
197  {
198  if (ex.error == MEMORY_ERROR)
199  saw_memory_error = true;
200  }
201  END_CATCH
202 
203  /* Expect MEMORY_ERROR. */
204  SELF_CHECK (saw_memory_error);
205 }
206 
207 } // namespace selftests
208 #endif /* GDB_SELF_TEST */
209 
210 void
212 {
213 #if GDB_SELF_TEST
214  selftests::register_test_foreach_arch ("print_one_insn",
215  selftests::print_one_insn_test);
217  selftests::memory_error_test);
218 #endif
219 }
bfd_vma CORE_ADDR
Definition: common-types.h:41
int print_insn(CORE_ADDR memaddr, int *branch_delay_insns=NULL)
Definition: disasm.c:759
int gdbarch_breakpoint_kind_from_pc(struct gdbarch *gdbarch, CORE_ADDR *pcptr)
Definition: gdbarch.c:2861
void register_test_foreach_arch(const std::string &name, self_test_foreach_arch_function *function)
#define END_CATCH
#define TRY
#define CATCH(EXCEPTION, MASK)
null_file null_stream
Definition: ui-file.c:28
void fprintf_unfiltered(struct ui_file *stream, const char *format,...)
Definition: utils.c:2018
void read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
Definition: corefile.c:258
void _initialize_disasm_selftests(void)
const gdb_byte * gdbarch_sw_breakpoint_from_kind(struct gdbarch *gdbarch, int kind, int *size)
Definition: gdbarch.c:2878
bfd_byte gdb_byte
Definition: common-types.h:38
const struct bfd_arch_info * gdbarch_bfd_arch_info(struct gdbarch *gdbarch)
Definition: gdbarch.c:1500
#define SELF_CHECK(VALUE)
Definition: selftest.h:67
#define gdb_stdout
Definition: utils.h:340