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) != 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 }