1 /* Self tests for gdbarch for GDB, the GNU debugger.
3 Copyright (C) 2017 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
23 #include "selftest-arch.h"
28 /* A read-write regcache which doesn't write the target. */
30 class regcache_test
: public regcache
33 explicit regcache_test (struct gdbarch
*gdbarch
)
34 : regcache (gdbarch
, NULL
, false)
36 set_ptid (inferior_ptid
);
38 current_regcache
.push_front (this);
41 void raw_write (int regnum
, const gdb_byte
*buf
) override
43 raw_set_cached_value (regnum
, buf
);
47 /* Test gdbarch methods register_to_value and value_to_register. */
50 register_to_value_test (struct gdbarch
*gdbarch
)
52 const struct builtin_type
*builtin
= builtin_type (gdbarch
);
53 struct type
*types
[] =
55 builtin
->builtin_void
,
56 builtin
->builtin_char
,
57 builtin
->builtin_short
,
59 builtin
->builtin_long
,
60 builtin
->builtin_signed_char
,
61 builtin
->builtin_unsigned_short
,
62 builtin
->builtin_unsigned_int
,
63 builtin
->builtin_unsigned_long
,
64 builtin
->builtin_float
,
65 builtin
->builtin_double
,
66 builtin
->builtin_long_double
,
67 builtin
->builtin_complex
,
68 builtin
->builtin_double_complex
,
69 builtin
->builtin_string
,
70 builtin
->builtin_bool
,
71 builtin
->builtin_long_long
,
72 builtin
->builtin_unsigned_long_long
,
73 builtin
->builtin_int8
,
74 builtin
->builtin_uint8
,
75 builtin
->builtin_int16
,
76 builtin
->builtin_uint16
,
77 builtin
->builtin_int32
,
78 builtin
->builtin_uint32
,
79 builtin
->builtin_int64
,
80 builtin
->builtin_uint64
,
81 builtin
->builtin_int128
,
82 builtin
->builtin_uint128
,
83 builtin
->builtin_char16
,
84 builtin
->builtin_char32
,
87 current_inferior()->gdbarch
= gdbarch
;
89 struct regcache
*regcache
= new regcache_test (gdbarch
);
90 struct frame_info
*frame
= create_test_frame (regcache
);
91 const int num_regs
= (gdbarch_num_regs (gdbarch
)
92 + gdbarch_num_pseudo_regs (gdbarch
));
94 SELF_CHECK (regcache
== get_current_regcache ());
96 /* Test gdbarch methods register_to_value and value_to_register with
97 different combinations of register numbers and types. */
98 for (const auto &type
: types
)
100 for (auto regnum
= 0; regnum
< num_regs
; regnum
++)
102 if (gdbarch_convert_register_p (gdbarch
, regnum
, type
))
104 std::vector
<gdb_byte
> expected (TYPE_LENGTH (type
), 0);
106 if (TYPE_CODE (type
) == TYPE_CODE_FLT
)
110 /* Generate valid float format. */
111 floatformat_from_doublest (floatformat_from_type (type
),
112 &d
, expected
.data ());
116 for (auto j
= 0; j
< expected
.size (); j
++)
117 expected
[j
] = (regnum
+ j
) % 16;
120 gdbarch_value_to_register (gdbarch
, frame
, regnum
, type
,
123 /* Allocate two bytes more for overflow check. */
124 std::vector
<gdb_byte
> buf (TYPE_LENGTH (type
) + 2, 0);
125 int optim
, unavail
, ok
;
127 /* Set the fingerprint in the last two bytes. */
128 buf
[TYPE_LENGTH (type
)]= 'w';
129 buf
[TYPE_LENGTH (type
) + 1]= 'l';
130 ok
= gdbarch_register_to_value (gdbarch
, frame
, regnum
, type
,
131 buf
.data (), &optim
, &unavail
);
135 SELF_CHECK (!unavail
);
137 SELF_CHECK (buf
[TYPE_LENGTH (type
)] == 'w');
138 SELF_CHECK (buf
[TYPE_LENGTH (type
) + 1] == 'l');
140 for (auto k
= 0; k
< TYPE_LENGTH(type
); k
++)
141 SELF_CHECK (buf
[k
] == expected
[k
]);
147 } // namespace selftests
148 #endif /* GDB_SELF_TEST */
151 _initialize_gdbarch_selftests (void)
154 selftests::register_test_foreach_arch ("register_to_value",
155 selftests::register_to_value_test
);