userspace/ffi/ctype.c - ktap

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. #include "../../include/ktap_types.h"
  2. #include "../../include/ktap_opcodes.h"
  3. #include "../ktapc.h"
  4. #include "../cparser.h"


  5. /* for ktap vm */
  6. cp_csymbol_state csym_state;

  7. #define cs_nr (csym_state.cs_nr)
  8. #define cs_arr_size (csym_state.cs_arr_size)
  9. #define cs_arr (csym_state.cs_arr)

  10. csymbol *cp_id_to_csym(int id)
  11. {
  12.     return &cs_arr[id];
  13. }


  14. typedef struct cp_ctype_entry {
  15.     char name[MAX_TYPE_NAME_LEN];
  16.     struct cp_ctype ct;
  17. } cp_ctype_entry;

  18. #define DEFAULT_CTYPE_ARR_SIZE 100
  19. static int cte_nr;
  20. static int cte_arr_size;
  21. static cp_ctype_entry *cte_arr;


  22. /* stack to help maintain state during parsing */
  23. typedef struct cp_ctype_stack {
  24.     int size;
  25.     int top;
  26.     cp_ctype_entry *stack;
  27. } ctype_stack;


  28. static ctype_stack cts;

  29. #define ct_stack(id) (&(cts.stack[id]))
  30. #define ct_stack_ct(id) (&(cts.stack[id].ct))



  31. csymbol_id cp_ctype_reg_csymbol(csymbol *cs);
  32. csymbol_id ctype_lookup_csymbol_id(const char *name);


  33. size_t ctype_size(const struct cp_ctype *ct)
  34. {
  35.     if (ct->pointers - ct->is_array) {
  36.         return sizeof(void*) * (ct->is_array ? ct->array_size : 1);

  37.     } else if (!ct->is_defined || ct->type == VOID_TYPE) {
  38.         cp_error("can't calculate size of an undefined type");
  39.         return 0;
  40.     } else if (ct->variable_size_known) {
  41.         assert(ct->is_variable_struct && !ct->is_array);
  42.         return ct->base_size + ct->variable_increment;
  43.     } else if (ct->is_variable_array || ct->is_variable_struct) {
  44.         cp_error("internal error: calc size of variable type with "
  45.                 "unknown size");
  46.         return 0;
  47.     } else {
  48.         return ct->base_size * (ct->is_array ? ct->array_size : 1);
  49.     }
  50. }

  51. #define MAX_STACK_SIZE 100
  52. int ctype_stack_grow(int size)
  53. {
  54.     struct cp_ctype_entry *new_st;

  55.     assert(cts.size + size < MAX_STACK_SIZE);

  56.     new_st = realloc(cts.stack, (cts.size+size)*sizeof(cp_ctype_entry));
  57.     if (new_st)
  58.         cts.stack = new_st;
  59.     else
  60.         return -1;

  61.     cts.size += size;

  62.     return size;
  63. }

  64. int ctype_stack_free_space()
  65. {
  66.     return cts.size - cts.top;
  67. }

  68. int ctype_stack_top()
  69. {
  70.     return cts.top;
  71. }

  72. void ctype_stack_reset(int top)
  73. {
  74.     cts.top = top;
  75. }

  76. /* This function should be called before you would fetch
  77. * ffi_cs_id from ctype */
  78. void cp_update_csym_in_ctype(struct cp_ctype *ct)
  79. {
  80.     int i;
  81.     struct cp_ctype *nct;

  82.     assert(ct->ffi_cs_id >= 0);
  83.     /* we have to check pointer here because cparser does type lookup by name
  84.      * before parsing '*', and for pointers, ct will always be the
  85.      * original type */
  86.     if (ct->pointers) {
  87.         for (i = 0; i < cte_nr; i++) {
  88.             nct = &(cte_arr[i].ct);
  89.             if (nct->type == ct->type &&
  90.                     ct->ffi_base_cs_id == nct->ffi_base_cs_id &&
  91.                     nct->pointers == ct->pointers) {
  92.                 break;
  93.             }
  94.         }

  95.         if (i == cte_nr) {
  96.             /* pointer type not found
  97.              * create a new pointer symbol for this type */
  98.             /* associate ctype with new csymbol */
  99.             ct->ffi_cs_id = cp_symbol_build_pointer(ct);
  100.             /* register wit new pointer name */
  101.             cp_ctype_reg_type(csym_name(ct_ffi_cs(ct)), ct);
  102.         } else {
  103.             /* pointer type already registered, reinstantiate ct */
  104.             ct->ffi_cs_id = cte_arr[i].ct.ffi_cs_id;
  105.         }
  106.     }
  107. }

  108. /* push ctype to stack, create new csymbol if needed */
  109. void cp_push_ctype_with_name(struct cp_ctype *ct, const char *name, int nlen)
  110. {
  111.     if (ctype_stack_free_space() < 1)
  112.         ctype_stack_grow(4);

  113.     cp_update_csym_in_ctype(ct);
  114.     memset(ct_stack(cts.top), 0, sizeof(cp_ctype_entry));
  115.     ct_stack(cts.top)->ct = *ct;
  116.     if (name)
  117.         strncpy(ct_stack(cts.top)->name, name, nlen);
  118.     cts.top++;
  119. }

  120. void cp_push_ctype(struct cp_ctype *ct)
  121. {
  122.     cp_push_ctype_with_name(ct, NULL, 0);
  123. }

  124. void cp_set_defined(struct cp_ctype *ct)
  125. {
  126.     ct->is_defined = 1;

  127.     /* @TODO: update ctypes and cdatas that were created before the
  128.      * definition came in */
  129. }

  130. void cp_ctype_dump_stack()
  131. {
  132.     int i;
  133.     struct cp_ctype *ct;

  134.     printf("---------------------------\n");
  135.     printf("start of ctype stack (%d) dump: \n", cts.top);
  136.     for (i = 0; i < cts.top; i++) {
  137.         ct = ct_stack_ct(i);
  138.         printf("[%d] -> cp_ctype: %d, sym_type: %d, pointer: %d "
  139.             "symbol_id: %d, name: %s\n",
  140.             i, ct->type,
  141.             csym_type(ct_ffi_cs(ct)), ct->pointers, ct->ffi_cs_id,
  142.             ct_stack(i)->name);
  143.     }
  144. }

  145. int ctype_reg_table_grow()
  146. {
  147.     cp_ctype_entry *new_arr;

  148.     new_arr = realloc(cte_arr, sizeof(cp_ctype_entry)*cte_arr_size*2);
  149.     if (!new_arr)
  150.         cp_error("failed to allocate memory for ctype array\n");

  151.     cte_arr_size = cte_arr_size * 2;
  152.     return 0;
  153. }

  154. /* return index in csymbol array */
  155. csymbol_id cp_ctype_reg_csymbol(csymbol *cs)
  156. {
  157.     if (cs_nr >= cs_arr_size) {
  158.         cs_arr_size *= 2;
  159.         cs_arr = realloc(cs_arr, cs_arr_size*sizeof(csymbol));
  160.         if (!cs_arr)
  161.             cp_error("failed to extend csymbol array!\n");
  162.     }

  163.     cs_arr[cs_nr] = *cs;
  164.     cs_nr++;

  165.     return cs_nr-1;
  166. }

  167. /* start csymbol reg table */
  168. csymbol_id ctype_lookup_csymbol_id(const char *name)
  169. {
  170.     int i;
  171.     csymbol *ct;

  172.     for (i = 0; i < cs_nr; i++) {
  173.         ct = cp_id_to_csym(i);
  174.         if (!strcmp(name, ct->name))
  175.             return i;
  176.     }

  177.     return -1;
  178. }

  179. void __cp_symbol_dump_struct(csymbol *cs)
  180. {
  181.     int i;
  182.     csymbol *ncs;
  183.     csymbol_struct *stcs = csym_struct(cs);

  184.     printf("=== [%s] definition ==================\n", csym_name(cs));
  185.     for (i = 0; i < stcs->memb_nr; i++) {
  186.         printf("\t(%d) ", i);
  187.         printf("csym_id: %d, ", stcs->members[i].id);
  188.         ncs = cp_id_to_csym(stcs->members[i].id);
  189.         printf("name: %s, ffi_ctype: %d, %s\n",
  190.             stcs->members[i].name, ncs->type, csym_name(ncs));
  191.     }
  192. }

  193. void cp_symbol_dump_struct(int id)
  194. {
  195.     __cp_symbol_dump_struct(cp_id_to_csym(id));
  196. }

  197. int cp_symbol_build_record(const char *stname, int type, int start_top)
  198. {
  199.     int i, id, memb_size;
  200.     cp_ctype_entry *cte;
  201.     csymbol nst;
  202.     struct_member *st_membs;
  203.     csymbol_struct *stcs;
  204.     struct cp_ctype *ct;

  205.     if (cts.top <= start_top || !stname ||
  206.             (type != STRUCT_TYPE && type != UNION_TYPE)) {
  207.         cp_error("invalid struct/union definition.\n");
  208.     }

  209.     id = ctype_lookup_csymbol_id(stname);
  210.     if (id >= 0) {
  211.         assert(cp_id_to_csym(id)->type == FFI_STRUCT ||
  212.                 cp_id_to_csym(id)->type == FFI_UNION);
  213.         assert(csym_struct(cp_id_to_csym(id))->memb_nr == -1);
  214.     }

  215.     memb_size = cts.top - start_top;
  216.     st_membs = malloc(memb_size*sizeof(struct_member));
  217.     if (!st_membs)
  218.         cp_error("failed to allocate memory for struct members.\n");
  219.     memset(st_membs, 0, memb_size*sizeof(struct_member));

  220.     if (type == STRUCT_TYPE)
  221.         nst.type = FFI_STRUCT;
  222.     else
  223.         nst.type = FFI_UNION;
  224.     strcpy(nst.name, stname);

  225.     stcs = csym_struct(&nst);
  226.     stcs->align = 0;
  227.     stcs->memb_nr = memb_size;
  228.     stcs->members = st_membs;

  229.     for (i = 0; i < memb_size; i++) {
  230.         cte = ct_stack(i + start_top);
  231.         if (cte->name)
  232.             strcpy(st_membs[i].name, cte->name);
  233.         ct = ct_stack_ct(i + start_top);
  234.         st_membs[i].id = ct->ffi_cs_id;
  235.         if (!ct->is_array)
  236.             st_membs[i].len = -1;
  237.         else
  238.             st_membs[i].len = ct->array_size;
  239.     }

  240.     if (id < 0)
  241.         id = cp_ctype_reg_csymbol(&nst);
  242.     else
  243.         cs_arr[id] = nst;

  244.     ctype_stack_reset(start_top);

  245.     return id;
  246. }

  247. int cp_symbol_build_fake_record(const char *stname, int type)
  248. {
  249.     int id;
  250.     csymbol nst;
  251.     csymbol_struct *stcs;

  252.     if (!stname || (type != STRUCT_TYPE && type != UNION_TYPE)) {
  253.         cp_error("invalid fake struct/union definition.\n");
  254.     }

  255.     id = ctype_lookup_csymbol_id(stname);
  256.     if (id >= 0)
  257.         return id;

  258.     if (type == STRUCT_TYPE)
  259.         nst.type = FFI_STRUCT;
  260.     else
  261.         nst.type = FFI_UNION;
  262.     strcpy(nst.name, stname);

  263.     stcs = csym_struct(&nst);
  264.     stcs->align = 0;
  265.     stcs->memb_nr = -1;
  266.     stcs->members = NULL;

  267.     id = cp_ctype_reg_csymbol(&nst);

  268.     return id;
  269. }


  270. /* build pointer symbol from given csymbol */
  271. int cp_symbol_build_pointer(struct cp_ctype *ct)
  272. {
  273.     int id, ret;
  274.     csymbol ncspt;
  275.     csymbol *ref_cs = ct_ffi_cs(ct);

  276.     /* TODO: Check correctness of multi-level pointer 24.11.2013(unihorn) */
  277.     memset(&ncspt, 0, sizeof(csymbol));
  278.     ncspt.type = FFI_PTR;
  279.     ret = sprintf(ncspt.name, "%s *", csym_name(ref_cs));
  280.     assert(ret < MAX_TYPE_NAME_LEN);

  281.     csym_set_ptr_deref_id(&ncspt, ct->ffi_cs_id);
  282.     id = cp_ctype_reg_csymbol(&ncspt);

  283.     return id;
  284. }

  285. void __cp_symbol_dump_func(csymbol *cs)
  286. {
  287.     int i;
  288.     csymbol *ncs;
  289.     csymbol_func *fcs = csym_func(cs);

  290.     printf("=== [%s] function definition =============\n", csym_name(cs));
  291.     ncs = cp_csymf_ret(fcs);
  292.     printf("address: %p\n", fcs->addr);
  293.     printf("return type: \n");
  294.     printf("\tcsym_id: %d, ffi_ctype: %d, %s\n",
  295.             fcs->ret_id, ncs->type, csym_name(ncs));
  296.     printf("args type (%d): \n", fcs->arg_nr);
  297.     for (i = 0; i < csymf_arg_nr(fcs); i++) {
  298.         printf("\t (%d) ", i);
  299.         printf("csym_id: %d, ", fcs->arg_ids[i]);
  300.         ncs = cp_csymf_arg(fcs, i);
  301.         printf("ffi_ctype: %d, %s\n", ncs->type, csym_name(ncs));
  302.     }
  303. }

  304. void cp_symbol_dump_func(int id)
  305. {
  306.     __cp_symbol_dump_func(cp_id_to_csym(id));
  307. }

  308. int cp_symbol_build_func(struct cp_ctype *type, const char *fname, int fn_size)
  309. {
  310.     int i = 1, arg_nr, id;
  311.     int *argsym_id_arr;
  312.     csymbol nfcs;
  313.     csymbol_func *fcs;

  314.     if (cts.top == 0 || fn_size < 0 || !fname) {
  315.         cp_error("invalid function definition.\n");
  316.     }

  317.     argsym_id_arr = NULL;
  318.     memset(&nfcs, 0, sizeof(csymbol));
  319.     csym_type(&nfcs) = FFI_FUNC;

  320.     strncpy(csym_name(&nfcs), fname, fn_size);

  321.     fcs = csym_func(&nfcs);
  322.     fcs->has_var_arg = type->has_var_arg;
  323.     /* Type needed for handling variable args handle */
  324.     if (fcs->has_var_arg && !ctype_lookup_type("void *"))
  325.         cp_symbol_build_pointer(ctype_lookup_type("void"));

  326.     /* Fetch start address of function  */
  327.     fcs->addr = (void *)find_kernel_symbol(csym_name(&nfcs));
  328.     if (!fcs->addr)
  329.         cp_error("wrong function address for %s\n", csym_name(&nfcs));

  330.     /* bottom of the stack is return type */
  331.     fcs->ret_id = ct_stack_ct(0)->ffi_cs_id;

  332.     /* the rest is argument type */
  333.     if (cts.top == 1) {
  334.         /* function takes no argument */
  335.         arg_nr = 0;
  336.     } else {
  337.         arg_nr = cts.top - 1;
  338.         argsym_id_arr = malloc(arg_nr * sizeof(int));
  339.         if (!argsym_id_arr)
  340.             cp_error("failed to allocate memory for function args.\n");
  341.         for (i = 0; i < arg_nr; i++) {
  342.             argsym_id_arr[i] = ct_stack_ct(i+1)->ffi_cs_id;
  343.         }
  344.     }
  345.     fcs->arg_nr = arg_nr;
  346.     fcs->arg_ids = argsym_id_arr;

  347.     id = cp_ctype_reg_csymbol(&nfcs);

  348.     /* clear stack since we have consumed all the ctypes */
  349.     ctype_stack_reset(0);

  350.     return id;
  351. }

  352. struct cp_ctype *cp_ctype_reg_type(char *name, struct cp_ctype *ct)
  353. {
  354.     if (cte_nr >= cte_arr_size)
  355.         ctype_reg_table_grow();

  356.     memset(cte_arr[cte_nr].name, 0, MAX_TYPE_NAME_LEN);
  357.     strcpy(cte_arr[cte_nr].name, name);

  358.     cte_arr[cte_nr].ct = *ct;
  359.     cte_nr++;

  360.     return &(cte_arr[cte_nr-1].ct);
  361. }

  362. #if 0
  363. /* TODO: used for size calculation */
  364. static ffi_type ffi_int_type(ktap_state *ks, int size, bool sign)
  365. {
  366.     switch(size) {
  367.     case 1:
  368.         if (!sign)
  369.             return FFI_UINT8;
  370.         else
  371.             return FFI_INT8;
  372.     case 2:
  373.         if (!sign)
  374.             return FFI_UINT16;
  375.         else
  376.             return FFI_INT16;
  377.     case 4:
  378.         if (!sign)
  379.             return FFI_UINT32;
  380.         else
  381.             return FFI_INT32;
  382.     case 8:
  383.         if (!sign)
  384.             return FFI_UINT64;
  385.         else
  386.             return FFI_INT64;
  387.     default:
  388.         kp_error(ks, "Error: Have not support int type of size %d\n", size);
  389.         return FFI_UNKNOWN;
  390.     }

  391.     /* NEVER reach here, silence compiler */
  392.     return -1;
  393. }
  394. #endif


  395. static inline void ct_set_type(struct cp_ctype *ct, int type, int is_unsigned)
  396. {
  397.     ct->type = type;
  398.     ct->is_unsigned = is_unsigned;
  399. }

  400. static void init_builtin_type(struct cp_ctype *ct, ffi_type ftype)
  401. {
  402.     csymbol cs;
  403.     int cs_id;

  404.     csym_type(&cs) = ftype;
  405.     strncpy(csym_name(&cs), ffi_type_name(ftype), CSYM_NAME_MAX_LEN);
  406.     cs_id = cp_ctype_reg_csymbol(&cs);

  407.     memset(ct, 0, sizeof(*ct));
  408.     ct->ffi_base_cs_id = ct->ffi_cs_id = cs_id;
  409.     switch (ftype) {
  410.     case FFI_VOID:        ct_set_type(ct, VOID_TYPE, 0); break;
  411.     case FFI_UINT8:        ct_set_type(ct, INT8_TYPE, 1); break;
  412.     case FFI_INT8:        ct_set_type(ct, INT8_TYPE, 0); break;
  413.     case FFI_UINT16:    ct_set_type(ct, INT16_TYPE, 1); break;
  414.     case FFI_INT16:        ct_set_type(ct, INT16_TYPE, 0); break;
  415.     case FFI_UINT32:    ct_set_type(ct, INT32_TYPE, 1); break;
  416.     case FFI_INT32:        ct_set_type(ct, INT32_TYPE, 0); break;
  417.     case FFI_UINT64:    ct_set_type(ct, INT64_TYPE, 1); break;
  418.     case FFI_INT64:        ct_set_type(ct, INT64_TYPE, 0); break;
  419.     default:        break;
  420.     }
  421.     ct->base_size = ffi_type_size(ftype);
  422.     ct->align_mask = ffi_type_align(ftype) - 1;
  423.     ct->is_defined = 1;
  424. }

  425. /*
  426. * lookup and register builtin C type on demand
  427. * You should ensure that the type with name doesn't appear in
  428. * csymbol table before calling.
  429. */
  430. struct cp_ctype *ctype_lookup_builtin_type(char *name)
  431. {
  432.     struct cp_ctype ct;

  433.     if (!strncmp(name, "void", sizeof("void"))) {
  434.         init_builtin_type(&ct, FFI_VOID);
  435.         return cp_ctype_reg_type("void", &ct);
  436.     } else if (!strncmp(name, "int8_t", sizeof("int8_t"))) {
  437.         init_builtin_type(&ct, FFI_INT8);
  438.         return cp_ctype_reg_type("int8_t", &ct);
  439.     } else if (!strncmp(name, "uint8_t", sizeof("uint8_t"))) {
  440.         init_builtin_type(&ct, FFI_UINT8);
  441.         return cp_ctype_reg_type("uint8_t", &ct);
  442.     } else if (!strncmp(name, "int16_t", sizeof("int16_t"))) {
  443.         init_builtin_type(&ct, FFI_INT16);
  444.         return cp_ctype_reg_type("int16_t", &ct);
  445.     } else if (!strncmp(name, "uint16_t", sizeof("uint16_t"))) {
  446.         init_builtin_type(&ct, FFI_UINT16);
  447.         return cp_ctype_reg_type("uint16_t", &ct);
  448.     } else if (!strncmp(name, "int32_t", sizeof("int32_t"))) {
  449.         init_builtin_type(&ct, FFI_INT32);
  450.         return cp_ctype_reg_type("int32_t", &ct);
  451.     } else if (!strncmp(name, "uint32_t", sizeof("uint32_t"))) {
  452.         init_builtin_type(&ct, FFI_UINT32);
  453.         return cp_ctype_reg_type("uint32_t", &ct);
  454.     } else if (!strncmp(name, "int64_t", sizeof("int64_t"))) {
  455.         init_builtin_type(&ct, FFI_INT64);
  456.         return cp_ctype_reg_type("int64_t", &ct);
  457.     } else if (!strncmp(name, "uint64_t", sizeof("uint64_t"))) {
  458.         init_builtin_type(&ct, FFI_UINT64);
  459.         return cp_ctype_reg_type("uint64_t", &ct);
  460.     } else {
  461.         /* no builtin type matched */
  462.         return NULL;
  463.     }
  464. }

  465. /* start ctype reg table */
  466. struct cp_ctype *ctype_lookup_type(char *name)
  467. {
  468.     int i;
  469.     struct cp_ctype *ct;

  470.     for (i = 0; i < cte_nr; i++) {
  471.         ct = &cte_arr[i].ct;
  472.         if (!strcmp(name, cte_arr[i].name))
  473.             return ct;
  474.     }

  475.     /* see if it's a builtin C type
  476.      * return NULL if still no match */
  477.     return ctype_lookup_builtin_type(name);
  478. }

  479. cp_csymbol_state *ctype_get_csym_state(void)
  480. {
  481.     return &csym_state;
  482. }

  483. #define DEFAULT_STACK_SIZE 20
  484. #define DEFAULT_SYM_ARR_SIZE 20
  485. int cp_ctype_init()
  486. {
  487.     cts.size = DEFAULT_STACK_SIZE;
  488.     cts.top = 0;
  489.     cts.stack = malloc(sizeof(cp_ctype_entry)*DEFAULT_STACK_SIZE);

  490.     cs_nr = 0;
  491.     cs_arr_size = DEFAULT_SYM_ARR_SIZE;
  492.     cs_arr = malloc(sizeof(csymbol)*DEFAULT_SYM_ARR_SIZE);
  493.     memset(cs_arr, 0, sizeof(csymbol)*DEFAULT_SYM_ARR_SIZE);

  494.     cte_nr = 0;
  495.     cte_arr_size = DEFAULT_CTYPE_ARR_SIZE;
  496.     cte_arr = malloc(sizeof(cp_ctype_entry)*DEFAULT_CTYPE_ARR_SIZE);

  497.     return 0;
  498. }

  499. int cp_ctype_free()
  500. {
  501.     int i;
  502.     csymbol *cs;

  503.     if (cts.stack)
  504.         free(cts.stack);

  505.     if (cs_arr) {
  506.         for (i = 0; i < cs_nr; i++) {
  507.             cs = cp_id_to_csym(i);
  508.             if (csym_type(cs) == FFI_FUNC) {
  509.                 if (csym_func(cs)->arg_ids)
  510.                     free(csym_func(cs)->arg_ids);
  511.             } else if (csym_type(cs) == FFI_STRUCT) {
  512.                 if (csym_struct(cs)->members)
  513.                     free(csym_struct(cs)->members);
  514.             }
  515.         }
  516.         free(cs_arr);
  517.     }

  518.     if (cte_arr) {
  519.         free(cte_arr);
  520.     }

  521.     return 0;
  522. }