]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/gdbarch-selftests.c
Use std::vector in h8300-tdep.c
[thirdparty/binutils-gdb.git] / gdb / gdbarch-selftests.c
1 /* Self tests for gdbarch for GDB, the GNU debugger.
2
3 Copyright (C) 2017 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 #if GDB_SELF_TEST
22 #include "selftest.h"
23 #include "selftest-arch.h"
24 #include "inferior.h"
25 #include "gdbthread.h"
26 #include "target.h"
27
28 namespace selftests {
29
30 /* A mock process_stratum target_ops that doesn't read/write registers
31 anywhere. */
32
33 static int
34 test_target_has_registers (target_ops *self)
35 {
36 return 1;
37 }
38
39 static int
40 test_target_has_stack (target_ops *self)
41 {
42 return 1;
43 }
44
45 static int
46 test_target_has_memory (target_ops *self)
47 {
48 return 1;
49 }
50
51 static void
52 test_target_prepare_to_store (target_ops *self, regcache *regs)
53 {
54 }
55
56 static void
57 test_target_store_registers (target_ops *self, regcache *regs, int regno)
58 {
59 }
60
61 class test_target_ops : public target_ops
62 {
63 public:
64 test_target_ops ()
65 : target_ops {}
66 {
67 to_magic = OPS_MAGIC;
68 to_stratum = process_stratum;
69 to_has_memory = test_target_has_memory;
70 to_has_stack = test_target_has_stack;
71 to_has_registers = test_target_has_registers;
72 to_prepare_to_store = test_target_prepare_to_store;
73 to_store_registers = test_target_store_registers;
74
75 complete_target_initialization (this);
76 }
77 };
78
79 /* Test gdbarch methods register_to_value and value_to_register. */
80
81 static void
82 register_to_value_test (struct gdbarch *gdbarch)
83 {
84 const struct builtin_type *builtin = builtin_type (gdbarch);
85 struct type *types[] =
86 {
87 builtin->builtin_void,
88 builtin->builtin_char,
89 builtin->builtin_short,
90 builtin->builtin_int,
91 builtin->builtin_long,
92 builtin->builtin_signed_char,
93 builtin->builtin_unsigned_short,
94 builtin->builtin_unsigned_int,
95 builtin->builtin_unsigned_long,
96 builtin->builtin_float,
97 builtin->builtin_double,
98 builtin->builtin_long_double,
99 builtin->builtin_complex,
100 builtin->builtin_double_complex,
101 builtin->builtin_string,
102 builtin->builtin_bool,
103 builtin->builtin_long_long,
104 builtin->builtin_unsigned_long_long,
105 builtin->builtin_int8,
106 builtin->builtin_uint8,
107 builtin->builtin_int16,
108 builtin->builtin_uint16,
109 builtin->builtin_int32,
110 builtin->builtin_uint32,
111 builtin->builtin_int64,
112 builtin->builtin_uint64,
113 builtin->builtin_int128,
114 builtin->builtin_uint128,
115 builtin->builtin_char16,
116 builtin->builtin_char32,
117 };
118
119 /* Error out if debugging something, because we're going to push the
120 test target, which would pop any existing target. */
121 if (current_target.to_stratum >= process_stratum)
122 error (_("target already pushed"));
123
124 /* Create a mock environment. An inferior with a thread, with a
125 process_stratum target pushed. */
126
127 test_target_ops mock_target;
128 ptid_t mock_ptid (1, 1);
129 inferior mock_inferior (mock_ptid.pid ());
130 address_space mock_aspace {};
131 mock_inferior.gdbarch = gdbarch;
132 mock_inferior.aspace = &mock_aspace;
133 thread_info mock_thread (&mock_inferior, mock_ptid);
134
135 scoped_restore restore_thread_list
136 = make_scoped_restore (&thread_list, &mock_thread);
137
138 /* Add the mock inferior to the inferior list so that look ups by
139 target+ptid can find it. */
140 scoped_restore restore_inferior_list
141 = make_scoped_restore (&inferior_list);
142 inferior_list = &mock_inferior;
143
144 /* Switch to the mock inferior. */
145 scoped_restore_current_inferior restore_current_inferior;
146 set_current_inferior (&mock_inferior);
147
148 /* Push the process_stratum target so we can mock accessing
149 registers. */
150 push_target (&mock_target);
151
152 /* Pop it again on exit (return/exception). */
153 struct on_exit
154 {
155 ~on_exit ()
156 {
157 pop_all_targets_at_and_above (process_stratum);
158 }
159 } pop_targets;
160
161 /* Switch to the mock thread. */
162 scoped_restore restore_inferior_ptid
163 = make_scoped_restore (&inferior_ptid, mock_ptid);
164
165 struct frame_info *frame = get_current_frame ();
166 const int num_regs = (gdbarch_num_regs (gdbarch)
167 + gdbarch_num_pseudo_regs (gdbarch));
168
169 /* Test gdbarch methods register_to_value and value_to_register with
170 different combinations of register numbers and types. */
171 for (const auto &type : types)
172 {
173 for (auto regnum = 0; regnum < num_regs; regnum++)
174 {
175 if (gdbarch_convert_register_p (gdbarch, regnum, type))
176 {
177 std::vector<gdb_byte> expected (TYPE_LENGTH (type), 0);
178
179 if (TYPE_CODE (type) == TYPE_CODE_FLT)
180 {
181 DOUBLEST d = 1.25;
182
183 /* Generate valid float format. */
184 floatformat_from_doublest (floatformat_from_type (type),
185 &d, expected.data ());
186 }
187 else
188 {
189 for (auto j = 0; j < expected.size (); j++)
190 expected[j] = (regnum + j) % 16;
191 }
192
193 gdbarch_value_to_register (gdbarch, frame, regnum, type,
194 expected.data ());
195
196 /* Allocate two bytes more for overflow check. */
197 std::vector<gdb_byte> buf (TYPE_LENGTH (type) + 2, 0);
198 int optim, unavail, ok;
199
200 /* Set the fingerprint in the last two bytes. */
201 buf [TYPE_LENGTH (type)]= 'w';
202 buf [TYPE_LENGTH (type) + 1]= 'l';
203 ok = gdbarch_register_to_value (gdbarch, frame, regnum, type,
204 buf.data (), &optim, &unavail);
205
206 SELF_CHECK (ok);
207 SELF_CHECK (!optim);
208 SELF_CHECK (!unavail);
209
210 SELF_CHECK (buf[TYPE_LENGTH (type)] == 'w');
211 SELF_CHECK (buf[TYPE_LENGTH (type) + 1] == 'l');
212
213 for (auto k = 0; k < TYPE_LENGTH(type); k++)
214 SELF_CHECK (buf[k] == expected[k]);
215 }
216 }
217 }
218 }
219
220 } // namespace selftests
221 #endif /* GDB_SELF_TEST */
222
223 void
224 _initialize_gdbarch_selftests (void)
225 {
226 #if GDB_SELF_TEST
227 selftests::register_test_foreach_arch ("register_to_value",
228 selftests::register_to_value_test);
229 #endif
230 }