blob: 4987cfb47c060a7101f3b9860d64b129fde4915b [file] [log] [blame]
/*
* Copyright (c) 2012 The Native Client 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 <float.h>
#include <string.h>
#include "native_client/src/include/build_config.h"
/*
* This header declares the _mm_getcsr function.
*/
#if NACL_WINDOWS
#include <intrin.h>
#else
#include <xmmintrin.h>
#endif
#include "native_client/src/shared/platform/nacl_log.h"
#include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
#include "native_client/src/trusted/service_runtime/nacl_signal.h"
#include "native_client/src/trusted/service_runtime/nacl_tls.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#include "native_client/src/trusted/service_runtime/sel_rt.h"
#include "native_client/src/trusted/service_runtime/include/sys/errno.h"
void NaClInitGlobals(void) {
/* no need to save segment registers */
;
}
int NaClAppThreadInitArchSpecific(struct NaClAppThread *natp,
nacl_reg_t prog_ctr,
nacl_reg_t stack_ptr) {
struct NaClThreadContext *ntcp = &natp->user;
struct NaClApp *nap = natp->nap;
NaClThreadContextOffsetCheck();
memset(ntcp, 0, sizeof(*ntcp));
ntcp->rax = 0;
ntcp->rbx = 0;
ntcp->rcx = 0;
ntcp->rdx = 0;
ntcp->rbp = stack_ptr; /* must be a valid stack addr! */
ntcp->rsi = 0;
ntcp->rdi = 0;
ntcp->rsp = stack_ptr;
ntcp->r8 = 0;
ntcp->r9 = 0;
ntcp->r10 = 0;
ntcp->r11 = 0;
ntcp->r12 = 0;
ntcp->r13 = 0;
ntcp->r14 = 0;
ntcp->r15 = nap->mem_start;
ntcp->prog_ctr = NaClUserToSys(nap, prog_ctr);
ntcp->new_prog_ctr = 0;
ntcp->sysret = (nacl_reg_t) -NACL_ABI_EINVAL;
ntcp->tls_idx = NaClTlsAllocate(natp);
if (ntcp->tls_idx == NACL_TLS_INDEX_INVALID)
return 0;
ntcp->fcw = NACL_X87_FCW_DEFAULT;
ntcp->mxcsr = NACL_MXCSR_DEFAULT;
/*
* Save the system's state of the x87 FPU control word so we can restore
* the same state when returning to trusted code.
*/
#if NACL_WINDOWS
NaClDoFnstcw(&ntcp->sys_fcw);
#else
__asm__ __volatile__("fnstcw %0" : "=m" (ntcp->sys_fcw));
#endif
/*
* Likewise for the SSE control word.
*/
ntcp->sys_mxcsr = _mm_getcsr();
return 1;
}
void NaClThreadContextToSignalContext(const struct NaClThreadContext *th_ctx,
struct NaClSignalContext *sig_ctx) {
sig_ctx->rax = 0;
sig_ctx->rbx = th_ctx->rbx;
sig_ctx->rcx = 0;
sig_ctx->rdx = 0;
sig_ctx->rsi = 0;
sig_ctx->rdi = 0;
sig_ctx->rbp = th_ctx->rbp;
sig_ctx->stack_ptr = th_ctx->rsp;
sig_ctx->r8 = 0;
sig_ctx->r9 = 0;
sig_ctx->r10 = 0;
sig_ctx->r11 = 0;
sig_ctx->r12 = th_ctx->r12;
sig_ctx->r13 = th_ctx->r13;
sig_ctx->r14 = th_ctx->r14;
sig_ctx->r15 = th_ctx->r15;
sig_ctx->prog_ctr = th_ctx->new_prog_ctr;
sig_ctx->flags = 0;
sig_ctx->cs = 0;
sig_ctx->ss = 0;
sig_ctx->ds = 0;
sig_ctx->es = 0;
sig_ctx->fs = 0;
sig_ctx->gs = 0;
}
void NaClSignalContextUnsetClobberedRegisters(
struct NaClSignalContext *sig_ctx) {
sig_ctx->rax = 0;
sig_ctx->rcx = 0;
sig_ctx->rdx = 0;
sig_ctx->rsi = 0;
sig_ctx->rdi = 0;
sig_ctx->r8 = 0;
sig_ctx->r9 = 0;
sig_ctx->r10 = 0;
sig_ctx->r11 = 0;
sig_ctx->flags = 0;
}