A dynamic tracer for Linux

global.c 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include <errno.h>
  2. #include <string.h>
  3. #include "func.h"
  4. #include "node.h"
  5. #include "ply.h"
  6. #include "sym.h"
  7. #if 0
  8. /* pid */
  9. int pid_generate_ir(prog_t *prog, node_t *node)
  10. {
  11. /* TODO */
  12. return 0;
  13. }
  14. type_t t_pid_t = {
  15. .ttype = T_TYPEDEF,
  16. .t.tdef = {
  17. .name = "__ply_pid_t",
  18. .type = &t_u32,
  19. },
  20. };
  21. type_t t_pid_func = {
  22. .ttype = T_FUNC,
  23. .t.func = {
  24. .name = "pid",
  25. .type = &t_pid_t,
  26. .args = NULL,
  27. .generate_ir = pid_generate_ir,
  28. },
  29. };
  30. type_t *ts_pid[] = { &t_pid_t, &t_pid_func, NULL };
  31. /* quantize */
  32. int quantize_generate_ir(prog_t *prog, node_t *node)
  33. {
  34. /* TODO */
  35. return 0;
  36. }
  37. type_t t_u64_64 = {
  38. .ttype = T_ARRAY,
  39. .t.array = {
  40. .type = &t_u64,
  41. .len = 64,
  42. },
  43. };
  44. type_t t_quantize_t = {
  45. .ttype = T_TYPEDEF,
  46. .t.tdef = {
  47. .name = "__ply_quantize_t",
  48. .type = &t_u64_64,
  49. },
  50. };
  51. field_t f_quantize_args[] = {
  52. { .type = &t_s64 },
  53. { .type = NULL }
  54. };
  55. type_t t_quantize_func = {
  56. .ttype = T_FUNC,
  57. .t.func = {
  58. .name = "quantize",
  59. .type = &t_quantize_t,
  60. .args = f_quantize_args,
  61. .generate_ir = quantize_generate_ir,
  62. },
  63. };
  64. type_t *ts_quantize[] = { &t_u64_64, &t_quantize_t, &t_quantize_func, NULL };
  65. /* time */
  66. int time_generate_ir(prog_t *prog, node_t *node)
  67. {
  68. ir_emit_call(prog->ir, BPF_FUNC_ktime_get_ns);
  69. irs_alloc_reg(&node->irs, prog->ir);
  70. ir_emit_insn(prog->ir, MOV(0, 0), node->irs.reg, BPF_REG_0);
  71. return 0;
  72. }
  73. type_t t_time_t = {
  74. .ttype = T_TYPEDEF,
  75. .t.tdef = {
  76. .name = "__ply_time_t",
  77. .type = &t_s64,
  78. },
  79. };
  80. type_t t_time_func = {
  81. .ttype = T_FUNC,
  82. .t.func = {
  83. .name = "time",
  84. .type = &t_time_t,
  85. .args = NULL,
  86. .generate_ir = time_generate_ir,
  87. },
  88. };
  89. type_t *ts_time[] = { &t_time_t, &t_time_func, NULL };
  90. #endif
  91. /* int global_resolve(prog_t *prog, node_t *n) */
  92. /* { */
  93. /* type_t **ts = NULL; */
  94. /* type_t *t; */
  95. /* int err; */
  96. /* if (!strcmp(n->ident, "pid")) { */
  97. /* ts = ts_pid; */
  98. /* t = &t_pid_func; */
  99. /* } else if (!strcmp(n->ident, "quantize")) { */
  100. /* ts = ts_quantize; */
  101. /* t = &t_quantize_func; */
  102. /* } else if (!strcmp(n->ident, "time")) { */
  103. /* ts = ts_time; */
  104. /* t = &t_time_func; */
  105. /* } else { */
  106. /* return -ENOENT; */
  107. /* } */
  108. /* if (ts) { */
  109. /* err = type_add_list(ts); */
  110. /* if (err) */
  111. /* return err; */
  112. /* } */
  113. /* n->type = t; */
  114. /* return sym_add(prog->locals, n->ident, t, &n->sym); */
  115. /* } */
  116. static const struct func global_funcs[] = {
  117. /* block */
  118. { .name = "{}", },
  119. { .name = "+", },
  120. { .name = "-", },
  121. { .name = "=", },
  122. { .name = "[]", },
  123. { .name = "pid", },
  124. { .name = "time", },
  125. { .name = "quantize", },
  126. { .name = NULL }
  127. };
  128. static const struct func global_num_func = {
  129. .name = ":num",
  130. };
  131. static const struct func global_string_func = {
  132. .name = ":string",
  133. };
  134. static const struct func global_ident_func = {
  135. .name = ":ident",
  136. };
  137. int global_sym_alloc(struct prog *prog, struct node *n)
  138. {
  139. const struct func *func;
  140. switch (n->ntype) {
  141. case N_EXPR:
  142. for (func = global_funcs; func->name; func++) {
  143. if (strcmp(func->name, n->expr.func))
  144. continue;
  145. n->sym = sym_alloc(prog->locals, n, func);
  146. return 0;
  147. }
  148. return -ENOENT;
  149. case N_IDENT:
  150. n->sym = sym_alloc(prog->globals, n, &global_ident_func);
  151. return 0;
  152. case N_NUM:
  153. n->sym = sym_alloc(prog->locals, n, &global_num_func);
  154. return 0;
  155. case N_STRING:
  156. n->sym = sym_alloc(prog->locals, n, &global_string_func);
  157. return 0;
  158. }
  159. return -ENOENT;
  160. }
  161. int global_probe(struct prog *prog)
  162. {
  163. return 0;
  164. }
  165. struct provider global = {
  166. .name = ":",
  167. .sym_alloc = global_sym_alloc,
  168. .probe = global_probe,
  169. };
  170. __attribute__((constructor))
  171. static void global_init(void)
  172. {
  173. provider_register(&global);
  174. }