Commit f309b4ba authored by Andrii Nakryiko's avatar Andrii Nakryiko
Browse files

Merge branch 'libbpf: rename btf__get_from_id() and btf__load() APIs, support split BTF'

Quentin Monnet says:

====================

As part of the effort to move towards a v1.0 for libbpf [0], this set
improves some confusing function names related to BTF loading from and to
the kernel:

- btf__load() becomes btf__load_into_kernel().
- btf__get_from_id becomes btf__load_from_kernel_by_id().
- A new version btf__load_from_kernel_by_id_split() extends the former to
  add support for split BTF.

The last patch is a trivial change to bpftool to add support for dumping
split BTF objects by referencing them by their id (and not only by their
BTF path).

[0] https://github.com/libbpf/libbpf/wiki/Libbpf:-the-road-to-v1.0#btfh-apis



v3:
- Use libbpf_err_ptr() in btf__load_from_kernel_by_id(), ERR_PTR() in
  bpftool's get_map_kv_btf().
- Move the definition of btf__load_from_kernel_by_id() closer to the
  btf__parse() group in btf.h (move the legacy function with it).
- Fix a bug on the return value in libbpf_find_prog_btf_id(), as a new
  patch.
- Move the btf__free() fixes to their own patch.
- Add "Fixes:" tags to relevant patches.

v2:
- Remove deprecation marking of legacy functions (patch 4/6 from v1).
- Make btf__load_from_kernel_by_id{,_split}() return the btf struct, adjust
  surrounding code and call btf__free() when missing.
- Add new functions to v0.5.0 API (and not v0.6.0).
====================

Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
parents d3621642 211ab78f
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -580,16 +580,12 @@ static int do_dump(int argc, char **argv)
	}

	if (!btf) {
		err = btf__get_from_id(btf_id, &btf);
		btf = btf__load_from_kernel_by_id_split(btf_id, base_btf);
		err = libbpf_get_error(btf);
		if (err) {
			p_err("get btf by id (%u): %s", btf_id, strerror(err));
			goto done;
		}
		if (!btf) {
			err = -ENOENT;
			p_err("can't find btf with ID (%u)", btf_id);
			goto done;
		}
	}

	if (dump_c) {
+4 −2
Original line number Diff line number Diff line
@@ -64,8 +64,10 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,
	}
	info = &prog_info->info;

	if (!info->btf_id || !info->nr_func_info ||
	    btf__get_from_id(info->btf_id, &prog_btf))
	if (!info->btf_id || !info->nr_func_info)
		goto print;
	prog_btf = btf__load_from_kernel_by_id(info->btf_id);
	if (libbpf_get_error(prog_btf))
		goto print;
	finfo = u64_to_ptr(info->func_info);
	func_type = btf__type_by_id(prog_btf, finfo->type_id);
+7 −7
Original line number Diff line number Diff line
@@ -807,10 +807,11 @@ static struct btf *get_map_kv_btf(const struct bpf_map_info *info)
	} else if (info->btf_value_type_id) {
		int err;

		err = btf__get_from_id(info->btf_id, &btf);
		if (err || !btf) {
		btf = btf__load_from_kernel_by_id(info->btf_id);
		err = libbpf_get_error(btf);
		if (err) {
			p_err("failed to get btf");
			btf = err ? ERR_PTR(err) : ERR_PTR(-ESRCH);
			btf = ERR_PTR(err);
		}
	}

@@ -1039,11 +1040,10 @@ static void print_key_value(struct bpf_map_info *info, void *key,
			    void *value)
{
	json_writer_t *btf_wtr;
	struct btf *btf = NULL;
	int err;
	struct btf *btf;

	err = btf__get_from_id(info->btf_id, &btf);
	if (err) {
	btf = btf__load_from_kernel_by_id(info->btf_id);
	if (libbpf_get_error(btf)) {
		p_err("failed to get btf");
		return;
	}
+20 −9
Original line number Diff line number Diff line
@@ -249,10 +249,10 @@ static void show_prog_metadata(int fd, __u32 num_maps)
	struct bpf_map_info map_info;
	struct btf_var_secinfo *vsi;
	bool printed_header = false;
	struct btf *btf = NULL;
	unsigned int i, vlen;
	void *value = NULL;
	const char *name;
	struct btf *btf;
	int err;

	if (!num_maps)
@@ -263,8 +263,8 @@ static void show_prog_metadata(int fd, __u32 num_maps)
	if (!value)
		return;

	err = btf__get_from_id(map_info.btf_id, &btf);
	if (err || !btf)
	btf = btf__load_from_kernel_by_id(map_info.btf_id);
	if (libbpf_get_error(btf))
		goto out_free;

	t_datasec = btf__type_by_id(btf, map_info.btf_value_type_id);
@@ -646,10 +646,13 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
		member_len = info->xlated_prog_len;
	}

	if (info->btf_id && btf__get_from_id(info->btf_id, &btf)) {
	if (info->btf_id) {
		btf = btf__load_from_kernel_by_id(info->btf_id);
		if (libbpf_get_error(btf)) {
			p_err("failed to get btf");
			return -1;
		}
	}

	func_info = u64_to_ptr(info->func_info);

@@ -781,6 +784,8 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
		kernel_syms_destroy(&dd);
	}

	btf__free(btf);

	return 0;
}

@@ -2002,8 +2007,8 @@ static char *profile_target_name(int tgt_fd)
	struct bpf_prog_info_linear *info_linear;
	struct bpf_func_info *func_info;
	const struct btf_type *t;
	struct btf *btf = NULL;
	char *name = NULL;
	struct btf *btf;

	info_linear = bpf_program__get_prog_info_linear(
		tgt_fd, 1UL << BPF_PROG_INFO_FUNC_INFO);
@@ -2012,12 +2017,17 @@ static char *profile_target_name(int tgt_fd)
		return NULL;
	}

	if (info_linear->info.btf_id == 0 ||
	    btf__get_from_id(info_linear->info.btf_id, &btf)) {
	if (info_linear->info.btf_id == 0) {
		p_err("prog FD %d doesn't have valid btf", tgt_fd);
		goto out;
	}

	btf = btf__load_from_kernel_by_id(info_linear->info.btf_id);
	if (libbpf_get_error(btf)) {
		p_err("failed to load btf for prog FD %d", tgt_fd);
		goto out;
	}

	func_info = u64_to_ptr(info_linear->info.func_info);
	t = btf__type_by_id(btf, func_info[0].type_id);
	if (!t) {
@@ -2027,6 +2037,7 @@ static char *profile_target_name(int tgt_fd)
	}
	name = strdup(btf__name_by_offset(btf, t->name_off));
out:
	btf__free(btf);
	free(info_linear);
	return name;
}
+24 −9
Original line number Diff line number Diff line
@@ -1180,7 +1180,7 @@ int btf__finalize_data(struct bpf_object *obj, struct btf *btf)

static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian);

int btf__load(struct btf *btf)
int btf__load_into_kernel(struct btf *btf)
{
	__u32 log_buf_size = 0, raw_size;
	char *log_buf = NULL;
@@ -1228,6 +1228,7 @@ int btf__load(struct btf *btf)
	free(log_buf);
	return libbpf_err(err);
}
int btf__load(struct btf *) __attribute__((alias("btf__load_into_kernel")));

int btf__fd(const struct btf *btf)
{
@@ -1382,21 +1383,35 @@ struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf)
	return btf;
}

int btf__get_from_id(__u32 id, struct btf **btf)
struct btf *btf__load_from_kernel_by_id_split(__u32 id, struct btf *base_btf)
{
	struct btf *res;
	int err, btf_fd;
	struct btf *btf;
	int btf_fd;

	*btf = NULL;
	btf_fd = bpf_btf_get_fd_by_id(id);
	if (btf_fd < 0)
		return libbpf_err(-errno);

	res = btf_get_from_fd(btf_fd, NULL);
	err = libbpf_get_error(res);
		return libbpf_err_ptr(-errno);

	btf = btf_get_from_fd(btf_fd, base_btf);
	close(btf_fd);

	return libbpf_ptr(btf);
}

struct btf *btf__load_from_kernel_by_id(__u32 id)
{
	return btf__load_from_kernel_by_id_split(id, NULL);
}

int btf__get_from_id(__u32 id, struct btf **btf)
{
	struct btf *res;
	int err;

	*btf = NULL;
	res = btf__load_from_kernel_by_id(id);
	err = libbpf_get_error(res);

	if (err)
		return libbpf_err(err);

Loading