diff options
Diffstat (limited to 'tools/lib/bpf/btf.c')
-rw-r--r-- | tools/lib/bpf/btf.c | 69 |
1 files changed, 27 insertions, 42 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 1cd4e5d67158..aacb7608f02d 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -35,47 +35,6 @@ struct btf { int fd; }; -struct btf_ext_info { - /* - * info points to the individual info section (e.g. func_info and - * line_info) from the .BTF.ext. It does not include the __u32 rec_size. - */ - void *info; - __u32 rec_size; - __u32 len; -}; - -struct btf_ext { - union { - struct btf_ext_header *hdr; - void *data; - }; - struct btf_ext_info func_info; - struct btf_ext_info line_info; - __u32 data_size; -}; - -struct btf_ext_info_sec { - __u32 sec_name_off; - __u32 num_info; - /* Followed by num_info * record_size number of bytes */ - __u8 data[0]; -}; - -/* The minimum bpf_func_info checked by the loader */ -struct bpf_func_info_min { - __u32 insn_off; - __u32 type_id; -}; - -/* The minimum bpf_line_info checked by the loader */ -struct bpf_line_info_min { - __u32 insn_off; - __u32 file_name_off; - __u32 line_off; - __u32 line_col; -}; - static inline __u64 ptr_to_u64(const void *ptr) { return (__u64) (unsigned long) ptr; @@ -822,6 +781,9 @@ static int btf_ext_setup_info(struct btf_ext *btf_ext, /* The start of the info sec (including the __u32 record_size). */ void *info; + if (ext_sec->len == 0) + return 0; + if (ext_sec->off & 0x03) { pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n", ext_sec->desc); @@ -925,11 +887,24 @@ static int btf_ext_setup_line_info(struct btf_ext *btf_ext) return btf_ext_setup_info(btf_ext, ¶m); } +static int btf_ext_setup_offset_reloc(struct btf_ext *btf_ext) +{ + struct btf_ext_sec_setup_param param = { + .off = btf_ext->hdr->offset_reloc_off, + .len = btf_ext->hdr->offset_reloc_len, + .min_rec_size = sizeof(struct bpf_offset_reloc), + .ext_info = &btf_ext->offset_reloc_info, + .desc = "offset_reloc", + }; + + return btf_ext_setup_info(btf_ext, ¶m); +} + static int btf_ext_parse_hdr(__u8 *data, __u32 data_size) { const struct btf_ext_header *hdr = (struct btf_ext_header *)data; - if (data_size < offsetof(struct btf_ext_header, func_info_off) || + if (data_size < offsetofend(struct btf_ext_header, hdr_len) || data_size < hdr->hdr_len) { pr_debug("BTF.ext header not found"); return -EINVAL; @@ -987,6 +962,9 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size) } memcpy(btf_ext->data, data, size); + if (btf_ext->hdr->hdr_len < + offsetofend(struct btf_ext_header, line_info_len)) + goto done; err = btf_ext_setup_func_info(btf_ext); if (err) goto done; @@ -995,6 +973,13 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size) if (err) goto done; + if (btf_ext->hdr->hdr_len < + offsetofend(struct btf_ext_header, offset_reloc_len)) + goto done; + err = btf_ext_setup_offset_reloc(btf_ext); + if (err) + goto done; + done: if (err) { btf_ext__free(btf_ext); |