From 0e8f1ae02d601de8413766ac71ab12a3c2885ee0 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 6 Oct 2014 16:42:54 -0500 Subject: [PATCH] use kpatch_mangled_strcmp in rela_equal Use kpatch_mangled_strcmp() to compare the prefixes of special static locals. --- kpatch-build/create-diff-object.c | 60 ++++++++++++++----------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index da15267..c9f3a37 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -556,10 +556,32 @@ char *special_static_prefix(struct symbol *sym) return NULL; } +/* + * 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. + */ +static int kpatch_mangled_strcmp(char *s1, char *s2) +{ + while (*s1 == *s2) { + if (!*s1) + return 0; + if (*s1 == '.' && isdigit(s1[1])) { + if (!isdigit(s2[1])) + return 1; + while (isdigit(*++s1)) + ; + while (isdigit(*++s2)) + ; + } else { + s1++; + s2++; + } + } + return 1; +} + int rela_equal(struct rela *rela1, struct rela *rela2) { - char *prefix1, *prefix2; - if (rela1->type != rela2->type || rela1->offset != rela2->offset) return 0; @@ -570,13 +592,9 @@ int rela_equal(struct rela *rela1, struct rela *rela2) if (rela1->addend != rela2->addend) return 0; - prefix1 = special_static_prefix(rela1->sym); - if (prefix1) { - prefix2 = special_static_prefix(rela2->sym); - if (!prefix2) - return 0; - return !strcmp(prefix1, prefix2); - } + if (special_static_prefix(rela1->sym)) + return !kpatch_mangled_strcmp(rela1->sym->name, + rela2->sym->name); return !strcmp(rela1->sym->name, rela2->sym->name); } @@ -832,30 +850,6 @@ void kpatch_mark_grouped_sections(struct kpatch_elf *kelf) } } -/* - * 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. - */ -static int kpatch_mangled_strcmp(char *s1, char *s2) -{ - while (*s1 == *s2) { - if (!*s1) - return 0; - if (*s1 == '.' && isdigit(s1[1])) { - if (!isdigit(s2[1])) - return 1; - while (isdigit(*++s1)) - ; - while (isdigit(*++s2)) - ; - } else { - s1++; - s2++; - } - } - return 1; -} - /* * When gcc makes compiler optimizations which affect a function's calling * interface, it mangles the function's name. For example, sysctl_print_dir is