From cbe24fb9c438f147fdd70c41f2a66844457ffed4 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 31 Oct 2016 15:06:48 +0300 Subject: compel: Move in parasite engine This is the final patch in the series. It does a bunch of renames and fixes headers respectively. Signed-off-by: Cyrill Gorcunov Signed-off-by: Andrei Vagin --- compel/arch/aarch64/src/lib/include/ptrace.h | 15 --- .../aarch64/src/lib/include/uapi/asm/breakpoints.h | 15 +++ .../src/lib/include/uapi/asm/infect-types.h | 57 +++++++++++ compel/arch/aarch64/src/lib/infect.c | 111 +++++++++++++++++++++ 4 files changed, 183 insertions(+), 15 deletions(-) delete mode 100644 compel/arch/aarch64/src/lib/include/ptrace.h create mode 100644 compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h create mode 100644 compel/arch/aarch64/src/lib/include/uapi/asm/infect-types.h create mode 100644 compel/arch/aarch64/src/lib/infect.c (limited to 'compel/arch/aarch64') diff --git a/compel/arch/aarch64/src/lib/include/ptrace.h b/compel/arch/aarch64/src/lib/include/ptrace.h deleted file mode 100644 index e18454df2..000000000 --- a/compel/arch/aarch64/src/lib/include/ptrace.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __COMPEL_PTRACE_H__ -#define __COMPEL_PTRACE_H__ -#define ARCH_SI_TRAP TRAP_BRKPT - -static inline int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - return 0; -} - -static inline int ptrace_flush_breakpoints(pid_t pid) -{ - return 0; -} - -#endif diff --git a/compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h new file mode 100644 index 000000000..5f090490d --- /dev/null +++ b/compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h @@ -0,0 +1,15 @@ +#ifndef __COMPEL_BREAKPOINTS_H__ +#define __COMPEL_BREAKPOINTS_H__ +#define ARCH_SI_TRAP TRAP_BRKPT + +static inline int ptrace_set_breakpoint(pid_t pid, void *addr) +{ + return 0; +} + +static inline int ptrace_flush_breakpoints(pid_t pid) +{ + return 0; +} + +#endif diff --git a/compel/arch/aarch64/src/lib/include/uapi/asm/infect-types.h b/compel/arch/aarch64/src/lib/include/uapi/asm/infect-types.h new file mode 100644 index 000000000..714881c57 --- /dev/null +++ b/compel/arch/aarch64/src/lib/include/uapi/asm/infect-types.h @@ -0,0 +1,57 @@ +#ifndef UAPI_COMPEL_ASM_TYPES_H__ +#define UAPI_COMPEL_ASM_TYPES_H__ + +#include +#include +#include +#include +#include "common/page.h" + +#define SIGMAX 64 +#define SIGMAX_OLD 31 + +/* + * Copied from the Linux kernel header arch/arm64/include/uapi/asm/ptrace.h + * + * A thread ARM CPU context + */ + +typedef struct user_pt_regs user_regs_struct_t; +typedef struct user_fpsimd_state user_fpregs_struct_t; + +#define REG_RES(r) ((uint64_t)(r).regs[0]) +#define REG_IP(r) ((uint64_t)(r).pc) +#define REG_SYSCALL_NR(r) ((uint64_t)(r).regs[8]) + +#define user_regs_native(pregs) true + +/* + * Range for task size calculated from the following Linux kernel files: + * arch/arm64/include/asm/memory.h + * arch/arm64/Kconfig + * + * TODO: handle 32 bit tasks + */ +#define TASK_SIZE_MIN (1UL << 39) +#define TASK_SIZE_MAX (1UL << 48) + +static inline unsigned long task_size(void) +{ + unsigned long task_size; + + for (task_size = TASK_SIZE_MIN; task_size < TASK_SIZE_MAX; task_size <<= 1) + if (munmap((void *)task_size, page_size())) + break; + return task_size; +} + +#define AT_VECTOR_SIZE 40 + +typedef uint64_t auxv_t; +typedef uint64_t tls_t; + +#define ARCH_SI_TRAP TRAP_BRKPT + +#define __NR(syscall, compat) __NR_##syscall + +#endif /* UAPI_COMPEL_ASM_TYPES_H__ */ diff --git a/compel/arch/aarch64/src/lib/infect.c b/compel/arch/aarch64/src/lib/infect.c new file mode 100644 index 000000000..fceea2816 --- /dev/null +++ b/compel/arch/aarch64/src/lib/infect.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include "uapi/compel/asm/infect-types.h" +#include "log.h" +#include "errno.h" +#include "infect.h" +#include "infect-priv.h" + +/* + * Injected syscall instruction + */ +const char code_syscall[] = { + 0x01, 0x00, 0x00, 0xd4, /* SVC #0 */ + 0x00, 0x00, 0x20, 0xd4 /* BRK #0 */ +}; + +static const int +code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long)); + +static inline void __always_unused __check_code_syscall(void) +{ + BUILD_BUG_ON(code_syscall_aligned != BUILTIN_SYSCALL_SIZE); + BUILD_BUG_ON(!is_log2(sizeof(code_syscall))); +} + +int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg) +{ + struct iovec iov; + user_fpregs_struct_t fpsimd; + int ret; + + pr_info("Dumping GP/FPU registers for %d\n", pid); + + iov.iov_base = ®s; + iov.iov_len = sizeof(user_regs_struct_t); + if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov))) { + pr_perror("Failed to obtain CPU registers for %d", pid); + goto err; + } + + iov.iov_base = &fpsimd; + iov.iov_len = sizeof(fpsimd); + if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov))) { + pr_perror("Failed to obtain FPU registers for %d", pid); + goto err; + } + + ret = save(arg, ®s, &fpsimd); +err: + return ret; +} + +int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6) +{ + user_regs_struct_t regs = ctl->orig.regs; + int err; + + regs.regs[8] = (unsigned long)nr; + regs.regs[0] = arg1; + regs.regs[1] = arg2; + regs.regs[2] = arg3; + regs.regs[3] = arg4; + regs.regs[4] = arg5; + regs.regs[5] = arg6; + regs.regs[6] = 0; + regs.regs[7] = 0; + + err = compel_execute_syscall(ctl, ®s, code_syscall); + + *ret = regs.regs[0]; + return err; +} + +void *remote_mmap(struct parasite_ctl *ctl, + void *addr, size_t length, int prot, + int flags, int fd, off_t offset) +{ + unsigned long map; + int err; + + err = compel_syscall(ctl, __NR_mmap, &map, + (unsigned long)addr, length, prot, flags, fd, offset); + if (err < 0 || (long)map < 0) + map = 0; + + return (void *)map; +} + +void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs) +{ + regs->pc = new_ip; + if (stack) + regs->sp = (unsigned long)stack; +} + +bool arch_can_dump_task(struct parasite_ctl *ctl) +{ + /* + * TODO: Add proper check here + */ + return true; +} -- cgit v1.2.3