mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
Merge branch 'libbpf-btf_ext'
Yonghong Song says: ==================== This patch set exposed a few functions in libbpf. All these newly added API functions are helpful for JIT based bpf compilation where .BTF and .BTF.ext are available as in-memory data blobs. Patch #1 exposed several btf_ext__* API functions which are used to handle .BTF.ext ELF sections. Patch #2 refactored the function bpf_map_find_btf_info() and exposed API function btf__get_map_kv_tids() to retrieve the map key/value type id's generated by bpf program through BPF_ANNOTATE_KV_PAIR macro. ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
commit
1728b11110
@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
/* Copyright (c) 2018 Facebook */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -504,6 +505,78 @@ exit_free:
|
||||
return err;
|
||||
}
|
||||
|
||||
int btf__get_map_kv_tids(const struct btf *btf, char *map_name,
|
||||
__u32 expected_key_size, __u32 expected_value_size,
|
||||
__u32 *key_type_id, __u32 *value_type_id)
|
||||
{
|
||||
const struct btf_type *container_type;
|
||||
const struct btf_member *key, *value;
|
||||
const size_t max_name = 256;
|
||||
char container_name[max_name];
|
||||
__s64 key_size, value_size;
|
||||
__s32 container_id;
|
||||
|
||||
if (snprintf(container_name, max_name, "____btf_map_%s", map_name) ==
|
||||
max_name) {
|
||||
pr_warning("map:%s length of '____btf_map_%s' is too long\n",
|
||||
map_name, map_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
container_id = btf__find_by_name(btf, container_name);
|
||||
if (container_id < 0) {
|
||||
pr_warning("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
|
||||
map_name, container_name);
|
||||
return container_id;
|
||||
}
|
||||
|
||||
container_type = btf__type_by_id(btf, container_id);
|
||||
if (!container_type) {
|
||||
pr_warning("map:%s cannot find BTF type for container_id:%u\n",
|
||||
map_name, container_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT ||
|
||||
BTF_INFO_VLEN(container_type->info) < 2) {
|
||||
pr_warning("map:%s container_name:%s is an invalid container struct\n",
|
||||
map_name, container_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
key = (struct btf_member *)(container_type + 1);
|
||||
value = key + 1;
|
||||
|
||||
key_size = btf__resolve_size(btf, key->type);
|
||||
if (key_size < 0) {
|
||||
pr_warning("map:%s invalid BTF key_type_size\n", map_name);
|
||||
return key_size;
|
||||
}
|
||||
|
||||
if (expected_key_size != key_size) {
|
||||
pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
|
||||
map_name, (__u32)key_size, expected_key_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
value_size = btf__resolve_size(btf, value->type);
|
||||
if (value_size < 0) {
|
||||
pr_warning("map:%s invalid BTF value_type_size\n", map_name);
|
||||
return value_size;
|
||||
}
|
||||
|
||||
if (expected_value_size != value_size) {
|
||||
pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n",
|
||||
map_name, (__u32)value_size, expected_value_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*key_type_id = key->type;
|
||||
*value_type_id = value->type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct btf_ext_sec_copy_param {
|
||||
__u32 off;
|
||||
__u32 len;
|
||||
|
@ -66,19 +66,23 @@ LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
|
||||
LIBBPF_API int btf__fd(const struct btf *btf);
|
||||
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
|
||||
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
|
||||
LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, char *map_name,
|
||||
__u32 expected_key_size,
|
||||
__u32 expected_value_size,
|
||||
__u32 *key_type_id, __u32 *value_type_id);
|
||||
|
||||
struct btf_ext *btf_ext__new(__u8 *data, __u32 size);
|
||||
void btf_ext__free(struct btf_ext *btf_ext);
|
||||
int btf_ext__reloc_func_info(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
const char *sec_name, __u32 insns_cnt,
|
||||
void **func_info, __u32 *func_info_len);
|
||||
int btf_ext__reloc_line_info(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
const char *sec_name, __u32 insns_cnt,
|
||||
void **line_info, __u32 *cnt);
|
||||
__u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext);
|
||||
__u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext);
|
||||
LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size);
|
||||
LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext);
|
||||
LIBBPF_API int btf_ext__reloc_func_info(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
const char *sec_name, __u32 insns_cnt,
|
||||
void **func_info, __u32 *cnt);
|
||||
LIBBPF_API int btf_ext__reloc_line_info(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
const char *sec_name, __u32 insns_cnt,
|
||||
void **line_info, __u32 *cnt);
|
||||
LIBBPF_API __u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext);
|
||||
LIBBPF_API __u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -1056,72 +1056,18 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
|
||||
|
||||
static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
|
||||
{
|
||||
const struct btf_type *container_type;
|
||||
const struct btf_member *key, *value;
|
||||
struct bpf_map_def *def = &map->def;
|
||||
const size_t max_name = 256;
|
||||
char container_name[max_name];
|
||||
__s64 key_size, value_size;
|
||||
__s32 container_id;
|
||||
__u32 key_type_id, value_type_id;
|
||||
int ret;
|
||||
|
||||
if (snprintf(container_name, max_name, "____btf_map_%s", map->name) ==
|
||||
max_name) {
|
||||
pr_warning("map:%s length of '____btf_map_%s' is too long\n",
|
||||
map->name, map->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = btf__get_map_kv_tids(btf, map->name, def->key_size,
|
||||
def->value_size, &key_type_id,
|
||||
&value_type_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
container_id = btf__find_by_name(btf, container_name);
|
||||
if (container_id < 0) {
|
||||
pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
|
||||
map->name, container_name);
|
||||
return container_id;
|
||||
}
|
||||
|
||||
container_type = btf__type_by_id(btf, container_id);
|
||||
if (!container_type) {
|
||||
pr_warning("map:%s cannot find BTF type for container_id:%u\n",
|
||||
map->name, container_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT ||
|
||||
BTF_INFO_VLEN(container_type->info) < 2) {
|
||||
pr_warning("map:%s container_name:%s is an invalid container struct\n",
|
||||
map->name, container_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
key = (struct btf_member *)(container_type + 1);
|
||||
value = key + 1;
|
||||
|
||||
key_size = btf__resolve_size(btf, key->type);
|
||||
if (key_size < 0) {
|
||||
pr_warning("map:%s invalid BTF key_type_size\n",
|
||||
map->name);
|
||||
return key_size;
|
||||
}
|
||||
|
||||
if (def->key_size != key_size) {
|
||||
pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
|
||||
map->name, (__u32)key_size, def->key_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
value_size = btf__resolve_size(btf, value->type);
|
||||
if (value_size < 0) {
|
||||
pr_warning("map:%s invalid BTF value_type_size\n", map->name);
|
||||
return value_size;
|
||||
}
|
||||
|
||||
if (def->value_size != value_size) {
|
||||
pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n",
|
||||
map->name, (__u32)value_size, def->value_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map->btf_key_type_id = key->type;
|
||||
map->btf_value_type_id = value->type;
|
||||
map->btf_key_type_id = key_type_id;
|
||||
map->btf_value_type_id = value_type_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -133,4 +133,11 @@ LIBBPF_0.0.2 {
|
||||
bpf_map_lookup_elem_flags;
|
||||
bpf_object__find_map_fd_by_name;
|
||||
bpf_get_link_xdp_id;
|
||||
btf__get_map_kv_tids;
|
||||
btf_ext__free;
|
||||
btf_ext__func_info_rec_size;
|
||||
btf_ext__line_info_rec_size;
|
||||
btf_ext__new;
|
||||
btf_ext__reloc_func_info;
|
||||
btf_ext__reloc_line_info;
|
||||
} LIBBPF_0.0.1;
|
||||
|
Loading…
Reference in New Issue
Block a user