Message ID | 20250122025308.2717553-2-ihor.solodrai@pm.me (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | BPF |
Headers | show |
Series | BTF: arbitrary __attribute__ encoding | expand |
On 22/01/2025 02:53, Ihor Solodrai wrote: > Add the following functions to libbpf API: > * btf__add_type_attr() > * btf__add_decl_attr() > > These functions allow to add to BTF the type tags and decl tags with > info->kflag set to 1. The kflag indicates that the tag directly > encodes an __attribute__ and not a normal tag. > > See Documentation/bpf/btf.rst changes for details on the semantics. > > Suggested-by: Andrii Nakryiko <andrii@kernel.org> > Signed-off-by: Ihor Solodrai <ihor.solodrai@pm.me> need to sync include/uapi/linux/btf.h with tools/include/uapi/linux/btf.h, but other than that Reviewed-by: Alan Maguire <alan.maguire@oracle.com> > --- > Documentation/bpf/btf.rst | 27 +++++++++-- > tools/include/uapi/linux/btf.h | 3 +- same change needed to include/uapi/linux/btf.h too, right? > tools/lib/bpf/btf.c | 87 +++++++++++++++++++++++++--------- > tools/lib/bpf/btf.h | 3 ++ > tools/lib/bpf/libbpf.map | 2 + > 5 files changed, 93 insertions(+), 29 deletions(-) > > diff --git a/Documentation/bpf/btf.rst b/Documentation/bpf/btf.rst > index 2478cef758f8..615ded7b2442 100644 > --- a/Documentation/bpf/btf.rst > +++ b/Documentation/bpf/btf.rst > @@ -102,8 +102,9 @@ Each type contains the following common data:: > * bits 24-28: kind (e.g. int, ptr, array...etc) > * bits 29-30: unused > * bit 31: kind_flag, currently used by > - * struct, union, fwd, enum and enum64. > - */ > + * struct, union, enum, fwd, enum64, > + * DECL_TAG and TYPE_TAG > + */ > __u32 info; > /* "size" is used by INT, ENUM, STRUCT, UNION and ENUM64. > * "size" tells the size of the type it is describing. > @@ -478,7 +479,7 @@ No additional type data follow ``btf_type``. > > ``struct btf_type`` encoding requirement: > * ``name_off``: offset to a non-empty string > - * ``info.kind_flag``: 0 > + * ``info.kind_flag``: 0 or 1 > * ``info.kind``: BTF_KIND_DECL_TAG > * ``info.vlen``: 0 > * ``type``: ``struct``, ``union``, ``func``, ``var`` or ``typedef`` > @@ -489,7 +490,6 @@ No additional type data follow ``btf_type``. > __u32 component_idx; > }; > > -The ``name_off`` encodes btf_decl_tag attribute string. > The ``type`` should be ``struct``, ``union``, ``func``, ``var`` or ``typedef``. > For ``var`` or ``typedef`` type, ``btf_decl_tag.component_idx`` must be ``-1``. > For the other three types, if the btf_decl_tag attribute is > @@ -499,12 +499,21 @@ the attribute is applied to a ``struct``/``union`` member or > a ``func`` argument, and ``btf_decl_tag.component_idx`` should be a > valid index (starting from 0) pointing to a member or an argument. > > +If ``info.kind_flag`` is 0, then this is a normal decl tag, and the > +``name_off`` encodes btf_decl_tag attribute string. > + > +If ``info.kind_flag`` is 1, then the decl tag represents an arbitrary > +__attribute__. In this case, ``name_off`` encodes a string > +representing the attribute-list of the attribute specifier. For > +example, for an ``__attribute__((aligned(4)))`` the string's contents > +is ``aligned(4)``. > + > 2.2.18 BTF_KIND_TYPE_TAG > ~~~~~~~~~~~~~~~~~~~~~~~~ > > ``struct btf_type`` encoding requirement: > * ``name_off``: offset to a non-empty string > - * ``info.kind_flag``: 0 > + * ``info.kind_flag``: 0 or 1 > * ``info.kind``: BTF_KIND_TYPE_TAG > * ``info.vlen``: 0 > * ``type``: the type with ``btf_type_tag`` attribute > @@ -522,6 +531,14 @@ type_tag, then zero or more const/volatile/restrict/typedef > and finally the base type. The base type is one of > int, ptr, array, struct, union, enum, func_proto and float types. > > +Similarly to decl tags, if the ``info.kind_flag`` is 0, then this is a > +normal type tag, and the ``name_off`` encodes btf_type_tag attribute > +string. > + > +If ``info.kind_flag`` is 1, then the type tag represents an arbitrary > +__attribute__, and the ``name_off`` encodes a string representing the > +attribute-list of the attribute specifier. > + > 2.2.19 BTF_KIND_ENUM64 > ~~~~~~~~~~~~~~~~~~~~~~ > > diff --git a/tools/include/uapi/linux/btf.h b/tools/include/uapi/linux/btf.h > index ec1798b6d3ff..d602c26a0c2a 100644 > --- a/tools/include/uapi/linux/btf.h > +++ b/tools/include/uapi/linux/btf.h > @@ -36,7 +36,8 @@ struct btf_type { > * bits 24-28: kind (e.g. int, ptr, array...etc) > * bits 29-30: unused > * bit 31: kind_flag, currently used by > - * struct, union, enum, fwd and enum64 > + * struct, union, enum, fwd, enum64, > + * DECL_TAG and TYPE_TAG > */ > __u32 info; > /* "size" is used by INT, ENUM, STRUCT, UNION, DATASEC and ENUM64. > diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c > index 48c66f3a9200..df2808cee009 100644 > --- a/tools/lib/bpf/btf.c > +++ b/tools/lib/bpf/btf.c > @@ -2090,7 +2090,7 @@ static int validate_type_id(int id) > } > > /* generic append function for PTR, TYPEDEF, CONST/VOLATILE/RESTRICT */ > -static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref_type_id) > +static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref_type_id, int kflag) > { > struct btf_type *t; > int sz, name_off = 0; > @@ -2113,7 +2113,7 @@ static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref > } > > t->name_off = name_off; > - t->info = btf_type_info(kind, 0, 0); > + t->info = btf_type_info(kind, 0, kflag); > t->type = ref_type_id; > > return btf_commit_type(btf, sz); > @@ -2128,7 +2128,7 @@ static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref > */ > int btf__add_ptr(struct btf *btf, int ref_type_id) > { > - return btf_add_ref_kind(btf, BTF_KIND_PTR, NULL, ref_type_id); > + return btf_add_ref_kind(btf, BTF_KIND_PTR, NULL, ref_type_id, 0); > } > > /* > @@ -2506,7 +2506,7 @@ int btf__add_fwd(struct btf *btf, const char *name, enum btf_fwd_kind fwd_kind) > struct btf_type *t; > int id; > > - id = btf_add_ref_kind(btf, BTF_KIND_FWD, name, 0); > + id = btf_add_ref_kind(btf, BTF_KIND_FWD, name, 0, 0); > if (id <= 0) > return id; > t = btf_type_by_id(btf, id); > @@ -2536,7 +2536,7 @@ int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id) > if (!name || !name[0]) > return libbpf_err(-EINVAL); > > - return btf_add_ref_kind(btf, BTF_KIND_TYPEDEF, name, ref_type_id); > + return btf_add_ref_kind(btf, BTF_KIND_TYPEDEF, name, ref_type_id, 0); > } > > /* > @@ -2548,7 +2548,7 @@ int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id) > */ > int btf__add_volatile(struct btf *btf, int ref_type_id) > { > - return btf_add_ref_kind(btf, BTF_KIND_VOLATILE, NULL, ref_type_id); > + return btf_add_ref_kind(btf, BTF_KIND_VOLATILE, NULL, ref_type_id, 0); > } > > /* > @@ -2560,7 +2560,7 @@ int btf__add_volatile(struct btf *btf, int ref_type_id) > */ > int btf__add_const(struct btf *btf, int ref_type_id) > { > - return btf_add_ref_kind(btf, BTF_KIND_CONST, NULL, ref_type_id); > + return btf_add_ref_kind(btf, BTF_KIND_CONST, NULL, ref_type_id, 0); > } > > /* > @@ -2572,7 +2572,7 @@ int btf__add_const(struct btf *btf, int ref_type_id) > */ > int btf__add_restrict(struct btf *btf, int ref_type_id) > { > - return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id); > + return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id, 0); > } > > /* > @@ -2588,7 +2588,24 @@ int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id) > if (!value || !value[0]) > return libbpf_err(-EINVAL); > > - return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id); > + return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id, 0); > +} > + > +/* > + * Append new BTF_KIND_TYPE_TAG type with: > + * - *value*, non-empty/non-NULL tag value; > + * - *ref_type_id* - referenced type ID, it might not exist yet; > + * Set info->kflag to 1, indicating this tag is an __attribute__ > + * Returns: > + * - >0, type ID of newly added BTF type; > + * - <0, on error. > + */ > +int btf__add_type_attr(struct btf *btf, const char *value, int ref_type_id) > +{ > + if (!value || !value[0]) > + return libbpf_err(-EINVAL); > + > + return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id, 1); > } > > /* > @@ -2610,7 +2627,7 @@ int btf__add_func(struct btf *btf, const char *name, > linkage != BTF_FUNC_EXTERN) > return libbpf_err(-EINVAL); > > - id = btf_add_ref_kind(btf, BTF_KIND_FUNC, name, proto_type_id); > + id = btf_add_ref_kind(btf, BTF_KIND_FUNC, name, proto_type_id, 0); > if (id > 0) { > struct btf_type *t = btf_type_by_id(btf, id); > > @@ -2845,18 +2862,9 @@ int btf__add_datasec_var_info(struct btf *btf, int var_type_id, __u32 offset, __ > return 0; > } > > -/* > - * Append new BTF_KIND_DECL_TAG type with: > - * - *value* - non-empty/non-NULL string; > - * - *ref_type_id* - referenced type ID, it might not exist yet; > - * - *component_idx* - -1 for tagging reference type, otherwise struct/union > - * member or function argument index; > - * Returns: > - * - >0, type ID of newly added BTF type; > - * - <0, on error. > - */ > -int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, > - int component_idx) > + > +static int __btf__add_decl_tag(struct btf *btf, const char *value, > + int ref_type_id, int component_idx, int kflag) > { > struct btf_type *t; > int sz, value_off; > @@ -2880,13 +2888,46 @@ int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, > return value_off; > > t->name_off = value_off; > - t->info = btf_type_info(BTF_KIND_DECL_TAG, 0, false); > + t->info = btf_type_info(BTF_KIND_DECL_TAG, 0, kflag); > t->type = ref_type_id; > btf_decl_tag(t)->component_idx = component_idx; > > return btf_commit_type(btf, sz); > } > > +/* > + * Append new BTF_KIND_DECL_TAG type with: > + * - *value* - non-empty/non-NULL string; > + * - *ref_type_id* - referenced type ID, it might not exist yet; > + * - *component_idx* - -1 for tagging reference type, otherwise struct/union > + * member or function argument index; > + * Returns: > + * - >0, type ID of newly added BTF type; > + * - <0, on error. > + */ > +int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, > + int component_idx) > +{ > + return __btf__add_decl_tag(btf, value, ref_type_id, component_idx, 0); > +} > + > +/* > + * Append new BTF_KIND_DECL_TAG type with: > + * - *value* - non-empty/non-NULL string; > + * - *ref_type_id* - referenced type ID, it might not exist yet; > + * - *component_idx* - -1 for tagging reference type, otherwise struct/union > + * member or function argument index; > + * Set info->kflag to 1, indicating this tag is an __attribute__ > + * Returns: > + * - >0, type ID of newly added BTF type; > + * - <0, on error. > + */ > +int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id, > + int component_idx) > +{ > + return __btf__add_decl_tag(btf, value, ref_type_id, component_idx, 1); > +} > + > struct btf_ext_sec_info_param { > __u32 off; > __u32 len; > diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h > index 47ee8f6ac489..1c969a530a3e 100644 > --- a/tools/lib/bpf/btf.h > +++ b/tools/lib/bpf/btf.h > @@ -227,6 +227,7 @@ LIBBPF_API int btf__add_volatile(struct btf *btf, int ref_type_id); > LIBBPF_API int btf__add_const(struct btf *btf, int ref_type_id); > LIBBPF_API int btf__add_restrict(struct btf *btf, int ref_type_id); > LIBBPF_API int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id); > +LIBBPF_API int btf__add_type_attr(struct btf *btf, const char *value, int ref_type_id); > > /* func and func_proto construction APIs */ > LIBBPF_API int btf__add_func(struct btf *btf, const char *name, > @@ -243,6 +244,8 @@ LIBBPF_API int btf__add_datasec_var_info(struct btf *btf, int var_type_id, > /* tag construction API */ > LIBBPF_API int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, > int component_idx); > +LIBBPF_API int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id, > + int component_idx); > > struct btf_dedup_opts { > size_t sz; > diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map > index a8b2936a1646..8616e10b3c1b 100644 > --- a/tools/lib/bpf/libbpf.map > +++ b/tools/lib/bpf/libbpf.map > @@ -436,4 +436,6 @@ LIBBPF_1.6.0 { > bpf_linker__add_buf; > bpf_linker__add_fd; > bpf_linker__new_fd; > + btf__add_decl_attr; > + btf__add_type_attr; > } LIBBPF_1.5.0;
On Wednesday, January 22nd, 2025 at 2:56 AM, Alan Maguire <alan.maguire@oracle.com> wrote: > > > On 22/01/2025 02:53, Ihor Solodrai wrote: > > > Add the following functions to libbpf API: > > * btf__add_type_attr() > > * btf__add_decl_attr() > > > > These functions allow to add to BTF the type tags and decl tags with > > info->kflag set to 1. The kflag indicates that the tag directly > > encodes an attribute and not a normal tag. > > > > See Documentation/bpf/btf.rst changes for details on the semantics. > > > > Suggested-by: Andrii Nakryiko andrii@kernel.org > > Signed-off-by: Ihor Solodrai ihor.solodrai@pm.me > > > need to sync include/uapi/linux/btf.h with > tools/include/uapi/linux/btf.h, but other than that > > Reviewed-by: Alan Maguire alan.maguire@oracle.com I haven't realized btf.h is copied in two places. Will fix, thanks. > > [...]
On Tue, Jan 21, 2025 at 6:53 PM Ihor Solodrai <ihor.solodrai@pm.me> wrote: > > Add the following functions to libbpf API: > * btf__add_type_attr() > * btf__add_decl_attr() > > These functions allow to add to BTF the type tags and decl tags with > info->kflag set to 1. The kflag indicates that the tag directly > encodes an __attribute__ and not a normal tag. > > See Documentation/bpf/btf.rst changes for details on the semantics. > > Suggested-by: Andrii Nakryiko <andrii@kernel.org> > Signed-off-by: Ihor Solodrai <ihor.solodrai@pm.me> > --- > Documentation/bpf/btf.rst | 27 +++++++++-- > tools/include/uapi/linux/btf.h | 3 +- kernel documentation and uapi changes should be in a separate patch from libbpf-side changes > tools/lib/bpf/btf.c | 87 +++++++++++++++++++++++++--------- > tools/lib/bpf/btf.h | 3 ++ > tools/lib/bpf/libbpf.map | 2 + > 5 files changed, 93 insertions(+), 29 deletions(-) > Please double-check whitespacing, tabs vs space might have been messed up in this patch. pw-bot: cr > diff --git a/Documentation/bpf/btf.rst b/Documentation/bpf/btf.rst > index 2478cef758f8..615ded7b2442 100644 > --- a/Documentation/bpf/btf.rst > +++ b/Documentation/bpf/btf.rst > @@ -102,8 +102,9 @@ Each type contains the following common data:: > * bits 24-28: kind (e.g. int, ptr, array...etc) > * bits 29-30: unused > * bit 31: kind_flag, currently used by > - * struct, union, fwd, enum and enum64. > - */ > + * struct, union, enum, fwd, enum64, > + * DECL_TAG and TYPE_TAG keep it lower case > + */ > __u32 info; > /* "size" is used by INT, ENUM, STRUCT, UNION and ENUM64. > * "size" tells the size of the type it is describing. [...] > -/* > - * Append new BTF_KIND_DECL_TAG type with: > - * - *value* - non-empty/non-NULL string; > - * - *ref_type_id* - referenced type ID, it might not exist yet; > - * - *component_idx* - -1 for tagging reference type, otherwise struct/union > - * member or function argument index; > - * Returns: > - * - >0, type ID of newly added BTF type; > - * - <0, on error. > - */ > -int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, > - int component_idx) > + > +static int __btf__add_decl_tag(struct btf *btf, const char *value, > + int ref_type_id, int component_idx, int kflag) nit: please call it "btf_add_decl_tag" (to distinguish it from public API, but also not use double-underscored name unnecessarily) > { > struct btf_type *t; > int sz, value_off; [..]
diff --git a/Documentation/bpf/btf.rst b/Documentation/bpf/btf.rst index 2478cef758f8..615ded7b2442 100644 --- a/Documentation/bpf/btf.rst +++ b/Documentation/bpf/btf.rst @@ -102,8 +102,9 @@ Each type contains the following common data:: * bits 24-28: kind (e.g. int, ptr, array...etc) * bits 29-30: unused * bit 31: kind_flag, currently used by - * struct, union, fwd, enum and enum64. - */ + * struct, union, enum, fwd, enum64, + * DECL_TAG and TYPE_TAG + */ __u32 info; /* "size" is used by INT, ENUM, STRUCT, UNION and ENUM64. * "size" tells the size of the type it is describing. @@ -478,7 +479,7 @@ No additional type data follow ``btf_type``. ``struct btf_type`` encoding requirement: * ``name_off``: offset to a non-empty string - * ``info.kind_flag``: 0 + * ``info.kind_flag``: 0 or 1 * ``info.kind``: BTF_KIND_DECL_TAG * ``info.vlen``: 0 * ``type``: ``struct``, ``union``, ``func``, ``var`` or ``typedef`` @@ -489,7 +490,6 @@ No additional type data follow ``btf_type``. __u32 component_idx; }; -The ``name_off`` encodes btf_decl_tag attribute string. The ``type`` should be ``struct``, ``union``, ``func``, ``var`` or ``typedef``. For ``var`` or ``typedef`` type, ``btf_decl_tag.component_idx`` must be ``-1``. For the other three types, if the btf_decl_tag attribute is @@ -499,12 +499,21 @@ the attribute is applied to a ``struct``/``union`` member or a ``func`` argument, and ``btf_decl_tag.component_idx`` should be a valid index (starting from 0) pointing to a member or an argument. +If ``info.kind_flag`` is 0, then this is a normal decl tag, and the +``name_off`` encodes btf_decl_tag attribute string. + +If ``info.kind_flag`` is 1, then the decl tag represents an arbitrary +__attribute__. In this case, ``name_off`` encodes a string +representing the attribute-list of the attribute specifier. For +example, for an ``__attribute__((aligned(4)))`` the string's contents +is ``aligned(4)``. + 2.2.18 BTF_KIND_TYPE_TAG ~~~~~~~~~~~~~~~~~~~~~~~~ ``struct btf_type`` encoding requirement: * ``name_off``: offset to a non-empty string - * ``info.kind_flag``: 0 + * ``info.kind_flag``: 0 or 1 * ``info.kind``: BTF_KIND_TYPE_TAG * ``info.vlen``: 0 * ``type``: the type with ``btf_type_tag`` attribute @@ -522,6 +531,14 @@ type_tag, then zero or more const/volatile/restrict/typedef and finally the base type. The base type is one of int, ptr, array, struct, union, enum, func_proto and float types. +Similarly to decl tags, if the ``info.kind_flag`` is 0, then this is a +normal type tag, and the ``name_off`` encodes btf_type_tag attribute +string. + +If ``info.kind_flag`` is 1, then the type tag represents an arbitrary +__attribute__, and the ``name_off`` encodes a string representing the +attribute-list of the attribute specifier. + 2.2.19 BTF_KIND_ENUM64 ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tools/include/uapi/linux/btf.h b/tools/include/uapi/linux/btf.h index ec1798b6d3ff..d602c26a0c2a 100644 --- a/tools/include/uapi/linux/btf.h +++ b/tools/include/uapi/linux/btf.h @@ -36,7 +36,8 @@ struct btf_type { * bits 24-28: kind (e.g. int, ptr, array...etc) * bits 29-30: unused * bit 31: kind_flag, currently used by - * struct, union, enum, fwd and enum64 + * struct, union, enum, fwd, enum64, + * DECL_TAG and TYPE_TAG */ __u32 info; /* "size" is used by INT, ENUM, STRUCT, UNION, DATASEC and ENUM64. diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 48c66f3a9200..df2808cee009 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -2090,7 +2090,7 @@ static int validate_type_id(int id) } /* generic append function for PTR, TYPEDEF, CONST/VOLATILE/RESTRICT */ -static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref_type_id) +static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref_type_id, int kflag) { struct btf_type *t; int sz, name_off = 0; @@ -2113,7 +2113,7 @@ static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref } t->name_off = name_off; - t->info = btf_type_info(kind, 0, 0); + t->info = btf_type_info(kind, 0, kflag); t->type = ref_type_id; return btf_commit_type(btf, sz); @@ -2128,7 +2128,7 @@ static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref */ int btf__add_ptr(struct btf *btf, int ref_type_id) { - return btf_add_ref_kind(btf, BTF_KIND_PTR, NULL, ref_type_id); + return btf_add_ref_kind(btf, BTF_KIND_PTR, NULL, ref_type_id, 0); } /* @@ -2506,7 +2506,7 @@ int btf__add_fwd(struct btf *btf, const char *name, enum btf_fwd_kind fwd_kind) struct btf_type *t; int id; - id = btf_add_ref_kind(btf, BTF_KIND_FWD, name, 0); + id = btf_add_ref_kind(btf, BTF_KIND_FWD, name, 0, 0); if (id <= 0) return id; t = btf_type_by_id(btf, id); @@ -2536,7 +2536,7 @@ int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id) if (!name || !name[0]) return libbpf_err(-EINVAL); - return btf_add_ref_kind(btf, BTF_KIND_TYPEDEF, name, ref_type_id); + return btf_add_ref_kind(btf, BTF_KIND_TYPEDEF, name, ref_type_id, 0); } /* @@ -2548,7 +2548,7 @@ int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id) */ int btf__add_volatile(struct btf *btf, int ref_type_id) { - return btf_add_ref_kind(btf, BTF_KIND_VOLATILE, NULL, ref_type_id); + return btf_add_ref_kind(btf, BTF_KIND_VOLATILE, NULL, ref_type_id, 0); } /* @@ -2560,7 +2560,7 @@ int btf__add_volatile(struct btf *btf, int ref_type_id) */ int btf__add_const(struct btf *btf, int ref_type_id) { - return btf_add_ref_kind(btf, BTF_KIND_CONST, NULL, ref_type_id); + return btf_add_ref_kind(btf, BTF_KIND_CONST, NULL, ref_type_id, 0); } /* @@ -2572,7 +2572,7 @@ int btf__add_const(struct btf *btf, int ref_type_id) */ int btf__add_restrict(struct btf *btf, int ref_type_id) { - return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id); + return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id, 0); } /* @@ -2588,7 +2588,24 @@ int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id) if (!value || !value[0]) return libbpf_err(-EINVAL); - return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id); + return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id, 0); +} + +/* + * Append new BTF_KIND_TYPE_TAG type with: + * - *value*, non-empty/non-NULL tag value; + * - *ref_type_id* - referenced type ID, it might not exist yet; + * Set info->kflag to 1, indicating this tag is an __attribute__ + * Returns: + * - >0, type ID of newly added BTF type; + * - <0, on error. + */ +int btf__add_type_attr(struct btf *btf, const char *value, int ref_type_id) +{ + if (!value || !value[0]) + return libbpf_err(-EINVAL); + + return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id, 1); } /* @@ -2610,7 +2627,7 @@ int btf__add_func(struct btf *btf, const char *name, linkage != BTF_FUNC_EXTERN) return libbpf_err(-EINVAL); - id = btf_add_ref_kind(btf, BTF_KIND_FUNC, name, proto_type_id); + id = btf_add_ref_kind(btf, BTF_KIND_FUNC, name, proto_type_id, 0); if (id > 0) { struct btf_type *t = btf_type_by_id(btf, id); @@ -2845,18 +2862,9 @@ int btf__add_datasec_var_info(struct btf *btf, int var_type_id, __u32 offset, __ return 0; } -/* - * Append new BTF_KIND_DECL_TAG type with: - * - *value* - non-empty/non-NULL string; - * - *ref_type_id* - referenced type ID, it might not exist yet; - * - *component_idx* - -1 for tagging reference type, otherwise struct/union - * member or function argument index; - * Returns: - * - >0, type ID of newly added BTF type; - * - <0, on error. - */ -int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, - int component_idx) + +static int __btf__add_decl_tag(struct btf *btf, const char *value, + int ref_type_id, int component_idx, int kflag) { struct btf_type *t; int sz, value_off; @@ -2880,13 +2888,46 @@ int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, return value_off; t->name_off = value_off; - t->info = btf_type_info(BTF_KIND_DECL_TAG, 0, false); + t->info = btf_type_info(BTF_KIND_DECL_TAG, 0, kflag); t->type = ref_type_id; btf_decl_tag(t)->component_idx = component_idx; return btf_commit_type(btf, sz); } +/* + * Append new BTF_KIND_DECL_TAG type with: + * - *value* - non-empty/non-NULL string; + * - *ref_type_id* - referenced type ID, it might not exist yet; + * - *component_idx* - -1 for tagging reference type, otherwise struct/union + * member or function argument index; + * Returns: + * - >0, type ID of newly added BTF type; + * - <0, on error. + */ +int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, + int component_idx) +{ + return __btf__add_decl_tag(btf, value, ref_type_id, component_idx, 0); +} + +/* + * Append new BTF_KIND_DECL_TAG type with: + * - *value* - non-empty/non-NULL string; + * - *ref_type_id* - referenced type ID, it might not exist yet; + * - *component_idx* - -1 for tagging reference type, otherwise struct/union + * member or function argument index; + * Set info->kflag to 1, indicating this tag is an __attribute__ + * Returns: + * - >0, type ID of newly added BTF type; + * - <0, on error. + */ +int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id, + int component_idx) +{ + return __btf__add_decl_tag(btf, value, ref_type_id, component_idx, 1); +} + struct btf_ext_sec_info_param { __u32 off; __u32 len; diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index 47ee8f6ac489..1c969a530a3e 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h @@ -227,6 +227,7 @@ LIBBPF_API int btf__add_volatile(struct btf *btf, int ref_type_id); LIBBPF_API int btf__add_const(struct btf *btf, int ref_type_id); LIBBPF_API int btf__add_restrict(struct btf *btf, int ref_type_id); LIBBPF_API int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id); +LIBBPF_API int btf__add_type_attr(struct btf *btf, const char *value, int ref_type_id); /* func and func_proto construction APIs */ LIBBPF_API int btf__add_func(struct btf *btf, const char *name, @@ -243,6 +244,8 @@ LIBBPF_API int btf__add_datasec_var_info(struct btf *btf, int var_type_id, /* tag construction API */ LIBBPF_API int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, int component_idx); +LIBBPF_API int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id, + int component_idx); struct btf_dedup_opts { size_t sz; diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index a8b2936a1646..8616e10b3c1b 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -436,4 +436,6 @@ LIBBPF_1.6.0 { bpf_linker__add_buf; bpf_linker__add_fd; bpf_linker__new_fd; + btf__add_decl_attr; + btf__add_type_attr; } LIBBPF_1.5.0;
Add the following functions to libbpf API: * btf__add_type_attr() * btf__add_decl_attr() These functions allow to add to BTF the type tags and decl tags with info->kflag set to 1. The kflag indicates that the tag directly encodes an __attribute__ and not a normal tag. See Documentation/bpf/btf.rst changes for details on the semantics. Suggested-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Ihor Solodrai <ihor.solodrai@pm.me> --- Documentation/bpf/btf.rst | 27 +++++++++-- tools/include/uapi/linux/btf.h | 3 +- tools/lib/bpf/btf.c | 87 +++++++++++++++++++++++++--------- tools/lib/bpf/btf.h | 3 ++ tools/lib/bpf/libbpf.map | 2 + 5 files changed, 93 insertions(+), 29 deletions(-)