A dynamic tracer for Linux

ply.c 1.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "node.h"
  4. #include "sym.h"
  5. typedef struct pass {
  6. int (*run)(void *);
  7. walk_fn pre;
  8. walk_fn post;
  9. } pass_t;
  10. typedef struct provider {
  11. } provider_t;
  12. typedef struct prog {
  13. const char *probe;
  14. provider_t *prov;
  15. node_t *ast;
  16. symtab_t *st;
  17. } prog_t;
  18. symtab_t symbols = { .sym = NULL, .len = 0 };
  19. prog_t *prog_get(void)
  20. {
  21. prog_t *p;
  22. p = calloc(1, sizeof(*p));
  23. p->st = &symbols,
  24. /* reads{pid()} @ quantize(arg2) */
  25. p->ast =
  26. node_expr('@',
  27. node_cons(
  28. node_expr('m',
  29. node_cons(
  30. node_ident("reads"),
  31. node_expr('(', node_ident("pid"))
  32. )
  33. ),
  34. node_expr('(',
  35. node_cons(
  36. node_ident("quantize"),
  37. node_ident("arg2")
  38. )
  39. )
  40. )
  41. );
  42. return p;
  43. }
  44. int symtab_populate(node_t *n, void *_prog)
  45. {
  46. prog_t *prog = _prog;
  47. if ((n->ntype != N_ATOM) || (n->atom.atype != A_IDENT))
  48. return 0;
  49. /* .IDENT/->IDENT is a struct/union member, skip */
  50. if (n->up
  51. && (n->up->ntype == N_EXPR)
  52. && ((n->up->expr.etype == E_DOT) || (n->up->expr.etype == E_DEREF))
  53. && (n != n->up->expr.arg))
  54. return 0;
  55. return sym_add(prog->st, n->atom.ident, tid_none, &n->sym);
  56. }
  57. int symtab_resolve(void *_prog)
  58. {
  59. prog_t *prog = _prog;
  60. return 0;
  61. }
  62. pass_t passes[] = {
  63. { .pre = symtab_populate },
  64. { .run = symtab_resolve },
  65. { NULL, NULL, NULL }
  66. };
  67. int main(void)
  68. {
  69. node_dump_info_t info = {
  70. .indent = 2,
  71. .fp = stdout,
  72. };
  73. prog_t *p = prog_get();
  74. pass_t *pass;
  75. int err;
  76. for (pass = passes; pass->run, pass->pre || pass->post; pass++) {
  77. err = pass->run ?
  78. pass->run(p) :
  79. node_walk(p->ast, pass->pre, pass->post, p);
  80. if (err)
  81. break;
  82. }
  83. node_dump(p->ast, &info);
  84. symtab_dump(p->st, stdout);
  85. return err;
  86. }