gendwarfksyms.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2024 Google LLC
  4. */
  5. #include <dwarf.h>
  6. #include <elfutils/libdw.h>
  7. #include <elfutils/libdwfl.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <hash.h>
  11. #include <hashtable.h>
  12. #include <xalloc.h>
  13. #ifndef __GENDWARFKSYMS_H
  14. #define __GENDWARFKSYMS_H
  15. /*
  16. * Options -- in gendwarfksyms.c
  17. */
  18. extern int debug;
  19. extern int dump_dies;
  20. extern int dump_die_map;
  21. extern int dump_types;
  22. extern int dump_versions;
  23. extern int stable;
  24. extern int symtypes;
  25. /*
  26. * Output helpers
  27. */
  28. #define __PREFIX "gendwarfksyms: "
  29. #define __println(prefix, format, ...) \
  30. fprintf(stderr, prefix __PREFIX "%s: " format "\n", __func__, \
  31. ##__VA_ARGS__)
  32. #define debug(format, ...) \
  33. do { \
  34. if (debug) \
  35. __println("", format, ##__VA_ARGS__); \
  36. } while (0)
  37. #define warn(format, ...) __println("warning: ", format, ##__VA_ARGS__)
  38. #define error(format, ...) \
  39. do { \
  40. __println("error: ", format, ##__VA_ARGS__); \
  41. exit(1); \
  42. } while (0)
  43. #define __die_debug(color, format, ...) \
  44. do { \
  45. if (dump_dies && dump_die_map) \
  46. fprintf(stderr, \
  47. "\033[" #color "m<" format ">\033[39m", \
  48. __VA_ARGS__); \
  49. } while (0)
  50. #define die_debug_r(format, ...) __die_debug(91, format, __VA_ARGS__)
  51. #define die_debug_g(format, ...) __die_debug(92, format, __VA_ARGS__)
  52. #define die_debug_b(format, ...) __die_debug(94, format, __VA_ARGS__)
  53. /*
  54. * Error handling helpers
  55. */
  56. #define __check(expr, test) \
  57. ({ \
  58. int __res = expr; \
  59. if (test) \
  60. error("`%s` failed: %d", #expr, __res); \
  61. __res; \
  62. })
  63. /* Error == non-zero values */
  64. #define check(expr) __check(expr, __res)
  65. /* Error == negative values */
  66. #define checkp(expr) __check(expr, __res < 0)
  67. /* Consistent aliases (DW_TAG_<type>_type) for DWARF tags */
  68. #define DW_TAG_enumerator_type DW_TAG_enumerator
  69. #define DW_TAG_formal_parameter_type DW_TAG_formal_parameter
  70. #define DW_TAG_member_type DW_TAG_member
  71. #define DW_TAG_template_type_parameter_type DW_TAG_template_type_parameter
  72. #define DW_TAG_typedef_type DW_TAG_typedef
  73. #define DW_TAG_variant_part_type DW_TAG_variant_part
  74. #define DW_TAG_variant_type DW_TAG_variant
  75. /*
  76. * symbols.c
  77. */
  78. /* See symbols.c:is_symbol_ptr */
  79. #define SYMBOL_PTR_PREFIX "__gendwarfksyms_ptr_"
  80. #define SYMBOL_PTR_PREFIX_LEN (sizeof(SYMBOL_PTR_PREFIX) - 1)
  81. static inline unsigned int addr_hash(uintptr_t addr)
  82. {
  83. return hash_ptr((const void *)addr);
  84. }
  85. enum symbol_state {
  86. SYMBOL_UNPROCESSED,
  87. SYMBOL_MAPPED,
  88. SYMBOL_PROCESSED
  89. };
  90. struct symbol_addr {
  91. uint32_t section;
  92. Elf64_Addr address;
  93. };
  94. struct symbol {
  95. const char *name;
  96. struct symbol_addr addr;
  97. struct hlist_node addr_hash;
  98. struct hlist_node name_hash;
  99. enum symbol_state state;
  100. uintptr_t die_addr;
  101. uintptr_t ptr_die_addr;
  102. unsigned long crc;
  103. };
  104. typedef void (*symbol_callback_t)(struct symbol *, void *arg);
  105. bool is_symbol_ptr(const char *name);
  106. int symbol_read_exports(FILE *file);
  107. void symbol_read_symtab(int fd);
  108. struct symbol *symbol_get(const char *name);
  109. void symbol_set_ptr(struct symbol *sym, Dwarf_Die *ptr);
  110. void symbol_set_die(struct symbol *sym, Dwarf_Die *die);
  111. void symbol_set_crc(struct symbol *sym, unsigned long crc);
  112. void symbol_for_each(symbol_callback_t func, void *arg);
  113. void symbol_print_versions(void);
  114. void symbol_free(void);
  115. /*
  116. * die.c
  117. */
  118. enum die_state {
  119. DIE_INCOMPLETE,
  120. DIE_FQN,
  121. DIE_UNEXPANDED,
  122. DIE_COMPLETE,
  123. DIE_SYMBOL,
  124. DIE_LAST = DIE_SYMBOL
  125. };
  126. enum die_fragment_type {
  127. FRAGMENT_EMPTY,
  128. FRAGMENT_STRING,
  129. FRAGMENT_LINEBREAK,
  130. FRAGMENT_DIE
  131. };
  132. struct die_fragment {
  133. enum die_fragment_type type;
  134. union {
  135. char *str;
  136. int linebreak;
  137. uintptr_t addr;
  138. } data;
  139. struct list_head list;
  140. };
  141. #define CASE_CONST_TO_STR(name) \
  142. case name: \
  143. return #name;
  144. static inline const char *die_state_name(enum die_state state)
  145. {
  146. switch (state) {
  147. CASE_CONST_TO_STR(DIE_INCOMPLETE)
  148. CASE_CONST_TO_STR(DIE_FQN)
  149. CASE_CONST_TO_STR(DIE_UNEXPANDED)
  150. CASE_CONST_TO_STR(DIE_COMPLETE)
  151. CASE_CONST_TO_STR(DIE_SYMBOL)
  152. }
  153. error("unexpected die_state: %d", state);
  154. }
  155. struct die {
  156. enum die_state state;
  157. bool mapped;
  158. char *fqn;
  159. int tag;
  160. uintptr_t addr;
  161. struct list_head fragments;
  162. struct hlist_node hash;
  163. };
  164. typedef void (*die_map_callback_t)(struct die *, void *arg);
  165. int __die_map_get(uintptr_t addr, enum die_state state, struct die **res);
  166. struct die *die_map_get(Dwarf_Die *die, enum die_state state);
  167. void die_map_add_string(struct die *pd, const char *str);
  168. void die_map_add_linebreak(struct die *pd, int linebreak);
  169. void die_map_for_each(die_map_callback_t func, void *arg);
  170. void die_map_add_die(struct die *pd, struct die *child);
  171. void die_map_free(void);
  172. /*
  173. * cache.c
  174. */
  175. #define CACHE_HASH_BITS 10
  176. /* A cache for addresses we've already seen. */
  177. struct cache {
  178. HASHTABLE_DECLARE(cache, 1 << CACHE_HASH_BITS);
  179. };
  180. void cache_set(struct cache *cache, unsigned long key, int value);
  181. int cache_get(struct cache *cache, unsigned long key);
  182. void cache_init(struct cache *cache);
  183. void cache_free(struct cache *cache);
  184. static inline void cache_mark_expanded(struct cache *cache, void *addr)
  185. {
  186. cache_set(cache, (unsigned long)addr, 1);
  187. }
  188. static inline bool cache_was_expanded(struct cache *cache, void *addr)
  189. {
  190. return cache_get(cache, (unsigned long)addr) == 1;
  191. }
  192. /*
  193. * dwarf.c
  194. */
  195. struct expansion_state {
  196. bool expand;
  197. const char *current_fqn;
  198. };
  199. struct kabi_state {
  200. int members;
  201. Dwarf_Die placeholder;
  202. const char *orig_name;
  203. };
  204. struct state {
  205. struct symbol *sym;
  206. Dwarf_Die die;
  207. /* List expansion */
  208. bool first_list_item;
  209. /* Structure expansion */
  210. struct expansion_state expand;
  211. struct cache expansion_cache;
  212. /* Reserved or ignored members */
  213. struct kabi_state kabi;
  214. };
  215. typedef int (*die_callback_t)(struct state *state, struct die *cache,
  216. Dwarf_Die *die);
  217. typedef bool (*die_match_callback_t)(Dwarf_Die *die);
  218. bool match_all(Dwarf_Die *die);
  219. int process_die_container(struct state *state, struct die *cache,
  220. Dwarf_Die *die, die_callback_t func,
  221. die_match_callback_t match);
  222. void process_cu(Dwarf_Die *cudie);
  223. /*
  224. * types.c
  225. */
  226. void generate_symtypes_and_versions(FILE *file);
  227. /*
  228. * kabi.c
  229. */
  230. bool kabi_get_byte_size(const char *fqn, unsigned long *value);
  231. bool kabi_is_enumerator_ignored(const char *fqn, const char *field);
  232. bool kabi_get_enumerator_value(const char *fqn, const char *field,
  233. unsigned long *value);
  234. bool kabi_is_declonly(const char *fqn);
  235. bool kabi_get_type_string(const char *type, const char **str);
  236. void kabi_read_rules(int fd);
  237. void kabi_free(void);
  238. #endif /* __GENDWARFKSYMS_H */