]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbarch-selftests.c
gdb: add gdbarch_stack_grows_down function
[thirdparty/binutils-gdb.git] / gdb / gdbarch-selftests.c
CommitLineData
b77b02a5
YQ
1/* Self tests for gdbarch for GDB, the GNU debugger.
2
1d506c26 3 Copyright (C) 2017-2024 Free Software Foundation, Inc.
b77b02a5
YQ
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
268a13a5 20#include "gdbsupport/selftest.h"
b77b02a5 21#include "selftest-arch.h"
55b11ddf 22#include "target.h"
c180496d 23#include "test-target.h"
f69fdf9b 24#include "target-float.h"
268a13a5 25#include "gdbsupport/def-vector.h"
0d12e84c 26#include "gdbarch.h"
236ef034 27#include "scoped-mock-context.h"
b77b02a5 28
9a103324
AB
29#include <map>
30
b77b02a5
YQ
31namespace selftests {
32
b77b02a5
YQ
33/* Test gdbarch methods register_to_value and value_to_register. */
34
35static void
36register_to_value_test (struct gdbarch *gdbarch)
37{
38 const struct builtin_type *builtin = builtin_type (gdbarch);
39 struct type *types[] =
40 {
41 builtin->builtin_void,
42 builtin->builtin_char,
43 builtin->builtin_short,
44 builtin->builtin_int,
45 builtin->builtin_long,
46 builtin->builtin_signed_char,
47 builtin->builtin_unsigned_short,
48 builtin->builtin_unsigned_int,
49 builtin->builtin_unsigned_long,
50 builtin->builtin_float,
51 builtin->builtin_double,
52 builtin->builtin_long_double,
53 builtin->builtin_complex,
54 builtin->builtin_double_complex,
55 builtin->builtin_string,
56 builtin->builtin_bool,
57 builtin->builtin_long_long,
58 builtin->builtin_unsigned_long_long,
59 builtin->builtin_int8,
60 builtin->builtin_uint8,
61 builtin->builtin_int16,
62 builtin->builtin_uint16,
63 builtin->builtin_int32,
64 builtin->builtin_uint32,
65 builtin->builtin_int64,
66 builtin->builtin_uint64,
67 builtin->builtin_int128,
68 builtin->builtin_uint128,
69 builtin->builtin_char16,
70 builtin->builtin_char32,
71 };
72
236ef034 73 scoped_mock_context<test_target_ops> mockctx (gdbarch);
55b11ddf 74
bd2b40ac 75 frame_info_ptr frame = get_current_frame ();
f6efe3f8 76 const int num_regs = gdbarch_num_cooked_regs (gdbarch);
b77b02a5 77
b77b02a5
YQ
78 /* Test gdbarch methods register_to_value and value_to_register with
79 different combinations of register numbers and types. */
80 for (const auto &type : types)
81 {
82 for (auto regnum = 0; regnum < num_regs; regnum++)
83 {
84 if (gdbarch_convert_register_p (gdbarch, regnum, type))
85 {
df86565b 86 std::vector<gdb_byte> expected (type->length (), 0);
b77b02a5 87
78134374 88 if (type->code () == TYPE_CODE_FLT)
b77b02a5 89 {
b77b02a5 90 /* Generate valid float format. */
f69fdf9b 91 target_float_from_string (expected.data (), type, "1.25");
b77b02a5
YQ
92 }
93 else
94 {
95 for (auto j = 0; j < expected.size (); j++)
96 expected[j] = (regnum + j) % 16;
97 }
98
99 gdbarch_value_to_register (gdbarch, frame, regnum, type,
100 expected.data ());
101
102 /* Allocate two bytes more for overflow check. */
df86565b 103 std::vector<gdb_byte> buf (type->length () + 2, 0);
b77b02a5
YQ
104 int optim, unavail, ok;
105
106 /* Set the fingerprint in the last two bytes. */
df86565b
SM
107 buf [type->length ()]= 'w';
108 buf [type->length () + 1]= 'l';
b77b02a5
YQ
109 ok = gdbarch_register_to_value (gdbarch, frame, regnum, type,
110 buf.data (), &optim, &unavail);
111
112 SELF_CHECK (ok);
113 SELF_CHECK (!optim);
114 SELF_CHECK (!unavail);
115
df86565b
SM
116 SELF_CHECK (buf[type->length ()] == 'w');
117 SELF_CHECK (buf[type->length () + 1] == 'l');
b77b02a5 118
df86565b 119 for (auto k = 0; k < type->length (); k++)
b77b02a5
YQ
120 SELF_CHECK (buf[k] == expected[k]);
121 }
122 }
123 }
124}
125
9a972b54
AB
126/* Test function gdbarch_register_name. */
127
128static void
129register_name_test (struct gdbarch *gdbarch)
130{
131 scoped_mock_context<test_target_ops> mockctx (gdbarch);
132
9a103324
AB
133 /* Track the number of times each register name appears. */
134 std::map<const std::string, int> name_counts;
135
9a972b54
AB
136 const int num_regs = gdbarch_num_cooked_regs (gdbarch);
137 for (auto regnum = 0; regnum < num_regs; regnum++)
138 {
139 /* If a register is to be hidden from the user then we should get
140 back an empty string, not nullptr. Every other register should
141 return a non-empty string. */
142 const char *name = gdbarch_register_name (gdbarch, regnum);
143
144 if (run_verbose() && name == nullptr)
145 debug_printf ("arch: %s, register: %d returned nullptr\n",
146 gdbarch_bfd_arch_info (gdbarch)->printable_name,
147 regnum);
9a972b54 148 SELF_CHECK (name != nullptr);
9a103324
AB
149
150 /* Every register name, that is not the empty string, should be
151 unique. If this is not the case then the user will see duplicate
152 copies of the register in e.g. 'info registers' output, but will
153 only be able to interact with one of the copies. */
154 if (*name != '\0')
155 {
156 std::string s (name);
157 name_counts[s]++;
158 if (run_verbose() && name_counts[s] > 1)
159 debug_printf ("arch: %s, register: %d (%s) is a duplicate\n",
160 gdbarch_bfd_arch_info (gdbarch)->printable_name,
161 regnum, name);
162 SELF_CHECK (name_counts[s] == 1);
163 }
9a972b54
AB
164 }
165}
166
a4f76c07
AB
167/* Test gdbarch_stack_grows_down. Stacks must either grow down or up. */
168
169static void
170check_stack_growth (struct gdbarch *gdbarch)
171{
172 /* We don't call gdbarch_stack_grows_down here, instead we're testing the
173 implementation by calling gdbarch_inner_than. GDB assumes that stacks
174 either grow down or up (see uses of gdbarch_stack_grows_down), so exactly
175 one of these needs to be true. */
176 bool stack_grows_down = gdbarch_inner_than (gdbarch, 1, 2) != 0;
177 bool stack_grows_up = gdbarch_inner_than (gdbarch, 2, 1) != 0;
178
179 SELF_CHECK (stack_grows_up != stack_grows_down);
180}
181
b77b02a5 182} // namespace selftests
b77b02a5 183
6c265988 184void _initialize_gdbarch_selftests ();
b77b02a5 185void
6c265988 186_initialize_gdbarch_selftests ()
b77b02a5 187{
1526853e
SM
188 selftests::register_test_foreach_arch ("register_to_value",
189 selftests::register_to_value_test);
9a972b54
AB
190
191 selftests::register_test_foreach_arch ("register_name",
192 selftests::register_name_test);
a4f76c07
AB
193
194 selftests::register_test_foreach_arch ("stack_growth",
195 selftests::check_stack_growth);
b77b02a5 196}