1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2012, Richard Lowe.
14 */
15
16 #include <stdio.h>
17 #include <sys/types.h>
18 #include <saveargs.h>
19
20 #define DEF_TEST(name) \
21 extern uint8_t name[]; \
22 extern int name##_end
23
24 #define SIZE_OF(name) ((caddr_t)&name##_end - (caddr_t)&name)
25
26 DEF_TEST(gcc_mov_align);
27 DEF_TEST(gcc_mov_basic);
28 DEF_TEST(gcc_mov_noorder);
29 DEF_TEST(gcc_mov_struct_noorder);
30 DEF_TEST(gcc_mov_big_struct_ret);
31 DEF_TEST(gcc_mov_big_struct_ret_and_spill);
32 DEF_TEST(gcc_mov_small_struct_ret);
33 DEF_TEST(gcc_mov_small_struct_ret_and_spill);
34 DEF_TEST(gcc_mov_stack_spill);
35
36 DEF_TEST(gcc_push_align);
37 DEF_TEST(gcc_push_basic);
38 DEF_TEST(gcc_push_noorder);
39 DEF_TEST(gcc_push_struct_noorder);
40 DEF_TEST(gcc_push_big_struct_ret);
41 DEF_TEST(gcc_push_big_struct_ret_and_spill);
42 DEF_TEST(gcc_push_small_struct_ret);
43 DEF_TEST(gcc_push_small_struct_ret_and_spill);
44 DEF_TEST(gcc_push_stack_spill);
45
46 DEF_TEST(ss_mov_align);
47 DEF_TEST(ss_mov_basic);
48 DEF_TEST(ss_mov_big_struct_ret);
49 DEF_TEST(ss_mov_big_struct_ret_and_spill);
50 DEF_TEST(ss_mov_small_struct_ret);
51 DEF_TEST(ss_mov_small_struct_ret_and_spill);
52 DEF_TEST(ss_mov_stack_spill);
53
54 DEF_TEST(dtrace_instrumented);
55 DEF_TEST(kmem_alloc);
56 DEF_TEST(uts_kill);
57 DEF_TEST(av1394_ic_bitreverse);
58
59 DEF_TEST(small_struct_ret_w_float);
60 DEF_TEST(big_struct_ret_w_float);
61
62 DEF_TEST(interleaved_argument_saves);
63 DEF_TEST(jmp_table);
64
65 /*
66 * Functions which should not match
67 *
68 * no_fp -- valid save-args sequence with no saved FP
69 * big_struct_arg_by_value -- function with big struct passed by value
70 * small_struct_arg_by_value -- function with small struct passed by value
71 */
72 DEF_TEST(no_fp);
73 DEF_TEST(big_struct_arg_by_value);
74 DEF_TEST(small_struct_arg_by_value);
75
76 int
main(int argc,char ** argv)77 main(int argc, char **argv)
78 {
79
80 #define TEST_GOOD(name, argc) \
81 do { \
82 if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == \
83 SAVEARGS_TRAD_ARGS) { \
84 printf("Pass: %s\n", #name); \
85 } else { \
86 res = 1; \
87 printf("FAIL: %s\n", #name); \
88 } \
89 } while (0)
90
91 #define TEST_GOOD_STRUCT(name, argc) \
92 do { \
93 if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \
94 SAVEARGS_STRUCT_ARGS) { \
95 printf("Pass: %s\n", #name); \
96 } else { \
97 res = 1; \
98 printf("FAIL: %s\n", #name); \
99 } \
100 } while (0)
101
102 /*
103 * GCC deals with structures differently, so TRAD args is actually correct for
104 * this
105 */
106 #define TEST_GOOD_GSTRUCT(name, argc) \
107 do { \
108 if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \
109 SAVEARGS_TRAD_ARGS) { \
110 printf("Pass: %s\n", #name); \
111 } else { \
112 res = 1; \
113 printf("FAIL: %s\n", #name); \
114 } \
115 } while (0)
116
117 #define TEST_BAD(name, argc) \
118 do { \
119 if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == \
120 SAVEARGS_NO_ARGS) { \
121 printf("Pass: %s\n", #name); \
122 } else { \
123 res = 1; \
124 printf("FAIL: %s\n", #name); \
125 } \
126 } while (0)
127
128 #define TEST_BAD_STRUCT(name, argc) \
129 do { \
130 if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \
131 SAVEARGS_NO_ARGS) { \
132 printf("Pass: %s\n", #name); \
133 } else { \
134 res = 1; \
135 printf("FAIL: %s\n", #name); \
136 } \
137 } while (0)
138
139 #define TEST_BAD_GSTRUCT(name, argc) \
140 do { \
141 if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \
142 SAVEARGS_NO_ARGS) { \
143 printf("Pass: %s\n", #name); \
144 } else { \
145 res = 1; \
146 printf("FAIL: %s\n", #name); \
147 } \
148 } while (0)
149
150 int res = 0;
151
152 TEST_GOOD(kmem_alloc, 2);
153 TEST_GOOD(uts_kill, 2);
154 TEST_GOOD(av1394_ic_bitreverse, 1);
155 TEST_GOOD(dtrace_instrumented, 4);
156 TEST_GOOD_GSTRUCT(big_struct_ret_w_float, 1);
157 TEST_BAD(no_fp, 5);
158
159 TEST_GOOD(gcc_mov_align, 5);
160 TEST_GOOD(gcc_push_align, 5);
161 TEST_GOOD(ss_mov_align, 5);
162
163 TEST_GOOD(gcc_mov_basic, 4);
164 TEST_GOOD(gcc_push_basic, 4);
165 TEST_GOOD(ss_mov_basic, 4);
166
167 TEST_GOOD(gcc_mov_noorder, 4);
168 TEST_GOOD(gcc_push_noorder, 4);
169
170 TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret, 4);
171 TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret, 4);
172 TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4);
173
174 TEST_GOOD_GSTRUCT(gcc_mov_struct_noorder, 4);
175 TEST_GOOD_GSTRUCT(gcc_push_struct_noorder, 4);
176
177 TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret_and_spill, 8);
178 TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret_and_spill, 8);
179 TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8);
180
181 TEST_GOOD(gcc_mov_small_struct_ret, 4);
182 TEST_GOOD(gcc_push_small_struct_ret, 4);
183 TEST_GOOD(ss_mov_small_struct_ret, 4);
184
185 TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8);
186 TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8);
187 TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8);
188
189 TEST_GOOD(gcc_mov_stack_spill, 8);
190 TEST_GOOD(gcc_push_stack_spill, 8);
191 TEST_GOOD(ss_mov_stack_spill, 8);
192
193 TEST_BAD(big_struct_arg_by_value, 2);
194
195 TEST_BAD_STRUCT(small_struct_ret_w_float, 1);
196
197 TEST_GOOD(interleaved_argument_saves, 4);
198 TEST_BAD(jmp_table, 1);
199
200 return (res);
201 }
202