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 /*
8  * NaCl Secure Runtime
9  */
10 
11 #ifndef __NATIVE_CLIENT_SERVICE_RUNTIME_ARCH_ARM_SEL_RT_H__
12 #define __NATIVE_CLIENT_SERVICE_RUNTIME_ARCH_ARM_SEL_RT_H__ 1
13 
14 /* This file can be #included from assembly to get the #defines. */
15 #if !defined(__ASSEMBLER__)
16 
17 #include <stddef.h>
18 
19 #include "native_client/src/include/nacl_base.h"
20 #include "native_client/src/include/nacl_macros.h"
21 #include "native_client/src/include/portability.h"
22 
23 EXTERN_C_BEGIN
24 
25 uint32_t NaClGetStackPtr(void);
26 
27 typedef uint32_t nacl_reg_t;
28 
29 #define NACL_PRIdNACL_REG NACL_PRId32
30 #define NACL_PRIiNACL_REG NACL_PRIi32
31 #define NACL_PRIoNACL_REG NACL_PRIo32
32 #define NACL_PRIuNACL_REG NACL_PRIu32
33 #define NACL_PRIxNACL_REG NACL_PRIx32
34 #define NACL_PRIXNACL_REG NACL_PRIX32
35 
36 struct NaClThreadContext {
37   /*
38    * r4 through to fp correspond to NACL_CALLEE_SAVE_LIST, and the assembly
39    * code expects them to appear at the start of the struct.
40    */
41   nacl_reg_t  r4, r5, r6, r7, r8, r9, r10, fp, stack_ptr, prog_ctr;
42   /*           0   4   8   c  10  14   18  1c         20        24 */
43   /*
44    * sys_ret and new_prog_ctr are not a part of the thread's register
45    * set, but are needed by NaClSwitch.  By including them here, the
46    * two use the same interface.
47    */
48   uint32_t  sysret;
49   /*            28 */
50   uint32_t  new_prog_ctr;
51   /*            2c */
52   uint32_t  trusted_stack_ptr;
53   /*            30 */
54   uint32_t  tls_idx;
55   /*            34 */
56   uint32_t  fpscr;
57   /*            38 */
58   uint32_t  sys_fpscr;
59   /*            3c */
60   uint32_t  tls_value1;
61   /*            40 */
62   uint32_t  tls_value2;
63   /*            44 */
64   uint32_t  syscall_routine;  /* Address of NaClSyscallSeg routine */
65   /*            48 */
66   uint32_t  guard_token;
67   /*            4c */
68 };
69 
NaClGetThreadCtxSp(struct NaClThreadContext * th_ctx)70 static INLINE uintptr_t NaClGetThreadCtxSp(struct NaClThreadContext *th_ctx) {
71   return th_ctx->stack_ptr;
72 }
73 
74 NORETURN void NaClStartSwitch(struct NaClThreadContext *);
75 
76 #endif /* !defined(__ASSEMBLER__) */
77 
78 /*
79  * List of registers at the start of NaClThreadContext, for use with the
80  * instructions LDM and STM.
81  *
82  * Note that we omit "sp" from this list and save/restore it separately,
83  * because using "sp" with LDM/STM is considered deprecated (see
84  * https://crbug.com/564044).
85  */
86 #define NACL_CALLEE_SAVE_LIST {r4, r5, r6, r7, r8, r9, r10, fp}
87 
88 /*
89  * Given an offset for a field in NaClThreadContext, this returns the
90  * field's offset from r9, given that r9 points to tls_value1.
91  */
92 #define NACL_R9_OFFSET(offset) \
93     ((offset) - NACL_THREAD_CONTEXT_OFFSET_TLS_VALUE1)
94 
95 #define NACL_THREAD_CONTEXT_OFFSET_STACK_PTR 0x20
96 #define NACL_THREAD_CONTEXT_OFFSET_SYSRET 0x28
97 #define NACL_THREAD_CONTEXT_OFFSET_TRUSTED_STACK_PTR 0x30
98 #define NACL_THREAD_CONTEXT_OFFSET_TLS_IDX 0x34
99 #define NACL_THREAD_CONTEXT_OFFSET_FPSCR 0x38
100 #define NACL_THREAD_CONTEXT_OFFSET_SYS_FPSCR 0x3c
101 #define NACL_THREAD_CONTEXT_OFFSET_TLS_VALUE1 0x40
102 #define NACL_THREAD_CONTEXT_OFFSET_SYSCALL_ROUTINE 0x48
103 #define NACL_THREAD_CONTEXT_OFFSET_GUARD_TOKEN 0x4c
104 
105 #if !defined(__ASSEMBLER__)
106 
107 /*
108  * This function exists as a function only because compile-time
109  * assertions need to be inside a function.  This function does not
110  * need to be called for the assertions to be checked.
111  */
NaClThreadContextOffsetCheck(void)112 static INLINE void NaClThreadContextOffsetCheck(void) {
113 #define NACL_CHECK_FIELD(offset_name, field) \
114     NACL_COMPILE_TIME_ASSERT(offset_name == \
115                              offsetof(struct NaClThreadContext, field));
116 
117   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_STACK_PTR, stack_ptr);
118   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_SYSRET, sysret);
119   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_TRUSTED_STACK_PTR,
120                    trusted_stack_ptr);
121   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_TLS_IDX, tls_idx);
122   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_FPSCR, fpscr);
123   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_SYS_FPSCR, sys_fpscr);
124   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_TLS_VALUE1, tls_value1);
125   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_SYSCALL_ROUTINE, syscall_routine);
126   NACL_CHECK_FIELD(NACL_THREAD_CONTEXT_OFFSET_GUARD_TOKEN, guard_token);
127 
128 #undef NACL_CHECK_FIELD
129 }
130 
131 EXTERN_C_END
132 
133 #endif /* !defined(__ASSEMBLER__) */
134 
135 #endif /* __NATIVE_CLIENT_SERVICE_RUNTIME_ARCH_ARM_SEL_RT_H___ */
136