runtime/ffi/ffi_util.c - ktap

Functions defined

Source code

  1. /*
  2. * ffi_util.c - utility function for ffi module
  3. *
  4. * This file is part of ktap by Jovi Zhangwei.
  5. *
  6. * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
  7. *
  8. * ktap is free software; you can redistribute it and/or modify it
  9. * under the terms and conditions of the GNU General Public License,
  10. * version 2, as published by the Free Software Foundation.
  11. *
  12. * ktap is distributed in the hope it will be useful, but WITHOUT
  13. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  15. * more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along with
  18. * this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  20. */


  21. #include "../../include/ktap_types.h"
  22. #include "../../include/ktap_ffi.h"
  23. #include "../ktap.h"

  24. static void init_csym_struct(ktap_state_t *ks, csymbol_struct *csst)
  25. {
  26.     int nr = csymst_mb_nr(csst);
  27.     size_t size = 0;
  28.     size_t align = 1;
  29.     int i, var_len;
  30.     size_t var_size, var_align;

  31.     if (csymst_mb_nr(csst) < 0) {
  32.         kp_error(ks, "Find size of undefined struct");
  33.         return;
  34.     }

  35.     for (i = 0; i < nr; i++) {
  36.         csymbol *var_cs = csymst_mb_csym(ks, csst, i);
  37.         var_len = csymst_mb_len(csst, i);
  38.         if (var_len < 0) {
  39.             var_len = 1;
  40.         } else {
  41.             var_cs = csym_ptr_deref(ks, var_cs);
  42.         }
  43.         var_size = csym_size(ks, var_cs) * var_len;
  44.         var_align = csym_align(ks, var_cs);
  45.         size = ALIGN(size, var_align);
  46.         size += var_size;
  47.         align = align > var_align ? align : var_align;
  48.     }
  49.     size = ALIGN(size, align);
  50.     csst->size = size;
  51.     csst->align = align;
  52. }

  53. static void init_csym_union(ktap_state_t *ks, csymbol_struct *csst)
  54. {
  55.     int nr = csymst_mb_nr(csst);
  56.     size_t size = 0;
  57.     size_t align = 1;
  58.     int i, var_len;
  59.     size_t var_size, var_align;

  60.     if (csymst_mb_nr(csst) < 0) {
  61.         kp_error(ks, "Find size of undefined struct");
  62.         return;
  63.     }

  64.     for (i = 0; i < nr; i++) {
  65.         csymbol *var_cs = csymst_mb_csym(ks, csst, i);
  66.         var_len = csymst_mb_len(csst, i);
  67.         if (var_len < 0) {
  68.             var_len = 1;
  69.         } else {
  70.             var_cs = csym_ptr_deref(ks, var_cs);
  71.         }
  72.         var_size = csym_size(ks, var_cs) * var_len;
  73.         var_align = csym_align(ks, var_cs);
  74.         size = size > var_size ? size : var_size;
  75.         align = align > var_align ? align : var_align;
  76.     }
  77.     csst->size = size;
  78.     csst->align = align;
  79. }


  80. size_t csym_size(ktap_state_t *ks, csymbol *cs)
  81. {
  82.     ffi_type type = csym_type(cs);
  83.     switch(type) {
  84.     case FFI_STRUCT:
  85.         if (csym_struct(cs)->align == 0)
  86.             init_csym_struct(ks, csym_struct(cs));
  87.         return csym_struct(cs)->size;
  88.     case FFI_UNION:
  89.         if (csym_struct(cs)->align == 0)
  90.             init_csym_union(ks, csym_struct(cs));
  91.         return csym_struct(cs)->size;
  92.     default:
  93.         return ffi_type_size(type);
  94.     }
  95. }

  96. size_t csym_align(ktap_state_t *ks, csymbol *cs)
  97. {
  98.     ffi_type type = csym_type(cs);
  99.     switch(type) {
  100.     case FFI_STRUCT:
  101.         if (csym_struct(cs)->align == 0)
  102.             init_csym_struct(ks, csym_struct(cs));
  103.         return csym_struct(cs)->align;
  104.     case FFI_UNION:
  105.         if (csym_struct(cs)->align == 0)
  106.             init_csym_union(ks, csym_struct(cs));
  107.         return csym_struct(cs)->align;
  108.     default:
  109.         return ffi_type_align(type);
  110.     }
  111. }

  112. size_t csym_record_mb_offset_by_name(ktap_state_t *ks,
  113.         csymbol *cs, const char *name)
  114. {
  115.     csymbol_struct *csst = csym_struct(cs);
  116.     int nr = csymst_mb_nr(csst);
  117.     size_t off = 0, sub_off;
  118.     size_t align = 1;
  119.     int i, var_len;
  120.     size_t var_size, var_align;

  121.     if (nr < 0) {
  122.         kp_error(ks, "Find size of undefined struct");
  123.         return 0;
  124.     }

  125.     for (i = 0; i < nr; i++) {
  126.         csymbol *var_cs = csymst_mb_csym(ks, csst, i);
  127.         var_len = csymst_mb_len(csst, i);
  128.         if (var_len < 0) {
  129.             var_len = 1;
  130.         } else {
  131.             var_cs = csym_ptr_deref(ks, var_cs);
  132.         }
  133.         var_size = csym_size(ks, var_cs) * var_len;
  134.         var_align = csym_align(ks, var_cs);
  135.         off = ALIGN(off, var_align);
  136.         if (!strcmp(name, csymst_mb_name(csst, i)))
  137.             return off;
  138.         if (!strcmp("", csymst_mb_name(csst, i))) {
  139.             if (csym_type(var_cs) != FFI_STRUCT &&
  140.                     csym_type(var_cs) != FFI_UNION) {
  141.                 kp_error(ks, "Parse error: non-record type without name");
  142.                 return -1;
  143.             }
  144.             sub_off = csym_record_mb_offset_by_name(ks,
  145.                     var_cs, name);
  146.             if (sub_off >= 0)
  147.                 return off + sub_off;
  148.         }
  149.         if (csym_type(cs) == FFI_STRUCT)
  150.             off += var_size;
  151.         else
  152.             off = 0;
  153.         align = align > var_align ? align : var_align;
  154.     }
  155.     return -1;
  156. }

  157. struct_member *csymst_mb_by_name(ktap_state_t *ks,
  158.         csymbol_struct *csst, const char *name)
  159. {
  160.     int nr = csymst_mb_nr(csst);
  161.     int i;
  162.     struct_member *memb;
  163.     csymbol *cs = NULL;

  164.     if (nr < 0) {
  165.         kp_error(ks, "Find size of undefined struct");
  166.         return NULL;
  167.     }

  168.     for (i = 0; i < nr; i++) {
  169.         if (!strcmp(name, csymst_mb_name(csst, i)))
  170.             return csymst_mb(csst, i);
  171.         if (!strcmp("", csymst_mb_name(csst, i))) {
  172.             cs = csymst_mb_csym(ks, csst, i);
  173.             if (csym_type(cs) != FFI_STRUCT && csym_type(cs) != FFI_UNION) {
  174.                 kp_error(ks, "Parse error: non-record type without name");
  175.                 return NULL;
  176.             }
  177.             memb = csymst_mb_by_name(ks, csym_struct(cs), name);
  178.             if (memb != NULL)
  179.                 return memb;
  180.         }
  181.     }
  182.     return NULL;
  183. }