1 #include <r_anal.h>
2 #include "minunit.h"
3 
4 #include "test_anal_block_invars.inl"
5 
ht_up_count(void * user,const ut64 k,const void * v)6 bool ht_up_count(void *user, const ut64 k, const void *v) {
7 	size_t *count = user;
8 	(*count)++;
9 	return true;
10 }
11 
ht_pp_count(void * user,const void * k,const void * v)12 bool ht_pp_count(void *user, const void *k, const void *v) {
13 	size_t *count = user;
14 	(*count)++;
15 	return true;
16 }
17 
function_check_invariants(RAnal * anal)18 static bool function_check_invariants(RAnal *anal) {
19 	if (!block_check_invariants (anal)) {
20 		return false;
21 	}
22 
23 	RListIter *it;
24 	RAnalFunction *fcn;
25 	r_list_foreach (anal->fcns, it, fcn) {
26 		mu_assert_ptreq (ht_up_find (anal->ht_addr_fun, fcn->addr, NULL), fcn, "function in addr ht");
27 		mu_assert_ptreq (ht_pp_find (anal->ht_name_fun, fcn->name, NULL), fcn, "function in name ht");
28 	}
29 
30 	size_t addr_count = 0;
31 	ht_up_foreach (anal->ht_addr_fun, ht_up_count, &addr_count);
32 	mu_assert_eq (addr_count, r_list_length (anal->fcns), "function addr ht count");
33 
34 	size_t name_count = 0;
35 	ht_pp_foreach (anal->ht_name_fun, ht_pp_count, &name_count);
36 	mu_assert_eq (name_count, r_list_length (anal->fcns), "function name ht count");
37 
38 	return true;
39 }
40 
41 #define check_invariants function_check_invariants
42 #define check_leaks block_check_leaks
43 
44 #define assert_invariants(anal) do { if (!check_invariants (anal)) { return false; } } while (0)
45 #define assert_leaks(anal) do { if (!check_leaks (anal)) { return false; } } while (0)
46 
test_r_anal_function_relocate()47 bool test_r_anal_function_relocate() {
48 	RAnal *anal = r_anal_new ();
49 	assert_invariants (anal);
50 
51 	RAnalFunction *fa = r_anal_create_function (anal, "do_something", 0x1337, 0, NULL);
52 	assert_invariants (anal);
53 	RAnalFunction *fb = r_anal_create_function (anal, "do_something_else", 0xdeadbeef, 0, NULL);
54 	assert_invariants (anal);
55 	r_anal_create_function (anal, "do_something_different", 0xc0ffee, 0, NULL);
56 	assert_invariants (anal);
57 
58 	bool success = r_anal_function_relocate (fa, fb->addr);
59 	assert_invariants (anal);
60 	mu_assert_false (success, "failed relocate");
61 	mu_assert_eq (fa->addr, 0x1337, "failed relocate addr");
62 
63 	success = r_anal_function_relocate (fa, 0x1234);
64 	assert_invariants (anal);
65 	mu_assert_true (success, "successful relocate");
66 	mu_assert_eq (fa->addr, 0x1234, "successful relocate addr");
67 
68 	assert_leaks (anal);
69 	r_anal_free (anal);
70 	mu_end;
71 }
72 
test_r_anal_function_labels()73 bool test_r_anal_function_labels() {
74 	RAnal *anal = r_anal_new ();
75 
76 	RAnalFunction *f = r_anal_create_function (anal, "do_something", 0x1337, 0, NULL);
77 
78 	bool s = r_anal_function_set_label (f, "smartfriend", 0x1339);
79 	mu_assert_true (s, "set label");
80 	s = r_anal_function_set_label (f, "stray", 0x133c);
81 	mu_assert_true (s, "set label");
82 	s = r_anal_function_set_label (f, "the", 0x1340);
83 	mu_assert_true (s, "set label");
84 	s = r_anal_function_set_label (f, "stray", 0x1234);
85 	mu_assert_false (s, "set label (existing name)");
86 	s = r_anal_function_set_label (f, "henlo", 0x133c);
87 	mu_assert_false (s, "set label (existing addr)");
88 
89 	ut64 addr = r_anal_function_get_label (f, "smartfriend");
90 	mu_assert_eq (addr, 0x1339, "get label");
91 	addr = r_anal_function_get_label (f, "stray");
92 	mu_assert_eq (addr, 0x133c, "get label");
93 	addr = r_anal_function_get_label (f, "skies");
94 	mu_assert_eq (addr, UT64_MAX, "get label (unknown)");
95 
96 	const char *name = r_anal_function_get_label_at (f, 0x1339);
97 	mu_assert_streq (name, "smartfriend", "get label at");
98 	name = r_anal_function_get_label_at (f, 0x133c);
99 	mu_assert_streq (name, "stray", "get label at");
100 	name = r_anal_function_get_label_at (f, 0x1234);
101 	mu_assert_null (name, "get label at (unknown)");
102 
103 	r_anal_function_delete_label (f, "stray");
104 	addr = r_anal_function_get_label (f, "stray");
105 	mu_assert_eq (addr, UT64_MAX, "get label (deleted)");
106 	name = r_anal_function_get_label_at (f, 0x133c);
107 	mu_assert_null (name, "get label at (deleted)");
108 	addr = r_anal_function_get_label (f, "smartfriend");
109 	mu_assert_eq (addr, 0x1339, "get label (unaffected by delete)");
110 	name = r_anal_function_get_label_at (f, 0x1339);
111 	mu_assert_streq (name, "smartfriend", "get label at (unaffected by delete)");
112 
113 	r_anal_function_delete_label_at (f, 0x1340);
114 	addr = r_anal_function_get_label (f, "the");
115 	mu_assert_eq (addr, UT64_MAX, "get label (deleted)");
116 	name = r_anal_function_get_label_at (f, 0x340);
117 	mu_assert_null (name, "get label at (deleted)");
118 	addr = r_anal_function_get_label (f, "smartfriend");
119 	mu_assert_eq (addr, 0x1339, "get label (unaffected by delete)");
120 	name = r_anal_function_get_label_at (f, 0x1339);
121 	mu_assert_streq (name, "smartfriend", "get label at (unaffected by delete)");
122 
123 	r_anal_free (anal);
124 	mu_end;
125 }
126 
all_tests()127 int all_tests() {
128 	mu_run_test (test_r_anal_function_relocate);
129 	mu_run_test (test_r_anal_function_labels);
130 	return tests_passed != tests_run;
131 }
132 
main(int argc,char ** argv)133 int main(int argc, char **argv) {
134 	return all_tests();
135 }
136