Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: src/trusted/service_runtime/thread_suspension_unwind.c

Issue 121833002: [MIPS] Add support for thread_suspension test (Closed) Base URL: http://git.chromium.org/native_client/src/native_client.git@master
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2013 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include "native_client/src/trusted/service_runtime/thread_suspension_unwind.h" 7 #include "native_client/src/trusted/service_runtime/thread_suspension_unwind.h"
8 8
9 #include "native_client/src/trusted/cpu_features/arch/x86/cpu_x86.h" 9 #include "native_client/src/trusted/cpu_features/arch/x86/cpu_x86.h"
10 #include "native_client/src/trusted/service_runtime/arch/arm/tramp_arm.h" 10 #include "native_client/src/trusted/service_runtime/arch/arm/tramp_arm.h"
11 #include "native_client/src/trusted/service_runtime/arch/x86_64/tramp_64.h" 11 #include "native_client/src/trusted/service_runtime/arch/x86_64/tramp_64.h"
12 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h" 12 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
13 #include "native_client/src/trusted/service_runtime/nacl_config.h" 13 #include "native_client/src/trusted/service_runtime/nacl_config.h"
14 #include "native_client/src/trusted/service_runtime/nacl_copy.h" 14 #include "native_client/src/trusted/service_runtime/nacl_copy.h"
15 #include "native_client/src/trusted/service_runtime/sel_ldr.h" 15 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
16 16
17 17
18 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 || \
19 NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
20
21 static void GetNaClSyscallSeg(struct NaClApp *nap, 18 static void GetNaClSyscallSeg(struct NaClApp *nap,
22 uintptr_t *nacl_syscall_seg, 19 uintptr_t *nacl_syscall_seg,
23 uintptr_t *nacl_syscall_seg_regs_saved) { 20 uintptr_t *nacl_syscall_seg_regs_saved) {
24 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 21 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
25 NaClCPUFeaturesX86 *features = (NaClCPUFeaturesX86 *) nap->cpu_features; 22 NaClCPUFeaturesX86 *features = (NaClCPUFeaturesX86 *) nap->cpu_features;
26 if (NaClGetCPUFeatureX86(features, NaClCPUFeatureX86_SSE)) { 23 if (NaClGetCPUFeatureX86(features, NaClCPUFeatureX86_SSE)) {
27 *nacl_syscall_seg = (uintptr_t) &NaClSyscallSegSSE; 24 *nacl_syscall_seg = (uintptr_t) &NaClSyscallSegSSE;
28 *nacl_syscall_seg_regs_saved = (uintptr_t) &NaClSyscallSegRegsSavedSSE; 25 *nacl_syscall_seg_regs_saved = (uintptr_t) &NaClSyscallSegRegsSavedSSE;
29 } else { 26 } else {
30 *nacl_syscall_seg = (uintptr_t) &NaClSyscallSegNoSSE; 27 *nacl_syscall_seg = (uintptr_t) &NaClSyscallSegNoSSE;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 regs->stack_ptr += 8; /* Pop user return address */ 68 regs->stack_ptr += 8; /* Pop user return address */
72 return 1; 69 return 1;
73 } 70 }
74 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm 71 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
75 if (regs->prog_ctr >= NACL_TRAMPOLINE_START && 72 if (regs->prog_ctr >= NACL_TRAMPOLINE_START &&
76 regs->prog_ctr < NACL_TRAMPOLINE_END) { 73 regs->prog_ctr < NACL_TRAMPOLINE_END) {
77 *unwind_case = NACL_UNWIND_in_trampoline; 74 *unwind_case = NACL_UNWIND_in_trampoline;
78 regs->prog_ctr = NaClSandboxCodeAddr(nap, regs->lr); 75 regs->prog_ctr = NaClSandboxCodeAddr(nap, regs->lr);
79 return 1; 76 return 1;
80 } 77 }
78 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
79 if (regs->prog_ctr >= NACL_TRAMPOLINE_START &&
80 regs->prog_ctr < NACL_TRAMPOLINE_END) {
81 *unwind_case = NACL_UNWIND_in_trampoline;
82 regs->prog_ctr = NaClSandboxCodeAddr(nap, regs->return_addr);
83 return 1;
84 }
81 #endif 85 #endif
82 86
83 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 87 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
84 if (regs->cs == NaClGetGlobalCs() && 88 if (regs->cs == NaClGetGlobalCs() &&
85 regs->prog_ctr >= nap->pcrel_thunk && 89 regs->prog_ctr >= nap->pcrel_thunk &&
86 regs->prog_ctr < nap->pcrel_thunk_end) { 90 regs->prog_ctr < nap->pcrel_thunk_end) {
87 *unwind_case = NACL_UNWIND_in_pcrel_thunk; 91 *unwind_case = NACL_UNWIND_in_pcrel_thunk;
88 regs->stack_ptr += 4 + 8; /* Pop user + trampoline return addresses */ 92 regs->stack_ptr += 4 + 8; /* Pop user + trampoline return addresses */
89 return 1; 93 return 1;
90 } 94 }
(...skipping 15 matching lines...) Expand all
106 regs->stack_ptr += 8; /* Pop user return address */ 110 regs->stack_ptr += 8; /* Pop user return address */
107 } 111 }
108 return 1; 112 return 1;
109 } 113 }
110 #endif 114 #endif
111 115
112 GetNaClSyscallSeg(nap, &nacl_syscall_seg, &nacl_syscall_seg_regs_saved); 116 GetNaClSyscallSeg(nap, &nacl_syscall_seg, &nacl_syscall_seg_regs_saved);
113 if (regs->prog_ctr >= nacl_syscall_seg && 117 if (regs->prog_ctr >= nacl_syscall_seg &&
114 regs->prog_ctr < nacl_syscall_seg_regs_saved) { 118 regs->prog_ctr < nacl_syscall_seg_regs_saved) {
115 *unwind_case = NACL_UNWIND_in_syscallseg; 119 *unwind_case = NACL_UNWIND_in_syscallseg;
116 if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86) { 120 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
117 if (NACL_BUILD_SUBARCH == 32) { 121 /* Pop user + trampoline return addresses */
118 /* Pop user + trampoline return addresses */ 122 regs->stack_ptr += 4 + 8;
119 regs->stack_ptr += 4 + 8; 123 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
120 } else { 124 /* Pop user return address. */
121 /* Pop user return address. */ 125 regs->stack_ptr += 8;
122 regs->stack_ptr += 8; 126 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
123 } 127 /*
124 } 128 * On MIPS, $ra is not modified from the start of the trampoline to the
129 * point where registers are saved.
130 */
131 regs->prog_ctr = NaClSandboxCodeAddr(nap, regs->return_addr);
132 #endif
125 return 1; 133 return 1;
126 } 134 }
127 135
128 *unwind_case = NACL_UNWIND_after_saving_regs; 136 *unwind_case = NACL_UNWIND_after_saving_regs;
129 return 0; 137 return 0;
130 } 138 }
131 139
132 /* 140 /*
133 * Given that thread |natp| has been suspended during a 141 * Given that thread |natp| has been suspended during a
134 * trusted/untrusted context switch and has trusted register state 142 * trusted/untrusted context switch and has trusted register state
135 * |regs|, this modifies |regs| to contain untrusted register state 143 * |regs|, this modifies |regs| to contain untrusted register state
136 * (that is, the state the syscall will return with). 144 * (that is, the state the syscall will return with).
137 */ 145 */
138 void NaClGetRegistersForContextSwitch(struct NaClAppThread *natp, 146 void NaClGetRegistersForContextSwitch(struct NaClAppThread *natp,
139 struct NaClSignalContext *regs, 147 struct NaClSignalContext *regs,
140 enum NaClUnwindCase *unwind_case) { 148 enum NaClUnwindCase *unwind_case) {
141 if (Unwind(natp, regs, unwind_case)) { 149 if (Unwind(natp, regs, unwind_case)) {
142 NaClSignalContextUnsetClobberedRegisters(regs); 150 NaClSignalContextUnsetClobberedRegisters(regs);
143 } else { 151 } else {
144 NaClThreadContextToSignalContext(&natp->user, regs); 152 NaClThreadContextToSignalContext(&natp->user, regs);
145 } 153 }
146 154
147 if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 || 155 if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 ||
148 (NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm && 156 (NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm &&
149 *unwind_case != NACL_UNWIND_in_trampoline)) { 157 *unwind_case != NACL_UNWIND_in_trampoline) ||
158 (NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips &&
159 *unwind_case != NACL_UNWIND_in_trampoline &&
160 *unwind_case != NACL_UNWIND_in_syscallseg)) {
150 /* 161 /*
151 * Read the return address from the untrusted stack. 162 * Read the return address from the untrusted stack.
152 * NaClCopyInFromUser() can fault or return an error here, but only 163 * NaClCopyInFromUser() can fault or return an error here, but only
153 * if the thread was suspended just before it was about to crash. 164 * if the thread was suspended just before it was about to crash.
154 * This can happen if untrusted code JMP'd to the trampoline with a 165 * This can happen if untrusted code JMP'd to the trampoline with a
155 * bad stack pointer or if the thread was racing with an munmap(). 166 * bad stack pointer or if the thread was racing with an munmap().
156 */ 167 */
157 nacl_reg_t user_ret = 0; 168 nacl_reg_t user_ret = 0;
158 if (!NaClCopyInFromUser(natp->nap, &user_ret, 169 if (!NaClCopyInFromUser(natp->nap, &user_ret,
159 (uint32_t) (regs->stack_ptr + NACL_USERRET_FIX), 170 (uint32_t) (regs->stack_ptr + NACL_USERRET_FIX),
160 sizeof(user_ret))) { 171 sizeof(user_ret))) {
161 NaClLog(LOG_WARNING, "NaClGetRegistersForContextSwitch: " 172 NaClLog(LOG_WARNING, "NaClGetRegistersForContextSwitch: "
162 "Failed to read return address; using dummy value\n"); 173 "Failed to read return address; using dummy value\n");
163 } 174 }
164 regs->prog_ctr = NaClSandboxCodeAddr(natp->nap, user_ret); 175 regs->prog_ctr = NaClSandboxCodeAddr(natp->nap, user_ret);
165 } 176 }
166 } 177 }
167
168 #else
169
170 /* TODO(mseaborn): Extend this to handle MIPS. */
171 void NaClGetRegistersForContextSwitch(struct NaClAppThread *natp,
172 struct NaClSignalContext *regs,
173 enum NaClUnwindCase *unwind_case) {
174 UNREFERENCED_PARAMETER(natp);
175 UNREFERENCED_PARAMETER(regs);
176 *unwind_case = 0;
177 }
178
179 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698