From 03995e5223a568021a031518d5e68a414b47a992 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 3 Oct 2014 11:35:58 -0500 Subject: [PATCH 1/2] make __func__ a special static local The __func__ static local variable should be deemed "special", because it doesn't need to be correlated and should be included when needed by an include function. I don't have a test case for F20, but this fixes the following types of issues when doing a full-tree recompile on RHEL 7: ERROR: cifssmb.o: object size mismatch: __func__.49322 ERROR: btmrvl_main.o: kpatch_correlate_static_local_variables: 982: static local variable __func__.44657 not used ERROR: iwch_qp.o: .rodata.__func__.46024 section header details differ --- kpatch-build/create-diff-object.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index bb12200..214c8e6 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -314,8 +314,7 @@ void kpatch_create_rela_list(struct kpatch_elf *kelf, struct section *sec) if (!rela->sym) ERROR("could not find rela entry symbol\n"); if (rela->sym->sec && - ((rela->sym->sec->sh.sh_flags & SHF_STRINGS) || - !strncmp(rela->sym->name, ".rodata.__func__.", 17))) { + (rela->sym->sec->sh.sh_flags & SHF_STRINGS)) { rela->string = rela->sym->sec->data->d_buf + rela->addend; if (!rela->string) ERROR("could not lookup rela string for %s+%d", @@ -537,12 +536,18 @@ char *special_static_prefix(struct symbol *sym) if (!strncmp(sym->name, "descriptor.", 11)) return "descriptor."; + + if (!strncmp(sym->name, "__func__.", 9)) + return "__func__."; } if (sym->type == STT_SECTION) { if (!strncmp(sym->name, ".bss.__key.", 11)) return ".bss.__key."; + if (!strncmp(sym->name, ".rodata.__func__.", 17)) + return ".rodata.__func__."; + /* __verbose section contains the descriptor variables */ if (!strcmp(sym->name, "__verbose")) return sym->name; @@ -952,15 +957,6 @@ void kpatch_correlate_static_local_variables(struct kpatch_elf *base, if (!strchr(sym->name, '.')) continue; - /* - * __func__'s are special gcc static variables which contain - * the function name. There's no need to correlate them - * because they're read-only and their comparison is done in - * rela_equal() by comparing the literal strings. - */ - if (!kpatch_mangled_strcmp(sym->name, "__func__.1")) - continue; - /* find the patched function which uses the static variable */ sec = NULL; list_for_each_entry(tmpsec, &patched->sections, list) { From f7c0e6849e438700f537ac73d1b751f4e07e8fd3 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 3 Oct 2014 15:39:53 -0500 Subject: [PATCH 2/2] allow static locals to be used by two functions Allow static locals to be used by two functions. This is possible if the static's containing function is inlined. We only need to find one of them to do the correlation. --- kpatch-build/create-diff-object.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 214c8e6..d029f9a 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -957,7 +957,12 @@ void kpatch_correlate_static_local_variables(struct kpatch_elf *base, if (!strchr(sym->name, '.')) continue; - /* find the patched function which uses the static variable */ + /* + * Find the first function which uses the static variable. + * It's possible for multiple functions to use the same static + * variable if the containing function is inlined, but we only + * need to find one of them to do the correlation. + */ sec = NULL; list_for_each_entry(tmpsec, &patched->sections, list) { if (!is_rela_section(tmpsec) || @@ -967,13 +972,11 @@ void kpatch_correlate_static_local_variables(struct kpatch_elf *base, list_for_each_entry(rela, &tmpsec->relas, list) { if (rela->sym != sym) continue; - if (sec) - ERROR("static local variable %s used by two functions", - sym->name); sec = tmpsec; - break; + goto done; } } +done: if (!sec) ERROR("static local variable %s not used", sym->name);