A dynamic tracer for Linux

kprobe.c 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include <assert.h>
  2. #include <errno.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <linux/ptrace.h>
  6. #include "ply.h"
  7. struct kprobe {
  8. };
  9. /* static int kprobe_ir_prologue(prog_t *prog) */
  10. /* { */
  11. /* sym_t *ctx = sym_get(prog->locals, "ctx"); */
  12. /* if (!ctx) */
  13. /* return 0; */
  14. /* irs_alloc_reg(&ctx->irs, prog->ir); */
  15. /* /\* kernel sets r1 to the address of the context *\/ */
  16. /* ir_emit_insn(prog->ir, MOV(0, 0), ctx->irs.reg, BPF_REG_1); */
  17. /* return 0; */
  18. /* } */
  19. /* static inline int is_arg(const char *name) */
  20. /* { */
  21. /* return (strstr(name, "arg") == name) */
  22. /* && (strlen(name) == 4) */
  23. /* && (name[3] >= '0' && name[3] <= '9'); */
  24. /* } */
  25. /* static int kprobe_rewrite_arg(prog_t *prog, node_t *n) */
  26. /* { */
  27. /* const char *reg; */
  28. /* int arg = n->ident[3] - '0'; */
  29. /* node_t *new, *ctx; */
  30. /* reg = arch_register_argument(arg); */
  31. /* if (!reg) { */
  32. /* node_print(n, stderr); */
  33. /* fputs(": the location of this argument is unknown\n", stderr); */
  34. /* /\* TODO: add ABI mappings for specifying arguments */
  35. /* * passed on the stack. *\/ */
  36. /* return -EINVAL; */
  37. /* } */
  38. /* ctx = node_ident("ctx"); */
  39. /* /\* argN => (*ctx).REG *\/ */
  40. /* new = node_vlist(node_keyword('.', 0), */
  41. /* node_vlist(node_keyword('*', 0), */
  42. /* ctx, */
  43. /* NULL), */
  44. /* node_string(reg), */
  45. /* NULL); */
  46. /* ctx->type = type_ptr_of(&t_pt_regs); */
  47. /* new->type = n->type; */
  48. /* new->list->type = &t_void; */
  49. /* new->list->next->type = &t_pt_regs; */
  50. /* new->list->next->list->type = &t_void; */
  51. /* node_replace(n, new); */
  52. /* return sym_add(prog->locals, ctx->ident, ctx->type, &ctx->sym); */
  53. /* } */
  54. /* static int kprobe_rewrite_node(prog_t *prog, node_t *n) */
  55. /* { */
  56. /* if ((n->ntype == N_IDENT) && is_arg(n->ident)) */
  57. /* return kprobe_rewrite_arg(prog, n); */
  58. /* return 0; */
  59. /* } */
  60. /* static int kprobe_resolve(prog_t *prog, node_t *n) */
  61. /* { */
  62. /* type_t *t; */
  63. /* if (is_arg(n->ident)) */
  64. /* t = &t_ulong; */
  65. /* else if (!strcmp(n->ident, "ctx")) */
  66. /* t = type_ptr_of(&t_pt_regs); */
  67. /* else */
  68. /* return -ENOENT; */
  69. /* n->type = t; */
  70. /* return sym_add(prog->locals, n->ident, t, &n->sym); */
  71. /* } */
  72. static int kprobe_sym_alloc(struct prog *prog, struct node *n)
  73. {
  74. return -ENOENT;
  75. }
  76. static int kprobe_probe(struct prog *prog)
  77. {
  78. struct kprobe *kp;
  79. kp = calloc(1, sizeof(*kp));
  80. assert(kp);
  81. prog->provider_data = kp;
  82. return 0;
  83. }
  84. struct provider kprobe = {
  85. .name = "kprobe",
  86. /* .ir_prologue = kprobe_ir_prologue, */
  87. /* .rewrite_node = kprobe_rewrite_node, */
  88. /* .resolve = kprobe_resolve, */
  89. .sym_alloc = kprobe_sym_alloc,
  90. .probe = kprobe_probe,
  91. };
  92. __attribute__((constructor))
  93. static void kprobe_init(void)
  94. {
  95. provider_register(&kprobe);
  96. }