| @@ -189,6 +189,7 @@ struct bpf_program { · 188 unmodified lines |
| 189 | 189 | |
| 190 | 190 | enum bpf_attach_type expected_attach_type; |
| 191 | 191 | __u32 attach_btf_id; |
| 192 | + __u32 attach_prog_fd; |
| 192 | 193 | void *func_info; |
| 193 | 194 | __u32 func_info_rec_size; |
| 194 | 195 | __u32 func_info_cnt; |
| @@ -3683,8 +3684,13 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, · 3488 unmodified lines |
| 3683 | 3684 | load_attr.insns = insns; |
| 3684 | 3685 | load_attr.insns_cnt = insns_cnt; |
| 3685 | 3686 | load_attr.license = license; |
| 3686 | | − load_attr.kern_version = kern_version; |
| 3687 | | − load_attr.prog_ifindex = prog->prog_ifindex; |
| 3687 | + if (prog->type == BPF_PROG_TYPE_TRACING) { |
| 3688 | + load_attr.attach_prog_fd = prog->attach_prog_fd; |
| 3689 | + load_attr.attach_btf_id = prog->attach_btf_id; |
| 3690 | + } else { |
| 3691 | + load_attr.kern_version = kern_version; |
| 3692 | + load_attr.prog_ifindex = prog->prog_ifindex; |
| 3693 | + } |
| 3688 | 3694 | /* if .BTF.ext was loaded, kernel supports associated BTF for prog */ |
| 3689 | 3695 | if (prog->obj->btf_ext) |
| 3690 | 3696 | btf_fd = bpf_object__btf_fd(prog->obj); |
| @@ -3699,7 +3705,6 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, · 8 unmodified lines |
| 3699 | 3705 | load_attr.line_info_cnt = prog->line_info_cnt; |
| 3700 | 3706 | load_attr.log_level = prog->log_level; |
| 3701 | 3707 | load_attr.prog_flags = prog->prog_flags; |
| 3702 | | − load_attr.attach_btf_id = prog->attach_btf_id; |
| 3703 | 3708 | |
| 3704 | 3709 | retry_load: |
| 3705 | 3710 | log_buf = malloc(log_buf_size); |
| @@ -3856,9 +3861,9 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level) · 150 unmodified lines |
| 3856 | 3861 | return 0; |
| 3857 | 3862 | } |
| 3858 | 3863 | |
| 3859 | | −static int libbpf_attach_btf_id_by_name(const char *name, |
| 3860 | | − enum bpf_attach_type attach_type); |
| 3861 | | − |
| 3864 | +static int libbpf_find_attach_btf_id(const char *name, |
| 3865 | + enum bpf_attach_type attach_type, |
| 3866 | + __u32 attach_prog_fd); |
| 3862 | 3867 | static struct bpf_object * |
| 3863 | 3868 | __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz, |
| 3864 | 3869 | struct bpf_object_open_opts *opts) |
| @@ -3869,6 +3874,7 @@ __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz, · 4 unmodified lines |
| 3869 | 3874 | const char *obj_name; |
| 3870 | 3875 | char tmp_name[64]; |
| 3871 | 3876 | bool relaxed_maps; |
| 3877 | + __u32 attach_prog_fd; |
| 3872 | 3878 | int err; |
| 3873 | 3879 | |
| 3874 | 3880 | if (elf_version(EV_CURRENT) == EV_NONE) { |
| @@ -3899,6 +3905,7 @@ __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz, · 24 unmodified lines |
| 3899 | 3905 | obj->relaxed_core_relocs = OPTS_GET(opts, relaxed_core_relocs, false); |
| 3900 | 3906 | relaxed_maps = OPTS_GET(opts, relaxed_maps, false); |
| 3901 | 3907 | pin_root_path = OPTS_GET(opts, pin_root_path, NULL); |
| 3908 | + attach_prog_fd = OPTS_GET(opts, attach_prog_fd, 0); |
| 3902 | 3909 | |
| 3903 | 3910 | CHECK_ERR(bpf_object__elf_init(obj), err, out); |
| 3904 | 3911 | CHECK_ERR(bpf_object__check_endianness(obj), err, out); |
| @@ -3923,11 +3930,13 @@ __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz, · 18 unmodified lines |
| 3923 | 3930 | bpf_program__set_type(prog, prog_type); |
| 3924 | 3931 | bpf_program__set_expected_attach_type(prog, attach_type); |
| 3925 | 3932 | if (prog_type == BPF_PROG_TYPE_TRACING) { |
| 3926 | | − err = libbpf_attach_btf_id_by_name(prog->section_name, |
| 3927 | | − attach_type); |
| 3933 | + err = libbpf_find_attach_btf_id(prog->section_name, |
| 3934 | + attach_type, |
| 3935 | + attach_prog_fd); |
| 3928 | 3936 | if (err <= 0) |
| 3929 | 3937 | goto out; |
| 3930 | 3938 | prog->attach_btf_id = err; |
| 3939 | + prog->attach_prog_fd = attach_prog_fd; |
| 3931 | 3940 | } |
| 3932 | 3941 | } |
| 3933 | 3942 | |
| @@ -5086,8 +5095,42 @@ int libbpf_find_vmlinux_btf_id(const char *name, · 1152 unmodified lines |
| 5086 | 5095 | return err; |
| 5087 | 5096 | } |
| 5088 | 5097 | |
| 5089 | | −static int libbpf_attach_btf_id_by_name(const char *name, |
| 5090 | | − enum bpf_attach_type attach_type) |
| 5098 | +static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd) |
| 5099 | +{ |
| 5100 | + struct bpf_prog_info_linear *info_linear; |
| 5101 | + struct bpf_prog_info *info; |
| 5102 | + struct btf *btf = NULL; |
| 5103 | + int err = -EINVAL; |
| 5104 | + |
| 5105 | + info_linear = bpf_program__get_prog_info_linear(attach_prog_fd, 0); |
| 5106 | + if (IS_ERR_OR_NULL(info_linear)) { |
| 5107 | + pr_warn("failed get_prog_info_linear for FD %d\n", |
| 5108 | + attach_prog_fd); |
| 5109 | + return -EINVAL; |
| 5110 | + } |
| 5111 | + info = &info_linear->info; |
| 5112 | + if (!info->btf_id) { |
| 5113 | + pr_warn("The target program doesn't have BTF\n"); |
| 5114 | + goto out; |
| 5115 | + } |
| 5116 | + if (btf__get_from_id(info->btf_id, &btf)) { |
| 5117 | + pr_warn("Failed to get BTF of the program\n"); |
| 5118 | + goto out; |
| 5119 | + } |
| 5120 | + err = btf__find_by_name_kind(btf, name, BTF_KIND_FUNC); |
| 5121 | + btf__free(btf); |
| 5122 | + if (err <= 0) { |
| 5123 | + pr_warn("%s is not found in prog's BTF\n", name); |
| 5124 | + goto out; |
| 5125 | + } |
| 5126 | +out: |
| 5127 | + free(info_linear); |
| 5128 | + return err; |
| 5129 | +} |
| 5130 | + |
| 5131 | +static int libbpf_find_attach_btf_id(const char *name, |
| 5132 | + enum bpf_attach_type attach_type, |
| 5133 | + __u32 attach_prog_fd) |
| 5091 | 5134 | { |
| 5092 | 5135 | int i, err; |
| 5093 | 5136 | |
| @@ -5099,8 +5142,12 @@ static int libbpf_attach_btf_id_by_name(const char *name, · 5 unmodified lines |
| 5099 | 5142 | continue; |
| 5100 | 5143 | if (strncmp(name, section_names[i].sec, section_names[i].len)) |
| 5101 | 5144 | continue; |
| 5102 | | − err = libbpf_find_vmlinux_btf_id(name + section_names[i].len, |
| 5103 | | − attach_type); |
| 5145 | + if (attach_prog_fd) |
| 5146 | + err = libbpf_find_prog_btf_id(name + section_names[i].len, |
| 5147 | + attach_prog_fd); |
| 5148 | + else |
| 5149 | + err = libbpf_find_vmlinux_btf_id(name + section_names[i].len, |
| 5150 | + attach_type); |
| 5104 | 5151 | if (err <= 0) |
| 5105 | 5152 | pr_warn("%s is not found in vmlinux BTF\n", name); |
| 5106 | 5153 | return err; |