Add unit test to gdbarch methods register_to_value and value_to_register
[external/binutils.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
26 namespace selftests {
27
28 /* A read-write regcache which doesn't write the target.  */
29
30 class regcache_test : public regcache
31 {
32 public:
33   explicit regcache_test (struct gdbarch *gdbarch)
34     : regcache (gdbarch, NULL, false)
35   {
36     set_ptid (inferior_ptid);
37
38     current_regcache.push_front (this);
39   }
40
41   void raw_write (int regnum, const gdb_byte *buf) override
42   {
43     raw_set_cached_value (regnum, buf);
44   }
45 };
46
47 /* Test gdbarch methods register_to_value and value_to_register.  */
48
49 static void
50 register_to_value_test (struct gdbarch *gdbarch)
51 {
52   const struct builtin_type *builtin = builtin_type (gdbarch);
53   struct type *types[] =
54     {
55       builtin->builtin_void,
56       builtin->builtin_char,
57       builtin->builtin_short,
58       builtin->builtin_int,
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,
85     };
86
87   current_inferior()->gdbarch = gdbarch;
88
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));
93
94   SELF_CHECK (regcache == get_current_regcache ());
95
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)
99     {
100       for (auto regnum = 0; regnum < num_regs; regnum++)
101         {
102           if (gdbarch_convert_register_p (gdbarch, regnum, type))
103             {
104               std::vector<gdb_byte> expected (TYPE_LENGTH (type), 0);
105
106               if (TYPE_CODE (type) == TYPE_CODE_FLT)
107                 {
108                   DOUBLEST d = 1.25;
109
110                   /* Generate valid float format.  */
111                   floatformat_from_doublest (floatformat_from_type (type),
112                                              &d, expected.data ());
113                 }
114               else
115                 {
116                   for (auto j = 0; j < expected.size (); j++)
117                     expected[j] = (regnum + j) % 16;
118                 }
119
120               gdbarch_value_to_register (gdbarch, frame, regnum, type,
121                                          expected.data ());
122
123               /* Allocate two bytes more for overflow check.  */
124               std::vector<gdb_byte> buf (TYPE_LENGTH (type) + 2, 0);
125               int optim, unavail, ok;
126
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);
132
133               SELF_CHECK (ok);
134               SELF_CHECK (!optim);
135               SELF_CHECK (!unavail);
136
137               SELF_CHECK (buf[TYPE_LENGTH (type)] == 'w');
138               SELF_CHECK (buf[TYPE_LENGTH (type) + 1] == 'l');
139
140               for (auto k = 0; k < TYPE_LENGTH(type); k++)
141                 SELF_CHECK (buf[k] == expected[k]);
142             }
143         }
144     }
145 }
146
147 } // namespace selftests
148 #endif /* GDB_SELF_TEST */
149
150 void
151 _initialize_gdbarch_selftests (void)
152 {
153 #if GDB_SELF_TEST
154   register_self_test_foreach_arch (selftests::register_to_value_test);
155 #endif
156 }