A dynamic tracer for Linux

global.c 9.2KB

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