Skip to content

Commit

Permalink
i#6514 null SP to clone(), part 1: Move dynamorio_clone to drlibc (#6557
Browse files Browse the repository at this point in the history
)

This patch is just moving code, no functional changes. dynamorio_clone
is moved to drlibc so that it can also be used by tests.

Issue: #6514
  • Loading branch information
xdje42 authored Jan 26, 2024
1 parent 04b32f5 commit 1ae669d
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 114 deletions.
17 changes: 0 additions & 17 deletions core/arch/aarch64/aarch64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 0 additions & 24 deletions core/arch/arm/arm.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 0 additions & 19 deletions core/arch/riscv64/riscv64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
54 changes: 0 additions & 54 deletions core/arch/x86/x86.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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 */


Expand Down
25 changes: 25 additions & 0 deletions core/drlibc/drlibc_aarch64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
32 changes: 32 additions & 0 deletions core/drlibc/drlibc_arm.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
27 changes: 27 additions & 0 deletions core/drlibc/drlibc_riscv64.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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, ...);
*
Expand Down Expand Up @@ -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
57 changes: 57 additions & 0 deletions core/drlibc/drlibc_x86.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

0 comments on commit 1ae669d

Please sign in to comment.