A dynamic tracer for Linux

type.c 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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_ALIAS:
  50. fputs(t->t.alias.name, fp);
  51. break;
  52. case T_SCALAR:
  53. fputs(t->t.scalar.name, fp);
  54. break;
  55. case T_POINTER:
  56. type_dump(type_info(t->t.pointer.type), fp);
  57. fputs(" *", fp);
  58. break;
  59. case T_ARRAY:
  60. type_dump(type_info(t->t.array.type), fp);
  61. fprintf(fp, "[%zu]", t->t.array.len);
  62. break;
  63. default:
  64. assert(0);
  65. }
  66. }
  67. void type_dump_cdecl(type_t *t, FILE *fp)
  68. {
  69. switch (t->type) {
  70. case T_ALIAS:
  71. fputs("typedef ", fp);
  72. type_dump(type_info(t->t.alias.type), fp);
  73. fprintf(fp, " %s", t->t.alias.name);
  74. break;
  75. case T_SCALAR:
  76. case T_POINTER:
  77. case T_ARRAY:
  78. type_dump(t, fp);
  79. break;
  80. default:
  81. assert(0);
  82. }
  83. }
  84. tid_t type_add(const type_t *type)
  85. {
  86. tid_t tid = types.next++;
  87. types.types = realloc(types.types, types.next * sizeof(type_t));
  88. assert(types.types);
  89. types.types[tid] = *type;
  90. types.types[tid].tid = tid;
  91. return tid;
  92. }
  93. tid_t type_add_list(const type_t *type)
  94. {
  95. tid_t first = 0;
  96. for (; type->type; type++) {
  97. if (!first)
  98. first = type_add(type);
  99. else
  100. type_add(type);
  101. }
  102. return first;
  103. }
  104. __attribute__((constructor))
  105. static void type_init(void)
  106. {
  107. type_add_list(builtin_types);
  108. type_add_list(arch_builtin_types);
  109. }
  110. /* int main(void) */
  111. /* { */
  112. /* tid_t tid; */
  113. /* type_init(); */
  114. /* for (tid = 0; tid < types.next; tid++) { */
  115. /* type_t *t = type_info(tid); */
  116. /* printf("tid:%3d sz:%2zx ", t->tid, t->size); */
  117. /* type_dump_cdecl(t, stdout); */
  118. /* putchar('\n'); */
  119. /* } */
  120. /* return 0; */
  121. /* } */