disasm-selftests.c revision 1.1.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