[PAHOLE v5 1/5] btf_loader: Handle decl tag component_idx for parameters
Vineet Gupta <[email protected]> Wed, 17 Jun 2026 17:57:27 -0700
| Newsgroups | org.kernel.vger.dwarves,org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
From: Alan Maguire <[email protected]> A BTF_KIND_DECL_TAG with a non-negative component_idx applies to a specific function parameter (or struct/union member), not to the function itself. btf_loader.c however attached every decl tag to the type named by btf_type->type, so parameter decl tags were recorded on the function rather than on the parameter, and pfunct never printed them with the parameter. Resolve a non-negative component_idx to the corresponding parameter via new helpers ftype__parameter()/function__parameter(), and attach the tag there. Teach the pretty printer to emit a parameter's attributes by factoring the function-level attribute loop into tag__attributes_fprintf() and calling it from ftype__fprintf_parms() for each parameter. Signed-off-by: Alan Maguire <[email protected]> Signed-off-by: Vineet Gupta <[email protected]> --- btf_loader.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- dwarves_fprintf.c | 20 ++++++++++++++++---- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/btf_loader.c b/btf_loader.c index b591219a245d..9bb52c3c5801 100644 --- a/btf_loader.c +++ b/btf_loader.c @@ -477,12 +477,56 @@ static struct attributes *attributes__realloc(struct attributes *attributes, con return result; } +static struct tag *ftype__parameter(const struct ftype *ftype, int component_idx) +{ + struct parameter *pos; + int idx = 0; + + ftype__for_each_parameter(ftype, pos) { + if (idx == component_idx) + return &pos->tag; + ++idx; + } + + return NULL; +} + +static struct tag *function__parameter(const struct function *func, struct cu *cu, + int component_idx) +{ + struct tag *tag; + + if (component_idx < 0) + return NULL; + + tag = cu__type(cu, func->proto.tag.type); + if (tag == NULL) + return NULL; + + return ftype__parameter(tag__ftype(tag), component_idx); +} + 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 attributes *tmp; - if (tag == NULL) + if (component_idx >= 0) { + struct tag *func_tag = cu__function(cu, tp->type); + + if (func_tag != NULL) { + tag = function__parameter(tag__function(func_tag), cu, + component_idx); + if (tag == NULL) { + fprintf(stderr, "WARNING: BTF_KIND_DECL_TAG for unknown parameter %d in BTF id %d\n", + component_idx, tp->type); + return 0; + } + } + } + + if (tag == NULL && component_idx < 0) tag = cu__function(cu, tp->type); if (tag == NULL) diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c index 1ec478c2a027..54f483244bd2 100644 --- a/dwarves_fprintf.c +++ b/dwarves_fprintf.c @@ -1199,6 +1199,18 @@ const char *function__prototype(const struct function *func, bf, len); } +static size_t tag__attributes_fprintf(const struct tag *tag, FILE *fp) +{ + size_t printed = 0; + int i; + + if (tag->attributes) + for (i = 0; i < tag->attributes->cnt; ++i) + printed += fprintf(fp, "%s ", tag->attributes->values[i]); + + return printed; +} + size_t ftype__fprintf_parms(const struct ftype *ftype, const struct cu *cu, int indent, const struct conf_fprintf *conf, FILE *fp) @@ -1240,6 +1252,7 @@ size_t ftype__fprintf_parms(const struct ftype *ftype, if (n) return printed + n; if (ptype->tag == DW_TAG_subroutine_type) { + printed += tag__attributes_fprintf(&pos->tag, fp); printed += ftype__fprintf(tag__ftype(ptype), cu, name, 0, 1, 0, @@ -1248,12 +1261,14 @@ size_t ftype__fprintf_parms(const struct ftype *ftype, } } } else if (type->tag == DW_TAG_subroutine_type) { + printed += tag__attributes_fprintf(&pos->tag, fp); printed += ftype__fprintf(tag__ftype(type), cu, name, true, 0, 0, 0, conf, fp); continue; } stype = tag__name(type, cu, sbf, sizeof(sbf), conf); print_it: + printed += tag__attributes_fprintf(&pos->tag, fp); printed += fprintf(fp, "%s%s%s", stype, name ? " " : "", name ?: ""); } @@ -1405,11 +1420,8 @@ static size_t function__fprintf(const struct tag *tag, const struct cu *cu, struct ftype *ftype = func->btf ? tag__ftype(cu__type(cu, func->proto.tag.type)) : &func->proto; size_t printed = 0; bool inlined = !conf->strip_inline && function__declared_inline(func); - int i; - if (tag->attributes) - for (i = 0; i < tag->attributes->cnt; ++i) - printed += fprintf(fp, "%s ", tag->attributes->values[i]); + printed += tag__attributes_fprintf(tag, fp); if (func->virtuality == DW_VIRTUALITY_virtual || func->virtuality == DW_VIRTUALITY_pure_virtual) -- 2.54.0