tools/perf/util/bpf-event.c

Source file repositories/reference/linux-study-clean/tools/perf/util/bpf-event.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/bpf-event.c
Extension
.c
Size
25503 bytes
Lines
987
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct bpf_metadata_map {
	struct btf *btf;
	const struct btf_type *datasec;
	void *rodata;
	size_t rodata_size;
	unsigned int num_vars;
};

static int bpf_metadata_read_map_data(__u32 map_id, struct bpf_metadata_map *map)
{
	int map_fd;
	struct bpf_map_info map_info;
	__u32 map_info_len;
	int key;
	struct btf *btf;
	const struct btf_type *datasec;
	struct btf_var_secinfo *vsi;
	unsigned int vlen, vars;
	void *rodata;

	map_fd = bpf_map_get_fd_by_id(map_id);
	if (map_fd < 0)
		return -1;

	memset(&map_info, 0, sizeof(map_info));
	map_info_len = sizeof(map_info);
	if (bpf_obj_get_info_by_fd(map_fd, &map_info, &map_info_len) < 0)
		goto out_close;

	/* If it's not an .rodata map, don't bother. */
	if (map_info.type != BPF_MAP_TYPE_ARRAY ||
	    map_info.key_size != sizeof(int) ||
	    map_info.max_entries != 1 ||
	    !map_info.btf_value_type_id ||
	    !strstr(map_info.name, ".rodata")) {
		goto out_close;
	}

	btf = btf__load_from_kernel_by_id(map_info.btf_id);
	if (!btf)
		goto out_close;
	datasec = btf__type_by_id(btf, map_info.btf_value_type_id);
	if (!btf_is_datasec(datasec))
		goto out_free_btf;

	/*
	 * If there aren't any variables with the "bpf_metadata_" prefix,
	 * don't bother.
	 */
	vlen = btf_vlen(datasec);
	vsi = btf_var_secinfos(datasec);
	vars = 0;
	for (unsigned int i = 0; i < vlen; i++, vsi++) {
		const struct btf_type *t_var = btf__type_by_id(btf, vsi->type);
		const char *name = btf__name_by_offset(btf, t_var->name_off);

		if (name_has_bpf_metadata_prefix(&name))
			vars++;
	}
	if (vars == 0)
		goto out_free_btf;

	rodata = zalloc(map_info.value_size);
	if (!rodata)
		goto out_free_btf;
	key = 0;
	if (bpf_map_lookup_elem(map_fd, &key, rodata)) {
		free(rodata);
		goto out_free_btf;
	}
	close(map_fd);

	map->btf = btf;
	map->datasec = datasec;
	map->rodata = rodata;
	map->rodata_size = map_info.value_size;
	map->num_vars = vars;
	return 0;

out_free_btf:
	btf__free(btf);
out_close:
	close(map_fd);
	return -1;
}

struct format_btf_ctx {
	char *buf;
	size_t buf_size;
	size_t buf_idx;

Annotation

Implementation Notes