tools/bpf: refactor to implement btf_get_from_id() in lib/bpf
The function get_btf() is implemented in tools/bpf/bpftool/map.c to get a btf structure given a map_info. This patch refactored this function to be function btf_get_from_id() in tools/lib/bpf so that it can be used later. Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Родитель
9ce6ae22c8
Коммит
d7f5b5e051
|
@ -215,70 +215,6 @@ err_end_obj:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_btf(struct bpf_map_info *map_info, struct btf **btf)
|
|
||||||
{
|
|
||||||
struct bpf_btf_info btf_info = { 0 };
|
|
||||||
__u32 len = sizeof(btf_info);
|
|
||||||
__u32 last_size;
|
|
||||||
int btf_fd;
|
|
||||||
void *ptr;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = 0;
|
|
||||||
*btf = NULL;
|
|
||||||
btf_fd = bpf_btf_get_fd_by_id(map_info->btf_id);
|
|
||||||
if (btf_fd < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* we won't know btf_size until we call bpf_obj_get_info_by_fd(). so
|
|
||||||
* let's start with a sane default - 4KiB here - and resize it only if
|
|
||||||
* bpf_obj_get_info_by_fd() needs a bigger buffer.
|
|
||||||
*/
|
|
||||||
btf_info.btf_size = 4096;
|
|
||||||
last_size = btf_info.btf_size;
|
|
||||||
ptr = malloc(last_size);
|
|
||||||
if (!ptr) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto exit_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
bzero(ptr, last_size);
|
|
||||||
btf_info.btf = ptr_to_u64(ptr);
|
|
||||||
err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
|
|
||||||
|
|
||||||
if (!err && btf_info.btf_size > last_size) {
|
|
||||||
void *temp_ptr;
|
|
||||||
|
|
||||||
last_size = btf_info.btf_size;
|
|
||||||
temp_ptr = realloc(ptr, last_size);
|
|
||||||
if (!temp_ptr) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto exit_free;
|
|
||||||
}
|
|
||||||
ptr = temp_ptr;
|
|
||||||
bzero(ptr, last_size);
|
|
||||||
btf_info.btf = ptr_to_u64(ptr);
|
|
||||||
err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err || btf_info.btf_size > last_size) {
|
|
||||||
err = errno;
|
|
||||||
goto exit_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
*btf = btf__new((__u8 *)btf_info.btf, btf_info.btf_size, NULL);
|
|
||||||
if (IS_ERR(*btf)) {
|
|
||||||
err = PTR_ERR(*btf);
|
|
||||||
*btf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit_free:
|
|
||||||
close(btf_fd);
|
|
||||||
free(ptr);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static json_writer_t *get_btf_writer(void)
|
static json_writer_t *get_btf_writer(void)
|
||||||
{
|
{
|
||||||
json_writer_t *jw = jsonw_new(stdout);
|
json_writer_t *jw = jsonw_new(stdout);
|
||||||
|
@ -775,7 +711,7 @@ static int do_dump(int argc, char **argv)
|
||||||
|
|
||||||
prev_key = NULL;
|
prev_key = NULL;
|
||||||
|
|
||||||
err = get_btf(&info, &btf);
|
err = btf_get_from_id(info.btf_id, &btf);
|
||||||
if (err) {
|
if (err) {
|
||||||
p_err("failed to get btf");
|
p_err("failed to get btf");
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
|
@ -919,7 +855,7 @@ static int do_lookup(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* here means bpf_map_lookup_elem() succeeded */
|
/* here means bpf_map_lookup_elem() succeeded */
|
||||||
err = get_btf(&info, &btf);
|
err = btf_get_from_id(info.btf_id, &btf);
|
||||||
if (err) {
|
if (err) {
|
||||||
p_err("failed to get btf");
|
p_err("failed to get btf");
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
|
|
|
@ -49,6 +49,11 @@ struct bpf_func_info_min {
|
||||||
__u32 type_id;
|
__u32 type_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline __u64 ptr_to_u64(const void *ptr)
|
||||||
|
{
|
||||||
|
return (__u64) (unsigned long) ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static int btf_add_type(struct btf *btf, struct btf_type *t)
|
static int btf_add_type(struct btf *btf, struct btf_type *t)
|
||||||
{
|
{
|
||||||
if (btf->types_size - btf->nr_types < 2) {
|
if (btf->types_size - btf->nr_types < 2) {
|
||||||
|
@ -410,6 +415,70 @@ const char *btf__name_by_offset(const struct btf *btf, __u32 offset)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btf_get_from_id(__u32 id, struct btf **btf)
|
||||||
|
{
|
||||||
|
struct bpf_btf_info btf_info = { 0 };
|
||||||
|
__u32 len = sizeof(btf_info);
|
||||||
|
__u32 last_size;
|
||||||
|
int btf_fd;
|
||||||
|
void *ptr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
*btf = NULL;
|
||||||
|
btf_fd = bpf_btf_get_fd_by_id(id);
|
||||||
|
if (btf_fd < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* we won't know btf_size until we call bpf_obj_get_info_by_fd(). so
|
||||||
|
* let's start with a sane default - 4KiB here - and resize it only if
|
||||||
|
* bpf_obj_get_info_by_fd() needs a bigger buffer.
|
||||||
|
*/
|
||||||
|
btf_info.btf_size = 4096;
|
||||||
|
last_size = btf_info.btf_size;
|
||||||
|
ptr = malloc(last_size);
|
||||||
|
if (!ptr) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto exit_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(ptr, last_size);
|
||||||
|
btf_info.btf = ptr_to_u64(ptr);
|
||||||
|
err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
|
||||||
|
|
||||||
|
if (!err && btf_info.btf_size > last_size) {
|
||||||
|
void *temp_ptr;
|
||||||
|
|
||||||
|
last_size = btf_info.btf_size;
|
||||||
|
temp_ptr = realloc(ptr, last_size);
|
||||||
|
if (!temp_ptr) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto exit_free;
|
||||||
|
}
|
||||||
|
ptr = temp_ptr;
|
||||||
|
bzero(ptr, last_size);
|
||||||
|
btf_info.btf = ptr_to_u64(ptr);
|
||||||
|
err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err || btf_info.btf_size > last_size) {
|
||||||
|
err = errno;
|
||||||
|
goto exit_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
*btf = btf__new((__u8 *)btf_info.btf, btf_info.btf_size, NULL);
|
||||||
|
if (IS_ERR(*btf)) {
|
||||||
|
err = PTR_ERR(*btf);
|
||||||
|
*btf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_free:
|
||||||
|
close(btf_fd);
|
||||||
|
free(ptr);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int btf_ext_validate_func_info(const void *finfo, __u32 size,
|
static int btf_ext_validate_func_info(const void *finfo, __u32 size,
|
||||||
btf_print_fn_t err_log)
|
btf_print_fn_t err_log)
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,6 +69,7 @@ LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
|
||||||
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
|
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
|
||||||
LIBBPF_API int btf__fd(const struct btf *btf);
|
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 const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
|
||||||
|
LIBBPF_API int btf_get_from_id(__u32 id, struct btf **btf);
|
||||||
|
|
||||||
struct btf_ext *btf_ext__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
|
struct btf_ext *btf_ext__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
|
||||||
void btf_ext__free(struct btf_ext *btf_ext);
|
void btf_ext__free(struct btf_ext *btf_ext);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче