From f1db049a60c3b05c24569b563537df201f7a6081 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 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Roger Pau Monné Reviewed-by: Ross Lagerwall --- create-diff-object.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/create-diff-object.c b/create-diff-object.c index 60ce73c..8175cba 100644 --- a/create-diff-object.c +++ b/create-diff-object.c @@ -55,6 +55,13 @@ #include "common.h" char *childobj; + +enum subsection { + SUBSECTION_NORMAL, + SUBSECTION_HOT, + SUBSECTION_UNLIKELY +}; + enum loglevel loglevel = NORMAL; static void kpatch_compare_elf_headers(Elf *elf1, Elf *elf2) @@ -833,6 +840,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; @@ -846,10 +869,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 DIFF_FATAL("symbol changed sections: %s, %s, %s, %s", sym1->name, sym2->name, sym1->sec->name, sym2->sec->name); -- 2.39.5