Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3001)

Unified Diff: src/trusted/service_runtime/osx/mach_exception_handler.c

Issue 12207165: Mac x86_64: Mach exception support (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/trusted/service_runtime/osx/mach_exception_handler.c
===================================================================
--- src/trusted/service_runtime/osx/mach_exception_handler.c (revision 10790)
+++ src/trusted/service_runtime/osx/mach_exception_handler.c (working copy)
@@ -26,11 +26,12 @@
#include "native_client/src/trusted/service_runtime/nacl_exception.h"
#include "native_client/src/trusted/service_runtime/nacl_globals.h"
#include "native_client/src/trusted/service_runtime/nacl_switch_to_app.h"
+#include "native_client/src/trusted/service_runtime/osx/crash_filter.h"
+#include "native_client/src/trusted/service_runtime/osx/mach_thread_map.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#include "native_client/src/trusted/service_runtime/sel_rt.h"
-/* Only handle x86_32 for now. */
-#if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
+#if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
/*
@@ -92,8 +93,10 @@
mach_msg_type_number_t size;
x86_thread_state_t regs;
kern_return_t result;
+#if NACL_BUILD_SUBARCH == 32
uint16_t trusted_cs = NaClGetGlobalCs();
uint16_t trusted_ds = NaClGetGlobalDs();
+#endif
uint32_t nacl_thread_index;
struct NaClApp *nap;
struct NaClAppThread *natp;
@@ -105,13 +108,19 @@
*is_untrusted = TRUE;
/* Capture the register state of the 'excepting' thread. */
- size = sizeof(regs) / sizeof(natural_t);
+ size = x86_THREAD_STATE_COUNT;
result = thread_get_state(thread_port, x86_THREAD_STATE,
- (void *) &regs, &size);
+ (thread_state_t) &regs, &size);
if (result != KERN_SUCCESS) {
return 0;
}
+#if NACL_BUILD_SUBARCH == 32
+ CHECK(regs.tsh.flavor == x86_THREAD_STATE32);
+#elif NACL_BUILD_SUBARCH == 64
+ CHECK(regs.tsh.flavor == x86_THREAD_STATE64);
+#endif
+#if NACL_BUILD_SUBARCH == 32
/*
* If trusted_cs is 0 (which is not a usable segment selector), the
* sandbox has not been initialised yet, so there can be no untrusted
@@ -121,6 +130,7 @@
*is_untrusted = FALSE;
return 0;
}
+#endif
/*
* If the current code segment is the trusted one, we aren't in the
@@ -129,6 +139,7 @@
* the last thing to change when switching into untrusted code. We need
* tests to vet this.
*/
+#if NACL_BUILD_SUBARCH == 32
if (regs.uts.ts32.__cs == trusted_cs) {
/*
* If we are single-stepping, allow NaClSwitchRemainingRegsViaECX()
@@ -150,13 +161,36 @@
* TODO(bradnelson): Migrate that knowledge to a single shared location.
*/
nacl_thread_index = regs.uts.ts32.__gs >> 3;
+#elif NACL_BUILD_SUBARCH == 64
+ nacl_thread_index = GetNaClThreadIndexForMachThread(thread_port);
+ if (!nacl_thread_index) {
Mark Seaborn 2013/02/14 00:37:54 Make this "if (nacl_thread_index == NACL_TLS_INDEX
+ *is_untrusted = FALSE;
+ return 0;
+ }
+#endif
+
natp = NaClAppThreadGetFromIndex(nacl_thread_index);
nap = natp->nap;
+#if NACL_BUILD_SUBARCH == 64
+ *is_untrusted = NaClMachThreadStateIsInUntrusted(natp, &regs);
+ /*
+ * If trusted code accidentally jumped to untrusted code, don't let the
+ * untrusted exception handler take over.
+ */
+ if (*is_untrusted &&
+ (natp->suspend_state & NACL_APP_THREAD_UNTRUSTED) == 0) {
+ *is_untrusted = 0;
+ }
+ if (!*is_untrusted) {
+ return 0;
+ }
+#endif
if (nap->enable_faulted_thread_queue) {
/*
* If we are single-stepping, step through until we reach untrusted code.
*/
+#if NACL_BUILD_SUBARCH == 32
if (exception == EXC_BREAKPOINT &&
(regs.uts.ts32.__eflags & NACL_X86_TRAP_FLAG) != 0) {
if (regs.uts.ts32.__eip >= nap->all_regs_springboard.start_addr &&
@@ -171,6 +205,7 @@
return 1;
}
}
+#endif
/*
* Increment the kernel's thread suspension count so that the
@@ -203,6 +238,11 @@
return 0;
}
+ /* Don't handle if no exception handler is set. */
+ if (nap->exception_handler == 0) {
+ return 0;
+ }
+
/* Don't handle it if the exception flag is set. */
if (natp->exception_flag) {
return 0;
@@ -210,17 +250,16 @@
/* Set the flag. */
natp->exception_flag = 1;
- /* Don't handle if no exception handler is set. */
- if (nap->exception_handler == 0) {
- return 0;
- }
-
/* Get location of exception stack frame. */
if (natp->exception_stack) {
frame_addr_user = natp->exception_stack;
} else {
/* If not set default to user stack. */
- frame_addr_user = regs.uts.ts32.__esp;
+#if NACL_BUILD_SUBARCH == 32
+ frame_addr_user = regs.uts.ts32.__esp - NACL_STACK_RED_ZONE;
+#elif NACL_BUILD_SUBARCH == 64
+ frame_addr_user = (regs.uts.ts64.__rsp & 0xffffffff) - NACL_STACK_RED_ZONE;
Mark Seaborn 2013/02/14 00:37:54 Casting to uint32_t would be preferred over '& 0xf
+#endif
}
/* Align stack frame properly. */
@@ -238,11 +277,17 @@
/* Set up the stack frame for the handler invocation. */
frame.return_addr = 0;
+#if NACL_BUILD_SUBARCH == 32
frame.context_ptr = frame_addr_user +
offsetof(struct NaClExceptionFrame, context);
frame.context.prog_ctr = regs.uts.ts32.__eip;
frame.context.stack_ptr = regs.uts.ts32.__esp;
frame.context.frame_ptr = regs.uts.ts32.__ebp;
+#elif NACL_BUILD_SUBARCH == 64
+ frame.context.prog_ctr = regs.uts.ts64.__rip;
+ frame.context.stack_ptr = regs.uts.ts64.__rsp;
+ frame.context.frame_ptr = regs.uts.ts64.__rbp;
+#endif
/*
* Write the stack frame into untrusted address space. We do not
@@ -259,8 +304,10 @@
}
/* Set up thread context to resume at handler. */
+#if NACL_BUILD_SUBARCH == 32
natp->user.new_prog_ctr = nap->exception_handler;
natp->user.stack_ptr = frame_addr_user;
+#endif
/* TODO(bradnelson): put all registers in some default state. */
/*
@@ -276,6 +323,7 @@
* Instead we call a variant of NaClSwitchNoSSE which takes a pointer
* to the thread user context in %ecx.
*/
+#if NACL_BUILD_SUBARCH == 32
regs.uts.ts32.__eip = (uint32_t) &NaClSwitchNoSSEViaECX;
regs.uts.ts32.__cs = trusted_cs;
regs.uts.ts32.__ecx = (uint32_t) &natp->user;
@@ -283,6 +331,16 @@
regs.uts.ts32.__es = trusted_ds; /* just for good measure */
regs.uts.ts32.__ss = trusted_ds; /* just for good measure */
regs.uts.ts32.__eflags &= ~NACL_X86_DIRECTION_FLAG;
+#elif NACL_BUILD_SUBARCH == 64
+ regs.uts.ts64.__rip = NaClUserToSys(nap, nap->exception_handler);
+ regs.uts.ts64.__rsp = frame_addr_sys;
+ regs.uts.ts64.__rflags &= ~NACL_X86_DIRECTION_FLAG;
+ regs.uts.ts64.__rbp = nap->mem_start;
+
+ /* Argument 1 */
+ regs.uts.ts64.__rdi = frame_addr_user +
+ offsetof(struct NaClExceptionFrame, context);
+#endif
result = thread_set_state(thread_port, x86_THREAD_STATE,
(void *) &regs, size);
if (result != KERN_SUCCESS) {
@@ -570,10 +628,4 @@
return FALSE;
}
-#else /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 */
-
-int NaClInterceptMachExceptions(void) {
- return FALSE;
-}
-
-#endif /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 */
+#endif /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 */

Powered by Google App Engine
This is Rietveld 408576698