A dynamic tracer for Linux

kprobe.c 2.9KB

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