[PATCH dwarves 1/2] btf_loader: Attach decl tags to struct and union members
Alan Maguire <[email protected]> Fri, 19 Jun 2026 16:21:02 +0100
| Newsgroups | org.kernel.vger.dwarves |
|---|---|
| Message-ID | <[email protected]> |
BTF_KIND_DECL_TAG with a non-negative component_idx can target either a function parameter or a struct/union member. The BTF loader only resolved the function-parameter case, so member decl tags were left attached to the aggregate type and were not shown by pahole. Add member lookup by component_idx for struct/union types and print stored attributes from class_member__fprintf(). Signed-off-by: Alan Maguire <[email protected]> --- btf_loader.c | 35 +++++++++++++++++++++++++++++++++-- dwarves_fprintf.c | 3 +++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/btf_loader.c b/btf_loader.c index 92d4832..406ee28 100644 --- a/btf_loader.c +++ b/btf_loader.c @@ -506,10 +506,24 @@ static struct tag *function__parameter(const struct function *func, struct cu *c return ftype__parameter(tag__ftype(tag), component_idx); } +static struct tag *type__member(struct type *type, int component_idx) +{ + struct class_member *member; + int idx = 0; + + type__for_each_data_member(type, member) { + if (idx == component_idx) + return &member->tag; + ++idx; + } + + return NULL; +} + static int process_decl_tag(struct cu *cu, const struct btf_type *tp) { int component_idx = btf_decl_tag(tp)->component_idx; - struct tag *tag = cu__type(cu, tp->type); + struct tag *tag; struct attributes *tmp; tag = cu__function(cu, tp->type); @@ -522,7 +536,24 @@ static int process_decl_tag(struct cu *cu, const struct btf_type *tp) } } - if (tag == NULL) + if (tag == NULL) { + tag = cu__type(cu, tp->type); + + if (component_idx >= 0 && tag != NULL) { + if (tag != NULL && (tag__is_struct(tag) || tag__is_union(tag))) { + tag = type__member(tag__type(tag), component_idx); + if (tag == NULL) { + fprintf(stderr, "WARNING: BTF_KIND_DECL_TAG for unknown member %d in BTF id %d\n", + component_idx, tp->type); + return 0; + } + } else { + tag = NULL; + } + } + } + + if (tag == NULL && component_idx < 0) tag = cu__tag(cu, tp->type); if (tag == NULL) { diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c index ab1c381..04f6569 100644 --- a/dwarves_fprintf.c +++ b/dwarves_fprintf.c @@ -963,6 +963,7 @@ out_type_not_found: static size_t class__fprintf_cacheline_boundary(struct conf_fprintf *conf, uint32_t offset, FILE *fp); +static size_t tag__attributes_fprintf(const struct tag *tag, FILE *fp); static size_t class_member__fprintf(struct class_member *member, bool union_member, struct tag *type, const struct cu *cu, @@ -996,6 +997,8 @@ static size_t class_member__fprintf(struct class_member *member, bool union_memb if (member->is_static) printed += fprintf(fp, "static "); + printed += tag__attributes_fprintf(&member->tag, fp); + /* For struct-like constructs, the name of the member cannot be * conflated with the name of its type, otherwise __attribute__ are * printed in the wrong order. -- 2.43.5