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