Add related code which make libcareplus can run basic demo on aarch64. Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
240 lines
5.7 KiB
Diff
240 lines
5.7 KiB
Diff
From 05b64620354b8f8bd36c3f782eff9cd145f57fea Mon Sep 17 00:00:00 2001
|
|
From: Jiajie Li <lijiajie11@huawei.com>
|
|
Date: Tue, 13 Oct 2020 11:10:11 +0800
|
|
Subject: [PATCH 45/89] kpatch_ptrace: Split function wait_for_mmap
|
|
|
|
The function wait_for_mmap is arch related, so make two separate
|
|
definations in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c
|
|
|
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
|
---
|
|
src/arch/aarch64/arch_ptrace.c | 58 ++++++++++++++++++++++++++++++++++
|
|
src/arch/x86/arch_ptrace.c | 58 ++++++++++++++++++++++++++++++++++
|
|
src/include/kpatch_ptrace.h | 3 ++
|
|
src/kpatch_ptrace.c | 58 ----------------------------------
|
|
4 files changed, 119 insertions(+), 58 deletions(-)
|
|
|
|
diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c
|
|
index a444285..b21189e 100644
|
|
--- a/src/arch/aarch64/arch_ptrace.c
|
|
+++ b/src/arch/aarch64/arch_ptrace.c
|
|
@@ -22,6 +22,64 @@
|
|
|
|
#include <gelf.h>
|
|
|
|
+int
|
|
+wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
|
+ unsigned long *pbase)
|
|
+{
|
|
+ int ret, status = 0, insyscall = 0;
|
|
+ long rv;
|
|
+
|
|
+ while (1) {
|
|
+ ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL,
|
|
+ (void *)(uintptr_t)status);
|
|
+ if (ret < 0) {
|
|
+ kplogerror("can't PTRACE_SYSCALL tracee - %d\n",
|
|
+ pctx->pid);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ ret = waitpid(pctx->pid, &status, __WALL);
|
|
+ if (ret < 0) {
|
|
+ kplogerror("can't wait tracee - %d\n", pctx->pid);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (WIFEXITED(status)) {
|
|
+ status = WTERMSIG(status);
|
|
+ continue;
|
|
+ } else if (!WIFSTOPPED(status)) {
|
|
+ status = 0;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ status = 0;
|
|
+
|
|
+ if (insyscall == 0) {
|
|
+ rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
|
+ offsetof(struct user_regs_struct,
|
|
+ regs[29]),
|
|
+ NULL);
|
|
+ if (rv == -1) {
|
|
+ kplogerror("ptrace(PTRACE_PEEKUSER)\n");
|
|
+ return -1;
|
|
+ }
|
|
+ insyscall = rv;
|
|
+ continue;
|
|
+ } else if (insyscall == __NR_mmap) {
|
|
+ rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
|
+ offsetof(struct user_regs_struct,
|
|
+ regs[8]),
|
|
+ NULL);
|
|
+ *pbase = rv;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ insyscall = !insyscall;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
|
unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
|
unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
|
diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c
|
|
index 10127a3..0032cbd 100644
|
|
--- a/src/arch/x86/arch_ptrace.c
|
|
+++ b/src/arch/x86/arch_ptrace.c
|
|
@@ -22,6 +22,64 @@
|
|
|
|
#include <gelf.h>
|
|
|
|
+int
|
|
+wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
|
+ unsigned long *pbase)
|
|
+{
|
|
+ int ret, status = 0, insyscall = 0;
|
|
+ long rv;
|
|
+
|
|
+ while (1) {
|
|
+ ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL,
|
|
+ (void *)(uintptr_t)status);
|
|
+ if (ret < 0) {
|
|
+ kplogerror("can't PTRACE_SYSCALL tracee - %d\n",
|
|
+ pctx->pid);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ ret = waitpid(pctx->pid, &status, __WALL);
|
|
+ if (ret < 0) {
|
|
+ kplogerror("can't wait tracee - %d\n", pctx->pid);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (WIFEXITED(status)) {
|
|
+ status = WTERMSIG(status);
|
|
+ continue;
|
|
+ } else if (!WIFSTOPPED(status)) {
|
|
+ status = 0;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ status = 0;
|
|
+
|
|
+ if (insyscall == 0) {
|
|
+ rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
|
+ offsetof(struct user_regs_struct,
|
|
+ orig_rax),
|
|
+ NULL);
|
|
+ if (rv == -1) {
|
|
+ kplogerror("ptrace(PTRACE_PEEKUSER)\n");
|
|
+ return -1;
|
|
+ }
|
|
+ insyscall = rv;
|
|
+ continue;
|
|
+ } else if (insyscall == __NR_mmap) {
|
|
+ rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
|
+ offsetof(struct user_regs_struct,
|
|
+ rax),
|
|
+ NULL);
|
|
+ *pbase = rv;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ insyscall = !insyscall;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
|
unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
|
unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
|
diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h
|
|
index c8cfd41..5abcf26 100644
|
|
--- a/src/include/kpatch_ptrace.h
|
|
+++ b/src/include/kpatch_ptrace.h
|
|
@@ -141,4 +141,7 @@ int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr,
|
|
unsigned long arg4, unsigned long arg5, unsigned long arg6,
|
|
unsigned long *res);
|
|
|
|
+int wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
|
+ unsigned long *pbase);
|
|
+
|
|
#endif
|
|
diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c
|
|
index 057b08a..7ab550c 100644
|
|
--- a/src/kpatch_ptrace.c
|
|
+++ b/src/kpatch_ptrace.c
|
|
@@ -448,64 +448,6 @@ wait_for_stop(struct kpatch_ptrace_ctx *pctx,
|
|
return 0;
|
|
}
|
|
|
|
-static int
|
|
-wait_for_mmap(struct kpatch_ptrace_ctx *pctx,
|
|
- unsigned long *pbase)
|
|
-{
|
|
- int ret, status = 0, insyscall = 0;
|
|
- long rv;
|
|
-
|
|
- while (1) {
|
|
- ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL,
|
|
- (void *)(uintptr_t)status);
|
|
- if (ret < 0) {
|
|
- kplogerror("can't PTRACE_SYSCALL tracee - %d\n",
|
|
- pctx->pid);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- ret = waitpid(pctx->pid, &status, __WALL);
|
|
- if (ret < 0) {
|
|
- kplogerror("can't wait tracee - %d\n", pctx->pid);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- if (WIFEXITED(status)) {
|
|
- status = WTERMSIG(status);
|
|
- continue;
|
|
- } else if (!WIFSTOPPED(status)) {
|
|
- status = 0;
|
|
- continue;
|
|
- }
|
|
-
|
|
- status = 0;
|
|
-
|
|
- if (insyscall == 0) {
|
|
- rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
|
- offsetof(struct user_regs_struct,
|
|
- orig_rax),
|
|
- NULL);
|
|
- if (rv == -1) {
|
|
- kplogerror("ptrace(PTRACE_PEEKUSER)\n");
|
|
- return -1;
|
|
- }
|
|
- insyscall = rv;
|
|
- continue;
|
|
- } else if (insyscall == __NR_mmap) {
|
|
- rv = ptrace(PTRACE_PEEKUSER, pctx->pid,
|
|
- offsetof(struct user_regs_struct,
|
|
- rax),
|
|
- NULL);
|
|
- *pbase = rv;
|
|
- break;
|
|
- }
|
|
-
|
|
- insyscall = !insyscall;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
int
|
|
kpatch_execute_remote(struct kpatch_ptrace_ctx *pctx,
|
|
const unsigned char *code,
|
|
--
|
|
2.23.0
|
|
|