Add related code which make libcareplus can run basic demo on aarch64. Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
308 lines
8.6 KiB
Diff
308 lines
8.6 KiB
Diff
From 9ac8822b66bb06a463a29ec86088cfe8adc1e6d4 Mon Sep 17 00:00:00 2001
|
|
From: Jiajie Li <lijiajie11@huawei.com>
|
|
Date: Mon, 12 Oct 2020 14:45:03 +0800
|
|
Subject: [PATCH 34/89] kpatch_coro: Split function locate_start_context_symbol
|
|
|
|
The function locate_start_context_symbol is arch related, so let's
|
|
make two separate definations in arch/x86/arch_coro.c and
|
|
arch/aarch64/arch_coro.c
|
|
|
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
|
---
|
|
src/arch/aarch64/arch_coro.c | 63 ++++++++++++++++++++++++++
|
|
src/arch/x86/arch_coro.c | 67 +++++++++++++++++++++++++++
|
|
src/include/kpatch_coro.h | 21 +++++++++
|
|
src/kpatch_coro.c | 87 ------------------------------------
|
|
4 files changed, 151 insertions(+), 87 deletions(-)
|
|
|
|
diff --git a/src/arch/aarch64/arch_coro.c b/src/arch/aarch64/arch_coro.c
|
|
index b93581e..f485cf9 100644
|
|
--- a/src/arch/aarch64/arch_coro.c
|
|
+++ b/src/arch/aarch64/arch_coro.c
|
|
@@ -11,6 +11,69 @@
|
|
#include "include/kpatch_ptrace.h"
|
|
#include "include/kpatch_log.h"
|
|
|
|
+asm (
|
|
+ "makecontext_call:\n"
|
|
+ "mov x29, sp\n"
|
|
+ "and x29,x29,#-16\n"
|
|
+ "sub x29, x29,#0x400\n"
|
|
+ "ldr x9,[x29,#-128]\n"
|
|
+ "str x9,[fp,#0x10]\n"
|
|
+ //"str #128,[fp.#0x20]\n"
|
|
+ "mov x0,fp\n"
|
|
+ "mov x1,#0x100\n"
|
|
+ "mov x2,#0\n"
|
|
+ "svc #0\n"
|
|
+ "brk #0\n"
|
|
+ "makecontext_call_end:"
|
|
+ );
|
|
+
|
|
+extern unsigned char makecontext_call, makecontext_call_end;
|
|
+
|
|
+int
|
|
+locate_start_context_symbol(struct kpatch_process *proc,
|
|
+ unsigned long *pstart_context)
|
|
+{
|
|
+ struct object_file *olibc;
|
|
+ struct user_regs_struct regs;
|
|
+ int rv;
|
|
+ unsigned long makecontext;
|
|
+
|
|
+ olibc = kpatch_process_get_obj_by_regex(proc, "^libc-.*\\.so");
|
|
+ if (olibc == NULL) {
|
|
+ kpdebug("FAIL. Can't find libc\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ rv = kpatch_resolve_undefined_single_dynamic(olibc,
|
|
+ "makecontext",
|
|
+ &makecontext);
|
|
+ makecontext = vaddr2addr(olibc, makecontext);
|
|
+ if (rv < 0 || makecontext == 0) {
|
|
+ kpdebug("FAIL. Can't find makecontext\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ regs.regs[8] = makecontext;
|
|
+ rv = kpatch_execute_remote(proc2pctx(proc),
|
|
+ &makecontext_call,
|
|
+ &makecontext_call_end - &makecontext_call,
|
|
+ ®s);
|
|
+ if (rv < 0) {
|
|
+ kpdebug("FAIL. Can't execute makecontext\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ rv = kpatch_process_mem_read(proc,
|
|
+ regs.regs[29]- STACK_OFFSET_START_CONTEXT,
|
|
+ pstart_context,
|
|
+ sizeof(*pstart_context));
|
|
+ if (rv < 0) {
|
|
+ kpdebug("FAIL. Can't peek __start_context address\n");
|
|
+ return -1;
|
|
+ }
|
|
+ return rv;
|
|
+}
|
|
+
|
|
int get_ptr_guard(struct kpatch_process *proc,
|
|
unsigned long *ptr_guard)
|
|
{
|
|
diff --git a/src/arch/x86/arch_coro.c b/src/arch/x86/arch_coro.c
|
|
index 86bf12f..27c834b 100644
|
|
--- a/src/arch/x86/arch_coro.c
|
|
+++ b/src/arch/x86/arch_coro.c
|
|
@@ -15,6 +15,73 @@
|
|
#include "include/kpatch_ptrace.h"
|
|
#include "include/kpatch_log.h"
|
|
|
|
+asm ("makecontext_call:\n"
|
|
+ "mov %rsp, %rbp\n"
|
|
+ "and $-16, %rbp\n"
|
|
+ /* ucontext_t is 0x3a8 bytes */
|
|
+ "sub $0x400, %rbp\n"
|
|
+ /* TODO interpolate these from the calculations above */
|
|
+
|
|
+ /* set uc_stack.ss_sp and uc_stack.ss_size */
|
|
+ /* TODO magic -128 is used below as well */
|
|
+ "lea -128(%rbp), %rbx\n"
|
|
+ "movq %rbx, 0x10(%rbp)\n"
|
|
+ "movq $128, 0x20(%rbp)\n"
|
|
+ "mov %rbp, %rdi\n"
|
|
+ "mov $0x100, %rsi\n"
|
|
+ "xor %rdx, %rdx\n"
|
|
+ /* call `makecontext` */
|
|
+ "call *%rax\n"
|
|
+ "int3\n"
|
|
+ "makecontext_call_end:");
|
|
+
|
|
+extern unsigned char makecontext_call, makecontext_call_end;
|
|
+
|
|
+int
|
|
+locate_start_context_symbol(struct kpatch_process *proc,
|
|
+ unsigned long *pstart_context)
|
|
+{
|
|
+ struct object_file *olibc;
|
|
+ struct user_regs_struct regs;
|
|
+ int rv;
|
|
+ unsigned long makecontext;
|
|
+
|
|
+ olibc = kpatch_process_get_obj_by_regex(proc, "^libc-.*\\.so");
|
|
+ if (olibc == NULL) {
|
|
+ kpdebug("FAIL. Can't find libc\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ rv = kpatch_resolve_undefined_single_dynamic(olibc,
|
|
+ "makecontext",
|
|
+ &makecontext);
|
|
+ makecontext = vaddr2addr(olibc, makecontext);
|
|
+ if (rv < 0 || makecontext == 0) {
|
|
+ kpdebug("FAIL. Can't find makecontext\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ regs.rax = makecontext;
|
|
+ rv = kpatch_execute_remote(proc2pctx(proc),
|
|
+ &makecontext_call,
|
|
+ &makecontext_call_end - &makecontext_call,
|
|
+ ®s);
|
|
+ if (rv < 0) {
|
|
+ kpdebug("FAIL. Can't execute makecontext\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ rv = kpatch_process_mem_read(proc,
|
|
+ regs.rbp - STACK_OFFSET_START_CONTEXT,
|
|
+ pstart_context,
|
|
+ sizeof(*pstart_context));
|
|
+ if (rv < 0) {
|
|
+ kpdebug("FAIL. Can't peek __start_context address\n");
|
|
+ return -1;
|
|
+ }
|
|
+ return rv;
|
|
+}
|
|
+
|
|
int get_ptr_guard(struct kpatch_process *proc,
|
|
unsigned long *ptr_guard)
|
|
{
|
|
diff --git a/src/include/kpatch_coro.h b/src/include/kpatch_coro.h
|
|
index 272855e..0b3a9a1 100644
|
|
--- a/src/include/kpatch_coro.h
|
|
+++ b/src/include/kpatch_coro.h
|
|
@@ -30,10 +30,31 @@ struct UCORO_info {
|
|
int _UCORO_access_reg(unw_addr_space_t as, unw_regnum_t reg,
|
|
unw_word_t *val, int write, void *arg);
|
|
|
|
+#define PTR_DEMANGLE(ptr, key) ((((ptr) >> 0x11) | ((ptr) << 47)) ^ key)
|
|
+#define JB_RBX 0
|
|
+#define JB_RBP 1
|
|
+#define JB_R12 2
|
|
+#define JB_R13 3
|
|
+#define JB_R14 4
|
|
+#define JB_R15 5
|
|
+#define JB_RSP 6
|
|
+#define JB_RIP 7
|
|
+
|
|
+#define STACK_OFFSET_UC_LINK (2 * sizeof(long))
|
|
+#define STACK_OFFSET_START_CONTEXT (3 * sizeof(long))
|
|
+#define STACK_OFFSET_UC_LINK_PTR (4 * sizeof(long))
|
|
+#define STACK_OFFSET_COROUTINE_UCONTEXT (7 * sizeof(long))
|
|
+#define STACK_OFFSET_COROUTINE (8 * sizeof(long))
|
|
+
|
|
+#define UCONTEXT_OFFSET_JMPBUF 0x38
|
|
+
|
|
#define GLIBC_TLS_PTR_GUARD 0x30
|
|
int get_ptr_guard(struct kpatch_process *proc,
|
|
unsigned long *ptr_guard);
|
|
|
|
+int locate_start_context_symbol(struct kpatch_process *proc,
|
|
+ unsigned long *pstart_context);
|
|
+
|
|
|
|
int kpatch_coroutines_init(struct kpatch_process *proc);
|
|
int kpatch_coroutines_find(struct kpatch_process *proc);
|
|
diff --git a/src/kpatch_coro.c b/src/kpatch_coro.c
|
|
index ea4050f..8457800 100644
|
|
--- a/src/kpatch_coro.c
|
|
+++ b/src/kpatch_coro.c
|
|
@@ -95,93 +95,6 @@ kpatch_coro_free(struct kpatch_coro *c)
|
|
* some kind of persistency (to allow kernelcare updates). This
|
|
* service also can listen to netlink events about new processes.
|
|
*/
|
|
-#define PTR_DEMANGLE(ptr, key) ((((ptr) >> 0x11) | ((ptr) << 47)) ^ key)
|
|
-#define JB_RBX 0
|
|
-#define JB_RBP 1
|
|
-#define JB_R12 2
|
|
-#define JB_R13 3
|
|
-#define JB_R14 4
|
|
-#define JB_R15 5
|
|
-#define JB_RSP 6
|
|
-#define JB_RIP 7
|
|
-
|
|
-#define STACK_OFFSET_UC_LINK (2 * sizeof(long))
|
|
-#define STACK_OFFSET_START_CONTEXT (3 * sizeof(long))
|
|
-#define STACK_OFFSET_UC_LINK_PTR (4 * sizeof(long))
|
|
-#define STACK_OFFSET_COROUTINE_UCONTEXT (7 * sizeof(long))
|
|
-#define STACK_OFFSET_COROUTINE (8 * sizeof(long))
|
|
-
|
|
-#define UCONTEXT_OFFSET_JMPBUF 0x38
|
|
-
|
|
-#define UCONTEXT_OFFSET_UC_STACK_SS_SP offsetof(ucontext_t, uc_stack.ss_sp)
|
|
-#define UCONTEXT_OFFSET_UC_STACK_SS_SIZE offsetof(ucontext_t, uc_stack.ss_size)
|
|
-
|
|
-asm ("makecontext_call:\n"
|
|
- "mov %rsp, %rbp\n"
|
|
- "and $-16, %rbp\n"
|
|
- /* ucontext_t is 0x3a8 bytes */
|
|
- "sub $0x400, %rbp\n"
|
|
- /* TODO interpolate these from the calculations above */
|
|
-
|
|
- /* set uc_stack.ss_sp and uc_stack.ss_size */
|
|
- /* TODO magic -128 is used below as well */
|
|
- "lea -128(%rbp), %rbx\n"
|
|
- "movq %rbx, 0x10(%rbp)\n"
|
|
- "movq $128, 0x20(%rbp)\n"
|
|
- "mov %rbp, %rdi\n"
|
|
- "mov $0x100, %rsi\n"
|
|
- "xor %rdx, %rdx\n"
|
|
- /* call `makecontext` */
|
|
- "call *%rax\n"
|
|
- "int3\n"
|
|
- "makecontext_call_end:");
|
|
-
|
|
-extern unsigned char makecontext_call, makecontext_call_end;
|
|
-
|
|
-static int
|
|
-locate_start_context_symbol(struct kpatch_process *proc,
|
|
- unsigned long *pstart_context)
|
|
-{
|
|
- struct object_file *olibc;
|
|
- struct user_regs_struct regs;
|
|
- int rv;
|
|
- unsigned long makecontext;
|
|
-
|
|
- olibc = kpatch_process_get_obj_by_regex(proc, "^libc-.*\\.so");
|
|
- if (olibc == NULL) {
|
|
- kpdebug("FAIL. Can't find libc\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- rv = kpatch_resolve_undefined_single_dynamic(olibc,
|
|
- "makecontext",
|
|
- &makecontext);
|
|
- makecontext = vaddr2addr(olibc, makecontext);
|
|
- if (rv < 0 || makecontext == 0) {
|
|
- kpdebug("FAIL. Can't find makecontext\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- regs.rax = makecontext;
|
|
- rv = kpatch_execute_remote(proc2pctx(proc),
|
|
- &makecontext_call,
|
|
- &makecontext_call_end - &makecontext_call,
|
|
- ®s);
|
|
- if (rv < 0) {
|
|
- kpdebug("FAIL. Can't execute makecontext\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- rv = kpatch_process_mem_read(proc,
|
|
- regs.rbp - STACK_OFFSET_START_CONTEXT,
|
|
- pstart_context,
|
|
- sizeof(*pstart_context));
|
|
- if (rv < 0) {
|
|
- kpdebug("FAIL. Can't peek __start_context address\n");
|
|
- return -1;
|
|
- }
|
|
- return rv;
|
|
-}
|
|
|
|
static int is_test_target(struct kpatch_process *proc,
|
|
const char *procname)
|
|
--
|
|
2.23.0
|
|
|