From ccd67bdb205b4693c12927464aba7dd8d36a606d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 9 Apr 2019 18:07:24 -0300 Subject: [PATCH] fprintf: Print "const" for class members more early, in type__fprintf() We want to reach array__fprintf() from here, with the class_member name, as __tag__name() isn't handling arrays properly. I.e. to print an array when we have its name we can't use __tag__name(). This also stops printing 0 for zero sized arrays and trows away the extra DW_TAG_const_type that comes with zero sized arrays, where we have: class_member type: DW_TAG_const_type 1 DW_TAG_const_type 1: DW_TAG_array_type 2 DW_TAG_array_type 2: 0 entries, type: DW_TAG_const_type 3 DW_TAG_const_type 3: real type of the zero sized array For instance, after this patch we get a sane reconstruction of this type: $ pahole -C filename /home/acme/git/build/v5.0-rc2+/ipc/mqueue.o struct filename { const char * name; /* 0 8 */ const char * uptr; /* 8 8 */ int refcnt; /* 16 4 */ /* XXX 4 bytes hole, try to pack */ struct audit_names * aname; /* 24 8 */ const char iname[]; /* 32 0 */ /* size: 32, cachelines: 1, members: 5 */ /* sum members: 28, holes: 1, sum holes: 4 */ /* last cacheline: 32 bytes */ }; $ Signed-off-by: Arnaldo Carvalho de Melo --- dwarves_fprintf.c | 56 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c index 61c9453..176f327 100644 --- a/dwarves_fprintf.c +++ b/dwarves_fprintf.c @@ -199,6 +199,10 @@ static size_t array_type__fprintf(const struct tag *tag, if (type == NULL) return tag__id_not_found_fprintf(fp, tag->type); + /* Zero sized arrays? */ + if (at->dimensions == 1 && at->nr_entries[0] == 0 && tag__is_const(type)) + type = cu__type(cu, type->type); + printed = type__fprintf(type, cu, name, conf, fp); for (i = 0; i < at->dimensions; ++i) { if (conf->flat_arrays || at->is_vector) { @@ -213,8 +217,12 @@ static size_t array_type__fprintf(const struct tag *tag, flat_dimensions = at->nr_entries[i]; else flat_dimensions *= at->nr_entries[i]; - } else - printed += fprintf(fp, "[%u]", at->nr_entries[i]); + } else { + if (at->nr_entries[i] != 0) + printed += fprintf(fp, "[%u]", at->nr_entries[i]); + else + printed += fprintf(fp, "[]"); + } } if (at->is_vector) { @@ -505,12 +513,6 @@ const char *tag__name(const struct tag *tag, const struct cu *cu, return bf; } - if (tag->tag == DW_TAG_const_type) { - snprintf(bf, len, "%s ", "const"); - printed = strlen(bf); - tag = cu__type(cu, tag->type); - } - __tag__name(tag, cu, bf + printed, len - printed, conf); return bf; @@ -637,9 +639,10 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu, printed += fprintf(fp, " */ "); } + tconf = *conf; + if (tag__is_struct(type) || tag__is_union(type) || tag__is_enumeration(type)) { - tconf = *conf; tconf.type_spacing -= 8; tconf.prefix = NULL; tconf.suffix = name; @@ -647,6 +650,7 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu, tconf.suppress_offset_comment = suppress_offset_comment; } +next_type: switch (type->tag) { case DW_TAG_pointer_type: if (type->type != 0) { @@ -660,23 +664,31 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu, if (ptype->tag == DW_TAG_subroutine_type) { printed += ftype__fprintf(tag__ftype(ptype), cu, name, 0, 1, - conf->type_spacing, - conf, fp); + tconf.type_spacing, + &tconf, fp); break; } } /* Fall Thru */ default: - printed += fprintf(fp, "%-*s %s", conf->type_spacing, - tag__name(type, cu, tbf, sizeof(tbf), conf), + printed += fprintf(fp, "%-*s %s", tconf.type_spacing, + tag__name(type, cu, tbf, sizeof(tbf), &tconf), name); break; case DW_TAG_subroutine_type: printed += ftype__fprintf(tag__ftype(type), cu, name, 0, 0, - conf->type_spacing, conf, fp); + tconf.type_spacing, &tconf, fp); break; + case DW_TAG_const_type: { + size_t const_printed = fprintf(fp, "%s ", "const"); + tconf.type_spacing -= const_printed; + printed += const_printed; + } + type = cu__type(cu, type->type); + goto next_type; + case DW_TAG_array_type: - printed += array_type__fprintf(type, cu, name, conf, fp); + printed += array_type__fprintf(type, cu, name, &tconf, fp); break; case DW_TAG_class_type: case DW_TAG_structure_type: @@ -685,13 +697,13 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu, if (type__name(ctype, cu) != NULL && !expand_types) { printed += fprintf(fp, "%s %-*s %s", (type->tag == DW_TAG_class_type && - !conf->classes_as_structs) ? "class" : "struct", - conf->type_spacing - 7, + !tconf.classes_as_structs) ? "class" : "struct", + tconf.type_spacing - 7, type__name(ctype, cu), name); } else { struct class *cclass = tag__class(type); - if (!conf->suppress_comments) + if (!tconf.suppress_comments) class__find_holes(cclass); printed += __class__fprintf(cclass, cu, &tconf, fp); @@ -702,7 +714,7 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu, if (type__name(ctype, cu) != NULL && !expand_types) printed += fprintf(fp, "union %-*s %s", - conf->type_spacing - 6, + tconf.type_spacing - 6, type__name(ctype, cu), name); else printed += union__fprintf(ctype, cu, &tconf, fp); @@ -712,19 +724,19 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu, if (type__name(ctype, cu) != NULL) printed += fprintf(fp, "enum %-*s %s", - conf->type_spacing - 5, + tconf.type_spacing - 5, type__name(ctype, cu), name); else printed += enumeration__fprintf(type, cu, &tconf, fp); break; } out: - if (conf->expand_types) + if (tconf.expand_types) --type->recursivity_level; return printed; out_type_not_found: - printed = fprintf(fp, "%-*s %s", conf->type_spacing, "", name); + printed = fprintf(fp, "%-*s %s", tconf.type_spacing, "", name); goto out; }