[PATCH pahole 2/2] btf_encoder: run BTF deduplication before writing out to ELF

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



After btf_encoder completes DWARF to BTF 1-to-1 conversion, utilize
libbpf to construct struct btf and run btf__dedup() algorithm on it.
This significantly reduces number of BTF types and strings section size
without losing any information.

Signed-off-by: Andrii Nakryiko <andriin@xxxxxx>
---
 libbtf.c | 44 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/libbtf.c b/libbtf.c
index 7b862cf..9c87c12 100644
--- a/libbtf.c
+++ b/libbtf.c
@@ -17,6 +17,9 @@
 
 #include "libbtf.h"
 #include "lib/bpf/include/uapi/linux/btf.h"
+#include "lib/bpf/include/linux/err.h"
+#include "lib/bpf/src/btf.h"
+#include "lib/bpf/src/libbpf.h"
 #include "dutil.h"
 #include "gobuffer.h"
 #include "dwarves.h"
@@ -566,19 +569,21 @@ int32_t btf_elf__add_func_proto(struct btf_elf *btfe, struct ftype *ftype, uint3
 	return type_id;
 }
 
-static int btf_elf__write(struct btf_elf *btfe)
+static int btf_elf__write(const char *filename, struct btf *btf)
 {
 	GElf_Shdr shdr_mem, *shdr;
 	GElf_Ehdr ehdr_mem, *ehdr;
 	Elf_Data *btf_elf = NULL;
 	Elf_Scn *scn = NULL;
 	Elf *elf = NULL;
+	const void *btf_data;
+	uint32_t btf_size;
 	int fd, err = -1;
 	size_t strndx;
 
-	fd = open(btfe->filename, O_RDWR);
+	fd = open(filename, O_RDWR);
 	if (fd < 0) {
-		fprintf(stderr, "Cannot open %s\n", btfe->filename);
+		fprintf(stderr, "Cannot open %s\n", filename);
 		return -1;
 	}
 
@@ -617,10 +622,12 @@ static int btf_elf__write(struct btf_elf *btfe)
 		}
 	}
 
+	btf_data = btf__get_raw_data(btf, &btf_size);
+
 	if (btf_elf) {
 		/* Exisiting .BTF section found */
-		btf_elf->d_buf = btfe->data;
-		btf_elf->d_size = btfe->size;
+		btf_elf->d_buf = (void *)btf_data;
+		btf_elf->d_size = btf_size;
 		elf_flagdata(btf_elf, ELF_C_SET, ELF_F_DIRTY);
 
 		if (elf_update(elf, ELF_C_NULL) >= 0 &&
@@ -636,7 +643,7 @@ static int btf_elf__write(struct btf_elf *btfe)
 			llvm_objcopy = "llvm-objcopy";
 
 		/* Use objcopy to add a .BTF section */
-		snprintf(tmp_fn, sizeof(tmp_fn), "%s.btfe", btfe->filename);
+		snprintf(tmp_fn, sizeof(tmp_fn), "%s.btf", filename);
 		close(fd);
 		fd = creat(tmp_fn, S_IRUSR | S_IWUSR);
 		if (fd == -1) {
@@ -646,10 +653,9 @@ static int btf_elf__write(struct btf_elf *btfe)
 		}
 
 		snprintf(cmd, sizeof(cmd), "%s --add-section .BTF=%s %s",
-			 llvm_objcopy, tmp_fn, btfe->filename);
+			 llvm_objcopy, tmp_fn, filename);
 
-		if (write(fd, btfe->data, btfe->size) == btfe->size &&
-		    !system(cmd))
+		if (write(fd, btf_data, btf_size) == btf_size && !system(cmd))
 			err = 0;
 
 		unlink(tmp_fn);
@@ -663,9 +669,15 @@ out:
 	return err;
 }
 
+static int libbpf_log(enum libbpf_print_level level, const char *format, va_list args)
+{
+	return vfprintf(stderr, format, args);
+}
+
 int btf_elf__encode(struct btf_elf *btfe, uint8_t flags)
 {
 	struct btf_header *hdr;
+	struct btf *btf;
 
 	/* Empty file, nothing to do, so... done! */
 	if (gobuffer__size(&btfe->types) == 0)
@@ -695,5 +707,17 @@ int btf_elf__encode(struct btf_elf *btfe, uint8_t flags)
 
 	*(char *)(btf_elf__nohdr_data(btfe) + hdr->str_off) = '\0';
 
-	return btf_elf__write(btfe);
+	libbpf_set_print(libbpf_log);
+
+	btf = btf__new(btfe->data, btfe->size);
+	if (IS_ERR(btf)) {
+		fprintf(stderr, "%s: btf__new failed!\n", __func__);
+		return -1;
+	}
+	if (btf__dedup(btf, NULL, NULL)) {
+		fprintf(stderr, "%s: btf__dedup failed!", __func__);
+		return -1;
+	}
+
+	return btf_elf__write(btfe->filename, btf);
 }
-- 
2.17.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux