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 structure types

Recursively expand DWARF structure types, i.e. structs, unions, and
enums. Also include relevant DWARF attributes in type strings to
encode structure layout, for example.

Example output with --dump-dies:

subprogram (
formal_parameter structure_type &str {
member pointer_type {
base_type u8 byte_size(1) encoding(7)
} data_ptr data_member_location(0) ,
member base_type usize byte_size(8) encoding(7) length data_member_location(8)
} byte_size(16) alignment(8) msg
)
-> base_type void

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
f6bb9245 c772f1d1

+141 -2
+136 -2
scripts/gendwarfksyms/dwarf.c
··· 208 208 value); \ 209 209 } 210 210 211 + DEFINE_PROCESS_UDATA_ATTRIBUTE(accessibility) 211 212 DEFINE_PROCESS_UDATA_ATTRIBUTE(alignment) 213 + DEFINE_PROCESS_UDATA_ATTRIBUTE(bit_size) 212 214 DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) 213 215 DEFINE_PROCESS_UDATA_ATTRIBUTE(encoding) 216 + DEFINE_PROCESS_UDATA_ATTRIBUTE(data_bit_offset) 217 + DEFINE_PROCESS_UDATA_ATTRIBUTE(data_member_location) 218 + DEFINE_PROCESS_UDATA_ATTRIBUTE(discr_value) 214 219 215 220 /* Match functions -- die_match_callback_t */ 216 221 #define DEFINE_MATCH(type) \ ··· 224 219 return dwarf_tag(die) == DW_TAG_##type##_type; \ 225 220 } 226 221 222 + DEFINE_MATCH(enumerator) 227 223 DEFINE_MATCH(formal_parameter) 224 + DEFINE_MATCH(member) 228 225 DEFINE_MATCH(subrange) 229 226 230 227 bool match_all(Dwarf_Die *die) ··· 305 298 process(cache, " "); 306 299 process(cache, name); 307 300 } 301 + process_accessibility_attr(cache, die); 302 + process_bit_size_attr(cache, die); 303 + process_data_bit_offset_attr(cache, die); 304 + process_data_member_location_attr(cache, die); 308 305 } 309 306 310 307 #define DEFINE_PROCESS_LIST_TYPE(type) \ ··· 319 308 } 320 309 321 310 DEFINE_PROCESS_LIST_TYPE(formal_parameter) 311 + DEFINE_PROCESS_LIST_TYPE(member) 322 312 323 313 /* Container types with DW_AT_type */ 324 314 static void __process_type(struct state *state, struct die *cache, ··· 352 340 DEFINE_PROCESS_TYPE(restrict) 353 341 DEFINE_PROCESS_TYPE(rvalue_reference) 354 342 DEFINE_PROCESS_TYPE(shared) 343 + DEFINE_PROCESS_TYPE(template_type_parameter) 355 344 DEFINE_PROCESS_TYPE(volatile) 356 345 DEFINE_PROCESS_TYPE(typedef) 357 346 ··· 406 393 __process_subroutine_type(state, cache, die, "subroutine_type"); 407 394 } 408 395 396 + static void process_variant_type(struct state *state, struct die *cache, 397 + Dwarf_Die *die) 398 + { 399 + process_list_comma(state, cache); 400 + process(cache, "variant {"); 401 + process_linebreak(cache, 1); 402 + check(process_die_container(state, cache, die, process_type, 403 + match_member_type)); 404 + process_linebreak(cache, -1); 405 + process(cache, "}"); 406 + process_discr_value_attr(cache, die); 407 + } 408 + 409 + static void process_variant_part_type(struct state *state, struct die *cache, 410 + Dwarf_Die *die) 411 + { 412 + process_list_comma(state, cache); 413 + process(cache, "variant_part {"); 414 + process_linebreak(cache, 1); 415 + check(process_die_container(state, cache, die, process_type, 416 + match_all)); 417 + process_linebreak(cache, -1); 418 + process(cache, "}"); 419 + } 420 + 421 + static int ___process_structure_type(struct state *state, struct die *cache, 422 + Dwarf_Die *die) 423 + { 424 + switch (dwarf_tag(die)) { 425 + case DW_TAG_member: 426 + case DW_TAG_variant_part: 427 + return check(process_type(state, cache, die)); 428 + case DW_TAG_class_type: 429 + case DW_TAG_enumeration_type: 430 + case DW_TAG_structure_type: 431 + case DW_TAG_template_type_parameter: 432 + case DW_TAG_union_type: 433 + case DW_TAG_subprogram: 434 + /* Skip non-member types, including member functions */ 435 + return 0; 436 + default: 437 + error("unexpected structure_type child: %x", dwarf_tag(die)); 438 + } 439 + } 440 + 441 + static void __process_structure_type(struct state *state, struct die *cache, 442 + Dwarf_Die *die, const char *type, 443 + die_callback_t process_func, 444 + die_match_callback_t match_func) 445 + { 446 + process(cache, type); 447 + process_fqn(cache, die); 448 + process(cache, " {"); 449 + process_linebreak(cache, 1); 450 + 451 + check(process_die_container(state, cache, die, process_func, 452 + match_func)); 453 + 454 + process_linebreak(cache, -1); 455 + process(cache, "}"); 456 + 457 + process_byte_size_attr(cache, die); 458 + process_alignment_attr(cache, die); 459 + } 460 + 461 + #define DEFINE_PROCESS_STRUCTURE_TYPE(structure) \ 462 + static void process_##structure##_type( \ 463 + struct state *state, struct die *cache, Dwarf_Die *die) \ 464 + { \ 465 + __process_structure_type(state, cache, die, \ 466 + #structure "_type", \ 467 + ___process_structure_type, \ 468 + match_all); \ 469 + } 470 + 471 + DEFINE_PROCESS_STRUCTURE_TYPE(class) 472 + DEFINE_PROCESS_STRUCTURE_TYPE(structure) 473 + DEFINE_PROCESS_STRUCTURE_TYPE(union) 474 + 475 + static void process_enumerator_type(struct state *state, struct die *cache, 476 + Dwarf_Die *die) 477 + { 478 + Dwarf_Word value; 479 + 480 + process_list_comma(state, cache); 481 + process(cache, "enumerator"); 482 + process_fqn(cache, die); 483 + 484 + if (get_udata_attr(die, DW_AT_const_value, &value)) { 485 + process(cache, " = "); 486 + process_fmt(cache, "%" PRIu64, value); 487 + } 488 + } 489 + 490 + static void process_enumeration_type(struct state *state, struct die *cache, 491 + Dwarf_Die *die) 492 + { 493 + __process_structure_type(state, cache, die, "enumeration_type", 494 + process_type, match_enumerator_type); 495 + } 496 + 409 497 static void process_base_type(struct state *state, struct die *cache, 410 498 Dwarf_Die *die) 411 499 { ··· 515 401 process_byte_size_attr(cache, die); 516 402 process_encoding_attr(cache, die); 517 403 process_alignment_attr(cache, die); 404 + } 405 + 406 + static void process_unspecified_type(struct state *state, struct die *cache, 407 + Dwarf_Die *die) 408 + { 409 + /* 410 + * These can be emitted for stand-alone assembly code, which means we 411 + * might run into them in vmlinux.o. 412 + */ 413 + process(cache, "unspecified_type"); 518 414 } 519 415 520 416 static void process_cached(struct state *state, struct die *cache, ··· 587 463 PROCESS_TYPE(rvalue_reference) 588 464 PROCESS_TYPE(shared) 589 465 PROCESS_TYPE(volatile) 466 + /* Container types */ 467 + PROCESS_TYPE(class) 468 + PROCESS_TYPE(structure) 469 + PROCESS_TYPE(union) 470 + PROCESS_TYPE(enumeration) 590 471 /* Subtypes */ 472 + PROCESS_TYPE(enumerator) 591 473 PROCESS_TYPE(formal_parameter) 474 + PROCESS_TYPE(member) 592 475 PROCESS_TYPE(subrange) 476 + PROCESS_TYPE(template_type_parameter) 477 + PROCESS_TYPE(variant) 478 + PROCESS_TYPE(variant_part) 593 479 /* Other types */ 594 480 PROCESS_TYPE(array) 595 481 PROCESS_TYPE(base) 596 482 PROCESS_TYPE(subroutine) 597 483 PROCESS_TYPE(typedef) 484 + PROCESS_TYPE(unspecified) 598 485 default: 599 - debug("unimplemented type: %x", tag); 600 - break; 486 + error("unexpected type: %x", tag); 601 487 } 602 488 603 489 /* Update cache state and append to the parent (if any) */
+5
scripts/gendwarfksyms/gendwarfksyms.h
··· 60 60 #define checkp(expr) __check(expr, __res < 0) 61 61 62 62 /* Consistent aliases (DW_TAG_<type>_type) for DWARF tags */ 63 + #define DW_TAG_enumerator_type DW_TAG_enumerator 63 64 #define DW_TAG_formal_parameter_type DW_TAG_formal_parameter 65 + #define DW_TAG_member_type DW_TAG_member 66 + #define DW_TAG_template_type_parameter_type DW_TAG_template_type_parameter 64 67 #define DW_TAG_typedef_type DW_TAG_typedef 68 + #define DW_TAG_variant_part_type DW_TAG_variant_part 69 + #define DW_TAG_variant_type DW_TAG_variant 65 70 66 71 /* 67 72 * symbols.c