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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include "native_client/src/trusted/service_runtime/osx/mach_exception_handler.h " 7 #include "native_client/src/trusted/service_runtime/osx/mach_exception_handler.h "
8 8
9 #include <mach/mach.h> 9 #include <mach/mach.h>
10 #include <mach/mach_vm.h> 10 #include <mach/mach_vm.h>
11 #include <mach/thread_status.h> 11 #include <mach/thread_status.h>
12 #include <pthread.h> 12 #include <pthread.h>
13 #include <stddef.h> 13 #include <stddef.h>
14 #include <stdio.h> 14 #include <stdio.h>
15 #include <stdlib.h> 15 #include <stdlib.h>
16 16
17 #include "native_client/src/include/nacl_macros.h" 17 #include "native_client/src/include/nacl_macros.h"
18 #include "native_client/src/include/portability.h" 18 #include "native_client/src/include/portability.h"
19 #include "native_client/src/shared/platform/nacl_check.h" 19 #include "native_client/src/shared/platform/nacl_check.h"
20 #include "native_client/src/shared/platform/nacl_log.h" 20 #include "native_client/src/shared/platform/nacl_log.h"
21 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" 21 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h"
22 #include "native_client/src/trusted/service_runtime/nacl_app.h" 22 #include "native_client/src/trusted/service_runtime/nacl_app.h"
23 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h" 23 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
24 #include "native_client/src/trusted/service_runtime/nacl_config.h" 24 #include "native_client/src/trusted/service_runtime/nacl_config.h"
25 #include "native_client/src/trusted/service_runtime/nacl_exc.h" 25 #include "native_client/src/trusted/service_runtime/nacl_exc.h"
26 #include "native_client/src/trusted/service_runtime/nacl_exception.h" 26 #include "native_client/src/trusted/service_runtime/nacl_exception.h"
27 #include "native_client/src/trusted/service_runtime/nacl_globals.h" 27 #include "native_client/src/trusted/service_runtime/nacl_globals.h"
28 #include "native_client/src/trusted/service_runtime/nacl_switch_to_app.h" 28 #include "native_client/src/trusted/service_runtime/nacl_switch_to_app.h"
29 #include "native_client/src/trusted/service_runtime/nacl_tls.h"
30 #include "native_client/src/trusted/service_runtime/osx/mach_thread_map.h"
31 #include "native_client/src/trusted/service_runtime/osx/mach_thread_trusted_stat e.h"
29 #include "native_client/src/trusted/service_runtime/sel_ldr.h" 32 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
30 #include "native_client/src/trusted/service_runtime/sel_rt.h" 33 #include "native_client/src/trusted/service_runtime/sel_rt.h"
31 34
32 /* Only handle x86_32 for now. */ 35 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
33 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
34 36
35 37
36 /* 38 /*
37 * MIG generated message pump from /usr/include/mach/exc.defs 39 * MIG generated message pump from /usr/include/mach/exc.defs
38 * Tweaked to place in an isolated namespace. 40 * Tweaked to place in an isolated namespace.
39 */ 41 */
40 boolean_t nacl_exc_server( 42 boolean_t nacl_exc_server(
41 mach_msg_header_t *InHeadP, 43 mach_msg_header_t *InHeadP,
42 mach_msg_header_t *OutHeadP); 44 mach_msg_header_t *OutHeadP);
43 45
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 } 82 }
81 } 83 }
82 84
83 static void FireDebugStubEvent(int pipe_fd) { 85 static void FireDebugStubEvent(int pipe_fd) {
84 char buf = 0; 86 char buf = 0;
85 if (write(pipe_fd, &buf, sizeof(buf)) != sizeof(buf)) { 87 if (write(pipe_fd, &buf, sizeof(buf)) != sizeof(buf)) {
86 NaClLog(LOG_FATAL, "FireDebugStubEvent: Can't send debug stub event\n"); 88 NaClLog(LOG_FATAL, "FireDebugStubEvent: Can't send debug stub event\n");
87 } 89 }
88 } 90 }
89 91
92 #if NACL_BUILD_SUBARCH == 32
93
94 #define NATIVE_x86_THREAD_STATE x86_THREAD_STATE32
95 #define TSx ts32
96
97 #define TS_xCX TSx.__ecx
Mark Seaborn 2013/02/14 23:55:02 I'm not overly keen on adding macros for accessing
98 #define TS_xBP TSx.__ebp
99 #define TS_xSP TSx.__esp
100 #define TS_SS TSx.__ss
101 #define TS_xFLAGS TSx.__eflags
102 #define TS_xIP TSx.__eip
103 #define TS_CS TSx.__cs
104 #define TS_DS TSx.__ds
105 #define TS_ES TSx.__es
106 #define TS_GS TSx.__gs
107
108 #elif NACL_BUILD_SUBARCH == 64
109
110 #define NATIVE_x86_THREAD_STATE x86_THREAD_STATE64
111 #define TSx ts64
112
113 #define TS_xDI TSx.__rdi
114 #define TS_xBP TSx.__rbp
115 #define TS_xSP TSx.__rsp
116 #define TS_xIP TSx.__rip
117 #define TS_xFLAGS TSx.__rflags
118
119 #endif /* NACL_BUILD_SUBARCH */
120
90 static int HandleException(mach_port_t thread_port, 121 static int HandleException(mach_port_t thread_port,
91 exception_type_t exception, int *is_untrusted) { 122 exception_type_t exception, int *is_untrusted) {
92 mach_msg_type_number_t size; 123 mach_msg_type_number_t size;
93 x86_thread_state_t regs; 124 x86_thread_state_t regs;
94 kern_return_t result; 125 kern_return_t result;
95 uint16_t trusted_cs = NaClGetGlobalCs();
96 uint16_t trusted_ds = NaClGetGlobalDs();
97 uint32_t nacl_thread_index; 126 uint32_t nacl_thread_index;
98 struct NaClApp *nap; 127 struct NaClApp *nap;
99 struct NaClAppThread *natp; 128 struct NaClAppThread *natp;
100 struct NaClExceptionFrame frame; 129 struct NaClExceptionFrame frame;
101 uintptr_t frame_addr_user; 130 uint32_t frame_addr_user;
102 uintptr_t frame_addr_sys; 131 uintptr_t frame_addr_sys;
132 #if NACL_BUILD_SUBARCH == 32
133 uint16_t trusted_cs = NaClGetGlobalCs();
134 uint16_t trusted_ds = NaClGetGlobalDs();
135 #endif
103 136
104 /* Assume untrusted crash until we know otherwise. */ 137 /* Assume untrusted crash until we know otherwise. */
105 *is_untrusted = TRUE; 138 *is_untrusted = TRUE;
106 139
107 /* Capture the register state of the 'excepting' thread. */ 140 /* Capture the register state of the 'excepting' thread. */
108 size = sizeof(regs) / sizeof(natural_t); 141 size = x86_THREAD_STATE_COUNT;
109 result = thread_get_state(thread_port, x86_THREAD_STATE, 142 result = thread_get_state(thread_port, x86_THREAD_STATE,
110 (void *) &regs, &size); 143 (thread_state_t) &regs, &size);
111 if (result != KERN_SUCCESS) { 144 if (result != KERN_SUCCESS) {
112 return 0; 145 return 0;
113 } 146 }
147 CHECK(regs.tsh.flavor == NATIVE_x86_THREAD_STATE);
114 148
149 #if NACL_BUILD_SUBARCH == 32
115 /* 150 /*
116 * If trusted_cs is 0 (which is not a usable segment selector), the 151 * If trusted_cs is 0 (which is not a usable segment selector), the
117 * sandbox has not been initialised yet, so there can be no untrusted 152 * sandbox has not been initialised yet, so there can be no untrusted
118 * code running. 153 * code running.
119 */ 154 */
120 if (trusted_cs == 0) { 155 if (trusted_cs == 0) {
121 *is_untrusted = FALSE; 156 *is_untrusted = FALSE;
122 return 0; 157 return 0;
123 } 158 }
124 159
125 /* 160 /*
126 * If the current code segment is the trusted one, we aren't in the 161 * If the current code segment is the trusted one, we aren't in the
127 * sandbox. 162 * sandbox.
128 * TODO(bradnelson): This makes the potentially false assumption that cs is 163 * TODO(bradnelson): This makes the potentially false assumption that cs is
129 * the last thing to change when switching into untrusted code. We need 164 * the last thing to change when switching into untrusted code. We need
130 * tests to vet this. 165 * tests to vet this.
131 */ 166 */
132 if (regs.uts.ts32.__cs == trusted_cs) { 167 if (regs.uts.TS_CS == trusted_cs) {
133 /* 168 /*
134 * If we are single-stepping, allow NaClSwitchRemainingRegsViaECX() 169 * If we are single-stepping, allow NaClSwitchRemainingRegsViaECX()
135 * to continue in order to restore control to untrusted code. 170 * to continue in order to restore control to untrusted code.
136 */ 171 */
137 if (exception == EXC_BREAKPOINT && 172 if (exception == EXC_BREAKPOINT &&
138 (regs.uts.ts32.__eflags & NACL_X86_TRAP_FLAG) != 0 && 173 (regs.uts.TS_xFLAGS & NACL_X86_TRAP_FLAG) != 0 &&
139 regs.uts.ts32.__eip >= (uintptr_t) NaClSwitchRemainingRegsViaECX && 174 regs.uts.TS_xIP >= (uintptr_t) NaClSwitchRemainingRegsViaECX &&
140 regs.uts.ts32.__eip < (uintptr_t) NaClSwitchRemainingRegsAsmEnd) { 175 regs.uts.TS_xIP < (uintptr_t) NaClSwitchRemainingRegsAsmEnd) {
141 return 1; 176 return 1;
142 } 177 }
143 *is_untrusted = FALSE; 178 *is_untrusted = FALSE;
144 return 0; 179 return 0;
145 } 180 }
146 181
147 /* 182 /*
148 * We can get the thread index from the segment selector used for TLS 183 * We can get the thread index from the segment selector used for TLS
149 * from %gs >> 3. 184 * from %gs >> 3.
150 * TODO(bradnelson): Migrate that knowledge to a single shared location. 185 * TODO(bradnelson): Migrate that knowledge to a single shared location.
151 */ 186 */
152 nacl_thread_index = regs.uts.ts32.__gs >> 3; 187 nacl_thread_index = regs.uts.TS_GS >> 3;
188 #elif NACL_BUILD_SUBARCH == 64
189 nacl_thread_index = NaClGetThreadIndexForMachThread(thread_port);
190 if (nacl_thread_index == NACL_TLS_INDEX_INVALID) {
191 *is_untrusted = FALSE;
192 return 0;
193 }
194 #endif
195
153 natp = NaClAppThreadGetFromIndex(nacl_thread_index); 196 natp = NaClAppThreadGetFromIndex(nacl_thread_index);
154 nap = natp->nap; 197 nap = natp->nap;
155 198
199 #if NACL_BUILD_SUBARCH == 64
Mark Seaborn 2013/02/14 23:55:02 It looks like you don't need this #if, and your in
200 *is_untrusted = NaClMachThreadStateIsInUntrusted(&regs, nacl_thread_index);
201 /*
202 * If trusted code accidentally jumped to untrusted code, don't let the
203 * untrusted exception handler take over.
204 */
205 if (*is_untrusted &&
206 (natp->suspend_state & NACL_APP_THREAD_UNTRUSTED) == 0) {
207 *is_untrusted = 0;
208 }
209 if (!*is_untrusted) {
210 return 0;
211 }
212 #endif
213
156 if (nap->enable_faulted_thread_queue) { 214 if (nap->enable_faulted_thread_queue) {
215 #if NACL_BUILD_SUBARCH == 32
157 /* 216 /*
158 * If we are single-stepping, step through until we reach untrusted code. 217 * If we are single-stepping, step through until we reach untrusted code.
159 */ 218 */
160 if (exception == EXC_BREAKPOINT && 219 if (exception == EXC_BREAKPOINT &&
161 (regs.uts.ts32.__eflags & NACL_X86_TRAP_FLAG) != 0) { 220 (regs.uts.TS_xFLAGS & NACL_X86_TRAP_FLAG) != 0) {
162 if (regs.uts.ts32.__eip >= nap->all_regs_springboard.start_addr && 221 if (regs.uts.TS_xIP >= nap->all_regs_springboard.start_addr &&
163 regs.uts.ts32.__eip < nap->all_regs_springboard.end_addr) { 222 regs.uts.TS_xIP < nap->all_regs_springboard.end_addr) {
164 return 1; 223 return 1;
165 } 224 }
166 /* 225 /*
167 * Step through the instruction we have been asked to restore 226 * Step through the instruction we have been asked to restore
168 * control to. 227 * control to.
169 */ 228 */
170 if (regs.uts.ts32.__eip == natp->user.gs_segment.new_prog_ctr) { 229 if (regs.uts.TS_xIP == natp->user.gs_segment.new_prog_ctr) {
171 return 1; 230 return 1;
172 } 231 }
173 } 232 }
233 #endif
174 234
175 /* 235 /*
176 * Increment the kernel's thread suspension count so that the 236 * Increment the kernel's thread suspension count so that the
177 * thread remains suspended after we return. 237 * thread remains suspended after we return.
178 */ 238 */
179 result = thread_suspend(thread_port); 239 result = thread_suspend(thread_port);
180 if (result != KERN_SUCCESS) { 240 if (result != KERN_SUCCESS) {
181 NaClLog(LOG_FATAL, "HandleException: thread_suspend() call failed\n"); 241 NaClLog(LOG_FATAL, "HandleException: thread_suspend() call failed\n");
182 } 242 }
183 /* 243 /*
184 * Notify the handler running on another thread. This must happen 244 * Notify the handler running on another thread. This must happen
185 * after the thread_suspend() call, otherwise the handler might 245 * after the thread_suspend() call, otherwise the handler might
186 * receive the notification and attempt to decrement the thread's 246 * receive the notification and attempt to decrement the thread's
187 * suspension count before we have incremented it. 247 * suspension count before we have incremented it.
188 */ 248 */
189 natp->fault_signal = ExceptionCodeToNaClSignalNumber(exception); 249 natp->fault_signal = ExceptionCodeToNaClSignalNumber(exception);
190 AtomicIncrement(&nap->faulted_thread_count, 1); 250 AtomicIncrement(&nap->faulted_thread_count, 1);
191 FireDebugStubEvent(nap->faulted_thread_fd_write); 251 FireDebugStubEvent(nap->faulted_thread_fd_write);
192 return 1; 252 return 1;
193 } 253 }
194 254
195 /*
196 * Ignore all but bad accesses for now.
197 * TODO(bradnelson): eventually consider these too:
198 * EXC_BAD_INSTRUCTION
199 * EXC_ARITHMETIC
200 * EXC_BREAKPOINT
201 */
202 if (exception != EXC_BAD_ACCESS) {
203 return 0;
204 }
205
206 /* Don't handle it if the exception flag is set. */
207 if (natp->exception_flag) {
208 return 0;
209 }
210 /* Set the flag. */
211 natp->exception_flag = 1;
212
213 /* Don't handle if no exception handler is set. */
214 if (nap->exception_handler == 0) {
215 return 0;
216 }
217
218 /* Get location of exception stack frame. */ 255 /* Get location of exception stack frame. */
219 if (natp->exception_stack) { 256 if (natp->exception_stack) {
220 frame_addr_user = natp->exception_stack; 257 frame_addr_user = natp->exception_stack;
221 } else { 258 } else {
222 /* If not set default to user stack. */ 259 /* If not set default to user stack. */
223 frame_addr_user = regs.uts.ts32.__esp; 260 frame_addr_user = regs.uts.TS_xSP - NACL_STACK_RED_ZONE;
224 } 261 }
225 262
226 /* Align stack frame properly. */ 263 /* Align stack frame properly. */
227 frame_addr_user -= 264 frame_addr_user -=
228 sizeof(struct NaClExceptionFrame) - NACL_STACK_PAD_BELOW_ALIGN; 265 sizeof(struct NaClExceptionFrame) - NACL_STACK_PAD_BELOW_ALIGN;
229 frame_addr_user &= ~NACL_STACK_ALIGN_MASK; 266 frame_addr_user &= ~NACL_STACK_ALIGN_MASK;
230 frame_addr_user -= NACL_STACK_PAD_BELOW_ALIGN; 267 frame_addr_user -= NACL_STACK_PAD_BELOW_ALIGN;
231 268
232 /* Convert from user to system space. */ 269 /* Convert from user to system space. */
233 frame_addr_sys = NaClUserToSysAddrRange( 270 frame_addr_sys = NaClUserToSysAddrRange(
234 nap, frame_addr_user, sizeof(struct NaClExceptionFrame)); 271 nap, frame_addr_user, sizeof(struct NaClExceptionFrame));
235 if (frame_addr_sys == kNaClBadAddress) { 272 if (frame_addr_sys == kNaClBadAddress) {
236 return 0; 273 return 0;
237 } 274 }
238 275
276 /*
277 * Ignore all but bad accesses for now.
278 * TODO(bradnelson): eventually consider these too:
279 * EXC_BAD_INSTRUCTION
280 * EXC_ARITHMETIC
281 * EXC_BREAKPOINT
282 */
283 if (exception != EXC_BAD_ACCESS) {
284 return 0;
285 }
286
287 /* Don't handle if no exception handler is set. */
288 if (nap->exception_handler == 0) {
Mark Seaborn 2013/02/14 23:55:02 I can see why you reordered this before checking e
Mark Mentovai 2013/02/15 17:36:42 Mark Seaborn wrote:
289 return 0;
290 }
291
292 /* Don't handle it if the exception flag is set. */
293 if (natp->exception_flag) {
294 return 0;
295 }
296 /* Set the flag. */
297 natp->exception_flag = 1;
298
239 /* Set up the stack frame for the handler invocation. */ 299 /* Set up the stack frame for the handler invocation. */
240 frame.return_addr = 0; 300 frame.return_addr = 0;
301 frame.context.prog_ctr = regs.uts.TS_xIP;
302 frame.context.stack_ptr = regs.uts.TS_xSP;
303 frame.context.frame_ptr = regs.uts.TS_xBP;
304 #if NACL_BUILD_SUBARCH == 32
241 frame.context_ptr = frame_addr_user + 305 frame.context_ptr = frame_addr_user +
242 offsetof(struct NaClExceptionFrame, context); 306 offsetof(struct NaClExceptionFrame, context);
243 frame.context.prog_ctr = regs.uts.ts32.__eip; 307 #endif
244 frame.context.stack_ptr = regs.uts.ts32.__esp;
245 frame.context.frame_ptr = regs.uts.ts32.__ebp;
246 308
247 /* 309 /*
248 * Write the stack frame into untrusted address space. We do not 310 * Write the stack frame into untrusted address space. We do not
249 * write to the memory directly because that will fault if the 311 * write to the memory directly because that will fault if the
250 * destination location is not writable. Faulting is OK for NaCl 312 * destination location is not writable. Faulting is OK for NaCl
251 * syscalls, but here we do not want to trigger an exception while 313 * syscalls, but here we do not want to trigger an exception while
252 * in the exception handler. The overhead of using a Mach system 314 * in the exception handler. The overhead of using a Mach system
253 * call to write to memory is acceptable here. 315 * call to write to memory is acceptable here.
254 */ 316 */
255 result = mach_vm_write(mach_task_self(), frame_addr_sys, 317 result = mach_vm_write(mach_task_self(), frame_addr_sys,
256 (uintptr_t) &frame, sizeof(frame)); 318 (uintptr_t) &frame, sizeof(frame));
257 if (result != KERN_SUCCESS) { 319 if (result != KERN_SUCCESS) {
258 return 0; 320 return 0;
259 } 321 }
260 322
261 /* Set up thread context to resume at handler. */ 323 /* Set up thread context to resume at handler. */
262 natp->user.new_prog_ctr = nap->exception_handler;
263 natp->user.stack_ptr = frame_addr_user;
264 /* TODO(bradnelson): put all registers in some default state. */ 324 /* TODO(bradnelson): put all registers in some default state. */
265 325 #if NACL_BUILD_SUBARCH == 32
266 /* 326 /*
267 * Put registers in right place to land at NaClSwitchNoSSEViaECX 327 * Put registers in right place to land at NaClSwitchNoSSEViaECX
268 * This is required because: 328 * This is required because:
269 * - For an unknown reason thread_set_state resets %cs to the default 329 * - For an unknown reason thread_set_state resets %cs to the default
270 * value, even when set to something else, in current XNU versions. 330 * value, even when set to something else, in current XNU versions.
271 * - An examination of the XNU sources indicates 331 * - An examination of the XNU sources indicates
272 * that setting the code which state the thread state resets 332 * that setting the code which state the thread state resets
273 * %cs, %ds, %es, %ss to their default values in some early versions. 333 * %cs, %ds, %es, %ss to their default values in some early versions.
274 * (For instance: xnu-792.6.22/osfmk/i386/pcb.c:616) 334 * (For instance: xnu-792.6.22/osfmk/i386/pcb.c:616)
275 * This precludes going directly to the untrusted handler. 335 * This precludes going directly to the untrusted handler.
276 * Instead we call a variant of NaClSwitchNoSSE which takes a pointer 336 * Instead we call a variant of NaClSwitchNoSSE which takes a pointer
277 * to the thread user context in %ecx. 337 * to the thread user context in %ecx.
278 */ 338 */
279 regs.uts.ts32.__eip = (uint32_t) &NaClSwitchNoSSEViaECX; 339 natp->user.new_prog_ctr = nap->exception_handler;
280 regs.uts.ts32.__cs = trusted_cs; 340 natp->user.stack_ptr = frame_addr_user;
281 regs.uts.ts32.__ecx = (uint32_t) &natp->user; 341 regs.uts.TS_xIP = (uint32_t) &NaClSwitchNoSSEViaECX;
282 regs.uts.ts32.__ds = trusted_ds; 342 regs.uts.TS_CS = trusted_cs;
283 regs.uts.ts32.__es = trusted_ds; /* just for good measure */ 343 regs.uts.TS_xCX = (uint32_t) &natp->user;
284 regs.uts.ts32.__ss = trusted_ds; /* just for good measure */ 344 regs.uts.TS_DS = trusted_ds;
285 regs.uts.ts32.__eflags &= ~NACL_X86_DIRECTION_FLAG; 345 regs.uts.TS_ES = trusted_ds; /* just for good measure */
346 regs.uts.TS_SS = trusted_ds; /* just for good measure */
347 #elif NACL_BUILD_SUBARCH == 64
348 regs.uts.TS_xIP = NaClUserToSys(nap, nap->exception_handler);
349 regs.uts.TS_xSP = frame_addr_sys;
350 regs.uts.TS_xBP = nap->mem_start;
351
352 /* Argument 1 */
353 regs.uts.TS_xDI = frame_addr_user +
354 offsetof(struct NaClExceptionFrame, context);
355 #endif
356 regs.uts.TS_xFLAGS &= ~NACL_X86_DIRECTION_FLAG;
286 result = thread_set_state(thread_port, x86_THREAD_STATE, 357 result = thread_set_state(thread_port, x86_THREAD_STATE,
287 (void *) &regs, size); 358 (thread_state_t) &regs, size);
288 if (result != KERN_SUCCESS) { 359 if (result != KERN_SUCCESS) {
289 return 0; 360 return 0;
290 } 361 }
291 362
292 /* Return success, and resume the thread. */ 363 /* Return success, and resume the thread. */
293 return 1; 364 return 1;
294 } 365 }
295 366
296 367
297 static kern_return_t ForwardException( 368 static kern_return_t ForwardException(
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 failure: 634 failure:
564 if (data) { 635 if (data) {
565 if (MACH_PORT_NULL != data->exception_port) { 636 if (MACH_PORT_NULL != data->exception_port) {
566 mach_port_deallocate(current_task, data->exception_port); 637 mach_port_deallocate(current_task, data->exception_port);
567 } 638 }
568 free(data); 639 free(data);
569 } 640 }
570 return FALSE; 641 return FALSE;
571 } 642 }
572 643
573 #else /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 */ 644 #endif /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 */
574
575 int NaClInterceptMachExceptions(void) {
576 return FALSE;
577 }
578
579 #endif /* NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698