A dynamic tracer for Linux

kprobe.c 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <assert.h>
  2. #include <errno.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <linux/ptrace.h>
  6. #include "arch.h"
  7. #include "func.h"
  8. #include "ir.h"
  9. #include "node.h"
  10. #include "ply.h"
  11. #include "sym.h"
  12. #include "type.h"
  13. struct kprobe {
  14. int use_ctx:1;
  15. struct irstate ctx_irs;
  16. };
  17. /* ctx */
  18. static struct type t_pt_regsp = {
  19. .ttype = T_POINTER,
  20. .ptr.type = &t_pt_regs,
  21. };
  22. static const struct func kprobe_ctx_func = {
  23. .name = "ctx",
  24. .type = &t_pt_regsp,
  25. .static_ret = 1,
  26. };
  27. /* argN */
  28. static inline int is_arg(const char *name)
  29. {
  30. return (strstr(name, "arg") == name)
  31. && (strlen(name) == 4)
  32. && (name[3] >= '0' && name[3] <= '9');
  33. }
  34. static int kprobe_arg_rewrite(const struct func *func, struct node *n,
  35. struct prog *prog)
  36. {
  37. struct node *new;
  38. const char *reg;
  39. int arg;
  40. arg = n->ident.name[3] - '0';
  41. reg = arch_register_argument(arg);
  42. if (!reg) {
  43. _e("%#N: the location of %N is unknown\n", n, n);
  44. /* TODO: add ABI mappings for specifying arguments
  45. * passed on the stack. */
  46. return -EINVAL;
  47. }
  48. /* argN => (*ctx).REG */
  49. new = node_expr(".",
  50. node_expr("*", node_ident("ctx"), NULL),
  51. node_string((char *)reg),
  52. NULL);
  53. ast_fprint(stdout, n);
  54. ast_fprint(stdout, new);
  55. node_replace(n, new);
  56. return 0;
  57. }
  58. static const struct func kprobe_arg_func = {
  59. .name = "argN",
  60. /* for now, in the future we could read dwarf symbols to
  61. * figure out the real type. */
  62. .type = &t_ulong,
  63. .static_ret = 1,
  64. .rewrite = kprobe_arg_rewrite,
  65. };
  66. /* */
  67. static int kprobe_ir_pre(struct prog *prog)
  68. {
  69. struct kprobe *kp = prog->provider_data;
  70. if (!kp->use_ctx)
  71. return 0;
  72. irs_alloc_reg(&kp->ctx_irs, prog->ir);
  73. /* kernel sets r1 to the address of the context */
  74. ir_emit_insn(prog->ir, MOV(0, 0), kp->ctx_irs.reg, BPF_REG_1);
  75. return 0;
  76. }
  77. static int kprobe_sym_alloc(struct prog *prog, struct node *n)
  78. {
  79. struct kprobe *kp = prog->provider_data;
  80. const struct func *func = NULL;
  81. int err;
  82. switch (n->ntype) {
  83. case N_EXPR:
  84. break;
  85. case N_IDENT:
  86. if (!is_arg(n->ident.name))
  87. break;
  88. func = &kprobe_arg_func;
  89. kp->use_ctx = 1;
  90. break;
  91. default:
  92. break;
  93. }
  94. if (!func)
  95. return -ENOENT;
  96. err = func_static_validate(func, n);
  97. if (err)
  98. return err;
  99. n->sym = sym_alloc(prog->locals, n, func);
  100. if (func->static_ret)
  101. n->sym->type = func_return_type(func);
  102. return 0;
  103. }
  104. static int kprobe_probe(struct prog *prog)
  105. {
  106. struct kprobe *kp;
  107. kp = calloc(1, sizeof(*kp));
  108. assert(kp);
  109. prog->provider_data = kp;
  110. return 0;
  111. }
  112. struct provider kprobe = {
  113. .name = "kprobe",
  114. .ir_pre = kprobe_ir_pre,
  115. /* .rewrite_node = kprobe_rewrite_node, */
  116. /* .resolve = kprobe_resolve, */
  117. .sym_alloc = kprobe_sym_alloc,
  118. .probe = kprobe_probe,
  119. };
  120. __attribute__((constructor))
  121. static void kprobe_init(void)
  122. {
  123. provider_register(&kprobe);
  124. }