Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / native_client / tests / common / register_set.c
1 /*
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
4  * found in the LICENSE file.
5  */
6
7 #include "native_client/tests/common/register_set.h"
8
9 #include <assert.h>
10 #include <stddef.h>
11 #include <string.h>
12
13 #include "native_client/src/include/nacl_assert.h"
14
15 #if defined(__native_client__)
16 # include "native_client/src/untrusted/nacl/nacl_thread.h"
17 #endif
18
19
20 struct RegInfo {
21   const char *reg_name;
22   int reg_offset;
23   int reg_size;
24   int user_register_state_reg_offset;
25   int user_register_state_reg_size;
26 };
27
28 #define DEFINE_REG(regname) \
29     { \
30       #regname, \
31       offsetof(struct NaClSignalContext, regname), \
32       sizeof(((struct NaClSignalContext *) NULL)->regname), \
33       offsetof(NaClUserRegisterState, regname), \
34       sizeof(((NaClUserRegisterState *) NULL)->regname) \
35     }
36
37 const struct RegInfo kRegs[] = {
38   /*
39    * We do not look at x86 segment registers because they are not
40    * saved by REGS_SAVER_FUNC.
41    */
42 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
43   DEFINE_REG(eax),
44   DEFINE_REG(ecx),
45   DEFINE_REG(edx),
46   DEFINE_REG(ebx),
47   DEFINE_REG(stack_ptr),
48   DEFINE_REG(ebp),
49   DEFINE_REG(esi),
50   DEFINE_REG(edi),
51   DEFINE_REG(prog_ctr),
52   DEFINE_REG(flags)
53 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
54   DEFINE_REG(rax),
55   DEFINE_REG(rbx),
56   DEFINE_REG(rcx),
57   DEFINE_REG(rdx),
58   DEFINE_REG(rsi),
59   DEFINE_REG(rdi),
60   DEFINE_REG(rbp),
61   DEFINE_REG(stack_ptr),
62   DEFINE_REG(r8),
63   DEFINE_REG(r9),
64   DEFINE_REG(r10),
65   DEFINE_REG(r11),
66   DEFINE_REG(r12),
67   DEFINE_REG(r13),
68   DEFINE_REG(r14),
69   DEFINE_REG(r15),
70   DEFINE_REG(prog_ctr),
71   DEFINE_REG(flags)
72 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
73   DEFINE_REG(r0),
74   DEFINE_REG(r1),
75   DEFINE_REG(r2),
76   DEFINE_REG(r3),
77   DEFINE_REG(r4),
78   DEFINE_REG(r5),
79   DEFINE_REG(r6),
80   DEFINE_REG(r7),
81   DEFINE_REG(r8),
82   DEFINE_REG(r9),
83   DEFINE_REG(r10),
84   DEFINE_REG(r11),
85   DEFINE_REG(r12),
86   DEFINE_REG(stack_ptr),
87   DEFINE_REG(lr),
88   DEFINE_REG(prog_ctr),
89   DEFINE_REG(cpsr)
90 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
91   DEFINE_REG(zero),
92   DEFINE_REG(at),
93   DEFINE_REG(v0),
94   DEFINE_REG(v1),
95   DEFINE_REG(a0),
96   DEFINE_REG(a1),
97   DEFINE_REG(a2),
98   DEFINE_REG(a3),
99   DEFINE_REG(t0),
100   DEFINE_REG(t1),
101   DEFINE_REG(t2),
102   DEFINE_REG(t3),
103   DEFINE_REG(t4),
104   DEFINE_REG(t5),
105   DEFINE_REG(t6),
106   DEFINE_REG(t7),
107   DEFINE_REG(s0),
108   DEFINE_REG(s1),
109   DEFINE_REG(s2),
110   DEFINE_REG(s3),
111   DEFINE_REG(s4),
112   DEFINE_REG(s5),
113   DEFINE_REG(s6),
114   DEFINE_REG(s7),
115   DEFINE_REG(t8),
116   DEFINE_REG(t9),
117   DEFINE_REG(k0),
118   DEFINE_REG(k1),
119   DEFINE_REG(global_ptr),
120   DEFINE_REG(stack_ptr),
121   DEFINE_REG(frame_ptr),
122   DEFINE_REG(return_addr),
123   DEFINE_REG(prog_ctr)
124 #else
125 # error Unsupported architecture
126 #endif
127 };
128
129 #undef DEFINE_REG
130
131 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
132 /* Flags readable and writable by untrusted code. */
133 const uint8_t kX86FlagBits[5] = { 0, 2, 6, 7, 11 };
134 /*
135  * kX86KnownFlagsMask contains kX86FlagBits plus the trap flag (which
136  * is not readable or writable by untrusted code) so that trusted-code
137  * tests will check that the trap flag is still set.
138  */
139 static const uint32_t kX86KnownFlagsMask =
140     (1<<0) | (1<<2) | (1<<6) | (1<<7) | (1<<11) |
141     (1<<8); /* Trap flag */
142 #endif
143
144 void RegsFillTestValues(struct NaClSignalContext *regs, int seed) {
145   unsigned int index;
146   for (index = 0; index < sizeof(*regs); index++) {
147     ((char *) regs)[index] = index + seed + 1;
148   }
149 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
150   /* Set x86 flags to a value that we know will work. */
151   regs->flags = RESET_X86_FLAGS_VALUE;
152 #endif
153 }
154
155 #if defined(__native_client__)
156 void RegsApplySandboxConstraints(struct NaClSignalContext *regs) {
157 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
158   uint64_t r15;
159   __asm__("mov %%r15, %0" : "=r"(r15));
160   regs->r15 = r15;
161   regs->prog_ctr = r15 + (uint32_t) regs->prog_ctr;
162   regs->stack_ptr = r15 + (uint32_t) regs->stack_ptr;
163   regs->rbp = r15 + (uint32_t) regs->rbp;
164 #else
165   UNREFERENCED_PARAMETER(regs);
166 #endif
167 }
168 #endif
169
170 static uint64_t RegsGetRegValue(const struct NaClSignalContext *regs,
171                                 unsigned int regnum) {
172   uintptr_t ptr = (uintptr_t) regs + kRegs[regnum].reg_offset;
173   assert(regnum < NACL_ARRAY_SIZE(kRegs));
174   if (kRegs[regnum].reg_size == 4) {
175     return *(uint32_t *) ptr;
176   } else if (kRegs[regnum].reg_size == 8) {
177     return *(uint64_t *) ptr;
178   } else {
179     fprintf(stderr, "Unknown register size: %i\n", kRegs[regnum].reg_size);
180     _exit(1);
181   }
182 }
183
184 static void RegsDump(const struct NaClSignalContext *regs) {
185   unsigned int regnum;
186   for (regnum = 0; regnum < NACL_ARRAY_SIZE(kRegs); regnum++) {
187     long long value = RegsGetRegValue(regs, regnum);
188     fprintf(stderr, "  %s=0x%llx (%lld)\n",
189             kRegs[regnum].reg_name, value, value);
190   }
191 }
192
193 static void RegsNormalizeFlags(struct NaClSignalContext *regs) {
194 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
195   regs->flags &= kX86KnownFlagsMask;
196 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
197   regs->cpsr &= REGS_ARM_USER_CPSR_FLAGS_MASK;
198 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
199   /* No flags field on MIPS. */
200   UNREFERENCED_PARAMETER(regs);
201 #endif
202 }
203
204 void RegsAssertEqual(const struct NaClSignalContext *actual,
205                      const struct NaClSignalContext *expected) {
206   int match = 1;
207   unsigned int regnum;
208
209   /* Make a copy so that we can ignore some of the x86/ARM flags. */
210   struct NaClSignalContext copy_actual = *actual;
211   struct NaClSignalContext copy_expected = *expected;
212   RegsNormalizeFlags(&copy_actual);
213   RegsNormalizeFlags(&copy_expected);
214
215 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
216   /*
217    * We skip comparison of r9 because it is not supposed to be
218    * settable or readable by untrusted code.  However, for debugging
219    * purposes we still include r9 in register dumps printed by
220    * RegsDump(), so r9 remains listed in kRegs[].
221    */
222   copy_expected.r9 = copy_actual.r9;
223 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
224   /*
225    * The registers below are all read-only, so we skip their comparison. We
226    * expect t6 and t7 to hold control flow masks. For t8, which holds TLS
227    * index, we skip comparison. Zero register holds zero always. All of the
228    * above named registers are not settable by untrusted code. We also skip
229    * comparison for k0 and k1 registers because those are registers reserved for
230    * use by interrupt/trap handler and therefore volatile.
231    * However, for debugging purposes we still include those in register dumps
232    * printed by RegsDump(), so they remain listed in kRegs[].
233    */
234   copy_expected.zero = 0;
235   copy_expected.t6 = NACL_CONTROL_FLOW_MASK;
236   copy_expected.t7 = NACL_DATA_FLOW_MASK;
237   copy_expected.t8 = copy_actual.t8;
238   copy_expected.k0 = copy_actual.k0;
239   copy_expected.k1 = copy_actual.k1;
240 #endif
241
242   for (regnum = 0; regnum < NACL_ARRAY_SIZE(kRegs); regnum++) {
243     if (RegsGetRegValue(&copy_actual, regnum) !=
244         RegsGetRegValue(&copy_expected, regnum)) {
245       fprintf(stderr, "Mismatch in register %s\n", kRegs[regnum].reg_name);
246       match = 0;
247     }
248   }
249   if (!match) {
250     fprintf(stderr, "Expected register state:\n");
251     RegsDump(expected);
252     fprintf(stderr, "Actual register state:\n");
253     RegsDump(actual);
254     _exit(1);
255   }
256 }
257
258 void RegsCopyFromUserRegisterState(struct NaClSignalContext *dest,
259                                    const NaClUserRegisterState *src) {
260   unsigned int regnum;
261
262   /* Fill out trusted registers with dummy values. */
263   memset(dest, 0xff, sizeof(*dest));
264
265   for (regnum = 0; regnum < NACL_ARRAY_SIZE(kRegs); regnum++) {
266     ASSERT_EQ(kRegs[regnum].reg_size,
267               kRegs[regnum].user_register_state_reg_size);
268     memcpy((char *) dest + kRegs[regnum].reg_offset,
269            (char *) src + kRegs[regnum].user_register_state_reg_offset,
270            kRegs[regnum].reg_size);
271   }
272 }
273
274 void RegsUnsetNonCalleeSavedRegisters(struct NaClSignalContext *regs) {
275 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
276   regs->eax = 0;
277   regs->ecx = 0;
278   regs->edx = 0;
279   regs->flags = 0;
280 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
281   regs->rax = 0;
282   regs->rcx = 0;
283   regs->rdx = 0;
284   regs->rsi = 0;
285   regs->rdi = 0;
286   regs->r8 = 0;
287   regs->r9 = 0;
288   regs->r10 = 0;
289   regs->r11 = 0;
290   regs->flags = 0;
291 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
292   regs->r0 = 0;
293   regs->r1 = 0;
294   regs->r2 = 0;
295   regs->r3 = 0;
296   regs->r12 = 0;
297   regs->lr = 0;
298   regs->cpsr = 0;
299 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
300   regs->zero = 0;
301   regs->at = 0;
302   regs->v0 = 0;
303   regs->v1 = 0;
304   regs->a0 = 0;
305   regs->a1 = 0;
306   regs->a2 = 0;
307   regs->a3 = 0;
308   regs->t0 = 0;
309   regs->t1 = 0;
310   regs->t2 = 0;
311   regs->t3 = 0;
312   regs->t4 = 0;
313   regs->t5 = 0;
314   regs->t9 = 0;
315   regs->k0 = 0;
316   regs->k1 = 0;
317   regs->global_ptr  = 0;
318   regs->return_addr = 0;
319 #else
320 # error Unsupported architecture
321 #endif
322 }
323
324 #if defined(__native_client__)
325 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
326
327 uintptr_t RegsGetArg1(const struct NaClSignalContext *regs) {
328   return ((uint32_t *) regs->stack_ptr)[1];
329 }
330
331 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
332
333 uintptr_t RegsGetArg1(const struct NaClSignalContext *regs) {
334   return regs->rdi;
335 }
336
337 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
338
339 uintptr_t RegsGetArg1(const struct NaClSignalContext *regs) {
340   return regs->r0;
341 }
342
343 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
344
345 uintptr_t RegsGetArg1(const struct NaClSignalContext *regs) {
346   return regs->a0;
347 }
348
349 #else
350 # error Unsupported architecture
351 #endif
352 #endif