Add related code which make libcareplus can run basic demo on aarch64. Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
238 lines
7.1 KiB
Diff
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
|
|
|