In case the kernel doesn't support BTF_FUNC_GLOBAL sanitize BTF produced by the compiler for global functions.
Unified · Split
| @@ -146,6 +146,12 @@ enum { · 145 unmodified lines | |||
| 146 | BTF_VAR_GLOBAL_EXTERN = 2, | 146 | BTF_VAR_GLOBAL_EXTERN = 2, |
| 147 | }; | 147 | }; |
| 148 | 148 | ||
| 149 | enum btf_func_linkage { | ||
| 150 | BTF_FUNC_STATIC = 0, | ||
| 151 | BTF_FUNC_GLOBAL = 1, | ||
| 152 | BTF_FUNC_EXTERN = 2, | ||
| 153 | }; | ||
| 154 | |||
| 149 | /* BTF_KIND_VAR is followed by a single "struct btf_var" to describe | 155 | /* BTF_KIND_VAR is followed by a single "struct btf_var" to describe |
| 150 | * additional information related to the variable such as its linkage. | 156 | * additional information related to the variable such as its linkage. |
| 151 | */ | 157 | */ |
| @@ -173,6 +173,8 @@ struct bpf_capabilities { · 172 unmodified lines | |||
| 173 | __u32 btf_datasec:1; | 173 | __u32 btf_datasec:1; |
| 174 | /* BPF_F_MMAPABLE is supported for arrays */ | 174 | /* BPF_F_MMAPABLE is supported for arrays */ |
| 175 | __u32 array_mmap:1; | 175 | __u32 array_mmap:1; |
| 176 | /* BTF_FUNC_GLOBAL is supported */ | ||
| 177 | __u32 btf_func_global:1; | ||
| 176 | }; | 178 | }; |
| 177 | 179 | ||
| 178 | enum reloc_type { | 180 | enum reloc_type { |
| @@ -2209,13 +2211,14 @@ static bool section_have_execinstr(struct bpf_object *obj, int idx) · 2030 unmodified lines | |||
| 2209 | 2211 | ||
| 2210 | static void bpf_object__sanitize_btf(struct bpf_object *obj) | 2212 | static void bpf_object__sanitize_btf(struct bpf_object *obj) |
| 2211 | { | 2213 | { |
| 2214 | bool has_func_global = obj->caps.btf_func_global; | ||
| 2212 | bool has_datasec = obj->caps.btf_datasec; | 2215 | bool has_datasec = obj->caps.btf_datasec; |
| 2213 | bool has_func = obj->caps.btf_func; | 2216 | bool has_func = obj->caps.btf_func; |
| 2214 | struct btf *btf = obj->btf; | 2217 | struct btf *btf = obj->btf; |
| 2215 | struct btf_type *t; | 2218 | struct btf_type *t; |
| 2216 | int i, j, vlen; | 2219 | int i, j, vlen; |
| 2217 | 2220 | ||
| 2218 | if (!obj->btf || (has_func && has_datasec)) | 2221 | if (!obj->btf || (has_func && has_datasec && has_func_global)) |
| 2219 | return; | 2222 | return; |
| 2220 | 2223 | ||
| 2221 | for (i = 1; i <= btf__get_nr_types(btf); i++) { | 2224 | for (i = 1; i <= btf__get_nr_types(btf); i++) { |
| @@ -2263,6 +2266,9 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj) · 41 unmodified lines | |||
| 2263 | } else if (!has_func && btf_is_func(t)) { | 2266 | } else if (!has_func && btf_is_func(t)) { |
| 2264 | /* replace FUNC with TYPEDEF */ | 2267 | /* replace FUNC with TYPEDEF */ |
| 2265 | t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0); | 2268 | t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0); |
| 2269 | } else if (!has_func_global && btf_is_func(t)) { | ||
| 2270 | /* replace BTF_FUNC_GLOBAL with BTF_FUNC_STATIC */ | ||
| 2271 | t->info = BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0); | ||
| 2266 | } | 2272 | } |
| 2267 | } | 2273 | } |
| 2268 | } | 2274 | } |
| @@ -3205,6 +3211,32 @@ static int bpf_object__probe_btf_func(struct bpf_object *obj) · 936 unmodified lines | |||
| 3205 | return 0; | 3211 | return 0; |
| 3206 | } | 3212 | } |
| 3207 | 3213 | ||
| 3214 | static int bpf_object__probe_btf_func_global(struct bpf_object *obj) | ||
| 3215 | { | ||
| 3216 | static const char strs[] = "\0int\0x\0a"; | ||
| 3217 | /* static void x(int a) {} */ | ||
| 3218 | __u32 types[] = { | ||
| 3219 | /* int */ | ||
| 3220 | BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ | ||
| 3221 | /* FUNC_PROTO */ /* [2] */ | ||
| 3222 | BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0), | ||
| 3223 | BTF_PARAM_ENC(7, 1), | ||
| 3224 | /* FUNC x BTF_FUNC_GLOBAL */ /* [3] */ | ||
| 3225 | BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 2), | ||
| 3226 | }; | ||
| 3227 | int btf_fd; | ||
| 3228 | |||
| 3229 | btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types), | ||
| 3230 | strs, sizeof(strs)); | ||
| 3231 | if (btf_fd >= 0) { | ||
| 3232 | obj->caps.btf_func_global = 1; | ||
| 3233 | close(btf_fd); | ||
| 3234 | return 1; | ||
| 3235 | } | ||
| 3236 | |||
| 3237 | return 0; | ||
| 3238 | } | ||
| 3239 | |||
| 3208 | static int bpf_object__probe_btf_datasec(struct bpf_object *obj) | 3240 | static int bpf_object__probe_btf_datasec(struct bpf_object *obj) |
| 3209 | { | 3241 | { |
| 3210 | static const char strs[] = "\0x\0.data"; | 3242 | static const char strs[] = "\0x\0.data"; |
| @@ -3260,6 +3292,7 @@ bpf_object__probe_caps(struct bpf_object *obj) · 49 unmodified lines | |||
| 3260 | bpf_object__probe_name, | 3292 | bpf_object__probe_name, |
| 3261 | bpf_object__probe_global_data, | 3293 | bpf_object__probe_global_data, |
| 3262 | bpf_object__probe_btf_func, | 3294 | bpf_object__probe_btf_func, |
| 3295 | bpf_object__probe_btf_func_global, | ||
| 3263 | bpf_object__probe_btf_datasec, | 3296 | bpf_object__probe_btf_datasec, |
| 3264 | bpf_object__probe_array_mmap, | 3297 | bpf_object__probe_array_mmap, |
| 3265 | }; | 3298 | }; |