blob: c9bbdabae98867b92857d135a7a2b7866a3c7494 [file] [log] [blame]
/* **********************************************************
* Copyright (c) 2014-2016 Google, Inc. All rights reserved.
* ********************************************************** */
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Google, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
/*
* ARM-specific assembly and trampoline code, shared w/ non-core-DR-lib.
*/
#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
* signature: dynamorio_syscall(sys_num, num_args, arg1, arg2, ...)
* For Linux, the argument max is 6.
*/
/* Linux system call on AArch32:
* - r7: syscall number
* - r0..r6: syscall arguments
* We need to not de-ref stack args that weren't passed so we can't ignore num_args.
*/
DECLARE_FUNC(dynamorio_syscall)
GLOBAL_LABEL(dynamorio_syscall:)
push {REG_R4-REG_R9}
/* Point r8 at the args on the stack */
add REG_R8, sp, #(6*ARG_SZ) /* size for {r4-r9} */
mov REG_R7, ARG1 /* sysnum */
mov REG_R0, ARG3 /* syscall arg1 */
mov REG_R9, ARG4 /* syscall arg2 */
cmp ARG2, #2
blt syscall_0_or_1arg
beq syscall_2args
cmp ARG2, #3
beq syscall_3args
cmp ARG2, #4
beq syscall_4args
cmp ARG2, #5
beq syscall_5args
cmp ARG2, #6
beq syscall_6args
syscall_7args:
ldr REG_R6, [REG_R8, #(4*ARG_SZ)] /* syscall arg7 */
syscall_6args:
ldr REG_R5, [REG_R8, #(3*ARG_SZ)] /* syscall arg6 */
syscall_5args:
ldr REG_R4, [REG_R8, #(2*ARG_SZ)] /* syscall arg5 */
syscall_4args:
ldr REG_R3, [REG_R8, #(1*ARG_SZ)] /* syscall arg4 */
syscall_3args:
ldr REG_R2, [REG_R8, #(0*ARG_SZ)] /* syscall arg3 */
syscall_2args:
mov REG_R1, REG_R9 /* syscall arg2 */
syscall_0_or_1arg:
/* arg1 is already in place */
svc #0
pop {REG_R4-REG_R9}
bx lr
/* FIXME i#1551: just a shell to get things compiling. We need to fill
* in the real implementation.
*/
#define FUNCNAME dr_fpu_exception_init
DECLARE_FUNC(FUNCNAME)
GLOBAL_LABEL(FUNCNAME:)
bx lr
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))
* TODO i#6514: Add support for passing NULL for newsp.
*/
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