| Index: components/nacl/loader/nonsfi/irt_exception_handling.cc
|
| diff --git a/components/nacl/loader/nonsfi/irt_exception_handling.cc b/components/nacl/loader/nonsfi/irt_exception_handling.cc
|
| index cdd33aff3f6164caa9d7a2d0f7d01ba23e80765e..d310e19bd5687b929a52c55f9be659f45abb8fb6 100644
|
| --- a/components/nacl/loader/nonsfi/irt_exception_handling.cc
|
| +++ b/components/nacl/loader/nonsfi/irt_exception_handling.cc
|
| @@ -1,15 +1,15 @@
|
| // Copyright 2014 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
| +#include <elf.h>
|
| #include <errno.h>
|
| #include <signal.h>
|
| +#include <sys/ucontext.h>
|
|
|
| -#include <map>
|
| -
|
| +#include "base/logging.h"
|
| #include "components/nacl/loader/nonsfi/irt_interfaces.h"
|
| +#include "native_client/src/include/nacl/nacl_exception.h"
|
| #include "native_client/src/include/nacl_macros.h"
|
| -#include "native_client/src/trusted/service_runtime/nacl_exception.h"
|
| -#include "native_client/src/trusted/service_runtime/nacl_signal.h"
|
|
|
| namespace nacl {
|
| namespace nonsfi {
|
| @@ -33,18 +33,91 @@ static const int kSignals[] = {
|
|
|
| NaClExceptionHandler signal_handler_function_pointer = NULL;
|
|
|
| +struct NonSfiExceptionFrame {
|
| + struct NaClExceptionContext context;
|
| + struct NaClExceptionPortableContext portable;
|
| +};
|
| +
|
| +// Convert context reported by signal to NaClExceptionContext format.
|
| +void MachineContextToRegister(const mcontext_t *mctx,
|
| + // what is volatile about it?
|
| + NaClUserRegisterState *dest) {
|
| +
|
| +#if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
|
| + dest->eax = mctx->gregs[REG_EAX];
|
| + dest->ecx = mctx->gregs[REG_ECX];
|
| + dest->edx = mctx->gregs[REG_EDX];
|
| + dest->ebx = mctx->gregs[REG_EBX];
|
| + dest->stack_ptr = mctx->gregs[REG_ESP];
|
| + dest->ebp = mctx->gregs[REG_EBP];
|
| + dest->esi = mctx->gregs[REG_ESI];
|
| + dest->edi = mctx->gregs[REG_EDI];
|
| + dest->prog_ctr = mctx->gregs[REG_EIP];
|
| + dest->flags = mctx->gregs[REG_EFL];
|
| +
|
| +#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
|
| + dest->r0 = mctx->arm_r0;
|
| + dest->r1 = mctx->arm_r1;
|
| + dest->r2 = mctx->arm_r2;
|
| + dest->r3 = mctx->arm_r3;
|
| + dest->r4 = mctx->arm_r4;
|
| + dest->r5 = mctx->arm_r5;
|
| + dest->r6 = mctx->arm_r6;
|
| + dest->r7 = mctx->arm_r7;
|
| + dest->r8 = mctx->arm_r8;
|
| + // TODO(uekawa): We don't really use r9 for trusted thread pointer
|
| + // for Non-SFI NaCl, do we?
|
| + dest->r9 = mctx->arm_r9;
|
| + dest->r10 = mctx->arm_r10;
|
| + dest->r11 = mctx->arm_fp;
|
| + dest->r12 = mctx->arm_ip;
|
| + dest->stack_ptr = mctx->arm_sp;
|
| + dest->lr = mctx->arm_lr;
|
| + dest->prog_ctr = mctx->arm_pc;
|
| + dest->cpsr = mctx->arm_cpsr;
|
| +#else
|
| +# error Unsupported architecture
|
| +#endif
|
| +}
|
| +
|
| +void ExceptionFrameFromSignalContext(NonSfiExceptionFrame* frame,
|
| + const void* raw_ctx) {
|
| + const ucontext_t *uctx = (ucontext_t *) raw_ctx;
|
| + // mcontext_t is sigcontext in ARM.
|
| + const mcontext_t *mctx = &uctx->uc_mcontext;
|
| + frame->context.size = (((uintptr_t)&frame->portable + 1)
|
| + - (uintptr_t)&frame->context);
|
| + frame->context.portable_context_offset = ((uintptr_t)&frame->portable
|
| + - (uintptr_t)&frame->context);
|
| + frame->context.portable_context_size = sizeof(frame->portable);
|
| + frame->context.regs_size = sizeof(frame->context.regs);
|
| +
|
| + for (size_t i = 0; i < NACL_ARRAY_SIZE(frame->context.reserved); i++) {
|
| + frame->context.reserved[i] = 0;
|
| + }
|
| +
|
| + MachineContextToRegister(mctx, &frame->context.regs);
|
| +
|
| + frame->portable.prog_ctr = frame->context.regs.prog_ctr;
|
| + frame->portable.stack_ptr = frame->context.regs.stack_ptr;
|
| +
|
| +#if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
|
| + frame->context.arch = EM_386;
|
| + frame->portable.frame_ptr = frame->context.regs.ebp;
|
| +#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
|
| + frame->context.arch = EM_ARM;
|
| + // R11 is frame pointer in ARM mode, R8 is frame pointer in thumb mode.
|
| + frame->portable.frame_ptr = frame->context.regs.r11;
|
| +#else
|
| +# error Unsupported architecture
|
| +#endif
|
| +}
|
| +
|
| // Signal handler, responsible for calling the registered handlers.
|
| static void SignalCatch(int sig, siginfo_t *info, void *uc) {
|
| if (signal_handler_function_pointer) {
|
| - // TODO(uekawa): Whether to add dependency or copy the implementation?
|
| - NaClSignalContext signal_context;
|
| - NaClSignalContextFromHandler(&signal_context, uc);
|
| - // Is this safe to allocate this on stack ?
|
| - NaClExceptionFrame exception_frame;
|
| - NaClSignalSetUpExceptionFrame(&exception_frame,
|
| - &signal_context,
|
| - 0 /* context_user_addr, what is this? */);
|
| -
|
| + NonSfiExceptionFrame exception_frame;
|
| + ExceptionFrameFromSignalContext(&exception_frame, uc);
|
| signal_handler_function_pointer(&exception_frame.context);
|
| }
|
| // TODO(uekawa): Only exit on crash signals?
|
| @@ -104,7 +177,7 @@ void InitializeSignalHandler(void) {
|
| /* Install all handlers */
|
| for (a = 0; a < NACL_ARRAY_SIZE(kSignals); a++) {
|
| if (sigaction(kSignals[a], &sa, NULL) != 0) {
|
| - perror("sigaction");
|
| + PLOG(FATAL) << "Registering signal handlers failed";
|
| }
|
| }
|
| }
|
|
|