xref: /illumos-gate/usr/src/test/os-tests/tests/saveargs/testmatch/testmatch.c (revision 9b9d39d2a32ff806d2431dbcc50968ef1e6d46b2)
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
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