runtime/ktap.h - ktap

Data types defined

Functions defined

Macros defined

Source code

  1. #ifndef __KTAP_H__
  2. #define __KTAP_H__

  3. #include <linux/version.h>
  4. #include <linux/hardirq.h>
  5. #include <linux/trace_seq.h>

  6. #ifndef raw_cpu_ptr
  7. #define raw_cpu_ptr __this_cpu_ptr
  8. #endif

  9. /* for built-in library C function register */
  10. typedef struct ktap_libfunc {
  11.         const char *name; /* function name */
  12.         ktap_cfunction func; /* function pointer */
  13. } ktap_libfunc_t;

  14. long gettimeofday_ns(void); /* common helper function */
  15. int kp_lib_init_base(ktap_state_t *ks);
  16. int kp_lib_init_kdebug(ktap_state_t *ks);
  17. int kp_lib_init_timer(ktap_state_t *ks);
  18. int kp_lib_init_table(ktap_state_t *ks);
  19. int kp_lib_init_ansi(ktap_state_t *ks);
  20. int kp_lib_init_net(ktap_state_t *ks);
  21. #ifdef CONFIG_KTAP_FFI
  22. int kp_lib_init_ffi(ktap_state_t *ks);
  23. #endif

  24. void kp_exit_timers(ktap_state_t *ks);
  25. void kp_freeupval(ktap_state_t *ks, ktap_upval_t *uv);

  26. extern int (*kp_ftrace_profile_set_filter)(struct perf_event *event,
  27.                        int event_id,
  28.                        const char *filter_str);

  29. extern struct syscall_metadata **syscalls_metadata;

  30. /* get from kernel/trace/trace.h */
  31. static __always_inline int trace_get_context_bit(void)
  32. {
  33.     int bit;

  34.     if (in_interrupt()) {
  35.         if (in_nmi())
  36.             bit = 0;
  37.         else if (in_irq())
  38.             bit = 1;
  39.         else
  40.             bit = 2;
  41.     } else
  42.         bit = 3;

  43.     return bit;
  44. }

  45. static __always_inline int get_recursion_context(ktap_state_t *ks)
  46. {
  47.     int rctx = trace_get_context_bit();
  48.     int *val = raw_cpu_ptr(G(ks)->recursion_context[rctx]);

  49.     if (*val)
  50.         return -1;

  51.     *val = true;
  52.     return rctx;
  53. }

  54. static inline void put_recursion_context(ktap_state_t *ks, int rctx)
  55. {
  56.     int *val = raw_cpu_ptr(G(ks)->recursion_context[rctx]);
  57.     *val = false;
  58. }

  59. static inline void *kp_this_cpu_state(ktap_state_t *ks, int rctx)
  60. {
  61.     return this_cpu_ptr(G(ks)->percpu_state[rctx]);
  62. }

  63. static inline void *kp_this_cpu_print_buffer(ktap_state_t *ks)
  64. {
  65.     return this_cpu_ptr(G(ks)->percpu_print_buffer[trace_get_context_bit()]);
  66. }

  67. static inline void *kp_this_cpu_temp_buffer(ktap_state_t *ks)
  68. {
  69.     return this_cpu_ptr(G(ks)->percpu_temp_buffer[trace_get_context_bit()]);
  70. }

  71. #define kp_verbose_printf(ks, ...) \
  72.     if (G(ks)->parm->verbose)    \
  73.         kp_printf(ks, "[verbose] "__VA_ARGS__);

  74. /* argument operation macro */
  75. #define kp_arg(ks, idx)    ((ks)->func + (idx))
  76. #define kp_arg_nr(ks)    ((int)(ks->top - (ks->func + 1)))

  77. #define kp_arg_check(ks, idx, type)                \
  78.     do {                            \
  79.         if (unlikely(itype(kp_arg(ks, idx)) != type)) {    \
  80.             kp_error(ks, "wrong type of argument %d\n", idx);\
  81.             return -1;                \
  82.         }                        \
  83.     } while (0)

  84. #define kp_arg_checkstring(ks, idx)                \
  85.     ({                            \
  86.         ktap_val_t *o = kp_arg(ks, idx);        \
  87.         if (unlikely(!is_string(o))) {            \
  88.             kp_error(ks, "wrong type of argument %d\n", idx); \
  89.             return -1;                \
  90.         }                        \
  91.         svalue(o);                    \
  92.     })

  93. #define kp_arg_checkfunction(ks, idx)                \
  94.     ({                            \
  95.         ktap_val_t *o = kp_arg(ks, idx);        \
  96.         if (unlikely(!is_function(o))) {            \
  97.             kp_error(ks, "wrong type of argument %d\n", idx); \
  98.             return -1;                \
  99.         }                        \
  100.         clvalue(o);                    \
  101.     })

  102. #define kp_arg_checknumber(ks, idx)                \
  103.     ({                            \
  104.         ktap_val_t *o = kp_arg(ks, idx);        \
  105.         if (unlikely(!is_number(o))) {            \
  106.             kp_error(ks, "wrong type of argument %d\n", idx); \
  107.             return -1;                \
  108.         }                        \
  109.         nvalue(o);                    \
  110.     })

  111. #define kp_arg_checkoptnumber(ks, idx, def)            \
  112.     ({                            \
  113.         ktap_number n;                    \
  114.         if (idx > kp_arg_nr(ks)) {                \
  115.             n = def;                \
  116.         } else {                    \
  117.             ktap_val_t *o = kp_arg(ks, idx);    \
  118.             if (unlikely(!is_number(o))) {        \
  119.                 kp_error(ks, "wrong type of argument %d\n", \
  120.                          idx);        \
  121.                 return -1;            \
  122.             }                    \
  123.             n = nvalue(o);                \
  124.         }                        \
  125.         n;                        \
  126.     })

  127. #define kp_error(ks, args...)            \
  128.     do {                    \
  129.         kp_printf(ks, "error: "args);    \
  130.         kp_vm_try_to_exit(ks);        \
  131.         G(ks)->state = KTAP_ERROR;    \
  132.     } while(0)


  133. /* TODO: this code need to cleanup */
  134. #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 5, 0)
  135. #define SPRINT_SYMBOL    sprint_symbol_no_offset
  136. #else
  137. #define SPRINT_SYMBOL    sprint_symbol
  138. #endif

  139. extern int kp_max_loop_count;

  140. void kp_printf(ktap_state_t *ks, const char *fmt, ...);
  141. void __kp_puts(ktap_state_t *ks, const char *str);
  142. void __kp_bputs(ktap_state_t *ks, const char *str);

  143. #define kp_puts(ks, str) ({                        \
  144.     static const char *trace_printk_fmt                \
  145.         __attribute__((section("__trace_printk_fmt"))) =    \
  146.         __builtin_constant_p(str) ? str : NULL;            \
  147.                                     \
  148.     if (__builtin_constant_p(str))                    \
  149.         __kp_bputs(ks, trace_printk_fmt);        \
  150.     else                                \
  151.         __kp_puts(ks, str);        \
  152. })

  153. #define err2msg(em)     (kp_err_allmsg+(int)(em))
  154. extern const char *kp_err_allmsg;

  155. #endif /* __KTAP_H__ */