Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / native_client / tests / faulted_thread_queue / faultqueue_test_guest.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 <assert.h>
8 #include <setjmp.h>
9 #include <stdio.h>
10
11 #include "native_client/src/include/arm_sandbox.h"
12 #include "native_client/src/include/nacl_macros.h"
13 #include "native_client/tests/common/register_set.h"
14
15
16 /*
17  * This test program sets registers to a known state and then faults,
18  * so that faultqueue_test_host.c can check that it receives
19  * notification of the fault.
20  *
21  * faultqueue_test_host.c makes execution resume from the instruction
22  * after FaultAddr.  On x86, it also checks that single-stepping these
23  * following instructions works.
24  */
25
26 void FaultAddr(void);
27
28 jmp_buf return_jmp_buf;
29
30 void DoLongjmp(void) {
31   longjmp(return_jmp_buf, 1);
32 }
33
34 int main(int argc, char **argv) {
35   if (argc != 2) {
36     fprintf(stderr, "Expected 1 argument: <memory-address>\n");
37     return 1;
38   }
39   char *end;
40   struct NaClSignalContext *expected_regs =
41       (struct NaClSignalContext *) strtoul(argv[1], &end, 0);
42   assert(*end == '\0');
43
44   char stack[0x10000];
45
46   RegsFillTestValues(expected_regs, /* seed= */ 0);
47   expected_regs->stack_ptr = (uintptr_t) stack + sizeof(stack);
48   expected_regs->prog_ctr = (uintptr_t) FaultAddr;
49   RegsApplySandboxConstraints(expected_regs);
50
51   if (!setjmp(return_jmp_buf)) {
52 #if defined(__i386__) || defined(__x86_64__)
53     ASM_WITH_REGS(
54         expected_regs,
55         /*
56          * Align so that the following instructions do not cross an
57          * instruction bundle boundary.
58          */
59         ".p2align 5\n"
60         "FaultAddr: hlt\n"
61         /* Test single-stepping with some no-op instructions of known sizes. */
62         ".byte 0x90\n" /* nop */
63         ".byte 0x66, 0x90\n" /* xchg %ax, %ax */
64         ".byte 0x0f, 0x1f, 0x00\n" /* nopl (%eax) */
65         ".byte 0x0f, 0x1f, 0x40, 0x00\n" /* nopl 0x0(%eax) */
66         ".byte 0x0f, 0x1f, 0x44, 0x00, 0x00\n" /* nopl 0x0(%eax, %eax, 1) */
67         "jmp DoLongjmp\n");
68 #elif defined(__arm__)
69     ASM_WITH_REGS(
70         expected_regs,
71         ".p2align 4\n"
72         "FaultAddr: .word " NACL_TO_STRING(NACL_INSTR_ARM_ABORT_NOW) "\n"
73         /*
74          * ARM does not provide hardware single-stepping so we do not
75          * test it here, unlike in the x86 case.
76          */
77         "b DoLongjmp\n"
78         ".p2align 4\n");
79 #else
80 # error Unknown architecture
81 #endif
82   }
83
84   /*
85    * Avoid calling exit().  This nexe's _start() entry point is called
86    * multiple times by faultqueue_test_host.c, without resetting the
87    * data segment, which is unusual.  This causes exit() to hang when
88    * libpthread is linked in, which recent PNaCl toolchains have
89    * started to do by default.
90    */
91   _exit(0);
92 }