1
2 #include <r_anal.h>
3
4 #include "minunit.h"
5
6 const RAnalHint empty_hint = {
7 .addr = UT64_MAX,
8 .ptr = 0,
9 .val = UT64_MAX,
10 .jump = UT64_MAX,
11 .fail = UT64_MAX,
12 .ret = UT64_MAX,
13 .arch = 0,
14 .opcode = NULL,
15 .syntax = NULL,
16 .esil = NULL,
17 .offset = NULL,
18 .type = 0,
19 .size = 0,
20 .bits = 0,
21 .new_bits = 0,
22 .immbase = 0,
23 .high = 0,
24 .nword = 0,
25 .stackframe = UT64_MAX,
26 };
27
hint_equals(const RAnalHint * a,const RAnalHint * b)28 bool hint_equals(const RAnalHint *a, const RAnalHint *b) {
29 #define CHECK_EQ(member) mu_assert_eq (a->member, b->member, "hint member " #member)
30 CHECK_EQ (ptr);
31 CHECK_EQ (val);
32 CHECK_EQ (jump);
33 CHECK_EQ (fail);
34 CHECK_EQ (ret);
35 CHECK_EQ (type);
36 CHECK_EQ (size);
37 CHECK_EQ (bits);
38 CHECK_EQ (new_bits);
39 CHECK_EQ (immbase);
40 CHECK_EQ (high);
41 CHECK_EQ (nword);
42 CHECK_EQ (stackframe);
43 #undef CHECK_EQ
44 #define CHECK_STREQ(member) mu_assert_nullable_streq (a->member, b->member, "hint member " #member)
45 CHECK_STREQ (arch);
46 CHECK_STREQ (opcode);
47 CHECK_STREQ (syntax);
48 CHECK_STREQ (esil);
49 CHECK_STREQ (offset);
50 #undef CHECK_STREQ
51 return true;
52 }
53
54 #define assert_hint_eq(actual, expected) do { \
55 if (actual == NULL) \
56 mu_assert ("hint", expected == &empty_hint); /* TODO: remove this part, only else should be used! */ \
57 else \
58 mu_assert ("hint", hint_equals (actual, expected)); \
59 } while (0)
60
test_r_anal_addr_hints()61 bool test_r_anal_addr_hints() {
62 RAnal *anal = r_anal_new ();
63 RAnalHint *hint = r_anal_hint_get (anal, 0x1337);
64 assert_hint_eq (hint, &empty_hint);
65 r_anal_hint_free (hint);
66
67 RAnalHint cur = empty_hint;
68 #define CHECK \
69 hint = r_anal_hint_get (anal, 0x1337); \
70 assert_hint_eq (hint, &cur); \
71 r_anal_hint_free (hint);
72 hint = r_anal_hint_get (anal, 0x1338); \
73 assert_hint_eq (hint, &empty_hint); \
74 r_anal_hint_free (hint);
75 hint = r_anal_hint_get (anal, 0x1336); \
76 assert_hint_eq (hint, &empty_hint); \
77 r_anal_hint_free (hint);
78
79 // set --------
80
81 r_anal_hint_set_syntax (anal, 0x1337, "mysyntax");
82 cur.syntax = "mysyntax";
83 CHECK
84
85 r_anal_hint_set_type (anal, 0x1337, R_ANAL_OP_TYPE_RET);
86 cur.type = R_ANAL_OP_TYPE_RET;
87 CHECK
88
89 r_anal_hint_set_jump (anal, 0x1337, 0xdeadbeef);
90 cur.jump = 0xdeadbeef;
91 CHECK
92
93 r_anal_hint_set_fail (anal, 0x1337, 0xc0ffee);
94 cur.fail = 0xc0ffee;
95 CHECK
96
97 r_anal_hint_set_nword (anal, 0x1337, 42);
98 cur.nword = 42;
99 CHECK
100
101 r_anal_hint_set_offset (anal, 0x1337, "mytypeoff");
102 cur.offset = "mytypeoff";
103 CHECK
104
105 r_anal_hint_set_immbase (anal, 0x1337, 7);
106 cur.immbase = 7;
107 CHECK
108
109 r_anal_hint_set_size (anal, 0x1337, 0x123);
110 cur.size = 0x123;
111 CHECK
112
113 r_anal_hint_set_opcode (anal, 0x1337, "myopcode");
114 cur.opcode = "myopcode";
115 CHECK
116
117 r_anal_hint_set_esil (anal, 0x1337, "/,-rf,rm");
118 cur.esil = "/,-rf,rm";
119 CHECK
120
121 r_anal_hint_set_pointer (anal, 0x1337, 0x4242);
122 cur.ptr = 0x4242;
123 CHECK
124
125 r_anal_hint_set_ret (anal, 0x1337, 0xf00d);
126 cur.ret = 0xf00d;
127 CHECK
128
129 r_anal_hint_set_high (anal, 0x1337);
130 cur.high = true;
131 CHECK
132
133 r_anal_hint_set_stackframe (anal, 0x1337, 0x4321);
134 cur.stackframe = 0x4321;
135 CHECK
136
137 r_anal_hint_set_val (anal, 0x1337, 0x112358d);
138 cur.val = 0x112358d;
139 CHECK
140
141 r_anal_hint_set_newbits (anal, 0x1337, 16);
142 cur.new_bits = 16;
143 CHECK
144
145 // unset --------
146
147 r_anal_hint_unset_syntax (anal, 0x1337);
148 cur.syntax = NULL;
149 CHECK
150
151 r_anal_hint_unset_type (anal, 0x1337);
152 cur.type = 0;
153 CHECK
154
155 r_anal_hint_unset_jump (anal, 0x1337);
156 cur.jump = UT64_MAX;
157 CHECK
158
159 r_anal_hint_unset_fail (anal, 0x1337);
160 cur.fail = UT64_MAX;
161 CHECK
162
163 r_anal_hint_unset_nword (anal, 0x1337);
164 cur.nword = 0;
165 CHECK
166
167 r_anal_hint_unset_offset (anal, 0x1337);
168 cur.offset = NULL;
169 CHECK
170
171 r_anal_hint_unset_immbase (anal, 0x1337);
172 cur.immbase = 0;
173 CHECK
174
175 r_anal_hint_unset_size (anal, 0x1337);
176 cur.size = 0;
177 CHECK
178
179 r_anal_hint_unset_opcode (anal, 0x1337);
180 cur.opcode = NULL;
181 CHECK
182
183 r_anal_hint_unset_esil (anal, 0x1337);
184 cur.esil = NULL;
185 CHECK
186
187 r_anal_hint_unset_pointer (anal, 0x1337);
188 cur.ptr = 0;
189 CHECK
190
191 r_anal_hint_unset_ret (anal, 0x1337);
192 cur.ret = UT64_MAX;
193 CHECK
194
195 r_anal_hint_unset_high (anal, 0x1337);
196 cur.high = false;
197 CHECK
198
199 r_anal_hint_unset_stackframe (anal, 0x1337);
200 cur.stackframe = UT64_MAX;
201 CHECK
202
203 r_anal_hint_unset_val (anal, 0x1337);
204 cur.val = UT64_MAX;
205 CHECK
206
207 r_anal_hint_unset_newbits (anal, 0x1337);
208 cur.new_bits = 0;
209 //CHECK
210 hint = r_anal_hint_get (anal, 0x1337);
211 assert_hint_eq (hint, &empty_hint);
212 r_anal_hint_free (hint);
213
214 r_anal_free (anal);
215 mu_end;
216 #undef CHECK
217 }
218
219 #define RANGED_TEST(name, val, resetval, assert_val) \
220 bool test_r_anal_hints_##name() { \
221 RAnal *anal = r_anal_new (); \
222 \
223 ut64 hint_addr = 0xdead; \
224 assert_val (r_anal_hint_##name##_at (anal, 0x1337, &hint_addr), resetval, "no " #name ""); \
225 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
226 \
227 r_anal_hint_##name##_at (anal, 0x1337, NULL); /* make sure this does not null-deref */ \
228 \
229 /* -- */ \
230 r_anal_hint_set_##name (anal, 0x1337, val); \
231 \
232 hint_addr = 0xdead; \
233 assert_val (r_anal_hint_##name##_at (anal, 0x1337, &hint_addr), val, #name " at addr"); \
234 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
235 hint_addr = 0xdead; \
236 assert_val (r_anal_hint_##name##_at (anal, 0x1338, &hint_addr), val, #name " after addr"); \
237 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
238 hint_addr = 0xdead; \
239 assert_val (r_anal_hint_##name##_at (anal, UT64_MAX, &hint_addr), val, #name " after addr"); \
240 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
241 hint_addr = 0xdead; \
242 assert_val (r_anal_hint_##name##_at (anal, 0x1336, &hint_addr), resetval, "no " #name " before addr"); \
243 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
244 hint_addr = 0xdead; \
245 assert_val (r_anal_hint_##name##_at (anal, 0, &hint_addr), resetval, "no " #name " before addr"); \
246 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
247 \
248 r_anal_hint_##name##_at (anal, 0x1337, NULL); /* make sure this does not null-deref */ \
249 \
250 RAnalHint cur = empty_hint; \
251 cur.name = val; \
252 RAnalHint *hint = r_anal_hint_get (anal, 0x1337); \
253 assert_hint_eq (hint, &cur); \
254 r_anal_hint_free (hint); \
255 hint = r_anal_hint_get (anal, 0x1338); \
256 assert_hint_eq (hint, &cur); \
257 r_anal_hint_free (hint); \
258 hint = r_anal_hint_get (anal, 0x1336); \
259 assert_hint_eq (hint, &empty_hint); \
260 r_anal_hint_free (hint); \
261 \
262 /* -- */ \
263 hint_addr = 0xdead; \
264 assert_val (r_anal_hint_##name##_at (anal, 0xdeadbeef, &hint_addr), val, "before reset " #name " at addr"); \
265 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
266 r_anal_hint_set_##name (anal, 0xdeadbeef, resetval); \
267 hint_addr = 0xdead; \
268 assert_val (r_anal_hint_##name##_at (anal, 0xdeadbeef, &hint_addr), resetval, "reset " #name " at addr"); \
269 mu_assert_eq (hint_addr, 0xdeadbeef, "hint addr"); \
270 hint_addr = 0xdead; \
271 assert_val (r_anal_hint_##name##_at (anal, 0xdeadbeef + 1, &hint_addr), resetval, "reset " #name " after addr"); \
272 mu_assert_eq (hint_addr, 0xdeadbeef, "hint addr"); \
273 hint_addr = 0xdead; \
274 assert_val (r_anal_hint_##name##_at (anal, UT64_MAX, &hint_addr), resetval, "reset " #name " after addr"); \
275 mu_assert_eq (hint_addr, 0xdeadbeef, "hint addr"); \
276 hint_addr = 0xdead; \
277 assert_val (r_anal_hint_##name##_at (anal, 0xdeadbeef - 1, &hint_addr), val, "" #name " before addr"); \
278 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
279 \
280 /* -- */ \
281 r_anal_hint_unset_##name (anal, 0xdeadbeef); \
282 hint_addr = 0xdead; \
283 assert_val (r_anal_hint_##name##_at (anal, 0x1337, &hint_addr), val, #name " at addr"); \
284 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
285 hint_addr = 0xdead; \
286 assert_val (r_anal_hint_##name##_at (anal, 0x1338, &hint_addr), val, #name " after addr"); \
287 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
288 hint_addr = 0xdead; \
289 assert_val (r_anal_hint_##name##_at (anal, UT64_MAX, &hint_addr), val, #name " after addr"); \
290 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
291 hint_addr = 0xdead; \
292 assert_val (r_anal_hint_##name##_at (anal, 0x1336, &hint_addr), resetval, "no " #name " before addr"); \
293 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
294 hint_addr = 0xdead; \
295 assert_val (r_anal_hint_##name##_at (anal, 0, &hint_addr), resetval, "no " #name " before addr"); \
296 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
297 hint_addr = 0xdead; \
298 assert_val (r_anal_hint_##name##_at (anal, 0xdeadbeef, &hint_addr), val, "unset reset " #name " at addr"); \
299 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
300 hint_addr = 0xdead; \
301 assert_val (r_anal_hint_##name##_at (anal, 0xdeadbeef + 1, &hint_addr), val, "unset reset " #name " after addr"); \
302 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
303 hint_addr = 0xdead; \
304 assert_val (r_anal_hint_##name##_at (anal, UT64_MAX, &hint_addr), val, "unset reset " #name " after addr"); \
305 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
306 hint_addr = 0xdead; \
307 assert_val (r_anal_hint_##name##_at (anal, 0xdeadbeef - 1, &hint_addr), val, #name " before addr"); \
308 mu_assert_eq (hint_addr, 0x1337, "hint addr"); \
309 \
310 /* -- */ \
311 r_anal_hint_unset_##name (anal, 0x1337); \
312 hint_addr = 0xdead; \
313 assert_val (r_anal_hint_##name##_at (anal, 0x1336, &hint_addr), resetval, "unset " #name ""); \
314 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
315 hint_addr = 0xdead; \
316 assert_val (r_anal_hint_##name##_at (anal, 0, &hint_addr), resetval, "unset " #name ""); \
317 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
318 hint_addr = 0xdead; \
319 assert_val (r_anal_hint_##name##_at (anal, 0x1337, &hint_addr), resetval, "unset " #name ""); \
320 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
321 hint_addr = 0xdead; \
322 assert_val (r_anal_hint_##name##_at (anal, 0x1338, &hint_addr), resetval, "unset " #name ""); \
323 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
324 hint_addr = 0xdead; \
325 assert_val (r_anal_hint_##name##_at (anal, UT64_MAX, &hint_addr), resetval, "unset " #name ""); \
326 mu_assert_eq (hint_addr, UT64_MAX, "hint addr"); \
327 hint_addr = 0xdead; \
328 \
329 r_anal_free (anal); \
330 mu_end; \
331 }
332
333 RANGED_TEST(arch, "6502", NULL, mu_assert_nullable_streq)
334 RANGED_TEST(bits, 16, 0, mu_assert_eq)
335
all_tests()336 bool all_tests() {
337 mu_run_test(test_r_anal_addr_hints);
338 mu_run_test(test_r_anal_hints_arch);
339 mu_run_test(test_r_anal_hints_bits);
340 return tests_passed != tests_run;
341 }
342
main(int argc,char ** argv)343 int main(int argc, char **argv) {
344 return all_tests();
345 }
346