runtime/kp_obj.c - ktap

Global variables defined

Functions defined

Macros defined

Source code

  1. /*
  2. * kp_obj.c - ktap object generic operation
  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. * Adapted from luajit and lua interpreter.
  9. * Copyright (C) 2005-2014 Mike Pall.
  10. * Copyright (C) 1994-2008 Lua.org, PUC-Rio.
  11. *
  12. * ktap is free software; you can redistribute it and/or modify it
  13. * under the terms and conditions of the GNU General Public License,
  14. * version 2, as published by the Free Software Foundation.
  15. *
  16. * ktap is distributed in the hope it will be useful, but WITHOUT
  17. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  18. * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  19. * more details.
  20. *
  21. * You should have received a copy of the GNU General Public License along with
  22. * this program; if not, write to the Free Software Foundation, Inc.,
  23. * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  24. */

  25. #include <linux/stacktrace.h>
  26. #include <linux/module.h>
  27. #include <linux/kallsyms.h>
  28. #include <linux/slab.h>
  29. #include "../include/ktap_types.h"
  30. #include "../include/ktap_ffi.h"
  31. #include "kp_obj.h"
  32. #include "kp_str.h"
  33. #include "kp_tab.h"
  34. #include "ktap.h"
  35. #include "kp_vm.h"
  36. #include "kp_transport.h"

  37. /* Error message strings. */
  38. const char *kp_err_allmsg =
  39. #define ERRDEF(name, msg)       msg "\0"
  40. #include "../include/ktap_errmsg.h"
  41. ;

  42. /* memory allocation flag */
  43. #define KTAP_ALLOC_FLAGS ((GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN) \
  44.              & ~__GFP_WAIT)

  45. /*
  46. * TODO: It's not safe to call into facilities in the kernel at-large,
  47. * so we may need to use ktap own memory pool, not kmalloc.
  48. */


  49. void *kp_malloc(ktap_state_t *ks, int size)
  50. {
  51.     void *addr;

  52.     addr = kmalloc(size, KTAP_ALLOC_FLAGS);
  53.     if (unlikely(!addr)) {
  54.         kp_error(ks, "kmalloc failed\n");
  55.     }
  56.     return addr;
  57. }

  58. void *kp_zalloc(ktap_state_t *ks, int size)
  59. {
  60.     void *addr;

  61.     addr = kzalloc(size, KTAP_ALLOC_FLAGS);
  62.     if (unlikely(!addr))
  63.         kp_error(ks, "kzalloc failed\n");
  64.     return addr;
  65. }

  66. void kp_free(ktap_state_t *ks, void *addr)
  67. {
  68.     kfree(addr);
  69. }


  70. void kp_obj_dump(ktap_state_t *ks, const ktap_val_t *v)
  71. {
  72.     switch (itype(v)) {
  73.     case KTAP_TNIL:
  74.         kp_puts(ks, "NIL");
  75.         break;
  76.     case KTAP_TTRUE:
  77.         kp_printf(ks, "true");
  78.         break;
  79.     case KTAP_TFALSE:
  80.         kp_printf(ks, "false");
  81.         break;
  82.     case KTAP_TNUM:
  83.         kp_printf(ks, "NUM %ld", nvalue(v));
  84.         break;
  85.     case KTAP_TLIGHTUD:
  86.         kp_printf(ks, "LIGHTUD 0x%lx", (unsigned long)pvalue(v));
  87.         break;
  88.     case KTAP_TFUNC:
  89.         kp_printf(ks, "FUNCTION 0x%lx", (unsigned long)fvalue(v));
  90.         break;
  91.     case KTAP_TSTR:
  92.         kp_printf(ks, "STR #%s", svalue(v));
  93.         break;
  94.     case KTAP_TTAB:
  95.         kp_printf(ks, "TABLE 0x%lx", (unsigned long)hvalue(v));
  96.         break;
  97.         default:
  98.         kp_printf(ks, "GCVALUE 0x%lx", (unsigned long)gcvalue(v));
  99.         break;
  100.     }
  101. }

  102. void kp_obj_show(ktap_state_t *ks, const ktap_val_t *v)
  103. {
  104.     switch (itype(v)) {
  105.     case KTAP_TNIL:
  106.         kp_puts(ks, "nil");
  107.         break;
  108.     case KTAP_TTRUE:
  109.         kp_puts(ks, "true");
  110.         break;
  111.     case KTAP_TFALSE:
  112.         kp_puts(ks, "false");
  113.         break;
  114.     case KTAP_TNUM:
  115.         kp_printf(ks, "%ld", nvalue(v));
  116.         break;
  117.     case KTAP_TLIGHTUD:
  118.         kp_printf(ks, "lightud 0x%lx", (unsigned long)pvalue(v));
  119.         break;
  120.     case KTAP_TCFUNC:
  121.         kp_printf(ks, "cfunction 0x%lx", (unsigned long)fvalue(v));
  122.         break;
  123.     case KTAP_TFUNC:
  124.         kp_printf(ks, "function 0x%lx", (unsigned long)gcvalue(v));
  125.         break;
  126.     case KTAP_TSTR:
  127.         kp_puts(ks, svalue(v));
  128.         break;
  129.     case KTAP_TTAB:
  130.         kp_printf(ks, "table 0x%lx", (unsigned long)hvalue(v));
  131.         break;
  132. #ifdef CONFIG_KTAP_FFI
  133.     case KTAP_TCDATA:
  134.         kp_cdata_dump(ks, cdvalue(v));
  135.         break;
  136. #endif
  137.     case KTAP_TEVENTSTR:
  138.         /* check event context */
  139.         if (!ks->current_event) {
  140.             kp_error(ks,
  141.             "cannot stringify event str in invalid context\n");
  142.             return;
  143.         }

  144.         kp_transport_event_write(ks, ks->current_event);
  145.         break;
  146.     case KTAP_TKSTACK:
  147.         kp_transport_print_kstack(ks, v->val.stack.depth,
  148.                           v->val.stack.skip);
  149.         break;
  150.         default:
  151.         kp_error(ks, "print unknown value type: %d\n", itype(v));
  152.         break;
  153.     }
  154. }


  155. /*
  156. * equality of ktap values.
  157. */
  158. int kp_obj_rawequal(const ktap_val_t *t1, const ktap_val_t *t2)
  159. {
  160.     switch (itype(t1)) {
  161.     case KTAP_TNIL:
  162.     case KTAP_TTRUE:
  163.     case KTAP_TFALSE:
  164.         return 1;
  165.     case KTAP_TNUM:
  166.         return nvalue(t1) == nvalue(t2);
  167.     case KTAP_TLIGHTUD:
  168.         return pvalue(t1) == pvalue(t2);
  169.     case KTAP_TFUNC:
  170.         return fvalue(t1) == fvalue(t2);
  171.     case KTAP_TSTR:
  172.         return rawtsvalue(t1) == rawtsvalue(t2);
  173.     case KTAP_TTAB:
  174.         return hvalue(t1) == hvalue(t2);
  175.     default:
  176.         return gcvalue(t1) == gcvalue(t2);
  177.     }

  178.     return 0;
  179. }

  180. /*
  181. * ktap will not use lua's length operator for table,
  182. * also # is not for length operator any more in ktap.
  183. */
  184. int kp_obj_len(ktap_state_t *ks, const ktap_val_t *v)
  185. {
  186.     switch(itype(v)) {
  187.     case KTAP_TTAB:
  188.         return kp_tab_len(ks, hvalue(v));
  189.     case KTAP_TSTR:
  190.         return rawtsvalue(v)->len;
  191.     default:
  192.         kp_printf(ks, "cannot get length of type %d\n", v->type);
  193.         return -1;
  194.     }
  195.     return 0;
  196. }

  197. /* need to protect allgc field? */
  198. ktap_obj_t *kp_obj_new(ktap_state_t *ks, size_t size)
  199. {
  200.     ktap_obj_t *o, **list;

  201.     if (ks != G(ks)->mainthread) {
  202.         kp_error(ks, "kp_obj_new only can be called in mainthread\n");
  203.         return NULL;
  204.     }

  205.     o = kp_malloc(ks, size);
  206.     if (unlikely(!o))
  207.         return NULL;

  208.     list = &G(ks)->allgc;
  209.     gch(o)->nextgc = *list;
  210.     *list = o;

  211.     return o;
  212. }


  213. /* this function may be time consuming, move out from table set/get? */
  214. ktap_str_t *kp_obj_kstack2str(ktap_state_t *ks, uint16_t depth, uint16_t skip)
  215. {
  216.     struct stack_trace trace;
  217.     unsigned long *bt;
  218.     char *btstr, *p;
  219.     int i;

  220.     bt = kp_this_cpu_print_buffer(ks); /* use print percpu buffer */
  221.     trace.nr_entries = 0;
  222.     trace.skip = skip;
  223.     trace.max_entries = depth;
  224.     trace.entries = (unsigned long *)(bt + 1);
  225.     save_stack_trace(&trace);

  226.     /* convert backtrace to string */
  227.     p = btstr = kp_this_cpu_temp_buffer(ks);
  228.     for (i = 0; i < trace.nr_entries; i++) {
  229.         unsigned long addr = trace.entries[i];

  230.         if (addr == ULONG_MAX)
  231.             break;

  232.         p += sprint_symbol(p, addr);
  233.         *p++ = '\n';
  234.         }

  235.     return kp_str_new(ks, btstr, p - btstr);
  236. }

  237. void kp_obj_free_gclist(ktap_state_t *ks, ktap_obj_t *o)
  238. {
  239.     while (o) {
  240.         ktap_obj_t *next;

  241.         next = gch(o)->nextgc;
  242.         switch (gch(o)->gct) {
  243.         case ~KTAP_TTAB:
  244.             kp_tab_free(ks, (ktap_tab_t *)o);
  245.             break;
  246.         case ~KTAP_TUPVAL:
  247.             kp_freeupval(ks, (ktap_upval_t *)o);
  248.             break;
  249.         default:
  250.             kp_free(ks, o);
  251.         }
  252.         o = next;
  253.     }
  254. }

  255. void kp_obj_freeall(ktap_state_t *ks)
  256. {
  257.     kp_obj_free_gclist(ks, G(ks)->allgc);
  258.     G(ks)->allgc = NULL;
  259. }