netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel
@ 2019-02-08 19:19 Andrii Nakryiko
  2019-02-08 19:19 ` [PATCH v4 bpf-next 1/4] btf: separate btf creation and loading Andrii Nakryiko
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Andrii Nakryiko @ 2019-02-08 19:19 UTC (permalink / raw)
  To: alexei.starovoitov, andrii.nakryiko, songliubraving, yhs, ast,
	kafai, netdev, kernel-team, daniel, acme
  Cc: Andrii Nakryiko

This patchset introduces a set of new APIs that make it possible to work with BTF
more effectively (and without involving kernel) for applications like pahole that
need to manipulate .BTF and .BTF.ext data.

Patch #1 changes existing btf__new() API call to only load and initialize
struct btf, while exposing new btf__load() API to attempt to load and validate
BTF in kernel.

Patch #2 adds btf__get_raw_data() API allowing to get access to raw BTF data from
struct btf.

Patch #3 adds similar btf_ext__get_raw_data() API for working with struct btf_ext.

Patch #4 removes not-yet-stable btf__get_strings() API which was added to be able
to test contents of struct btf for btf__dedup(). It's now superseded by raw APIs.

v3->v4:
- formatting fixes
- renamed btf_ext functions/structs to use "setup" language instead of "copy"
- removed btf__get_strings from libbpf.map

v2->v3:
- const void* variants of btf__get_raw_data()
- added btf_ext__get_raw_data()
- removed btf__get_strings() and adapted test_btf.c to use btf__get_raw_data()

v1->v2:
- btf_load() returns just error, not fd
- fix ordering in libbpf.map

Andrii Nakryiko (4):
  btf: separate btf creation and loading
  btf: expose API to work with raw btf data
  btf: expose API to work with raw btf_ext data
  tools/bpf: remove btf__get_strings() superseded by raw data API

 tools/lib/bpf/btf.c                    | 163 +++++++++++++------------
 tools/lib/bpf/btf.h                    |   6 +-
 tools/lib/bpf/libbpf.c                 |   2 +-
 tools/lib/bpf/libbpf.map               |   4 +-
 tools/testing/selftests/bpf/test_btf.c |  39 ++++--
 5 files changed, 121 insertions(+), 93 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v4 bpf-next 1/4] btf: separate btf creation and loading
  2019-02-08 19:19 [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Andrii Nakryiko
@ 2019-02-08 19:19 ` Andrii Nakryiko
  2019-02-08 19:19 ` [PATCH v4 bpf-next 2/4] btf: expose API to work with raw btf data Andrii Nakryiko
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Andrii Nakryiko @ 2019-02-08 19:19 UTC (permalink / raw)
  To: alexei.starovoitov, andrii.nakryiko, songliubraving, yhs, ast,
	kafai, netdev, kernel-team, daniel, acme
  Cc: Andrii Nakryiko

This change splits out previous btf__new functionality of constructing
struct btf and loading it into kernel into two:
- btf__new() just creates and initializes struct btf
- btf__load() attempts to load existing struct btf into kernel

btf__free will still close BTF fd, if it was ever loaded successfully
into kernel.

This change allows users of libbpf to manipulate BTF using its API,
without the need to unnecessarily load it into kernel.

One of the intended use cases is pahole, which will do DWARF to BTF
conversion and then use libbpf to do type deduplication, while then
handling ELF sections overwriting and other concerns on its own.

Fixes: 2d3feca8c44f ("bpf: btf: print map dump and lookup with btf info")
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
---
 tools/lib/bpf/btf.c      | 54 ++++++++++++++++++++++------------------
 tools/lib/bpf/btf.h      |  1 +
 tools/lib/bpf/libbpf.c   |  2 +-
 tools/lib/bpf/libbpf.map |  1 +
 4 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index ab6528c935a1..96674057224d 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -366,8 +366,6 @@ void btf__free(struct btf *btf)
 
 struct btf *btf__new(__u8 *data, __u32 size)
 {
-	__u32 log_buf_size = 0;
-	char *log_buf = NULL;
 	struct btf *btf;
 	int err;
 
@@ -377,15 +375,6 @@ struct btf *btf__new(__u8 *data, __u32 size)
 
 	btf->fd = -1;
 
-	log_buf = malloc(BPF_LOG_BUF_SIZE);
-	if (!log_buf) {
-		err = -ENOMEM;
-		goto done;
-	}
-
-	*log_buf = 0;
-	log_buf_size = BPF_LOG_BUF_SIZE;
-
 	btf->data = malloc(size);
 	if (!btf->data) {
 		err = -ENOMEM;
@@ -395,17 +384,6 @@ struct btf *btf__new(__u8 *data, __u32 size)
 	memcpy(btf->data, data, size);
 	btf->data_size = size;
 
-	btf->fd = bpf_load_btf(btf->data, btf->data_size,
-			       log_buf, log_buf_size, false);
-
-	if (btf->fd == -1) {
-		err = -errno;
-		pr_warning("Error loading BTF: %s(%d)\n", strerror(errno), errno);
-		if (log_buf && *log_buf)
-			pr_warning("%s\n", log_buf);
-		goto done;
-	}
-
 	err = btf_parse_hdr(btf);
 	if (err)
 		goto done;
@@ -417,8 +395,6 @@ struct btf *btf__new(__u8 *data, __u32 size)
 	err = btf_parse_type_sec(btf);
 
 done:
-	free(log_buf);
-
 	if (err) {
 		btf__free(btf);
 		return ERR_PTR(err);
@@ -427,6 +403,36 @@ struct btf *btf__new(__u8 *data, __u32 size)
 	return btf;
 }
 
+int btf__load(struct btf *btf)
+{
+	__u32 log_buf_size = BPF_LOG_BUF_SIZE;
+	char *log_buf = NULL;
+	int err = 0;
+
+	if (btf->fd >= 0)
+		return -EEXIST;
+
+	log_buf = malloc(log_buf_size);
+	if (!log_buf)
+		return -ENOMEM;
+
+	*log_buf = 0;
+
+	btf->fd = bpf_load_btf(btf->data, btf->data_size,
+			       log_buf, log_buf_size, false);
+	if (btf->fd < 0) {
+		err = -errno;
+		pr_warning("Error loading BTF: %s(%d)\n", strerror(errno), errno);
+		if (*log_buf)
+			pr_warning("%s\n", log_buf);
+		goto done;
+	}
+
+done:
+	free(log_buf);
+	return err;
+}
+
 int btf__fd(const struct btf *btf)
 {
 	return btf->fd;
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index b393da90cc85..f55b7bc98d9e 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -57,6 +57,7 @@ struct btf_ext_header {
 
 LIBBPF_API void btf__free(struct btf *btf);
 LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size);
+LIBBPF_API int btf__load(struct btf *btf);
 LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
 				   const char *type_name);
 LIBBPF_API __u32 btf__get_nr_types(const struct btf *btf);
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 47969aa0faf8..ff86a43a4336 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -835,7 +835,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
 			obj->efile.maps_shndx = idx;
 		else if (strcmp(name, BTF_ELF_SEC) == 0) {
 			obj->btf = btf__new(data->d_buf, data->d_size);
-			if (IS_ERR(obj->btf)) {
+			if (IS_ERR(obj->btf) || btf__load(obj->btf)) {
 				pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
 					   BTF_ELF_SEC, PTR_ERR(obj->btf));
 				obj->btf = NULL;
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 89c1149e32ee..f5372df143f4 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -137,6 +137,7 @@ LIBBPF_0.0.2 {
 		btf__get_map_kv_tids;
 		btf__get_nr_types;
 		btf__get_strings;
+		btf__load;
 		btf_ext__free;
 		btf_ext__func_info_rec_size;
 		btf_ext__line_info_rec_size;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v4 bpf-next 2/4] btf: expose API to work with raw btf data
  2019-02-08 19:19 [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Andrii Nakryiko
  2019-02-08 19:19 ` [PATCH v4 bpf-next 1/4] btf: separate btf creation and loading Andrii Nakryiko
@ 2019-02-08 19:19 ` Andrii Nakryiko
  2019-02-08 19:19 ` [PATCH v4 bpf-next 3/4] btf: expose API to work with raw btf_ext data Andrii Nakryiko
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Andrii Nakryiko @ 2019-02-08 19:19 UTC (permalink / raw)
  To: alexei.starovoitov, andrii.nakryiko, songliubraving, yhs, ast,
	kafai, netdev, kernel-team, daniel, acme
  Cc: Andrii Nakryiko

This patch exposes new API btf__get_raw_data() that allows to get a copy
of raw BTF data out of struct btf. This is useful for external programs
that need to manipulate raw data, e.g., pahole using btf__dedup() to
deduplicate BTF type info and then writing it back to file.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
---
 tools/lib/bpf/btf.c      | 6 ++++++
 tools/lib/bpf/btf.h      | 1 +
 tools/lib/bpf/libbpf.map | 1 +
 3 files changed, 8 insertions(+)

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 96674057224d..1216b93eed03 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -438,6 +438,12 @@ int btf__fd(const struct btf *btf)
 	return btf->fd;
 }
 
+const void *btf__get_raw_data(const struct btf *btf, __u32 *size)
+{
+	*size = btf->data_size;
+	return btf->data;
+}
+
 void btf__get_strings(const struct btf *btf, const char **strings,
 		      __u32 *str_len)
 {
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index f55b7bc98d9e..10fe412461fe 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -66,6 +66,7 @@ LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
 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__fd(const struct btf *btf);
+LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
 LIBBPF_API void btf__get_strings(const struct btf *btf, const char **strings,
 				 __u32 *str_len);
 LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index f5372df143f4..9e10467f8cbb 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -136,6 +136,7 @@ LIBBPF_0.0.2 {
 		btf__dedup;
 		btf__get_map_kv_tids;
 		btf__get_nr_types;
+		btf__get_raw_data;
 		btf__get_strings;
 		btf__load;
 		btf_ext__free;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v4 bpf-next 3/4] btf: expose API to work with raw btf_ext data
  2019-02-08 19:19 [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Andrii Nakryiko
  2019-02-08 19:19 ` [PATCH v4 bpf-next 1/4] btf: separate btf creation and loading Andrii Nakryiko
  2019-02-08 19:19 ` [PATCH v4 bpf-next 2/4] btf: expose API to work with raw btf data Andrii Nakryiko
@ 2019-02-08 19:19 ` Andrii Nakryiko
  2019-02-08 19:50   ` Yonghong Song
  2019-02-08 19:19 ` [PATCH v4 bpf-next 4/4] tools/bpf: remove btf__get_strings() superseded by raw data API Andrii Nakryiko
  2019-02-08 20:08 ` [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Alexei Starovoitov
  4 siblings, 1 reply; 7+ messages in thread
From: Andrii Nakryiko @ 2019-02-08 19:19 UTC (permalink / raw)
  To: alexei.starovoitov, andrii.nakryiko, songliubraving, yhs, ast,
	kafai, netdev, kernel-team, daniel, acme
  Cc: Andrii Nakryiko

This patch changes struct btf_ext to retain original data in sequential
block of memory, which makes it possible to expose
btf_ext__get_raw_data() interface similar to btf__get_raw_data(), allowing
users of libbpf to get access to raw representation of .BTF.ext section.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 tools/lib/bpf/btf.c      | 102 +++++++++++++++++++++------------------
 tools/lib/bpf/btf.h      |   2 +
 tools/lib/bpf/libbpf.map |   1 +
 3 files changed, 57 insertions(+), 48 deletions(-)

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 1216b93eed03..2779043b3375 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -41,9 +41,8 @@ struct btf {
 
 struct btf_ext_info {
 	/*
-	 * info points to a deep copy of the individual info section
-	 * (e.g. func_info and line_info) from the .BTF.ext.
-	 * It does not include the __u32 rec_size.
+	 * 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;
@@ -51,8 +50,13 @@ struct btf_ext_info {
 };
 
 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 {
@@ -595,7 +599,7 @@ int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
 	return 0;
 }
 
-struct btf_ext_sec_copy_param {
+struct btf_ext_sec_setup_param {
 	__u32 off;
 	__u32 len;
 	__u32 min_rec_size;
@@ -603,20 +607,14 @@ struct btf_ext_sec_copy_param {
 	const char *desc;
 };
 
-static int btf_ext_copy_info(struct btf_ext *btf_ext,
-			     __u8 *data, __u32 data_size,
-			     struct btf_ext_sec_copy_param *ext_sec)
+static int btf_ext_setup_info(struct btf_ext *btf_ext,
+			      struct btf_ext_sec_setup_param *ext_sec)
 {
-	const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
 	const struct btf_ext_info_sec *sinfo;
 	struct btf_ext_info *ext_info;
 	__u32 info_left, record_size;
 	/* The start of the info sec (including the __u32 record_size). */
-	const void *info;
-
-	/* data and data_size do not include btf_ext_header from now on */
-	data = data + hdr->hdr_len;
-	data_size -= hdr->hdr_len;
+	void *info;
 
 	if (ext_sec->off & 0x03) {
 		pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n",
@@ -624,16 +622,15 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
 		return -EINVAL;
 	}
 
-	if (data_size < ext_sec->off ||
-	    ext_sec->len > data_size - ext_sec->off) {
+	info = btf_ext->data + btf_ext->hdr->hdr_len + ext_sec->off;
+	info_left = ext_sec->len;
+
+	if (btf_ext->data + btf_ext->data_size < info + ext_sec->len) {
 		pr_debug("%s section (off:%u len:%u) is beyond the end of the ELF section .BTF.ext\n",
-		     ext_sec->desc, ext_sec->off, ext_sec->len);
+			 ext_sec->desc, ext_sec->off, ext_sec->len);
 		return -EINVAL;
 	}
 
-	info = data + ext_sec->off;
-	info_left = ext_sec->len;
-
 	/* At least a record size */
 	if (info_left < sizeof(__u32)) {
 		pr_debug(".BTF.ext %s record size not found\n", ext_sec->desc);
@@ -645,7 +642,7 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
 	if (record_size < ext_sec->min_rec_size ||
 	    record_size & 0x03) {
 		pr_debug("%s section in .BTF.ext has invalid record size %u\n",
-		     ext_sec->desc, record_size);
+			 ext_sec->desc, record_size);
 		return -EINVAL;
 	}
 
@@ -691,42 +688,35 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
 	ext_info = ext_sec->ext_info;
 	ext_info->len = ext_sec->len - sizeof(__u32);
 	ext_info->rec_size = record_size;
-	ext_info->info = malloc(ext_info->len);
-	if (!ext_info->info)
-		return -ENOMEM;
-	memcpy(ext_info->info, info + sizeof(__u32), ext_info->len);
+	ext_info->info = info + sizeof(__u32);
 
 	return 0;
 }
 
-static int btf_ext_copy_func_info(struct btf_ext *btf_ext,
-				  __u8 *data, __u32 data_size)
+static int btf_ext_setup_func_info(struct btf_ext *btf_ext)
 {
-	const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
-	struct btf_ext_sec_copy_param param = {
-		.off = hdr->func_info_off,
-		.len = hdr->func_info_len,
+	struct btf_ext_sec_setup_param param = {
+		.off = btf_ext->hdr->func_info_off,
+		.len = btf_ext->hdr->func_info_len,
 		.min_rec_size = sizeof(struct bpf_func_info_min),
 		.ext_info = &btf_ext->func_info,
 		.desc = "func_info"
 	};
 
-	return btf_ext_copy_info(btf_ext, data, data_size, &param);
+	return btf_ext_setup_info(btf_ext, &param);
 }
 
-static int btf_ext_copy_line_info(struct btf_ext *btf_ext,
-				  __u8 *data, __u32 data_size)
+static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
 {
-	const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
-	struct btf_ext_sec_copy_param param = {
-		.off = hdr->line_info_off,
-		.len = hdr->line_info_len,
+	struct btf_ext_sec_setup_param param = {
+		.off = btf_ext->hdr->line_info_off,
+		.len = btf_ext->hdr->line_info_len,
 		.min_rec_size = sizeof(struct bpf_line_info_min),
 		.ext_info = &btf_ext->line_info,
 		.desc = "line_info",
 	};
 
-	return btf_ext_copy_info(btf_ext, data, data_size, &param);
+	return btf_ext_setup_info(btf_ext, &param);
 }
 
 static int btf_ext_parse_hdr(__u8 *data, __u32 data_size)
@@ -766,9 +756,7 @@ void btf_ext__free(struct btf_ext *btf_ext)
 {
 	if (!btf_ext)
 		return;
-
-	free(btf_ext->func_info.info);
-	free(btf_ext->line_info.info);
+	free(btf_ext->data);
 	free(btf_ext);
 }
 
@@ -785,13 +773,23 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
 	if (!btf_ext)
 		return ERR_PTR(-ENOMEM);
 
-	err = btf_ext_copy_func_info(btf_ext, data, size);
-	if (err) {
-		btf_ext__free(btf_ext);
-		return ERR_PTR(err);
+	btf_ext->data_size = size;
+	btf_ext->data = malloc(size);
+	if (!btf_ext->data) {
+		err = -ENOMEM;
+		goto done;
 	}
+	memcpy(btf_ext->data, data, size);
+
+	err = btf_ext_setup_func_info(btf_ext);
+	if (err)
+		goto done;
 
-	err = btf_ext_copy_line_info(btf_ext, data, size);
+	err = btf_ext_setup_line_info(btf_ext);
+	if (err)
+		goto done;
+
+done:
 	if (err) {
 		btf_ext__free(btf_ext);
 		return ERR_PTR(err);
@@ -800,6 +798,12 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
 	return btf_ext;
 }
 
+const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size)
+{
+	*size = btf_ext->data_size;
+	return btf_ext->data;
+}
+
 static int btf_ext_reloc_info(const struct btf *btf,
 			      const struct btf_ext_info *ext_info,
 			      const char *sec_name, __u32 insns_cnt,
@@ -848,7 +852,8 @@ static int btf_ext_reloc_info(const struct btf *btf,
 	return -ENOENT;
 }
 
-int btf_ext__reloc_func_info(const struct btf *btf, const 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 *cnt)
 {
@@ -856,7 +861,8 @@ int btf_ext__reloc_func_info(const struct btf *btf, const struct btf_ext *btf_ex
 				  insns_cnt, func_info, cnt);
 }
 
-int btf_ext__reloc_line_info(const struct btf *btf, const struct btf_ext *btf_ext,
+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)
 {
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 10fe412461fe..0306b54d54eb 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -78,6 +78,8 @@ LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
 
 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 const void *btf_ext__get_raw_data(const struct btf_ext* btf_ext,
+					     __u32 *size);
 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,
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 9e10467f8cbb..eb78c7c261d9 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -141,6 +141,7 @@ LIBBPF_0.0.2 {
 		btf__load;
 		btf_ext__free;
 		btf_ext__func_info_rec_size;
+		btf_ext__get_raw_data;
 		btf_ext__line_info_rec_size;
 		btf_ext__new;
 		btf_ext__reloc_func_info;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v4 bpf-next 4/4] tools/bpf: remove btf__get_strings() superseded by raw data API
  2019-02-08 19:19 [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Andrii Nakryiko
                   ` (2 preceding siblings ...)
  2019-02-08 19:19 ` [PATCH v4 bpf-next 3/4] btf: expose API to work with raw btf_ext data Andrii Nakryiko
@ 2019-02-08 19:19 ` Andrii Nakryiko
  2019-02-08 20:08 ` [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Alexei Starovoitov
  4 siblings, 0 replies; 7+ messages in thread
From: Andrii Nakryiko @ 2019-02-08 19:19 UTC (permalink / raw)
  To: alexei.starovoitov, andrii.nakryiko, songliubraving, yhs, ast,
	kafai, netdev, kernel-team, daniel, acme
  Cc: Andrii Nakryiko

Now that we have btf__get_raw_data() it's trivial for tests to iterate
over all strings for testing purposes, which eliminates the need for
btf__get_strings() API.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
---
 tools/lib/bpf/btf.c                    |  7 -----
 tools/lib/bpf/btf.h                    |  2 --
 tools/lib/bpf/libbpf.map               |  1 -
 tools/testing/selftests/bpf/test_btf.c | 39 +++++++++++++++++---------
 4 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 2779043b3375..b86a5da85c69 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -448,13 +448,6 @@ const void *btf__get_raw_data(const struct btf *btf, __u32 *size)
 	return btf->data;
 }
 
-void btf__get_strings(const struct btf *btf, const char **strings,
-		      __u32 *str_len)
-{
-	*strings = btf->strings;
-	*str_len = btf->hdr->str_len;
-}
-
 const char *btf__name_by_offset(const struct btf *btf, __u32 offset)
 {
 	if (offset < btf->hdr->str_len)
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 0306b54d54eb..94bbc249b0f1 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -67,8 +67,6 @@ 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__fd(const struct btf *btf);
 LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
-LIBBPF_API void btf__get_strings(const struct btf *btf, const char **strings,
-				 __u32 *str_len);
 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, const char *map_name,
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index eb78c7c261d9..5fc8222209f8 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -137,7 +137,6 @@ LIBBPF_0.0.2 {
 		btf__get_map_kv_tids;
 		btf__get_nr_types;
 		btf__get_raw_data;
-		btf__get_strings;
 		btf__load;
 		btf_ext__free;
 		btf_ext__func_info_rec_size;
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
index 447acc34db94..bbcacba39590 100644
--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -5882,15 +5882,17 @@ static void dump_btf_strings(const char *strs, __u32 len)
 static int do_test_dedup(unsigned int test_num)
 {
 	const struct btf_dedup_test *test = &dedup_tests[test_num - 1];
-	int err = 0, i;
-	__u32 test_nr_types, expect_nr_types, test_str_len, expect_str_len;
-	void *raw_btf;
-	unsigned int raw_btf_size;
+	__u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
+	const struct btf_header *test_hdr, *expect_hdr;
 	struct btf *test_btf = NULL, *expect_btf = NULL;
+	const void *test_btf_data, *expect_btf_data;
 	const char *ret_test_next_str, *ret_expect_next_str;
 	const char *test_strs, *expect_strs;
 	const char *test_str_cur, *test_str_end;
 	const char *expect_str_cur, *expect_str_end;
+	unsigned int raw_btf_size;
+	void *raw_btf;
+	int err = 0, i;
 
 	fprintf(stderr, "BTF dedup test[%u] (%s):", test_num, test->descr);
 
@@ -5927,23 +5929,34 @@ static int do_test_dedup(unsigned int test_num)
 		goto done;
 	}
 
-	btf__get_strings(test_btf, &test_strs, &test_str_len);
-	btf__get_strings(expect_btf, &expect_strs, &expect_str_len);
-	if (CHECK(test_str_len != expect_str_len,
-		  "test_str_len:%u != expect_str_len:%u",
-		  test_str_len, expect_str_len)) {
+	test_btf_data = btf__get_raw_data(test_btf, &test_btf_size);
+	expect_btf_data = btf__get_raw_data(expect_btf, &expect_btf_size);
+	if (CHECK(test_btf_size != expect_btf_size,
+		  "test_btf_size:%u != expect_btf_size:%u",
+		  test_btf_size, expect_btf_size)) {
+		err = -1;
+		goto done;
+	}
+
+	test_hdr = test_btf_data;
+	test_strs = test_btf_data + test_hdr->str_off;
+	expect_hdr = expect_btf_data;
+	expect_strs = expect_btf_data + expect_hdr->str_off;
+	if (CHECK(test_hdr->str_len != expect_hdr->str_len,
+		  "test_hdr->str_len:%u != expect_hdr->str_len:%u",
+		  test_hdr->str_len, expect_hdr->str_len)) {
 		fprintf(stderr, "\ntest strings:\n");
-		dump_btf_strings(test_strs, test_str_len);
+		dump_btf_strings(test_strs, test_hdr->str_len);
 		fprintf(stderr, "\nexpected strings:\n");
-		dump_btf_strings(expect_strs, expect_str_len);
+		dump_btf_strings(expect_strs, expect_hdr->str_len);
 		err = -1;
 		goto done;
 	}
 
 	test_str_cur = test_strs;
-	test_str_end = test_strs + test_str_len;
+	test_str_end = test_strs + test_hdr->str_len;
 	expect_str_cur = expect_strs;
-	expect_str_end = expect_strs + expect_str_len;
+	expect_str_end = expect_strs + expect_hdr->str_len;
 	while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) {
 		size_t test_len, expect_len;
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 bpf-next 3/4] btf: expose API to work with raw btf_ext data
  2019-02-08 19:19 ` [PATCH v4 bpf-next 3/4] btf: expose API to work with raw btf_ext data Andrii Nakryiko
@ 2019-02-08 19:50   ` Yonghong Song
  0 siblings, 0 replies; 7+ messages in thread
From: Yonghong Song @ 2019-02-08 19:50 UTC (permalink / raw)
  To: Andrii Nakryiko, alexei.starovoitov, andrii.nakryiko, Song Liu,
	Alexei Starovoitov, Martin Lau, netdev, Kernel Team, daniel,
	acme



On 2/8/19 11:19 AM, Andrii Nakryiko wrote:
> This patch changes struct btf_ext to retain original data in sequential
> block of memory, which makes it possible to expose
> btf_ext__get_raw_data() interface similar to btf__get_raw_data(), allowing
> users of libbpf to get access to raw representation of .BTF.ext section.
> 
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>

Acked-by: Yonghong Song <yhs@fb.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel
  2019-02-08 19:19 [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Andrii Nakryiko
                   ` (3 preceding siblings ...)
  2019-02-08 19:19 ` [PATCH v4 bpf-next 4/4] tools/bpf: remove btf__get_strings() superseded by raw data API Andrii Nakryiko
@ 2019-02-08 20:08 ` Alexei Starovoitov
  4 siblings, 0 replies; 7+ messages in thread
From: Alexei Starovoitov @ 2019-02-08 20:08 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: andrii.nakryiko, songliubraving, yhs, ast, kafai, netdev,
	kernel-team, daniel, acme

On Fri, Feb 08, 2019 at 11:19:35AM -0800, Andrii Nakryiko wrote:
> This patchset introduces a set of new APIs that make it possible to work with BTF
> more effectively (and without involving kernel) for applications like pahole that
> need to manipulate .BTF and .BTF.ext data.
> 
> Patch #1 changes existing btf__new() API call to only load and initialize
> struct btf, while exposing new btf__load() API to attempt to load and validate
> BTF in kernel.
> 
> Patch #2 adds btf__get_raw_data() API allowing to get access to raw BTF data from
> struct btf.
> 
> Patch #3 adds similar btf_ext__get_raw_data() API for working with struct btf_ext.
> 
> Patch #4 removes not-yet-stable btf__get_strings() API which was added to be able
> to test contents of struct btf for btf__dedup(). It's now superseded by raw APIs.
> 
> v3->v4:
> - formatting fixes
> - renamed btf_ext functions/structs to use "setup" language instead of "copy"
> - removed btf__get_strings from libbpf.map
> 
> v2->v3:
> - const void* variants of btf__get_raw_data()
> - added btf_ext__get_raw_data()
> - removed btf__get_strings() and adapted test_btf.c to use btf__get_raw_data()
> 
> v1->v2:
> - btf_load() returns just error, not fd
> - fix ordering in libbpf.map

Applied, Thanks


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-02-08 20:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-08 19:19 [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Andrii Nakryiko
2019-02-08 19:19 ` [PATCH v4 bpf-next 1/4] btf: separate btf creation and loading Andrii Nakryiko
2019-02-08 19:19 ` [PATCH v4 bpf-next 2/4] btf: expose API to work with raw btf data Andrii Nakryiko
2019-02-08 19:19 ` [PATCH v4 bpf-next 3/4] btf: expose API to work with raw btf_ext data Andrii Nakryiko
2019-02-08 19:50   ` Yonghong Song
2019-02-08 19:19 ` [PATCH v4 bpf-next 4/4] tools/bpf: remove btf__get_strings() superseded by raw data API Andrii Nakryiko
2019-02-08 20:08 ` [PATCH v4 bpf-next 0/4] tools/btf: extend libbpf APIs to work with btf w/o kernel Alexei Starovoitov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).