Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libbpf: Introduce kflag for type_tags and decl_tags in BTF

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 in the subsequent patch for
details on the semantics.

Suggested-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20250130201239.1429648-2-ihor.solodrai@linux.dev

authored by

Ihor Solodrai and committed by
Andrii Nakryiko
51d1b1d4 03f3aa4a

+68 -23
+63 -23
tools/lib/bpf/btf.c
··· 2090 2090 } 2091 2091 2092 2092 /* generic append function for PTR, TYPEDEF, CONST/VOLATILE/RESTRICT */ 2093 - static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref_type_id) 2093 + static int btf_add_ref_kind(struct btf *btf, int kind, const char *name, int ref_type_id, int kflag) 2094 2094 { 2095 2095 struct btf_type *t; 2096 2096 int sz, name_off = 0; ··· 2113 2113 } 2114 2114 2115 2115 t->name_off = name_off; 2116 - t->info = btf_type_info(kind, 0, 0); 2116 + t->info = btf_type_info(kind, 0, kflag); 2117 2117 t->type = ref_type_id; 2118 2118 2119 2119 return btf_commit_type(btf, sz); ··· 2128 2128 */ 2129 2129 int btf__add_ptr(struct btf *btf, int ref_type_id) 2130 2130 { 2131 - return btf_add_ref_kind(btf, BTF_KIND_PTR, NULL, ref_type_id); 2131 + return btf_add_ref_kind(btf, BTF_KIND_PTR, NULL, ref_type_id, 0); 2132 2132 } 2133 2133 2134 2134 /* ··· 2506 2506 struct btf_type *t; 2507 2507 int id; 2508 2508 2509 - id = btf_add_ref_kind(btf, BTF_KIND_FWD, name, 0); 2509 + id = btf_add_ref_kind(btf, BTF_KIND_FWD, name, 0, 0); 2510 2510 if (id <= 0) 2511 2511 return id; 2512 2512 t = btf_type_by_id(btf, id); ··· 2536 2536 if (!name || !name[0]) 2537 2537 return libbpf_err(-EINVAL); 2538 2538 2539 - return btf_add_ref_kind(btf, BTF_KIND_TYPEDEF, name, ref_type_id); 2539 + return btf_add_ref_kind(btf, BTF_KIND_TYPEDEF, name, ref_type_id, 0); 2540 2540 } 2541 2541 2542 2542 /* ··· 2548 2548 */ 2549 2549 int btf__add_volatile(struct btf *btf, int ref_type_id) 2550 2550 { 2551 - return btf_add_ref_kind(btf, BTF_KIND_VOLATILE, NULL, ref_type_id); 2551 + return btf_add_ref_kind(btf, BTF_KIND_VOLATILE, NULL, ref_type_id, 0); 2552 2552 } 2553 2553 2554 2554 /* ··· 2560 2560 */ 2561 2561 int btf__add_const(struct btf *btf, int ref_type_id) 2562 2562 { 2563 - return btf_add_ref_kind(btf, BTF_KIND_CONST, NULL, ref_type_id); 2563 + return btf_add_ref_kind(btf, BTF_KIND_CONST, NULL, ref_type_id, 0); 2564 2564 } 2565 2565 2566 2566 /* ··· 2572 2572 */ 2573 2573 int btf__add_restrict(struct btf *btf, int ref_type_id) 2574 2574 { 2575 - return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id); 2575 + return btf_add_ref_kind(btf, BTF_KIND_RESTRICT, NULL, ref_type_id, 0); 2576 2576 } 2577 2577 2578 2578 /* ··· 2588 2588 if (!value || !value[0]) 2589 2589 return libbpf_err(-EINVAL); 2590 2590 2591 - return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id); 2591 + return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id, 0); 2592 + } 2593 + 2594 + /* 2595 + * Append new BTF_KIND_TYPE_TAG type with: 2596 + * - *value*, non-empty/non-NULL tag value; 2597 + * - *ref_type_id* - referenced type ID, it might not exist yet; 2598 + * Set info->kflag to 1, indicating this tag is an __attribute__ 2599 + * Returns: 2600 + * - >0, type ID of newly added BTF type; 2601 + * - <0, on error. 2602 + */ 2603 + int btf__add_type_attr(struct btf *btf, const char *value, int ref_type_id) 2604 + { 2605 + if (!value || !value[0]) 2606 + return libbpf_err(-EINVAL); 2607 + 2608 + return btf_add_ref_kind(btf, BTF_KIND_TYPE_TAG, value, ref_type_id, 1); 2592 2609 } 2593 2610 2594 2611 /* ··· 2627 2610 linkage != BTF_FUNC_EXTERN) 2628 2611 return libbpf_err(-EINVAL); 2629 2612 2630 - id = btf_add_ref_kind(btf, BTF_KIND_FUNC, name, proto_type_id); 2613 + id = btf_add_ref_kind(btf, BTF_KIND_FUNC, name, proto_type_id, 0); 2631 2614 if (id > 0) { 2632 2615 struct btf_type *t = btf_type_by_id(btf, id); 2633 2616 ··· 2862 2845 return 0; 2863 2846 } 2864 2847 2865 - /* 2866 - * Append new BTF_KIND_DECL_TAG type with: 2867 - * - *value* - non-empty/non-NULL string; 2868 - * - *ref_type_id* - referenced type ID, it might not exist yet; 2869 - * - *component_idx* - -1 for tagging reference type, otherwise struct/union 2870 - * member or function argument index; 2871 - * Returns: 2872 - * - >0, type ID of newly added BTF type; 2873 - * - <0, on error. 2874 - */ 2875 - int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, 2876 - int component_idx) 2848 + static int btf_add_decl_tag(struct btf *btf, const char *value, int ref_type_id, 2849 + int component_idx, int kflag) 2877 2850 { 2878 2851 struct btf_type *t; 2879 2852 int sz, value_off; ··· 2887 2880 return value_off; 2888 2881 2889 2882 t->name_off = value_off; 2890 - t->info = btf_type_info(BTF_KIND_DECL_TAG, 0, false); 2883 + t->info = btf_type_info(BTF_KIND_DECL_TAG, 0, kflag); 2891 2884 t->type = ref_type_id; 2892 2885 btf_decl_tag(t)->component_idx = component_idx; 2893 2886 2894 2887 return btf_commit_type(btf, sz); 2888 + } 2889 + 2890 + /* 2891 + * Append new BTF_KIND_DECL_TAG type with: 2892 + * - *value* - non-empty/non-NULL string; 2893 + * - *ref_type_id* - referenced type ID, it might not exist yet; 2894 + * - *component_idx* - -1 for tagging reference type, otherwise struct/union 2895 + * member or function argument index; 2896 + * Returns: 2897 + * - >0, type ID of newly added BTF type; 2898 + * - <0, on error. 2899 + */ 2900 + int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, 2901 + int component_idx) 2902 + { 2903 + return btf_add_decl_tag(btf, value, ref_type_id, component_idx, 0); 2904 + } 2905 + 2906 + /* 2907 + * Append new BTF_KIND_DECL_TAG type with: 2908 + * - *value* - non-empty/non-NULL string; 2909 + * - *ref_type_id* - referenced type ID, it might not exist yet; 2910 + * - *component_idx* - -1 for tagging reference type, otherwise struct/union 2911 + * member or function argument index; 2912 + * Set info->kflag to 1, indicating this tag is an __attribute__ 2913 + * Returns: 2914 + * - >0, type ID of newly added BTF type; 2915 + * - <0, on error. 2916 + */ 2917 + int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id, 2918 + int component_idx) 2919 + { 2920 + return btf_add_decl_tag(btf, value, ref_type_id, component_idx, 1); 2895 2921 } 2896 2922 2897 2923 struct btf_ext_sec_info_param {
+3
tools/lib/bpf/btf.h
··· 227 227 LIBBPF_API int btf__add_const(struct btf *btf, int ref_type_id); 228 228 LIBBPF_API int btf__add_restrict(struct btf *btf, int ref_type_id); 229 229 LIBBPF_API int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id); 230 + LIBBPF_API int btf__add_type_attr(struct btf *btf, const char *value, int ref_type_id); 230 231 231 232 /* func and func_proto construction APIs */ 232 233 LIBBPF_API int btf__add_func(struct btf *btf, const char *name, ··· 244 243 /* tag construction API */ 245 244 LIBBPF_API int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id, 246 245 int component_idx); 246 + LIBBPF_API int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id, 247 + int component_idx); 247 248 248 249 struct btf_dedup_opts { 249 250 size_t sz;
+2
tools/lib/bpf/libbpf.map
··· 436 436 bpf_linker__add_buf; 437 437 bpf_linker__add_fd; 438 438 bpf_linker__new_fd; 439 + btf__add_decl_attr; 440 + btf__add_type_attr; 439 441 } LIBBPF_1.5.0;