Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

gendwarfksyms: Expand type modifiers and typedefs

Add support for expanding DWARF type modifiers, such as pointers,
const values etc., and typedefs. These types all have DW_AT_type
attribute pointing to the underlying type, and thus produce similar
output.

Also add linebreaks and indentation to debugging output to make it
more readable.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>

authored by

Sami Tolvanen and committed by
Masahiro Yamada
06b8b036 0c1c7627

+84
+12
scripts/gendwarfksyms/die.c
··· 130 130 df->type = FRAGMENT_STRING; 131 131 } 132 132 133 + void die_map_add_linebreak(struct die *cd, int linebreak) 134 + { 135 + struct die_fragment *df; 136 + 137 + if (!cd) 138 + return; 139 + 140 + df = append_item(cd); 141 + df->data.linebreak = linebreak; 142 + df->type = FRAGMENT_LINEBREAK; 143 + } 144 + 133 145 void die_map_add_die(struct die *cd, struct die *child) 134 146 { 135 147 struct die_fragment *df;
+67
scripts/gendwarfksyms/dwarf.c
··· 7 7 #include <stdarg.h> 8 8 #include "gendwarfksyms.h" 9 9 10 + static bool do_linebreak; 11 + static int indentation_level; 12 + 13 + /* Line breaks and indentation for pretty-printing */ 14 + static void process_linebreak(struct die *cache, int n) 15 + { 16 + indentation_level += n; 17 + do_linebreak = true; 18 + die_map_add_linebreak(cache, n); 19 + } 20 + 10 21 #define DEFINE_GET_ATTR(attr, type) \ 11 22 static bool get_##attr##_attr(Dwarf_Die *die, unsigned int id, \ 12 23 type *value) \ ··· 87 76 { 88 77 s = s ?: "<null>"; 89 78 79 + if (dump_dies && do_linebreak) { 80 + fputs("\n", stderr); 81 + for (int i = 0; i < indentation_level; i++) 82 + fputs(" ", stderr); 83 + do_linebreak = false; 84 + } 90 85 if (dump_dies) 91 86 fputs(s, stderr); 92 87 ··· 256 239 process(cache, "base_type void"); 257 240 } 258 241 242 + /* Container types with DW_AT_type */ 243 + static void __process_type(struct state *state, struct die *cache, 244 + Dwarf_Die *die, const char *type) 245 + { 246 + process(cache, type); 247 + process_fqn(cache, die); 248 + process(cache, " {"); 249 + process_linebreak(cache, 1); 250 + process_type_attr(state, cache, die); 251 + process_linebreak(cache, -1); 252 + process(cache, "}"); 253 + process_byte_size_attr(cache, die); 254 + process_alignment_attr(cache, die); 255 + } 256 + 257 + #define DEFINE_PROCESS_TYPE(type) \ 258 + static void process_##type##_type(struct state *state, \ 259 + struct die *cache, Dwarf_Die *die) \ 260 + { \ 261 + __process_type(state, cache, die, #type "_type"); \ 262 + } 263 + 264 + DEFINE_PROCESS_TYPE(atomic) 265 + DEFINE_PROCESS_TYPE(const) 266 + DEFINE_PROCESS_TYPE(immutable) 267 + DEFINE_PROCESS_TYPE(packed) 268 + DEFINE_PROCESS_TYPE(pointer) 269 + DEFINE_PROCESS_TYPE(reference) 270 + DEFINE_PROCESS_TYPE(restrict) 271 + DEFINE_PROCESS_TYPE(rvalue_reference) 272 + DEFINE_PROCESS_TYPE(shared) 273 + DEFINE_PROCESS_TYPE(volatile) 274 + DEFINE_PROCESS_TYPE(typedef) 275 + 259 276 static void process_base_type(struct state *state, struct die *cache, 260 277 Dwarf_Die *die) 261 278 { ··· 310 259 switch (df->type) { 311 260 case FRAGMENT_STRING: 312 261 process(NULL, df->data.str); 262 + break; 263 + case FRAGMENT_LINEBREAK: 264 + process_linebreak(NULL, df->data.linebreak); 313 265 break; 314 266 case FRAGMENT_DIE: 315 267 if (!dwarf_die_addr_die(dwarf_cu_getdwarf(die->cu), ··· 349 295 } 350 296 351 297 switch (tag) { 298 + /* Type modifiers */ 299 + PROCESS_TYPE(atomic) 300 + PROCESS_TYPE(const) 301 + PROCESS_TYPE(immutable) 302 + PROCESS_TYPE(packed) 303 + PROCESS_TYPE(pointer) 304 + PROCESS_TYPE(reference) 305 + PROCESS_TYPE(restrict) 306 + PROCESS_TYPE(rvalue_reference) 307 + PROCESS_TYPE(shared) 308 + PROCESS_TYPE(volatile) 309 + /* Other types */ 352 310 PROCESS_TYPE(base) 311 + PROCESS_TYPE(typedef) 353 312 default: 354 313 debug("unimplemented type: %x", tag); 355 314 break;
+5
scripts/gendwarfksyms/gendwarfksyms.h
··· 59 59 /* Error == negative values */ 60 60 #define checkp(expr) __check(expr, __res < 0) 61 61 62 + /* Consistent aliases (DW_TAG_<type>_type) for DWARF tags */ 63 + #define DW_TAG_typedef_type DW_TAG_typedef 64 + 62 65 /* 63 66 * symbols.c 64 67 */ ··· 103 100 enum die_fragment_type { 104 101 FRAGMENT_EMPTY, 105 102 FRAGMENT_STRING, 103 + FRAGMENT_LINEBREAK, 106 104 FRAGMENT_DIE 107 105 }; 108 106 ··· 111 107 enum die_fragment_type type; 112 108 union { 113 109 char *str; 110 + int linebreak; 114 111 uintptr_t addr; 115 112 } data; 116 113 struct list_head list;