diff mbox series

[4/7] create-diff-object: allow changing subsections

Message ID 20250116175214.83742-5-roger.pau@citrix.com (mailing list archive)
State New
Headers show
Series livepatch-build-tools: fixes for handling .cold and .hot sections | expand

Commit Message

Roger Pau Monné Jan. 16, 2025, 5:52 p.m. UTC
From: Artem Savkov <asavkov@redhat.com>

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>
---
 create-diff-object.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/create-diff-object.c b/create-diff-object.c
index dd5466bff6ce..3189d3e8451c 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);