Blob Blame History Raw
From 46b54db1427ac7a58f986ae3506ce23c068d94e0 Mon Sep 17 00:00:00 2001
From: Josh Poimboeuf <jpoimboe@redhat.com>
Date: Tue, 23 Jun 2020 22:20:33 -0500
Subject: [PATCH] create-diff-object: change rela_equal() to return bool

Change rela_equal's return value to bool to make its return semantics
more clear.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>

create-diff-object: Ignore changes to .altinstr_aux

On x86, .altinstr_aux is used to store temporary code which allows
static_cpu_has() to work before apply_alternatives() has run.  This code
is completely inert for modules, because apply_alternatives() runs
during module init, before the module is fully formed.  Any changed
references to it (i.e. changed addend) can be ignored.  As long as
they're both references to .altinstr_aux, they can be considered equal,
even if the addends differ.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 kpatch-build/create-diff-object.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
index aedd07d..b7332b1 100644
--- a/kpatch-build/create-diff-object.c
+++ b/kpatch-build/create-diff-object.c
@@ -327,14 +327,27 @@ static int kpatch_mangled_strcmp(char *s1, char *s2)
 	return 1;
 }
 
-static int rela_equal(struct rela *rela1, struct rela *rela2)
+static bool rela_equal(struct rela *rela1, struct rela *rela2)
 {
 	struct rela *rela_toc1, *rela_toc2;
 	unsigned long toc_data1 = 0, toc_data2 = 0; /* = 0 to prevent gcc warning */
 
 	if (rela1->type != rela2->type ||
 	    rela1->offset != rela2->offset)
-		return 0;
+		return false;
+
+	/*
+	 * On x86, .altinstr_aux is used to store temporary code which allows
+	 * static_cpu_has() to work before apply_alternatives() has run.  This
+	 * code is completely inert for modules, because apply_alternatives()
+	 * runs during module init, before the module is fully formed.  Any
+	 * changed references to it (i.e. changed addend) can be ignored.  As
+	 * long as they're both references to .altinstr_aux, they can be
+	 * considered equal, even if the addends differ.
+	 */
+	if (!strcmp(rela1->sym->name, ".altinstr_aux") &&
+	    !strcmp(rela2->sym->name, ".altinstr_aux"))
+		return true;
 
 	/*
 	 * With -mcmodel=large on ppc64le, GCC might generate entries in the .toc
@@ -393,13 +406,13 @@ static int rela_equal(struct rela *rela1, struct rela *rela2)
 		return toc_data1 == toc_data2;
 
 	if (!rela_toc1 || !rela_toc2)
-		return 0;
+		return false;
 
 	if (rela_toc1->string)
 		return rela_toc2->string && !strcmp(rela_toc1->string, rela_toc2->string);
 
 	if (rela_toc1->addend != rela_toc2->addend)
-		return 0;
+		return false;
 
 	return !kpatch_mangled_strcmp(rela_toc1->sym->name, rela_toc2->sym->name);
 }
-- 
2.21.3