X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0a7de7458d150b5d4dffc935ba399be265ef0a1a..a991bd8d3e7fe02dbca0644054bab73c5b75324a:/osfmk/arm64/bsd_arm64.c diff --git a/osfmk/arm64/bsd_arm64.c b/osfmk/arm64/bsd_arm64.c index f40b6bfca..e4ac467e5 100644 --- a/osfmk/arm64/bsd_arm64.c +++ b/osfmk/arm64/bsd_arm64.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2019 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -54,7 +54,12 @@ #include +#if CONFIG_MACF +#include +#endif + extern void throttle_lowpri_io(int); +extern arm_debug_state64_t *find_or_allocate_debug_state64(thread_t thread); void mach_syscall(struct arm_saved_state*); typedef kern_return_t (*mach_call_t)(void *); @@ -116,10 +121,37 @@ arm_get_mach_syscall_args(struct arm_saved_state *state, struct mach_call_args * return KERN_SUCCESS; } +/** + * Marks or unmarks the given thread to be single stepped such + * that it executes exactly one instruction and then takes an exception to + * prevent further execution. + * + * @param thread 64 bit thread to be single stepped + * @param on boolean value representing whether the thread should be + * single stepped (on is true) or not (on is false) + * + * @returns KERN_SUCCESS if the status is successfully set or KERN_FAILURE if + * it fails for any reason. + */ kern_return_t -thread_setsinglestep(__unused thread_t thread, __unused int on) +thread_setsinglestep(thread_t thread, int on) { - return KERN_FAILURE; /* XXX TODO */ + arm_debug_state64_t *thread_state = find_or_allocate_debug_state64(thread); + + if (thread_state == NULL) { + return KERN_FAILURE; + } + + if (on) { + thread_state->mdscr_el1 |= MDSCR_SS; + } else { + thread_state->mdscr_el1 &= ~MDSCR_SS; + } + + if (thread == current_thread()) { + arm_debug_set64(thread->machine.DebugData); + } + return KERN_SUCCESS; } #if CONFIG_DTRACE @@ -143,7 +175,17 @@ mach_syscall(struct arm_saved_state *state) { kern_return_t retval; mach_call_t mach_call; - struct mach_call_args args = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + struct mach_call_args args = { + .arg1 = 0, + .arg2 = 0, + .arg3 = 0, + .arg4 = 0, + .arg5 = 0, + .arg6 = 0, + .arg7 = 0, + .arg8 = 0, + .arg9 = 0 + }; int call_number = get_saved_state_svc_number(state); int64_t exc_code; int argc; @@ -191,8 +233,34 @@ mach_syscall(struct arm_saved_state *state) MACHDBG_CODE(DBG_MACH_EXCP_SC, (call_number)) | DBG_FUNC_START, args.arg1, args.arg2, args.arg3, args.arg4, 0); +#if CONFIG_MACF + /* + * Check syscall filter mask, if exists. + * + * Not all mach traps are filtered. e.g., mach_absolute_time() and + * mach_continuous_time(). See handle_svc(). + */ + task_t task = current_task(); + uint8_t *filter_mask = task->mach_trap_filter_mask; + + if (__improbable(filter_mask != NULL && + !bitstr_test(filter_mask, call_number))) { + if (mac_task_mach_trap_evaluate != NULL) { + retval = mac_task_mach_trap_evaluate(get_bsdtask_info(task), + call_number); + if (retval) { + goto skip_machcall; + } + } + } +#endif /* CONFIG_MACF */ + retval = mach_call(&args); +#if CONFIG_MACF +skip_machcall: +#endif + DEBUG_KPRINT_SYSCALL_MACH("mach_syscall: retval=0x%x (pid %d, tid %lld)\n", retval, proc_pid(current_proc()), thread_tid(current_thread()));