A dynamic tracer for Linux

type.c 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "type.h"
  5. const type_t builtin_types[] = {
  6. { .type = T_NONE },
  7. #define SCALAR(_tid, _, _type) [_tid] = { \
  8. .tid = _tid, \
  9. .size = sizeof(_type), \
  10. .type = T_SCALAR, \
  11. .t = { \
  12. .scalar = { \
  13. .name = #_type, \
  14. }, \
  15. }, \
  16. },
  17. #define POINTER(_tid, _, _base) [_tid] = { \
  18. .tid = _tid, \
  19. .size = sizeof(void *), \
  20. .type = T_POINTER, \
  21. .t = { \
  22. .pointer = { \
  23. .type = _base, \
  24. }, \
  25. }, \
  26. },
  27. BUILTIN_TYPES
  28. #undef SCALAR
  29. #undef POINTER
  30. { .type = T_INVALID }
  31. };
  32. const type_t arch_builtin_types[] = {
  33. { .type = T_ALIAS, .t = { .alias = { .type = tid_c, .name = "s8" } } },
  34. { .type = T_ALIAS, .t = { .alias = { .type = tid_uc, .name = "u8" } } },
  35. { .type = T_INVALID }
  36. };
  37. static types_t types = {
  38. .types = NULL,
  39. .next = 0,
  40. };
  41. type_t *type_info(tid_t tid)
  42. {
  43. assert(tid < types.next);
  44. return &types.types[tid];
  45. }
  46. void type_dump(type_t *t, FILE *fp)
  47. {
  48. switch (t->type){
  49. case T_NONE:
  50. fputs("<NONE>", fp);
  51. break;
  52. case T_ALIAS:
  53. fputs(t->t.alias.name, fp);
  54. break;
  55. case T_SCALAR:
  56. fputs(t->t.scalar.name, fp);
  57. break;
  58. case T_POINTER:
  59. type_dump(type_info(t->t.pointer.type), fp);
  60. fputs(" *", fp);
  61. break;
  62. case T_ARRAY:
  63. type_dump(type_info(t->t.array.type), fp);
  64. fprintf(fp, "[%zu]", t->t.array.len);
  65. break;
  66. default:
  67. assert(0);
  68. }
  69. }
  70. void type_dump_cdecl(type_t *t, FILE *fp)
  71. {
  72. switch (t->type) {
  73. case T_ALIAS:
  74. fputs("typedef ", fp);
  75. type_dump(type_info(t->t.alias.type), fp);
  76. fprintf(fp, " %s", t->t.alias.name);
  77. break;
  78. case T_NONE:
  79. case T_SCALAR:
  80. case T_POINTER:
  81. case T_ARRAY:
  82. type_dump(t, fp);
  83. break;
  84. default:
  85. assert(0);
  86. }
  87. }
  88. tid_t type_add(const type_t *type)
  89. {
  90. tid_t tid = types.next++;
  91. types.types = realloc(types.types, types.next * sizeof(type_t));
  92. assert(types.types);
  93. types.types[tid] = *type;
  94. types.types[tid].tid = tid;
  95. return tid;
  96. }
  97. tid_t type_add_list(const type_t *type)
  98. {
  99. tid_t first = 0;
  100. for (; type->type; type++) {
  101. if (!first)
  102. first = type_add(type);
  103. else
  104. type_add(type);
  105. }
  106. return first;
  107. }
  108. __attribute__((constructor))
  109. static void type_init(void)
  110. {
  111. type_add_list(builtin_types);
  112. type_add_list(arch_builtin_types);
  113. }
  114. /* int main(void) */
  115. /* { */
  116. /* tid_t tid; */
  117. /* type_init(); */
  118. /* for (tid = 0; tid < types.next; tid++) { */
  119. /* type_t *t = type_info(tid); */
  120. /* printf("tid:%3d sz:%2zx ", t->tid, t->size); */
  121. /* type_dump_cdecl(t, stdout); */
  122. /* putchar('\n'); */
  123. /* } */
  124. /* return 0; */
  125. /* } */