A dynamic tracer for Linux

kprobe.c 2.8KB

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