From c351828bf35121628461095eeb25ea2152e98d38 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 21 Nov 2022 19:32:18 -0800 Subject: [PATCH] v0.9.7 backport: MR!1314 ("create-diff-object: fix __UNIQUE_ID() variable correlation") commit 901445a54fcecbd6852b79878e67153c5048602e Author: Josh Poimboeuf Date: Mon Nov 21 19:32:18 2022 -0800 create-diff-object: fix __UNIQUE_ID() variable correlation kpatch_mangled_strcmp() only ignores the digits after the period, but in the case of __UNIQUE_ID(), the symbol names have random digits before the period due to the use of `__COUNTER__`. Make sure such symbols are properly correlated. Signed-off-by: Josh Poimboeuf Signed-off-by: Yannick Cote --- kpatch-build/create-diff-object.c | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 360441111c5e..7106b67cfd25 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -396,6 +396,35 @@ static bool has_digit_tail(char *tail) return false; } +/* + * Hack for __UNIQUE_ID(). The following should match: + * + * __UNIQUE_ID_ddebug1131.186 + * __UNIQUE_ID_ddebug1132.187 + */ +static int __kpatch_unique_id_strcmp(char *s1, char *s2) +{ + /* match '__UNIQUE_ID_ddebug' */ + while (*s1 == *s2) { + if (!*s1) + return 0; + s1++; + s2++; + } + + /* skip digits before '.' or EOL */ + while (isdigit(*s1)) + s1++; + while (isdigit(*s2)) + s2++; + + if ((!*s1 || has_digit_tail(s1)) && + (!*s2 || has_digit_tail(s2))) + return 0; + + 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. @@ -409,6 +438,9 @@ static int kpatch_mangled_strcmp(char *s1, char *s2) if (strstr(s1, ".str1.")) return strcmp(s1, s2); + if (!strncmp(s1, "__UNIQUE_ID_", 12)) + return __kpatch_unique_id_strcmp(s1, s2); + while (*s1 == *s2) { if (!*s1) return 0; -- 2.38.1