From 290b8fdbdab791a243b15e3311475f3c21a87c96 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 21 Jan 2020 12:34:42 -0300 Subject: [PATCH] pahole: Improve --contains --recursive a bit Its not yet correct, misses cases where a top level struct doesn't have the contained type but some of its substructs have, i.e. right now it looks if the top level struct has the looked up container type and if it has, it prints its name and then goes to look at all its members if some has the looked up container type, recursively. It should go all the way down, even when a struct doesn't have the looked up contained type some of its members may have. So for now its better to use 'pahole -E struct_name | less' and then search for the type, will be fixed after DevConf.cz 2020 :-) Signed-off-by: Arnaldo Carvalho de Melo --- pahole.c | 68 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/pahole.c b/pahole.c index 75e7a77..e2a081b 100644 --- a/pahole.c +++ b/pahole.c @@ -729,6 +729,46 @@ static void print_structs_with_pointer_to(struct cu *cu, uint32_t type) } } +static int type__print_containers(struct type *type, struct cu *cu, uint32_t contained_type_id, int ident) +{ + const uint32_t n = type__nr_members_of_type(type, contained_type_id); + if (n == 0) + return 0; + + if (ident == 0) { + bool existing_entry; + struct structure *str = structures__add(type__class(type), cu, &existing_entry); + if (str == NULL) { + fprintf(stderr, "pahole: insufficient memory for " + "processing %s, skipping it...\n", + cu->name); + return -1; + } + /* + * We already printed this struct in another CU + */ + if (existing_entry) + return 0; + } + + printf("%.*s%s", ident * 2, tab, type__name(type, cu)); + if (global_verbose) + printf(": %u", n); + putchar('\n'); + if (recursive) { + struct class_member *member; + + type__for_each_member(type, member) { + struct tag *member_type = cu__type(cu, member->tag.type); + + if (tag__is_struct(member_type) || tag__is_union(member_type)) + type__print_containers(tag__type(member_type), cu, contained_type_id, ident + 1); + } + } + + return 0; +} + static void print_containers(struct cu *cu, uint32_t type, int ident) { struct class *pos; @@ -741,32 +781,8 @@ static void print_containers(struct cu *cu, uint32_t type, int ident) if (!class__filter(pos, cu, id)) continue; - const uint32_t n = type__nr_members_of_type(&pos->type, type); - if (n == 0) - continue; - - if (ident == 0) { - bool existing_entry; - struct structure *str = structures__add(pos, cu, &existing_entry); - if (str == NULL) { - fprintf(stderr, "pahole: insufficient memory for " - "processing %s, skipping it...\n", - cu->name); - return; - } - /* - * We already printed this struct in another CU - */ - if (existing_entry) - break; - } - - printf("%.*s%s", ident * 2, tab, class__name(pos, cu)); - if (global_verbose) - printf(": %u", n); - putchar('\n'); - if (recursive) - print_containers(cu, id, ident + 1); + if (type__print_containers(&pos->type, cu, type, ident)) + break; } }