A dynamic tracer for Linux

global.c 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include <errno.h>
  2. #include <string.h>
  3. #include "ply.h"
  4. /* pid */
  5. int pid_generate_ir(prog_t *prog, node_t *node)
  6. {
  7. /* TODO */
  8. return 0;
  9. }
  10. type_t t_pid_t = {
  11. .ttype = T_TYPEDEF,
  12. .t.tdef = {
  13. .name = "__ply_pid_t",
  14. .type = &t_u32,
  15. },
  16. };
  17. type_t t_pid_func = {
  18. .ttype = T_FUNC,
  19. .t.func = {
  20. .name = "pid",
  21. .type = &t_pid_t,
  22. .args = NULL,
  23. .generate_ir = pid_generate_ir,
  24. },
  25. };
  26. type_t *ts_pid[] = { &t_pid_t, &t_pid_func, NULL };
  27. /* quantize */
  28. int quantize_generate_ir(prog_t *prog, node_t *node)
  29. {
  30. /* TODO */
  31. return 0;
  32. }
  33. type_t t_u64_64 = {
  34. .ttype = T_ARRAY,
  35. .t.array = {
  36. .type = &t_u64,
  37. .len = 64,
  38. },
  39. };
  40. type_t t_quantize_t = {
  41. .ttype = T_TYPEDEF,
  42. .t.tdef = {
  43. .name = "__ply_quantize_t",
  44. .type = &t_u64_64,
  45. },
  46. };
  47. field_t f_quantize_args[] = {
  48. { .type = &t_s64 },
  49. { .type = NULL }
  50. };
  51. type_t t_quantize_func = {
  52. .ttype = T_FUNC,
  53. .t.func = {
  54. .name = "quantize",
  55. .type = &t_quantize_t,
  56. .args = f_quantize_args,
  57. .generate_ir = quantize_generate_ir,
  58. },
  59. };
  60. type_t *ts_quantize[] = { &t_u64_64, &t_quantize_t, &t_quantize_func, NULL };
  61. /* time */
  62. int time_generate_ir(prog_t *prog, node_t *node)
  63. {
  64. ir_emit_call(prog->ir, BPF_FUNC_ktime_get_ns);
  65. irs_alloc_reg(&node->irs, prog->ir);
  66. ir_emit_insn(prog->ir, MOV(0, 0), node->irs.reg, BPF_REG_0);
  67. return 0;
  68. }
  69. type_t t_time_t = {
  70. .ttype = T_TYPEDEF,
  71. .t.tdef = {
  72. .name = "__ply_time_t",
  73. .type = &t_s64,
  74. },
  75. };
  76. type_t t_time_func = {
  77. .ttype = T_FUNC,
  78. .t.func = {
  79. .name = "time",
  80. .type = &t_time_t,
  81. .args = NULL,
  82. .generate_ir = time_generate_ir,
  83. },
  84. };
  85. type_t *ts_time[] = { &t_time_t, &t_time_func, NULL };
  86. int global_resolve(prog_t *prog, node_t *n)
  87. {
  88. type_t **ts = NULL;
  89. type_t *t;
  90. int err;
  91. if (!strcmp(n->ident, "pid")) {
  92. ts = ts_pid;
  93. t = &t_pid_func;
  94. } else if (!strcmp(n->ident, "quantize")) {
  95. ts = ts_quantize;
  96. t = &t_quantize_func;
  97. } else if (!strcmp(n->ident, "time")) {
  98. ts = ts_time;
  99. t = &t_time_func;
  100. } else {
  101. return -ENOENT;
  102. }
  103. if (ts) {
  104. err = type_add_list(ts);
  105. if (err)
  106. return err;
  107. }
  108. n->type = t;
  109. return sym_add(prog->locals, n->ident, t, &n->sym);
  110. }
  111. int global_probe(prog_t *prog)
  112. {
  113. return 0;
  114. }
  115. provider_t global = {
  116. .name = ":",
  117. .resolve = global_resolve,
  118. .probe = global_probe,
  119. };
  120. __attribute__((constructor))
  121. static void global_init(void)
  122. {
  123. provider_register(&global);
  124. }