A dynamic tracer for Linux

global.c 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. #define _GNU_SOURCE /* asprintf */
  2. #include <assert.h>
  3. #include <errno.h>
  4. #include <limits.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include "arch.h"
  8. #include "func.h"
  9. #include "node.h"
  10. #include "ply.h"
  11. #include "sym.h"
  12. #include "type.h"
  13. /* . */
  14. static int global_dot_type_infer(const struct func *func, struct node *n)
  15. {
  16. struct node *sou, *member;
  17. struct type *t;
  18. struct tfield *f;
  19. if (n->sym->type)
  20. return 0;
  21. sou = n->expr.args;
  22. member = sou->next;
  23. if (!sou->sym->type)
  24. return 0;
  25. t = type_base(sou->sym->type);
  26. /* TODO: add union */
  27. if (t->ttype != T_STRUCT) {
  28. _e("%#N: %N is neither struct nor union (type '%T').\n",
  29. n, sou, sou->sym->type);
  30. return -EINVAL;
  31. }
  32. tfields_foreach(f, t->sou.fields) {
  33. if (!strcmp(f->name, member->string.data)) {
  34. /* given `sou.member` where sou is a
  35. * struct/union, infer that the expression's
  36. * type is equal to member's type. */
  37. n->sym->type = f->type;
  38. return 0;
  39. }
  40. }
  41. _e("%#N: type '%T' has no member named %N.\n", n, t, member);
  42. return -EINVAL;
  43. }
  44. /* :deref */
  45. static int global_deref_ir_post(const struct func *func, struct node *n,
  46. struct prog *prog)
  47. {
  48. struct node *ptr = n->expr.args;
  49. struct irstate *dst;
  50. size_t size;
  51. dst = &n->sym->irs;
  52. if (dst->hint.dot)
  53. /* (*ptr).member, ptr points to a struct and our
  54. * parent is only interested in one member. don't load
  55. * the struct, let the dot operaton steal the address
  56. * from our argument */
  57. return 0;
  58. if (dst->loc)
  59. return 0;
  60. size = type_sizeof(type_base(ptr->sym->type)->ptr.type);
  61. /* parent might have already allocated stack for us. typically
  62. * when the value is one part of a map key or value. */
  63. if (!dst->hint.stack)
  64. irs_alloc_stack(dst, prog->ir, size);
  65. ir_emit_insn(prog->ir, MOV(0, 0), BPF_REG_1, BPF_REG_BP);
  66. ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, 0, dst->stack), BPF_REG_1, 0);
  67. ir_emit_insn(prog->ir, MOV_IMM(0, (int32_t)size), BPF_REG_2, 0);
  68. ir_emit_mov_irs(prog->ir, BPF_REG_3, &ptr->sym->irs);
  69. ir_emit_insn(prog->ir, CALL(BPF_FUNC_probe_read), 0, 0);
  70. return 0;
  71. }
  72. static int global_deref_type_infer(const struct func *func, struct node *n)
  73. {
  74. struct node *ptr = n->expr.args;
  75. struct type *t;
  76. if (n->sym->type || !ptr->sym->type)
  77. return 0;
  78. t = type_base(ptr->sym->type);
  79. if (t->ttype != T_POINTER) {
  80. _e("%#N: can't dereference %N (type '%T').\n",
  81. n, ptr, ptr->sym->type);
  82. return -EINVAL;
  83. }
  84. /* given `*p` where p is a pointer, infer that the
  85. * expression's type is equal to p's concrete type. */
  86. n->sym->type = t->ptr.type;
  87. return 0;
  88. }
  89. /* :map */
  90. static struct type *global_map_ktype(struct node *n)
  91. {
  92. struct node *map, *key;
  93. struct type *ktype;
  94. struct tfield *kfields, *f;
  95. int i, nargs = node_nargs(n);
  96. char *kname;
  97. map = n->expr.args;
  98. if (nargs == 2)
  99. return map->next->sym->type;
  100. ktype = calloc(1, sizeof(*ktype));
  101. assert(ktype);
  102. kfields = calloc(nargs, sizeof(*kfields));
  103. assert(kfields);
  104. for (key = map->next, f = kfields, i = 0; key; key = key->next, f++, i++) {
  105. asprintf(&f->name, "k%d", i);
  106. f->type = key->sym->type;
  107. }
  108. asprintf(&ktype->sou.name, ":%s_key", map->ident.name);
  109. ktype->ttype = T_STRUCT;
  110. ktype->sou.fields = kfields;
  111. type_add(ktype);
  112. return ktype;
  113. }
  114. static int global_map_type_infer(const struct func *func, struct node *n)
  115. {
  116. struct node *map = n->expr.args;
  117. if (!map->sym->type)
  118. return 0;
  119. /* TODO validate key against known type */
  120. /* given `m[key]` where m's type is known, infer that the
  121. * expression's type is equal to m's value type. */
  122. n->sym->type = map->sym->type->map.vtype;
  123. return 0;
  124. }
  125. static int global_map_static_validate(const struct func *func, struct node *n)
  126. {
  127. if (n->expr.args->ntype != N_IDENT) {
  128. _e("%#N: can't lookup a key in %N, which is not a map.\n",
  129. n, n);
  130. return -EINVAL;
  131. }
  132. return 0;
  133. }
  134. /* :assign */
  135. static int global_assign_type_infer_map(struct node *n)
  136. {
  137. struct node *map, *key;
  138. struct type *ktype;
  139. map = n->expr.args;
  140. for (key = map->next; key; key = key->next) {
  141. if (type_sizeof(key->sym->type) < 0)
  142. return 0;
  143. }
  144. map->sym->type = type_map_of(global_map_ktype(n), n->sym->type);
  145. return 0;
  146. }
  147. static int global_assign_type_infer(const struct func *func, struct node *n)
  148. {
  149. struct node *lval, *rval;
  150. if (n->sym->type)
  151. return 0;
  152. lval = n->expr.args;
  153. rval = lval->next;
  154. if (!rval->sym->type)
  155. return 0;
  156. if (!lval->sym->type) {
  157. /* given `a = b` where b's type is known but not a's,
  158. * infer that a's type must be equal to b's */
  159. lval->sym->type = rval->sym->type;
  160. /* TODO do we need assignment expressions? */
  161. n->sym->type = &t_void;
  162. if (node_is_map(lval))
  163. return global_assign_type_infer_map(lval);
  164. return 0;
  165. }
  166. if (type_compatible(lval->sym->type, rval->sym->type))
  167. return 0;
  168. _e("%#N: can't assign %N (type '%T'), to %N (type '%T').\n",
  169. n, rval, rval->sym->type, lval, lval->sym->type);
  170. return -EINVAL;
  171. }
  172. static int global_assign_static_validate(const struct func *func, struct node *n)
  173. {
  174. struct node *lval;
  175. lval = n->expr.args;
  176. if (node_is_map(lval) || (lval->ntype == N_IDENT))
  177. return 0;
  178. _e("%#N: can't assign a value to %N.\n", n, lval);
  179. return -EINVAL;
  180. }
  181. /* :binop */
  182. static int global_binop_type_infer(const struct func *func, struct node *n)
  183. {
  184. struct node *lval, *rval;
  185. if (n->sym->type)
  186. return 0;
  187. lval = n->expr.args;
  188. rval = lval->next;
  189. if (!lval->sym->type || !rval->sym->type)
  190. return 0;
  191. if (type_equal(lval->sym->type, rval->sym->type)) {
  192. n->sym->type = lval->sym->type;
  193. return 0;
  194. }
  195. /* TODO handle integer promotion */
  196. return 0;
  197. }
  198. /* :binop */
  199. static int global_quantize_type_infer(const struct func *func, struct node *n)
  200. {
  201. struct node *arg;
  202. struct type *t;
  203. arg = n->expr.args;
  204. if (n->sym->type || !arg->sym->type)
  205. return 0;
  206. t = type_base(arg->sym->type);
  207. if (t->ttype != T_SCALAR) {
  208. _e("%#N: can't quantize non-scalar value %N (type '%T').\n",
  209. n, arg, arg->sym->type);
  210. return -EINVAL;
  211. }
  212. n->sym->type = type_array_of(arg->sym->type, type_sizeof(t) * 8);
  213. return 0;
  214. }
  215. /* pid */
  216. struct type t_pid = {
  217. .ttype = T_TYPEDEF,
  218. .tdef = { .name = ":pid", .type = &t_u32 },
  219. };
  220. struct type t_pid_func = {
  221. .ttype = T_FUNC,
  222. .func = { .type = &t_pid },
  223. };
  224. /* time */
  225. struct type t_time = {
  226. .ttype = T_TYPEDEF, /* TODO: should be a T_FUNC with a static
  227. * signature */
  228. .tdef = { .name = ":time", .type = &t_s64 },
  229. };
  230. struct type t_time_func = {
  231. .ttype = T_FUNC,
  232. .func = { .type = &t_time },
  233. };
  234. struct type t_block_func = {
  235. .ttype = T_FUNC,
  236. .func = { .type = &t_void, .vargs = 1 },
  237. };
  238. struct type t_string_array = {
  239. .ttype = T_ARRAY,
  240. .array = { .type = &t_char, .len = 64 }, /* TODO: tunable */
  241. };
  242. struct type t_string = {
  243. .ttype = T_TYPEDEF,
  244. .tdef = { .name = ":string", .type = &t_string_array },
  245. };
  246. struct tfield f_dot[] = {
  247. { .type = &t_void },
  248. { .type = &t_string },
  249. { .type = NULL }
  250. };
  251. struct type t_dot_func = {
  252. .ttype = T_FUNC,
  253. .func = { .type = &t_void, .args = f_dot },
  254. };
  255. struct tfield f_2args[] = {
  256. { .type = &t_void },
  257. { .type = &t_void },
  258. { .type = NULL }
  259. };
  260. struct type t_2args_func = {
  261. .ttype = T_FUNC,
  262. .func = { .type = &t_void, .args = f_2args },
  263. };
  264. struct tfield f_1arg[] = {
  265. { .type = &t_void },
  266. { .type = NULL }
  267. };
  268. struct type t_1arg_func = {
  269. .ttype = T_FUNC,
  270. .func = { .type = &t_void, .args = f_1arg },
  271. };
  272. static const struct func global_funcs[] = {
  273. {
  274. .name = ":block",
  275. .type = &t_block_func,
  276. .static_ret = 1,
  277. },
  278. {
  279. .name = ".",
  280. .type = &t_dot_func,
  281. .type_infer = global_dot_type_infer,
  282. },
  283. {
  284. .name = ":deref",
  285. .type = &t_1arg_func,
  286. .type_infer = global_deref_type_infer,
  287. .ir_post = global_deref_ir_post,
  288. },
  289. {
  290. .name = "+",
  291. .type = &t_2args_func,
  292. .type_infer = global_binop_type_infer,
  293. },
  294. {
  295. .name = "-",
  296. .type = &t_2args_func,
  297. .type_infer = global_binop_type_infer,
  298. },
  299. {
  300. .name = "=",
  301. .type = &t_2args_func,
  302. .type_infer = global_assign_type_infer,
  303. .static_validate = global_assign_static_validate,
  304. },
  305. {
  306. .name = "{}",
  307. /* .type = t_map_func, */
  308. .type_infer = global_map_type_infer,
  309. .static_validate = global_map_static_validate,
  310. },
  311. {
  312. .name = "pid",
  313. .type = &t_pid_func,
  314. .static_ret = 1,
  315. },
  316. {
  317. .name = "time",
  318. .type = &t_time_func,
  319. .static_ret = 1,
  320. },
  321. {
  322. .name = "quantize",
  323. .type = &t_1arg_func,
  324. .type_infer = global_quantize_type_infer,
  325. },
  326. { .name = NULL }
  327. };
  328. static struct type *global_num_type(struct node *n)
  329. {
  330. if (n->num.unsignd) {
  331. if (n->num.u64 <= INT_MAX)
  332. return &t_int;
  333. else if (n->num.u64 <= UINT_MAX)
  334. return &t_uint;
  335. else if (n->num.u64 <= LONG_MAX)
  336. return &t_long;
  337. else if (n->num.u64 <= ULONG_MAX)
  338. return &t_ulong;
  339. else if (n->num.u64 <= LLONG_MAX)
  340. return &t_llong;
  341. else if (n->num.u64 <= ULLONG_MAX)
  342. return &t_ullong;
  343. } else {
  344. if (n->num.s64 >= INT_MIN && n->num.s64 <= INT_MAX)
  345. return &t_int;
  346. else if (n->num.s64 >= LONG_MIN && n->num.s64 <= LONG_MAX)
  347. return &t_long;
  348. else if (n->num.s64 >= LLONG_MIN && n->num.s64 <= LLONG_MAX)
  349. return &t_llong;
  350. }
  351. assert(0);
  352. return NULL;
  353. }
  354. static const struct func global_num_func = {
  355. .name = ":num",
  356. };
  357. static const struct func global_string_func = {
  358. .name = ":string",
  359. .type = &t_string,
  360. .static_ret = 1,
  361. };
  362. static const struct func global_ident_func = {
  363. .name = ":ident",
  364. };
  365. static const struct func *global_sym_alloc_expr(struct node *n)
  366. {
  367. const struct func *func;
  368. int err;
  369. for (func = global_funcs; func->name; func++) {
  370. if (strcmp(func->name, n->expr.func))
  371. continue;
  372. return func;
  373. }
  374. return NULL;
  375. }
  376. int global_sym_alloc(struct prog *prog, struct node *n)
  377. {
  378. const struct func *func;
  379. struct symtab *st = prog->locals;
  380. int err;
  381. switch (n->ntype) {
  382. case N_EXPR:
  383. func = global_sym_alloc_expr(n);
  384. break;
  385. case N_IDENT:
  386. st = prog->globals;
  387. func = &global_ident_func;
  388. break;
  389. case N_NUM:
  390. func = &global_num_func;
  391. break;
  392. case N_STRING:
  393. func = &global_string_func;
  394. break;
  395. }
  396. if (!func)
  397. return -ENOENT;
  398. err = func_static_validate(func, n);
  399. if (err)
  400. return err;
  401. n->sym = sym_alloc(st, n, func);
  402. if (n->ntype == N_NUM)
  403. n->sym->type = global_num_type(n);
  404. else if (func->static_ret)
  405. n->sym->type = func_return_type(func);
  406. return 0;
  407. }
  408. int global_probe(struct prog *prog)
  409. {
  410. return 0;
  411. }
  412. struct provider global = {
  413. .name = ":",
  414. .sym_alloc = global_sym_alloc,
  415. .probe = global_probe,
  416. };
  417. __attribute__((constructor))
  418. static void global_init(void)
  419. {
  420. provider_register(&global);
  421. }