test/ffi_test/cparser_test.c - ktap

Global variables defined

Functions defined

Macros defined

Source code

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>

  5. #include "ktap_types.h"
  6. #include "ktap_opcodes.h"
  7. #include "../../userspace/ktapc.h"
  8. #include "cparser.h"

  9. void ffi_cparser_init(void);
  10. void ffi_cparser_free(void);
  11. int ffi_parse_cdef(const char *s);

  12. static cp_csymbol_state *csym_state;

  13. #define cs_nr (csym_state->cs_nr)
  14. #define cs_arr_size (csym_state->cs_arr_size)
  15. #define cs_arr (csym_state->cs_arr)


  16. #define DO_TEST(name) do {                    \
  17.     ffi_cparser_init();                    \
  18.     int ret;                        \
  19.     printf("[*] start "#name" test...  ");            \
  20.     ret = test_##name();                    \
  21.     if (ret)                        \
  22.         fprintf(stderr, "\n[!] "#name" test failed.\n");\
  23.     else                            \
  24.         printf(" passed.\n");                \
  25.     ffi_cparser_free();                    \
  26. } while (0)

  27. #define assert_csym_arr_type(cs_arr, n, t) do {            \
  28.     csymbol *ncs;                        \
  29.     ncs = &cs_arr[n];                    \
  30.     assert(ncs->type == t);                    \
  31. } while (0)

  32. #define assert_fret_type(fcs, t) do {                \
  33.     csymbol *ncs;                        \
  34.     ncs = &cs_arr[fcs->ret_id];                \
  35.     assert(ncs->type == t);                    \
  36. } while (0)

  37. #define assert_farg_type(fcs, n, t) do {            \
  38.     csymbol *ncs;                        \
  39.     ncs = &cs_arr[fcs->arg_ids[n]];                \
  40.     assert(ncs->type == t);                    \
  41. } while (0)




  42. /* mock find_kernel_symbol */
  43. unsigned long find_kernel_symbol(const char *symbol)
  44. {
  45.     return 0xdeadbeef;
  46. }

  47. int lookup_csymbol_id_by_name(char *name)
  48. {
  49.     int i;

  50.     for (i = 0; i < cs_nr; i++) {
  51.         if (!strcmp(name, cs_arr[i].name)) {
  52.             return i;
  53.         }
  54.     }

  55.     return -1;
  56. }

  57. int test_func_sched_clock()
  58. {
  59.     int idx;
  60.     csymbol *cs;
  61.     csymbol_func *fcs;

  62.     ffi_parse_cdef("unsigned long long sched_clock();");

  63.     csym_state = ctype_get_csym_state();
  64.     assert(cs_arr);

  65.     idx = lookup_csymbol_id_by_name("sched_clock");
  66.     assert(idx >= 0);
  67.     cs = &cs_arr[idx];
  68.     assert(cs->type == FFI_FUNC);

  69.     fcs = csym_func(cs);

  70.     /* check return type */
  71.     assert_fret_type(fcs, FFI_UINT64);

  72.     /* check arguments */
  73.     assert(fcs->arg_nr == 0);

  74.     return 0;
  75. }

  76. int test_func_funct_module()
  77. {
  78.     int idx;
  79.     csymbol *cs;
  80.     csymbol_func *fcs;

  81.     ffi_parse_cdef("void funct_void();");
  82.     ffi_parse_cdef("int funct_int1(unsigned char a, char b, unsigned short c, "
  83.             "short d);");
  84.     ffi_parse_cdef("long long funct_int2(unsigned int a, int b, "
  85.             "unsigned long c, long d, unsigned long long e, "
  86.             "long long f, long long g);");
  87.     ffi_parse_cdef("void *funct_pointer1(char *a);");

  88.     csym_state = ctype_get_csym_state();
  89.     assert(cs_arr);

  90.     /* check funct_void function */
  91.     idx = lookup_csymbol_id_by_name("funct_void");
  92.     assert(idx >= 0);
  93.     cs = &cs_arr[idx];
  94.     assert(cs->type == FFI_FUNC);
  95.     fcs = csym_func(cs);

  96.     /* check return type */
  97.     assert_fret_type(fcs, FFI_VOID);

  98.     /* check arguments */
  99.     assert(fcs->arg_nr == 0);



  100.     /* check funct_int1 function */
  101.     idx = lookup_csymbol_id_by_name("funct_int1");
  102.     assert(idx >= 0);
  103.     cs = &cs_arr[idx];
  104.     assert(cs);
  105.     assert(cs->type == FFI_FUNC);
  106.     fcs = csym_func(cs);

  107.     /* check return type */
  108.     assert_fret_type(fcs, FFI_INT32);

  109.     /* check arguments */
  110.     assert(fcs->arg_nr == 4);
  111.     assert_farg_type(fcs, 0, FFI_UINT8);
  112.     assert_farg_type(fcs, 1, FFI_INT8);
  113.     assert_farg_type(fcs, 2, FFI_UINT16);
  114.     assert_farg_type(fcs, 3, FFI_INT16);



  115.     /* check funct_int2 function */
  116.     idx = lookup_csymbol_id_by_name("funct_int2");
  117.     assert(idx >= 0);
  118.     cs = &cs_arr[idx];
  119.     assert(cs);
  120.     assert(cs->type == FFI_FUNC);
  121.     fcs = csym_func(cs);

  122.     /* check return type */
  123.     assert_fret_type(fcs, FFI_INT64);

  124.     /* check arguments */
  125.     assert(fcs->arg_nr == 7);
  126.     assert_farg_type(fcs, 0, FFI_UINT32);
  127.     assert_farg_type(fcs, 1, FFI_INT32);
  128.     assert_farg_type(fcs, 2, FFI_UINT64);
  129.     assert_farg_type(fcs, 3, FFI_INT64);
  130.     assert_farg_type(fcs, 4, FFI_UINT64);
  131.     assert_farg_type(fcs, 5, FFI_INT64);
  132.     assert_farg_type(fcs, 6, FFI_INT64);



  133.     /* check funct_pointer1 function */
  134.     idx = lookup_csymbol_id_by_name("funct_pointer1");
  135.     assert(idx >= 0);
  136.     cs = &cs_arr[idx];
  137.     assert(cs);
  138.     assert(cs->type == FFI_FUNC);
  139.     fcs = csym_func(cs);

  140.     /* check return type */
  141.     assert_fret_type(fcs, FFI_PTR);

  142.     /* check arguments */
  143.     assert(fcs->arg_nr == 1);
  144.     assert_farg_type(fcs, 0, FFI_PTR);
  145.     /*@TODO check pointer dereference type  18.11 2013 (houqp)*/

  146.     return 0;
  147. }

  148. int test_struct_timespec()
  149. {
  150.     int idx;
  151.     csymbol *cs;
  152.     csymbol_struct *stcs;

  153.     ffi_parse_cdef("struct timespec { long ts_sec; long ts_nsec; };");

  154.     csym_state = ctype_get_csym_state();
  155.     assert(cs_arr);

  156.     idx = lookup_csymbol_id_by_name("struct timespec");
  157.     assert(idx >= 0);
  158.     cs = &cs_arr[idx];
  159.     assert(cs);
  160.     assert(cs->type == FFI_STRUCT);

  161.     stcs = csym_struct(cs);
  162.     assert(stcs->memb_nr == 2);

  163.     return 0;
  164. }

  165. int test_func_time_to_tm()
  166. {
  167.     int idx;
  168.     csymbol *cs, *arg_cs;
  169.     csymbol_struct *stcs;
  170.     csymbol_func *fcs;

  171.     ffi_parse_cdef("typedef long time_t;");
  172.     ffi_parse_cdef("struct tm { "
  173.             "int tm_sec;"
  174.             "int tm_min;"
  175.             "int tm_hour;"
  176.             "int tm_mday;"
  177.             "int tm_mon;"
  178.             "long tm_year;"
  179.             "int tm_wday;"
  180.             "int tm_yday;"
  181.         "};");
  182.     ffi_parse_cdef("void time_to_tm(time_t totalsecs, int offset, struct tm *result);");

  183.     csym_state = ctype_get_csym_state();
  184.     assert(cs_arr);

  185.     idx = lookup_csymbol_id_by_name("struct tm");
  186.     assert(idx >= 0);
  187.     cs = cp_id_to_csym(idx);
  188.     assert(cs);
  189.     assert(cs->type == FFI_STRUCT);

  190.     stcs = csym_struct(cs);
  191.     assert(stcs->memb_nr == 8);


  192.     idx = lookup_csymbol_id_by_name("time_to_tm");
  193.     assert(idx >= 0);
  194.     cs = cp_id_to_csym(idx);
  195.     assert(cs);
  196.     assert(cs->type == FFI_FUNC);

  197.     fcs = csym_func(cs);
  198.     assert(csymf_arg_nr(fcs) == 3);
  199.     /* check first argument */
  200.     assert_farg_type(fcs, 0, FFI_INT64);

  201.     /* check second argument */
  202.     assert_farg_type(fcs, 1, FFI_INT32);
  203.     /* check third argument */
  204.     assert_farg_type(fcs, 2, FFI_PTR);
  205.     arg_cs = cp_csymf_arg(fcs, 2);
  206.     assert(!strcmp(csym_name(arg_cs), "struct tm *"));
  207.     assert(csym_ptr_deref_id(arg_cs) ==
  208.             lookup_csymbol_id_by_name("struct tm"));

  209.     return 0;
  210. }

  211. int test_pointer_symbols()
  212. {
  213.     csymbol_func *fcs_foo, *fcs_bar;

  214.     /* int pointer symbol should be resolved to the same id */
  215.     ffi_parse_cdef("void foo(int *a);");
  216.     ffi_parse_cdef("int *bar(void);");

  217.     csym_state = ctype_get_csym_state();
  218.     assert(cs_arr);

  219.     fcs_foo = csym_func(cp_id_to_csym(lookup_csymbol_id_by_name("foo")));
  220.     fcs_bar = csym_func(cp_id_to_csym(lookup_csymbol_id_by_name("bar")));

  221.     assert(csymf_arg_ids(fcs_foo)[0] == csymf_ret_id(fcs_bar));
  222.     assert(cp_csymf_arg(fcs_foo, 0) == cp_csymf_ret(fcs_bar));

  223.     return 0;
  224. }

  225. int test_var_arg_function()
  226. {
  227.     csymbol_func *fcs;

  228.     ffi_parse_cdef("int printk(char *fmt, ...);");

  229.     fcs = csym_func(cp_id_to_csym(lookup_csymbol_id_by_name("printk")));

  230.     /* var arg function needs void * type argument type checking */
  231.     assert(lookup_csymbol_id_by_name("void *") >= 0);

  232.     assert_fret_type(fcs, FFI_INT32);
  233.     assert_farg_type(fcs, 0, FFI_PTR);
  234.     assert(fcs->has_var_arg);

  235.     return 0;
  236. }

  237. int main (int argc, char *argv[])
  238. {
  239.     DO_TEST(func_sched_clock);
  240.     DO_TEST(func_funct_module);
  241.     DO_TEST(struct_timespec);
  242.     DO_TEST(func_time_to_tm);
  243.     DO_TEST(pointer_symbols);
  244.     DO_TEST(var_arg_function);

  245.     return 0;
  246. }