1 : /*
2 : * Copyright 2010 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : #include <signal.h>
8 : #include <string.h>
9 : #include <sys/ucontext.h>
10 :
11 : #include "native_client/src/trusted/service_runtime/nacl_signal.h"
12 :
13 : /*
14 : * Definition of the POSIX ucontext_t for Linux can be found in:
15 : * /usr/include/sys/ucontext.h
16 : */
17 :
18 : /*
19 : * Fill a signal context structure from the raw platform dependent
20 : * signal information.
21 : */
22 292091 : void NaClSignalContextFromHandler(struct NaClSignalContext *sig_ctx,
23 : const void *raw_ctx) {
24 292091 : const ucontext_t *uctx = (const ucontext_t *) raw_ctx;
25 292091 : const mcontext_t *mctx = &uctx->uc_mcontext;
26 :
27 292091 : memset(sig_ctx, 0, sizeof(*sig_ctx));
28 :
29 292091 : sig_ctx->prog_ctr = mctx->gregs[REG_RIP];
30 292091 : sig_ctx->stack_ptr = mctx->gregs[REG_RSP];
31 :
32 292091 : sig_ctx->rax = mctx->gregs[REG_RAX];
33 292091 : sig_ctx->rbx = mctx->gregs[REG_RBX];
34 292091 : sig_ctx->rcx = mctx->gregs[REG_RCX];
35 292091 : sig_ctx->rdx = mctx->gregs[REG_RDX];
36 292091 : sig_ctx->rsi = mctx->gregs[REG_RSI];
37 292091 : sig_ctx->rdi = mctx->gregs[REG_RDI];
38 292091 : sig_ctx->rbp = mctx->gregs[REG_RBP];
39 292091 : sig_ctx->r8 = mctx->gregs[REG_R8];
40 292091 : sig_ctx->r9 = mctx->gregs[REG_R9];
41 292091 : sig_ctx->r10 = mctx->gregs[REG_R10];
42 292091 : sig_ctx->r11 = mctx->gregs[REG_R11];
43 292091 : sig_ctx->r12 = mctx->gregs[REG_R12];
44 292091 : sig_ctx->r13 = mctx->gregs[REG_R13];
45 292091 : sig_ctx->r14 = mctx->gregs[REG_R14];
46 292091 : sig_ctx->r15 = mctx->gregs[REG_R15];
47 292091 : sig_ctx->flags = mctx->gregs[REG_EFL];
48 :
49 : /* Linux stores CS, GS, FS, PAD into one 64b word. */
50 292091 : sig_ctx->cs = (uint32_t) (mctx->gregs[REG_CSGSFS] & 0xFFFF);
51 292091 : sig_ctx->gs = (uint32_t) ((mctx->gregs[REG_CSGSFS] >> 16) & 0xFFFF);
52 292091 : sig_ctx->fs = (uint32_t) ((mctx->gregs[REG_CSGSFS] >> 32) & 0xFFFF);
53 :
54 : /*
55 : * TODO(noelallen) Pull from current context, since they must be
56 : * the same.
57 : */
58 292091 : sig_ctx->ds = 0;
59 292091 : sig_ctx->ss = 0;
60 292091 : }
61 :
62 :
63 : /*
64 : * Update the raw platform dependent signal information from the
65 : * signal context structure.
66 : */
67 276473 : void NaClSignalContextToHandler(void *raw_ctx,
68 : const struct NaClSignalContext *sig_ctx) {
69 276473 : ucontext_t *uctx = (ucontext_t *) raw_ctx;
70 276473 : mcontext_t *mctx = &uctx->uc_mcontext;
71 :
72 276473 : mctx->gregs[REG_RIP] = sig_ctx->prog_ctr;
73 276473 : mctx->gregs[REG_RSP] = sig_ctx->stack_ptr;
74 :
75 276473 : mctx->gregs[REG_RAX] = sig_ctx->rax;
76 276473 : mctx->gregs[REG_RBX] = sig_ctx->rbx;
77 276473 : mctx->gregs[REG_RCX] = sig_ctx->rcx;
78 276473 : mctx->gregs[REG_RDX] = sig_ctx->rdx;
79 276473 : mctx->gregs[REG_RSI] = sig_ctx->rsi;
80 276473 : mctx->gregs[REG_RDI] = sig_ctx->rdi;
81 276473 : mctx->gregs[REG_RBP] = sig_ctx->rbp;
82 276473 : mctx->gregs[REG_R8] = sig_ctx->r8;
83 276473 : mctx->gregs[REG_R9] = sig_ctx->r9;
84 276473 : mctx->gregs[REG_R10] = sig_ctx->r10;
85 276473 : mctx->gregs[REG_R11] = sig_ctx->r11;
86 276473 : mctx->gregs[REG_R12] = sig_ctx->r12;
87 276473 : mctx->gregs[REG_R13] = sig_ctx->r13;
88 276473 : mctx->gregs[REG_R14] = sig_ctx->r14;
89 276473 : mctx->gregs[REG_R15] = sig_ctx->r15;
90 276473 : mctx->gregs[REG_EFL] = sig_ctx->flags;
91 :
92 : /* Linux stores CS, GS, FS, PAD into one 64b word. */
93 552946 : mctx->gregs[REG_CSGSFS] = ((uint64_t) (sig_ctx->cs & 0xFFFF))
94 276473 : | (((uint64_t) (sig_ctx->gs & 0xFFFF)) << 16)
95 276473 : | (((uint64_t) (sig_ctx->fs & 0xFFFF)) << 32);
96 :
97 : /*
98 : * We do not support modification of DS & SS in 64b, so
99 : * we do not push them back into the context.
100 : */
101 276473 : }
102 :
103 :
104 :
|