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 #define TEST_GOOD(name, argc) \ 27 if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == \ 28 SAVEARGS_TRAD_ARGS) \ 29 printf("Pass: %s\n", #name); \ 30 else \ 31 printf("FAIL: %s\n", #name); 32 33 #define TEST_GOOD_STRUCT(name, argc) \ 34 if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \ 35 SAVEARGS_STRUCT_ARGS) \ 36 printf("Pass: %s\n", #name); \ 37 else \ 38 printf("FAIL: %s\n", #name); 39 40 /* 41 * GCC deals with structures differently, so TRAD args is actually correct for 42 * this 43 */ 44 #define TEST_GOOD_GSTRUCT(name, argc) \ 45 if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \ 46 SAVEARGS_TRAD_ARGS) \ 47 printf("Pass: %s\n", #name); \ 48 else \ 49 printf("FAIL: %s\n", #name); 50 51 #define TEST_BAD(name, argc) \ 52 if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == \ 53 SAVEARGS_NO_ARGS) \ 54 printf("Pass: %s\n", #name); \ 55 else \ 56 printf("FAIL: %s\n", #name); 57 58 #define TEST_BAD_STRUCT(name, argc) \ 59 if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \ 60 SAVEARGS_NO_ARGS) \ 61 printf("Pass: %s\n", #name); \ 62 else \ 63 printf("FAIL: %s\n", #name); 64 65 #define TEST_BAD_GSTRUCT(name, argc) \ 66 if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \ 67 SAVEARGS_NO_ARGS) \ 68 printf("Pass: %s\n", #name); \ 69 else \ 70 printf("FAIL: %s\n", #name); 71 72 DEF_TEST(gcc_mov_align); 73 DEF_TEST(gcc_mov_basic); 74 DEF_TEST(gcc_mov_noorder); 75 DEF_TEST(gcc_mov_struct_noorder); 76 DEF_TEST(gcc_mov_big_struct_ret); 77 DEF_TEST(gcc_mov_big_struct_ret_and_spill); 78 DEF_TEST(gcc_mov_small_struct_ret); 79 DEF_TEST(gcc_mov_small_struct_ret_and_spill); 80 DEF_TEST(gcc_mov_stack_spill); 81 82 DEF_TEST(gcc_push_align); 83 DEF_TEST(gcc_push_basic); 84 DEF_TEST(gcc_push_noorder); 85 DEF_TEST(gcc_push_struct_noorder); 86 DEF_TEST(gcc_push_big_struct_ret); 87 DEF_TEST(gcc_push_big_struct_ret_and_spill); 88 DEF_TEST(gcc_push_small_struct_ret); 89 DEF_TEST(gcc_push_small_struct_ret_and_spill); 90 DEF_TEST(gcc_push_stack_spill); 91 92 DEF_TEST(ss_mov_align); 93 DEF_TEST(ss_mov_basic); 94 DEF_TEST(ss_mov_big_struct_ret); 95 DEF_TEST(ss_mov_big_struct_ret_and_spill); 96 DEF_TEST(ss_mov_small_struct_ret); 97 DEF_TEST(ss_mov_small_struct_ret_and_spill); 98 DEF_TEST(ss_mov_stack_spill); 99 100 DEF_TEST(dtrace_instrumented); 101 DEF_TEST(kmem_alloc); 102 DEF_TEST(uts_kill); 103 DEF_TEST(av1394_ic_bitreverse); 104 105 DEF_TEST(small_struct_ret_w_float); 106 DEF_TEST(big_struct_ret_w_float); 107 108 DEF_TEST(interleaved_argument_saves); 109 DEF_TEST(jmp_table); 110 111 /* 112 * Functions which should not match 113 * 114 * no_fp -- valid save-args sequence with no saved FP 115 * big_struct_arg_by_value -- function with big struct passed by value 116 * small_struct_arg_by_value -- function with small struct passed by value 117 */ 118 DEF_TEST(no_fp); 119 DEF_TEST(big_struct_arg_by_value); 120 DEF_TEST(small_struct_arg_by_value); 121 122 int 123 main(int argc, char **argv) 124 { 125 TEST_GOOD(kmem_alloc, 2); 126 TEST_GOOD(uts_kill, 2); 127 TEST_GOOD(av1394_ic_bitreverse, 1); 128 TEST_GOOD(dtrace_instrumented, 4); 129 TEST_GOOD_GSTRUCT(big_struct_ret_w_float, 1); 130 TEST_BAD(no_fp, 5); 131 132 TEST_GOOD(gcc_mov_align, 5); 133 TEST_GOOD(gcc_push_align, 5); 134 TEST_GOOD(ss_mov_align, 5); 135 136 TEST_GOOD(gcc_mov_basic, 4); 137 TEST_GOOD(gcc_push_basic, 4); 138 TEST_GOOD(ss_mov_basic, 4); 139 140 TEST_GOOD(gcc_mov_noorder, 4); 141 TEST_GOOD(gcc_push_noorder, 4); 142 143 TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret, 4); 144 TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret, 4); 145 TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4); 146 147 TEST_GOOD_GSTRUCT(gcc_mov_struct_noorder, 4); 148 TEST_GOOD_GSTRUCT(gcc_push_struct_noorder, 4); 149 150 TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret_and_spill, 8); 151 TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret_and_spill, 8); 152 TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8); 153 154 TEST_GOOD(gcc_mov_small_struct_ret, 4); 155 TEST_GOOD(gcc_push_small_struct_ret, 4); 156 TEST_GOOD(ss_mov_small_struct_ret, 4); 157 158 TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8); 159 TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8); 160 TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8); 161 162 TEST_GOOD(gcc_mov_stack_spill, 8); 163 TEST_GOOD(gcc_push_stack_spill, 8); 164 TEST_GOOD(ss_mov_stack_spill, 8); 165 166 TEST_BAD(big_struct_arg_by_value, 2); 167 TEST_BAD(small_struct_arg_by_value, 2); 168 169 TEST_BAD(small_struct_ret_w_float, 1); 170 171 TEST_GOOD(interleaved_argument_saves, 4); 172 TEST_BAD(jmp_table, 1); 173 174 return (0); 175 } 176