Blob Blame History Raw
From 3672db9de548ed4ed5e87089a1263f6b5ddc4a11 Mon Sep 17 00:00:00 2001
From: Song Liu <song@kernel.org>
Date: Mon, 13 Feb 2023 15:14:32 -0800
Subject: [PATCH 101/107] create-diff-object: handle __initcall_stub with
 CONFIG_LTO_CLANG

The kernel use a special __initcall_stub() with CONFIG_LTO_CLANG to avoid
name collisions. Handle it in kpatch_mangled_strcmp() by ignoring all
digits for symbols start with __initstub__kmod_syscall__.

Signed-off-by: Song Liu <song@kernel.org>
---
 kpatch-build/create-diff-object.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
index 2d7b072..fec57b8 100644
--- a/kpatch-build/create-diff-object.c
+++ b/kpatch-build/create-diff-object.c
@@ -430,6 +430,23 @@ static int __kpatch_unique_id_strcmp(char *s1, char *s2)
 	return 1;
 }
 
+static int __kpatch_skip_digits_strcmp(char *s1, char *s2)
+{
+	while (*s1 == *s2) {
+		if (!*s1)
+			return 0;
+		s1++;
+		s2++;
+
+		while (isdigit(*s1))
+			s1++;
+		while (isdigit(*s2))
+			s2++;
+	}
+
+	return 1;
+}
+
 /*
  * This is like strcmp, but for gcc-mangled symbols.  It skips the comparison
  * of any substring which consists of '.' followed by any number of digits.
@@ -446,6 +463,19 @@ static int kpatch_mangled_strcmp(char *s1, char *s2)
 	if (!strncmp(s1, "__UNIQUE_ID_", 12))
 		return __kpatch_unique_id_strcmp(s1, s2);
 
+	/*
+	 * Hack for __initcall_stub() with CONFIG_LTO_CLANG.
+	 * The following should match:
+	 *
+	 *   __initstub__kmod_syscall__728_5326_bpf_syscall_sysctl_init7
+	 *   __initstub__kmod_syscall__728_5324_bpf_syscall_sysctl_init7
+	 *
+	 * Please refer to __initcall_stub() in include/linux/init.h for
+	 * more details.
+	 */
+	if (!strncmp(s1, "__initstub__kmod_syscall__", 26))
+		return __kpatch_skip_digits_strcmp(s1, s2);
+
 	while (*s1 == *s2) {
 		if (!*s1)
 			return 0;
-- 
2.37.3