diff --git a/core/arch/aarch64/aarch64.asm b/core/arch/aarch64/aarch64.asm index 4662c105ba3..bc8ec7af5f4 100644 --- a/core/arch/aarch64/aarch64.asm +++ b/core/arch/aarch64/aarch64.asm @@ -521,23 +521,6 @@ GLOBAL_LABEL(_dynamorio_runtime_resolve:) #endif /* UNIX */ #ifdef LINUX -/* thread_id_t dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, - * void *ctid, void (*func)(void)) - */ - DECLARE_FUNC(dynamorio_clone) -GLOBAL_LABEL(dynamorio_clone:) - stp ARG6, x0, [ARG2, #-16]! /* func is now on TOS of newsp */ - /* All args are already in syscall registers. */ - mov SYSNUM_REG, #SYS_clone - svc #0 - cbnz x0, dynamorio_clone_parent - ldp x0, x1, [sp], #16 - blr x0 - bl GLOBAL_REF(unexpected_return) -dynamorio_clone_parent: - ret - END_FUNC(dynamorio_clone) - DECLARE_FUNC(dynamorio_sigreturn) GLOBAL_LABEL(dynamorio_sigreturn:) mov SYSNUM_REG, #SYS_rt_sigreturn diff --git a/core/arch/arm/arm.asm b/core/arch/arm/arm.asm index d7b36251c44..f58073eca67 100644 --- a/core/arch/arm/arm.asm +++ b/core/arch/arm/arm.asm @@ -491,30 +491,6 @@ GLOBAL_LABEL(_dynamorio_runtime_resolve:) #endif /* UNIX */ #ifdef LINUX -/* thread_id_t dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, - * void *ctid, void (*func)(void)) - */ - DECLARE_FUNC(dynamorio_clone) -GLOBAL_LABEL(dynamorio_clone:) - /* Save callee-saved regs we clobber in the parent. */ - push {r4, r5, r7} - ldr r4, [sp, #12] /* ARG5 minus the pushes above */ - ldr r5, [sp, #16] /* ARG6 minus the pushes above */ - /* All args are now in syscall registers. */ - /* Push func on the new stack. */ - stmdb ARG2!, {r5} - mov r7, #SYS_clone - svc 0 - cmp r0, #0 - bne dynamorio_clone_parent - ldmia sp!, {r0} - blx r0 - bl GLOBAL_REF(unexpected_return) -dynamorio_clone_parent: - pop {r4, r5, r7} - bx lr - END_FUNC(dynamorio_clone) - DECLARE_FUNC(dynamorio_sigreturn) GLOBAL_LABEL(dynamorio_sigreturn:) mov r7, #SYS_rt_sigreturn diff --git a/core/arch/riscv64/riscv64.asm b/core/arch/riscv64/riscv64.asm index e44aca5e9e1..d64059bd1f8 100644 --- a/core/arch/riscv64/riscv64.asm +++ b/core/arch/riscv64/riscv64.asm @@ -525,25 +525,6 @@ GLOBAL_LABEL(_dynamorio_runtime_resolve:) #endif /* UNIX */ #ifdef LINUX -/* - * thread_id_t dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, - * void *ctid, void (*func)(void)) - */ - DECLARE_FUNC(dynamorio_clone) -GLOBAL_LABEL(dynamorio_clone:) - addi ARG2, ARG2, -16 /* Description: newsp = newsp - 16. */ - sd ARG6, 0 (ARG2) /* The func is now on TOS of newsp. */ - li SYSNUM_REG, SYS_clone /* All args are already in syscall registers.*/ - ecall - bnez ARG1, dynamorio_clone_parent - ld ARG1, 0 (sp) - addi sp, sp, 16 - jalr ARG1 - jal GLOBAL_REF(unexpected_return) -dynamorio_clone_parent: - ret - END_FUNC(dynamorio_clone) - DECLARE_FUNC(dynamorio_sigreturn) GLOBAL_LABEL(dynamorio_sigreturn:) li SYSNUM_REG, SYS_rt_sigreturn diff --git a/core/arch/x86/x86.asm b/core/arch/x86/x86.asm index c256f03a1ed..8fbdf124dbe 100644 --- a/core/arch/x86/x86.asm +++ b/core/arch/x86/x86.asm @@ -1556,60 +1556,6 @@ no_swap: END_FUNC(main_signal_handler) #endif /* !HAVE_SIGALTSTACK */ -#ifdef LINUX -/* SYS_clone swaps the stack so we need asm support to call it. - * signature: - * thread_id_t dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, - * void *ctid, void (*func)(void)) - */ - DECLARE_FUNC(dynamorio_clone) -GLOBAL_LABEL(dynamorio_clone:) - /* save func for use post-syscall on the newsp. - * when using clone_record_t we have 4 slots we can clobber. - */ -# ifdef X64 - sub ARG2, ARG_SZ - mov [ARG2], ARG6 /* func is now on TOS of newsp */ - /* all args are already in syscall registers */ - mov r10, rcx - mov REG_XAX, SYS_clone - syscall -# else - mov REG_XAX, ARG6 - mov REG_XCX, ARG2 - sub REG_XCX, ARG_SZ - mov [REG_XCX], REG_XAX /* func is now on TOS of newsp */ - mov REG_XDX, ARG3 - /* preserve callee-saved regs */ - push REG_XBX - push REG_XSI - push REG_XDI - /* now can't use ARG* since xsp modified by pushes */ - mov REG_XBX, DWORD [4*ARG_SZ + REG_XSP] /* ARG1 + 3 pushes */ - mov REG_XSI, DWORD [7*ARG_SZ + REG_XSP] /* ARG4 + 3 pushes */ - mov REG_XDI, DWORD [8*ARG_SZ + REG_XSP] /* ARG5 + 3 pushes */ - mov REG_XAX, SYS_clone - /* PR 254280: we assume int$80 is ok even for LOL64 */ - int HEX(80) -# endif - cmp REG_XAX, 0 - jne dynamorio_clone_parent - pop REG_XCX - call REG_XCX - /* shouldn't return */ - jmp GLOBAL_REF(unexpected_return) -dynamorio_clone_parent: -# ifndef X64 - /* restore callee-saved regs */ - pop REG_XDI - pop REG_XSI - pop REG_XBX -# endif - /* return val is in eax still */ - ret - END_FUNC(dynamorio_clone) -#endif /* LINUX */ - #endif /* UNIX */ diff --git a/core/drlibc/drlibc_aarch64.asm b/core/drlibc/drlibc_aarch64.asm index b56ed04781f..bc70a509d82 100644 --- a/core/drlibc/drlibc_aarch64.asm +++ b/core/drlibc/drlibc_aarch64.asm @@ -37,6 +37,12 @@ #include "../asm_defines.asm" START_FILE +#ifdef LINUX +#include "include/syscall.h" +#endif + +DECL_EXTERN(unexpected_return) + DECLARE_FUNC(dynamorio_syscall) GLOBAL_LABEL(dynamorio_syscall:) #ifdef LINUX @@ -125,4 +131,23 @@ GLOBAL_LABEL(dynamorio_mach_syscall:) END_FUNC(dynamorio_mach_syscall) #endif +#ifdef LINUX +/* thread_id_t dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, + * void *ctid, void (*func)(void)) + */ + DECLARE_FUNC(dynamorio_clone) +GLOBAL_LABEL(dynamorio_clone:) + stp ARG6, x0, [ARG2, #-16]! /* func is now on TOS of newsp */ + /* All args are already in syscall registers. */ + mov SYSNUM_REG, #SYS_clone + svc #0 + cbnz x0, dynamorio_clone_parent + ldp x0, x1, [sp], #16 + blr x0 + bl GLOBAL_REF(unexpected_return) +dynamorio_clone_parent: + ret + END_FUNC(dynamorio_clone) +#endif + END_FILE diff --git a/core/drlibc/drlibc_arm.asm b/core/drlibc/drlibc_arm.asm index e6eda4f6dd3..653c5c70b15 100644 --- a/core/drlibc/drlibc_arm.asm +++ b/core/drlibc/drlibc_arm.asm @@ -37,6 +37,12 @@ #include "../asm_defines.asm" START_FILE +#ifdef LINUX +#include "include/syscall.h" +#endif + +DECL_EXTERN(unexpected_return) + /* we share dynamorio_syscall w/ preload */ /* To avoid libc wrappers we roll our own syscall here. * Hardcoded to use svc/swi for 32-bit -- FIXME: use something like do_syscall @@ -95,4 +101,30 @@ GLOBAL_LABEL(FUNCNAME:) END_FUNC(FUNCNAME) #undef FUNCNAME +#ifdef LINUX +/* thread_id_t dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, + * void *ctid, void (*func)(void)) + */ + DECLARE_FUNC(dynamorio_clone) +GLOBAL_LABEL(dynamorio_clone:) + /* Save callee-saved regs we clobber in the parent. */ + push {r4, r5, r7} + ldr r4, [sp, #12] /* ARG5 minus the pushes above */ + ldr r5, [sp, #16] /* ARG6 minus the pushes above */ + /* All args are now in syscall registers. */ + /* Push func on the new stack. */ + stmdb ARG2!, {r5} + mov r7, #SYS_clone + svc 0 + cmp r0, #0 + bne dynamorio_clone_parent + ldmia sp!, {r0} + blx r0 + bl GLOBAL_REF(unexpected_return) +dynamorio_clone_parent: + pop {r4, r5, r7} + bx lr + END_FUNC(dynamorio_clone) +#endif + END_FILE diff --git a/core/drlibc/drlibc_riscv64.asm b/core/drlibc/drlibc_riscv64.asm index a1ae7343127..d2efa255056 100644 --- a/core/drlibc/drlibc_riscv64.asm +++ b/core/drlibc/drlibc_riscv64.asm @@ -37,6 +37,14 @@ #include "../asm_defines.asm" START_FILE +#ifndef LINUX +# error Non-Linux is not supported +#endif + +#include "include/syscall.h" + +DECL_EXTERN(unexpected_return) + /* * ptr_int_t dynamorio_syscall(uint sysnum, uint num_args, ...); * @@ -65,4 +73,23 @@ GLOBAL_LABEL(FUNCNAME:) END_FUNC(FUNCNAME) #undef FUNCNAME +/* + * thread_id_t dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, + * void *ctid, void (*func)(void)) + */ + DECLARE_FUNC(dynamorio_clone) +GLOBAL_LABEL(dynamorio_clone:) + addi ARG2, ARG2, -16 /* Description: newsp = newsp - 16. */ + sd ARG6, 0 (ARG2) /* The func is now on TOS of newsp. */ + li SYSNUM_REG, SYS_clone /* All args are already in syscall registers.*/ + ecall + bnez ARG1, dynamorio_clone_parent + ld ARG1, 0 (sp) + addi sp, sp, 16 + jalr ARG1 + jal GLOBAL_REF(unexpected_return) +dynamorio_clone_parent: + ret + END_FUNC(dynamorio_clone) + END_FILE diff --git a/core/drlibc/drlibc_x86.asm b/core/drlibc/drlibc_x86.asm index 430126c319b..23bfb7bf3c0 100644 --- a/core/drlibc/drlibc_x86.asm +++ b/core/drlibc/drlibc_x86.asm @@ -42,6 +42,9 @@ #include "../arch/asm_defines.asm" #include "../arch/x86/x86_asm_defines.asm" /* PUSHGPR, POPGPR, etc. */ +#ifdef LINUX +# include "include/syscall.h" +#endif #ifdef MACOS # include "include/syscall_mach.h" /* SYSCALL_NUM_MARKER_* */ #endif @@ -754,4 +757,58 @@ GLOBAL_LABEL(load_dynamo_failure:) #endif /* WINDOWS */ +#ifdef LINUX +/* SYS_clone swaps the stack so we need asm support to call it. + * signature: + * thread_id_t dynamorio_clone(uint flags, byte *newsp, void *ptid, void *tls, + * void *ctid, void (*func)(void)) + */ + DECLARE_FUNC(dynamorio_clone) +GLOBAL_LABEL(dynamorio_clone:) + /* save func for use post-syscall on the newsp. + * when using clone_record_t we have 4 slots we can clobber. + */ +# ifdef X64 + sub ARG2, ARG_SZ + mov [ARG2], ARG6 /* func is now on TOS of newsp */ + /* all args are already in syscall registers */ + mov r10, rcx + mov REG_XAX, SYS_clone + syscall +# else + mov REG_XAX, ARG6 + mov REG_XCX, ARG2 + sub REG_XCX, ARG_SZ + mov [REG_XCX], REG_XAX /* func is now on TOS of newsp */ + mov REG_XDX, ARG3 + /* preserve callee-saved regs */ + push REG_XBX + push REG_XSI + push REG_XDI + /* now can't use ARG* since xsp modified by pushes */ + mov REG_XBX, DWORD [4*ARG_SZ + REG_XSP] /* ARG1 + 3 pushes */ + mov REG_XSI, DWORD [7*ARG_SZ + REG_XSP] /* ARG4 + 3 pushes */ + mov REG_XDI, DWORD [8*ARG_SZ + REG_XSP] /* ARG5 + 3 pushes */ + mov REG_XAX, SYS_clone + /* PR 254280: we assume int$80 is ok even for LOL64 */ + int HEX(80) +# endif + cmp REG_XAX, 0 + jne dynamorio_clone_parent + pop REG_XCX + call REG_XCX + /* shouldn't return */ + jmp GLOBAL_REF(unexpected_return) +dynamorio_clone_parent: +# ifndef X64 + /* restore callee-saved regs */ + pop REG_XDI + pop REG_XSI + pop REG_XBX +# endif + /* return val is in eax still */ + ret + END_FUNC(dynamorio_clone) +#endif /* LINUX */ + END_FILE