Print this page
3544 save-args matcher could be considerably more robust
3545 save-args matcher should accept saves maybe out-of-order
Reviewed by: Joshua M. Clulow <josh@sysmgr.org>


   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) != 0)   \

  28         printf("Pass: %s\n", #name);                            \
  29     else                                                        \
  30         printf("FAIL: %s\n", #name);
  31 
  32 #define TEST_GOOD_STRUCT(name, argc)                            \
  33     if (saveargs_has_args(name, SIZE_OF(name), argc, 1) != 0)   \












  34         printf("Pass: %s\n", #name);                            \
  35     else                                                        \
  36         printf("FAIL: %s\n", #name);
  37 
  38 #define TEST_BAD(name, argc)                                    \
  39     if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == 0)   \

  40         printf("Pass: %s\n", #name);                            \
  41     else                                                        \
  42         printf("FAIL: %s\n", #name);
  43 
  44 #define TEST_BAD_STRUCT(name, argc)                             \
  45     if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == 0)   \








  46         printf("Pass: %s\n", #name);                            \
  47     else                                                        \
  48         printf("FAIL: %s\n", #name);
  49 
  50 DEF_TEST(gcc_mov_align);
  51 DEF_TEST(gcc_mov_basic);


  52 DEF_TEST(gcc_mov_big_struct_ret);
  53 DEF_TEST(gcc_mov_big_struct_ret_and_spill);
  54 DEF_TEST(gcc_mov_small_struct_ret);
  55 DEF_TEST(gcc_mov_small_struct_ret_and_spill);
  56 DEF_TEST(gcc_mov_stack_spill);
  57 
  58 DEF_TEST(gcc_push_align);
  59 DEF_TEST(gcc_push_basic);


  60 DEF_TEST(gcc_push_big_struct_ret);
  61 DEF_TEST(gcc_push_big_struct_ret_and_spill);
  62 DEF_TEST(gcc_push_small_struct_ret);
  63 DEF_TEST(gcc_push_small_struct_ret_and_spill);
  64 DEF_TEST(gcc_push_stack_spill);
  65 
  66 DEF_TEST(ss_mov_align);
  67 DEF_TEST(ss_mov_basic);
  68 DEF_TEST(ss_mov_big_struct_ret);
  69 DEF_TEST(ss_mov_big_struct_ret_and_spill);
  70 DEF_TEST(ss_mov_small_struct_ret);
  71 DEF_TEST(ss_mov_small_struct_ret_and_spill);
  72 DEF_TEST(ss_mov_stack_spill);
  73 
  74 DEF_TEST(dtrace_instrumented);
  75 DEF_TEST(kmem_alloc);
  76 DEF_TEST(uts_kill);
  77 DEF_TEST(av1394_ic_bitreverse);
  78 
  79 DEF_TEST(small_struct_ret_w_float);
  80 DEF_TEST(big_struct_ret_w_float);
  81 


  82 /*
  83  * Functions which should not match
  84  *
  85  * no_fp                        -- valid save-args sequence with no saved FP
  86  * big_struct_arg_by_value      -- function with big struct passed by value
  87  * small_struct_arg_by_value    -- function with small struct passed by value
  88  */
  89 DEF_TEST(no_fp);
  90 DEF_TEST(big_struct_arg_by_value);
  91 DEF_TEST(small_struct_arg_by_value);
  92 
  93 int
  94 main(int argc, char **argv)
  95 {
  96         TEST_GOOD(kmem_alloc, 2);
  97         TEST_GOOD(uts_kill, 2);
  98         TEST_GOOD(av1394_ic_bitreverse, 1);
  99         TEST_GOOD(dtrace_instrumented, 4);
 100         TEST_GOOD_STRUCT(big_struct_ret_w_float, 1);
 101         TEST_BAD(no_fp, 5);
 102 
 103         TEST_GOOD(gcc_mov_align, 5);
 104         TEST_GOOD(gcc_push_align, 5);
 105         TEST_GOOD(ss_mov_align, 5);
 106 
 107         TEST_GOOD(gcc_mov_basic, 4);
 108         TEST_GOOD(gcc_push_basic, 4);
 109         TEST_GOOD(ss_mov_basic, 4);
 110 
 111         TEST_GOOD_STRUCT(gcc_mov_big_struct_ret, 4);
 112         TEST_GOOD_STRUCT(gcc_push_big_struct_ret, 4);



 113         TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4);
 114 
 115         TEST_GOOD_STRUCT(gcc_mov_big_struct_ret_and_spill, 8);
 116         TEST_GOOD_STRUCT(gcc_push_big_struct_ret_and_spill, 8);



 117         TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8);
 118 
 119         TEST_GOOD(gcc_mov_small_struct_ret, 4);
 120         TEST_GOOD(gcc_push_small_struct_ret, 4);
 121         TEST_GOOD(ss_mov_small_struct_ret, 4);
 122 
 123         TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8);
 124         TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8);
 125         TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8);
 126 
 127         TEST_GOOD(gcc_mov_stack_spill, 8);
 128         TEST_GOOD(gcc_push_stack_spill, 8);
 129         TEST_GOOD(ss_mov_stack_spill, 8);
 130 
 131         TEST_BAD(big_struct_arg_by_value, 2);
 132         TEST_BAD(small_struct_arg_by_value, 2);
 133 
 134         TEST_BAD(small_struct_ret_w_float, 1);
 135 


 136         return (0);
 137 }


   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 
 110 /*
 111  * Functions which should not match
 112  *
 113  * no_fp                        -- valid save-args sequence with no saved FP
 114  * big_struct_arg_by_value      -- function with big struct passed by value
 115  * small_struct_arg_by_value    -- function with small struct passed by value
 116  */
 117 DEF_TEST(no_fp);
 118 DEF_TEST(big_struct_arg_by_value);
 119 DEF_TEST(small_struct_arg_by_value);
 120 
 121 int
 122 main(int argc, char **argv)
 123 {
 124         TEST_GOOD(kmem_alloc, 2);
 125         TEST_GOOD(uts_kill, 2);
 126         TEST_GOOD(av1394_ic_bitreverse, 1);
 127         TEST_GOOD(dtrace_instrumented, 4);
 128         TEST_GOOD_GSTRUCT(big_struct_ret_w_float, 1);
 129         TEST_BAD(no_fp, 5);
 130 
 131         TEST_GOOD(gcc_mov_align, 5);
 132         TEST_GOOD(gcc_push_align, 5);
 133         TEST_GOOD(ss_mov_align, 5);
 134 
 135         TEST_GOOD(gcc_mov_basic, 4);
 136         TEST_GOOD(gcc_push_basic, 4);
 137         TEST_GOOD(ss_mov_basic, 4);
 138 
 139         TEST_GOOD(gcc_mov_noorder, 4);
 140         TEST_GOOD(gcc_push_noorder, 4);
 141 
 142         TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret, 4);
 143         TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret, 4);
 144         TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4);
 145 
 146         TEST_GOOD_GSTRUCT(gcc_mov_struct_noorder, 4);
 147         TEST_GOOD_GSTRUCT(gcc_push_struct_noorder, 4);
 148 
 149         TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret_and_spill, 8);
 150         TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret_and_spill, 8);
 151         TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8);
 152 
 153         TEST_GOOD(gcc_mov_small_struct_ret, 4);
 154         TEST_GOOD(gcc_push_small_struct_ret, 4);
 155         TEST_GOOD(ss_mov_small_struct_ret, 4);
 156 
 157         TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8);
 158         TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8);
 159         TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8);
 160 
 161         TEST_GOOD(gcc_mov_stack_spill, 8);
 162         TEST_GOOD(gcc_push_stack_spill, 8);
 163         TEST_GOOD(ss_mov_stack_spill, 8);
 164 
 165         TEST_BAD(big_struct_arg_by_value, 2);
 166         TEST_BAD(small_struct_arg_by_value, 2);
 167 
 168         TEST_BAD(small_struct_ret_w_float, 1);
 169 
 170         TEST_GOOD(interleaved_argument_saves, 4);
 171 
 172         return (0);
 173 }