kpatch/9015-create-diff-object-exclude-line-only-change-for-arm6.patch
Zhipeng Xie 428b311440 sync code to openeuler
sync latest code to openeuler

Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
2019-12-30 15:59:18 +08:00

107 lines
3.1 KiB
Diff

From d1bbff5da464148e5d277b601a31d7872b4e376b Mon Sep 17 00:00:00 2001
From: Zhipeng Xie <xiezhipeng1@huawei.com>
Date: Fri, 2 Nov 2018 17:26:00 +0000
Subject: [PATCH 1015/1015] create-diff-object: exclude line only change for
arm64
exclude line only change for arm64 by compare mov instruction
except immediate part.
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
---
kpatch-build/create-diff-object.c | 71 ++++++++++++++++++++++++++++++++++++-
1 files changed, 70 insertions(+), 1 deletions(-)
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
index f8f3e15..12d8bd6 100644
--- a/kpatch-build/create-diff-object.c
+++ b/kpatch-build/create-diff-object.c
@@ -609,6 +609,68 @@ static int kpatch_line_macro_change_only(struct section *sec)
return 0;
}
#endif
+#define ARM64_INSTR_LEN 4
+static int arm64_kpatch_line_macro_change_only(struct section *sec)
+{
+ unsigned long start1, start2, size, offset;
+ struct rela *rela;
+ int lineonly = 0, found;
+ unsigned int mov_imm_mask = ((1<<16) - 1)<<5;
+
+ if (sec->status != CHANGED ||
+ is_rela_section(sec) ||
+ !is_text_section(sec) ||
+ sec->sh.sh_size != sec->twin->sh.sh_size ||
+ !sec->rela ||
+ sec->rela->status != SAME)
+ return 0;
+
+ start1 = (unsigned long)sec->twin->data->d_buf;
+ start2 = (unsigned long)sec->data->d_buf;
+ size = sec->sh.sh_size;
+ for (offset = 0; offset < size; offset += ARM64_INSTR_LEN) {
+ if (!memcmp((void *)start1 + offset, (void *)start2 + offset,
+ ARM64_INSTR_LEN))
+ continue;
+
+ /* verify it's a mov immediate to w1 */
+ if ((*(int *)(start1 + offset) & ~mov_imm_mask) !=
+ (*(int *)(start2 + offset) & ~mov_imm_mask))
+ return 0;
+
+ found = 0;
+ list_for_each_entry(rela, &sec->rela->relas, list) {
+ if (rela->offset < offset + ARM64_INSTR_LEN)
+ continue;
+ if (rela->string)
+ continue;
+ if (!strncmp(rela->sym->name, "__warned.", 9))
+ continue;
+ if (!strncmp(rela->sym->name, "warn_slowpath_", 14) ||
+ (!strcmp(rela->sym->name, "__warn_printk")) ||
+ (!strcmp(rela->sym->name, "__might_sleep")) ||
+ (!strcmp(rela->sym->name, "___might_sleep")) ||
+ (!strcmp(rela->sym->name, "__might_fault")) ||
+ (!strcmp(rela->sym->name, "printk")) ||
+ (!strcmp(rela->sym->name, "lockdep_rcu_suspicious"))) {
+ found = 1;
+ break;
+ }
+ return 0;
+ }
+ if (!found)
+ return 0;
+
+ lineonly = 1;
+ }
+
+ if (!lineonly)
+ ERROR("no instruction changes detected for changed section %s",
+ sec->name);
+
+ return 1;
+}
+
static void kpatch_compare_sections(struct list_head *seclist)
{
@@ -624,7 +686,14 @@ static void kpatch_compare_sections(struct list_head *seclist)
/* exclude WARN-only, might_sleep changes */
list_for_each_entry(sec, seclist, list) {
- if (kpatch_line_macro_change_only(sec)) {
+ int line_only;
+ if (arch == EM_X86_64)
+ line_only = kpatch_line_macro_change_only(sec);
+ else if (arch == EM_AARCH64)
+ line_only = arm64_kpatch_line_macro_change_only(sec);
+ else
+ line_only = 0;
+ if (line_only) {
log_debug("reverting macro / line number section %s status to SAME\n",
sec->name);
sec->status = SAME;
--
1.7.5.4