]> xenbits.xensource.com Git - livepatch-build-tools.git/commitdiff
create-diff-object: allow changing subsections
authorArtem Savkov <asavkov@redhat.com>
Tue, 12 Jun 2018 15:33:17 +0000 (17:33 +0200)
committerRoger Pau Monne <roger.pau@citrix.com>
Tue, 21 Jan 2025 13:13:13 +0000 (14:13 +0100)
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 <asavkov@redhat.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>
create-diff-object.c

index 60ce73c3262c1499489acbba0a1521a9c97137be..8175cba5586f5dca28e892e2464960cf895cfaf3 100644 (file)
 #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);