bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC dwarves] btf_encoder: Remove duplicates from functions entries
@ 2025-07-17 15:25 Jiri Olsa
  2025-07-21 11:41 ` Alan Maguire
  0 siblings, 1 reply; 12+ messages in thread
From: Jiri Olsa @ 2025-07-17 15:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Menglong Dong, dwarves, bpf, Alexei Starovoitov, Andrii Nakryiko,
	Yonghong Song, Song Liu, Alan Maguire, Eduard Zingerman,
	Ihor Solodrai

Menglong reported issue where we can have function in BTF which has
multiple addresses in kallsysm [1].

Rather than filtering this in runtime, let's teach pahole to remove
such functions.

Removing duplicate records from functions entries that have more
at least one different address. This way btf_encoder__find_function
won't find such functions and they won't be added in BTF.

In my setup it removed 428 functions out of 77141.

[1] https://lore.kernel.org/bpf/20250710070835.260831-1-dongml2@chinatelecom.cn/
Reported-by: Menglong Dong <menglong8.dong@gmail.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---

Alan, 
I'd like to test this in the pahole CI, is there a way to manualy trigger it?

thanks,
jirka


---
 btf_encoder.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/btf_encoder.c b/btf_encoder.c
index 16739066caae..a25fe2f8bfb1 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -99,6 +99,7 @@ struct elf_function {
 	size_t		prefixlen;
 	bool		kfunc;
 	uint32_t	kfunc_flags;
+	unsigned long	addr;
 };
 
 struct elf_secinfo {
@@ -1469,6 +1470,7 @@ static void elf_functions__collect_function(struct elf_functions *functions, GEl
 
 	func = &functions->entries[functions->cnt];
 	func->name = name;
+	func->addr = sym->st_value;
 	if (strchr(name, '.')) {
 		const char *suffix = strchr(name, '.');
 
@@ -2143,6 +2145,40 @@ int btf_encoder__encode(struct btf_encoder *encoder, struct conf_load *conf)
 	return err;
 }
 
+/*
+ * Remove name duplicates from functions->entries that have
+ * at least 2 different addresses.
+ */
+static void functions_remove_dups(struct elf_functions *functions)
+{
+	struct elf_function *n = &functions->entries[0];
+	bool matched = false, diff = false;
+	int i, j;
+
+	for (i = 0, j = 1; i < functions->cnt && j < functions->cnt; i++, j++) {
+		struct elf_function *a = &functions->entries[i];
+		struct elf_function *b = &functions->entries[j];
+
+		if (!strcmp(a->name, b->name)) {
+			matched = true;
+			diff |= a->addr != b->addr;
+			continue;
+		}
+
+		/*
+		 * Keep only not-matched entries and last one of the matched/duplicates
+		 * ones if all of the matched entries had the same address.
+		 **/
+		if (!matched || !diff)
+			*n++ = *a;
+		matched = diff = false;
+	}
+
+	if (!matched || !diff)
+		*n++ = functions->entries[functions->cnt - 1];
+	functions->cnt = n - &functions->entries[0];
+}
+
 static int elf_functions__collect(struct elf_functions *functions)
 {
 	uint32_t nr_symbols = elf_symtab__nr_symbols(functions->symtab);
@@ -2168,6 +2204,7 @@ static int elf_functions__collect(struct elf_functions *functions)
 
 	if (functions->cnt) {
 		qsort(functions->entries, functions->cnt, sizeof(*functions->entries), functions_cmp);
+		functions_remove_dups(functions);
 	} else {
 		err = 0;
 		goto out_free;
-- 
2.50.1


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

end of thread, other threads:[~2025-07-24 21:27 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-17 15:25 [RFC dwarves] btf_encoder: Remove duplicates from functions entries Jiri Olsa
2025-07-21 11:41 ` Alan Maguire
2025-07-21 14:27   ` Jiri Olsa
2025-07-21 14:32     ` Nick Alcock
2025-07-21 23:27     ` Ihor Solodrai
2025-07-22 10:45       ` Alan Maguire
2025-07-22 22:58         ` Ihor Solodrai
2025-07-23 11:22           ` Jiri Olsa
2025-07-24 17:54             ` Alan Maguire
2025-07-24 21:26               ` Ihor Solodrai
2025-07-22 10:54       ` Jiri Olsa
2025-07-22 16:07         ` Ihor Solodrai

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).