On Tue, 2024-01-02 at 11:00 -0800, Andrii Nakryiko wrote: [...] > +static int clone_func_btf_info(struct btf *btf, int orig_fn_id, struct bpf_program *prog) > +{ [...] > + /* clone FUNC first, btf__add_func() enforces > + * non-empty name, so use entry program's name as > + * a placeholder, which we replace immediately > + */ > + fn_id = btf__add_func(btf, prog->name, btf_func_linkage(fn_t), fn_t->type); Nit: Why not call this function near the end, when fn_proto_id is available? Thus avoiding need to "guess" fn_t->type. [...] > +static int bpf_program_fixup_func_info(struct bpf_object *obj, struct bpf_program *prog) > +{ [...] > + for (i = 1, n = btf__type_cnt(btf); i < n; i++) { [...] > + > + /* clone fn/fn_proto, unless we already did it for another arg */ > + if (func_rec->type_id == orig_fn_id) { > + int fn_id; > + > + fn_id = clone_func_btf_info(btf, orig_fn_id, prog); > + if (fn_id < 0) { > + err = fn_id; > + goto err_out; > + } > + > + /* point func_info record to a cloned FUNC type */ > + func_rec->type_id = fn_id; Would it be helpful to add a log here, saying that BTF for function so and so is changed before load? > + } > + > + /* create PTR -> STRUCT type chain to mark PTR_TO_CTX argument; > + * we do it just once per main BPF program, as all global > + * funcs share the same program type, so need only PTR -> > + * STRUCT type chain > + */ > + if (ptr_id == 0) { > + struct_id = btf__add_struct(btf, ctx_name, 0); Nit: Maybe try looking up existing id for type ctx_name first? > + ptr_id = btf__add_ptr(btf, struct_id); > + if (ptr_id < 0 || struct_id < 0) { > + err = -EINVAL; > + goto err_out; > + } > + } > + [...]