From 942cc3ace7edb7c15f40f931dd6f47a934b9fc77 Mon Sep 17 00:00:00 2001 From: Artem Savkov Date: Tue, 12 Jun 2018 17:33:17 +0200 Subject: [PATCH] create-diff-object: allow changing subsections gcc8 can place functions to .text.unlikely and .text.hot subsections during optimizations. Allow symbols to change subsections instead of failing. Signed-off-by: Artem Savkov backport from: https://github.com/jpoimboe/kpatch/commit/35cc6ff0162fc8008c4c639fdfcabd61b38a982f --- kpatch-build/create-diff-object.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 2ddd00d..61ce74f 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -68,6 +68,12 @@ char *childobj; +enum subsection { + SUBSECTION_NORMAL, + SUBSECTION_HOT, + SUBSECTION_UNLIKELY +}; + enum loglevel loglevel = NORMAL; #ifndef EM_X86_64 @@ -708,6 +714,22 @@ static void kpatch_compare_sections(struct list_head *seclist) } } +static enum subsection kpatch_subsection_type(struct section *sec) +{ + if (!strncmp(sec->name, ".text.unlikely.", 15)) + return SUBSECTION_UNLIKELY; + + if (!strncmp(sec->name, ".text.hot.", 10)) + return SUBSECTION_HOT; + + return SUBSECTION_NORMAL; +} + +static int kpatch_subsection_changed(struct section *sec1, struct section *sec2) +{ + return kpatch_subsection_type(sec1) != kpatch_subsection_type(sec2); +} + static void kpatch_compare_correlated_symbol(struct symbol *sym) { struct symbol *sym1 = sym, *sym2 = sym->twin; @@ -720,10 +742,12 @@ static void kpatch_compare_correlated_symbol(struct symbol *sym) /* * If two symbols are correlated but their sections are not, then the * symbol has changed sections. This is only allowed if the symbol is - * moving out of an ignored section. ++ * moving out of an ignored section, or moving between normal/hot/unlikely ++ * subsections. */ if (sym1->sec && sym2->sec && sym1->sec->twin != sym2->sec) { - if (sym2->sec->twin && sym2->sec->twin->ignore) + if ((sym2->sec->twin && sym2->sec->twin->ignore) || + kpatch_subsection_changed(sym1->sec, sym2->sec)) sym->status = CHANGED; else if (sym1->name[0] == '$') /* reserved symbols in aarch64 */ log_debug("maping symbols: %s", sym1->name); /* do nothing just ignogre */ -- 2.19.1