libcareplus/0035-kpatch_patch-Split-function-patch_apply_hunk.patch
Jiajie Li 2b0fff2855 AArch64 support: add aarch64 support for libcareplus
Add related code which make libcareplus can run basic demo on aarch64.

Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
2021-02-10 09:18:56 +08:00

238 lines
7.1 KiB
Diff

From 4f165eacd6d1d64cc43a58dd54e35017663d99e2 Mon Sep 17 00:00:00 2001
From: Jiajie Li <lijiajie11@huawei.com>
Date: Mon, 12 Oct 2020 14:58:18 +0800
Subject: [PATCH 35/89] kpatch_patch: Split function patch_apply_hunk
The function patch_apply_hunk is arch related, so make two
separate definations in arch/x86/arch_patch.c and arch/aarch64/arch_patch.c
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
Signed-off-by: Ying Fang <fangying1@huawei.com>
---
src/arch/aarch64/arch_patch.c | 68 +++++++++++++++++++++++++++++++++++
src/arch/x86/arch_patch.c | 66 ++++++++++++++++++++++++++++++++++
src/include/kpatch_patch.h | 2 ++
src/kpatch_patch.c | 44 ++---------------------
4 files changed, 139 insertions(+), 41 deletions(-)
diff --git a/src/arch/aarch64/arch_patch.c b/src/arch/aarch64/arch_patch.c
index e69de29..9102621 100644
--- a/src/arch/aarch64/arch_patch.c
+++ b/src/arch/aarch64/arch_patch.c
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/fcntl.h>
+#include <gelf.h>
+#include <libunwind.h>
+#include <libunwind-ptrace.h>
+#include "include/kpatch_patch.h"
+#include "include/kpatch_user.h"
+#include "include/kpatch_storage.h"
+#include "include/kpatch_process.h"
+#include "include/kpatch_file.h"
+#include "include/kpatch_common.h"
+#include "include/kpatch_elf.h"
+#include "include/kpatch_ptrace.h"
+#include "include/list.h"
+#include "include/kpatch_log.h"
+
+
+/*****************************************************************************
+ * Patch application subroutines
+ ****************************************************************************/
+/*
+ * This flag is local, i.e. it is never stored to the
+ * patch applied to patient's memory.
+ */
+int PATCH_APPLIED = (1 << 31);
+int HUNK_SIZE = 4;
+
+int patch_apply_hunk(struct object_file *o, size_t nhunk)
+{
+ int ret;
+ unsigned char code[] = {0x00, 0x00, 0x00, 0x00}; /* ins: b IMM */
+ struct kpatch_info *info = &o->info[nhunk];
+ unsigned long pundo;
+
+ if (is_new_func(info))
+ return 0;
+
+ pundo = o->kpta + o->kpfile.patch->user_undo + nhunk * HUNK_SIZE;
+ kpinfo("%s origcode from 0x%lx+0x%x to 0x%lx\n",
+ o->name, info->daddr, HUNK_SIZE, pundo);
+ ret = kpatch_process_memcpy(o->proc, pundo,
+ info->daddr, HUNK_SIZE);
+ if (ret < 0)
+ return ret;
+
+ kpinfo("%s hunk 0x%lx+0x%x -> 0x%lx+0x%x\n",
+ o->name, info->daddr, info->dlen, info->saddr, info->slen);
+
+ *(unsigned int *)(code) = (unsigned int)(info->saddr - info->daddr) / 4;
+ code[3] &= 0x3;
+ code[3] |= 0x14;
+
+ ret = kpatch_process_mem_write(o->proc,
+ code,
+ info->daddr,
+ sizeof(code));
+ /*
+ * NOTE(pboldin): This is only stored locally, as information have
+ * been copied to patient's memory already.
+ */
+ info->flags |= PATCH_APPLIED;
+ return ret ? -1 : 0;
+}
diff --git a/src/arch/x86/arch_patch.c b/src/arch/x86/arch_patch.c
index e69de29..a6e794d 100644
--- a/src/arch/x86/arch_patch.c
+++ b/src/arch/x86/arch_patch.c
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/fcntl.h>
+
+#include <gelf.h>
+#include <libunwind.h>
+#include <libunwind-ptrace.h>
+
+#include "include/kpatch_patch.h"
+#include "include/kpatch_user.h"
+#include "include/kpatch_storage.h"
+#include "include/kpatch_process.h"
+#include "include/kpatch_file.h"
+#include "include/kpatch_common.h"
+#include "include/kpatch_elf.h"
+#include "include/kpatch_ptrace.h"
+#include "include/list.h"
+#include "include/kpatch_log.h"
+
+/*****************************************************************************
+ * Patch application subroutines
+ ****************************************************************************/
+/*
+ * This flag is local, i.e. it is never stored to the
+ * patch applied to patient's memory.
+ */
+int PATCH_APPLIED = (1 << 31);
+int HUNK_SIZE = 5;
+
+int patch_apply_hunk(struct object_file *o, size_t nhunk)
+{
+ int ret;
+ char code[] = {0xe9, 0x00, 0x00, 0x00, 0x00}; /* jmp IMM */
+ struct kpatch_info *info = &o->info[nhunk];
+ unsigned long pundo;
+
+ if (is_new_func(info))
+ return 0;
+
+ pundo = o->kpta + o->kpfile.patch->user_undo + nhunk * HUNK_SIZE;
+ kpinfo("%s origcode from 0x%lx+0x%x to 0x%lx\n",
+ o->name, info->daddr, HUNK_SIZE, pundo);
+ ret = kpatch_process_memcpy(o->proc, pundo,
+ info->daddr, HUNK_SIZE);
+ if (ret < 0)
+ return ret;
+
+ kpinfo("%s hunk 0x%lx+0x%x -> 0x%lx+0x%x\n",
+ o->name, info->daddr, info->dlen, info->saddr, info->slen);
+ *(unsigned int *)(code + 1) = (unsigned int)(info->saddr - info->daddr - 5);
+ ret = kpatch_process_mem_write(o->proc,
+ code,
+ info->daddr,
+ sizeof(code));
+ /*
+ * NOTE(pboldin): This is only stored locally, as information have
+ * been copied to patient's memory already.
+ */
+ info->flags |= PATCH_APPLIED;
+ return ret ? -1 : 0;
+}
+
diff --git a/src/include/kpatch_patch.h b/src/include/kpatch_patch.h
index 44806ab..fa96b08 100644
--- a/src/include/kpatch_patch.h
+++ b/src/include/kpatch_patch.h
@@ -25,4 +25,6 @@ struct unpatch_data {
int process_patch(int pid, void *_data);
int process_unpatch(int pid, void *_data);
+int patch_apply_hunk(struct object_file *o, size_t nhunk);
+
#endif
diff --git a/src/kpatch_patch.c b/src/kpatch_patch.c
index 21a160a..4a1d149 100644
--- a/src/kpatch_patch.c
+++ b/src/kpatch_patch.c
@@ -270,47 +270,6 @@ patch_ensure_safety(struct object_file *o,
/*****************************************************************************
* Patch application subroutines
****************************************************************************/
-/*
- * This flag is local, i.e. it is never stored to the
- * patch applied to patient's memory.
- */
-#define PATCH_APPLIED (1 << 31)
-
-#define HUNK_SIZE 5
-
-static int
-patch_apply_hunk(struct object_file *o, size_t nhunk)
-{
- int ret;
- char code[HUNK_SIZE] = {0xe9, 0x00, 0x00, 0x00, 0x00}; /* jmp IMM */
- struct kpatch_info *info = &o->info[nhunk];
- unsigned long pundo;
-
- if (is_new_func(info))
- return 0;
-
- pundo = o->kpta + o->kpfile.patch->user_undo + nhunk * HUNK_SIZE;
- kpinfo("%s origcode from 0x%lx+0x%x to 0x%lx\n",
- o->name, info->daddr, HUNK_SIZE, pundo);
- ret = kpatch_process_memcpy(o->proc, pundo,
- info->daddr, HUNK_SIZE);
- if (ret < 0)
- return ret;
-
- kpinfo("%s hunk 0x%lx+0x%x -> 0x%lx+0x%x\n",
- o->name, info->daddr, info->dlen, info->saddr, info->slen);
- *(unsigned int *)(code + 1) = (unsigned int)(info->saddr - info->daddr - 5);
- ret = kpatch_process_mem_write(o->proc,
- code,
- info->daddr,
- sizeof(code));
- /*
- * NOTE(pboldin): This is only stored locally, as information have
- * been copied to patient's memory already.
- */
- info->flags |= PATCH_APPLIED;
- return ret ? -1 : 0;
-}
static int
duplicate_kp_file(struct object_file *o)
@@ -328,6 +287,9 @@ duplicate_kp_file(struct object_file *o)
return 0;
}
+extern int PATCH_APPLIED;
+extern int HUNK_SIZE;
+
static int
object_apply_patch(struct object_file *o)
{
--
2.23.0