OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 the V8 project authors. All rights reserved. | |
jochen (gone - plz use gerrit)
2017/02/20 09:23:04
nit. 2017
Eric Holk
2017/02/23 02:16:56
Done.
| |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // PLEASE READ BEFORE CHANGING THIS FILE! | |
jochen (gone - plz use gerrit)
2017/02/20 09:23:04
maybe move that to a README.md?
Eric Holk
2017/02/23 02:16:56
I'd rather leave it here so that people are more l
| |
6 // | |
7 // This file implements the support code for the out of bounds signal handler. | |
8 // Nothing in here actually runs in the signal handler, but the code here | |
9 // manipulates data structures used by the signal handler so we still need to be | |
10 // careful. In order to minimize this risk, here are some rules to follow. | |
11 // | |
12 // 1. Avoid introducing new external dependencies. The files in src/trap-handler | |
13 // should be as self-contained as possible to make it easy to audit the code. | |
14 // | |
15 // 2. Any changes must be reviewed by someone from the crash reporting | |
16 // or security team. Se OWNERS for suggested reviewers. | |
17 // | |
18 // For more information, see https://goo.gl/yMeyUY. | |
19 // | |
20 // For the code that runs in the signal handler itself, see handler-inside.cc. | |
21 | |
22 #include <signal.h> | |
23 #include <stddef.h> | |
24 #include <stdio.h> | |
25 #include <stdlib.h> | |
26 #include <string.h> | |
27 | |
28 #include <atomic> | |
29 | |
30 #include "src/flags.h" | |
31 #include "src/trap-handler/trap-handler-internal.h" | |
32 #include "src/trap-handler/trap-handler.h" | |
33 | |
34 #define TRACE(...) | |
Mark Seaborn
2017/02/17 21:41:12
I think you said you were removing the TRACE() log
Eric Holk
2017/02/23 02:16:56
I must have missed some. This is removed now too.
| |
35 | |
36 namespace v8 { | |
37 namespace internal { | |
38 namespace trap_handler { | |
39 | |
40 const size_t kInitialCodeObjectSize = 1024; | |
41 const size_t kCodeObjectGrowthFactor = 2; | |
42 | |
43 constexpr size_t HandlerDataSize(size_t num_protected_instructions) { | |
44 return offsetof(CodeProtectionInfo, instructions) + | |
45 num_protected_instructions * sizeof(ProtectedInstructionData); | |
46 } | |
47 | |
48 CodeProtectionInfo* CreateHandlerData( | |
49 void* base, size_t size, size_t num_protected_instructions, | |
50 ProtectedInstructionData* protected_instructions) { | |
51 const size_t alloc_size = HandlerDataSize(num_protected_instructions); | |
52 CodeProtectionInfo* data = | |
53 reinterpret_cast<CodeProtectionInfo*>(malloc(alloc_size)); | |
54 | |
55 if (data == nullptr) { | |
56 return nullptr; | |
57 } | |
58 | |
59 data->base = base; | |
60 data->size = size; | |
61 data->num_protected_instructions = num_protected_instructions; | |
62 | |
63 memcpy(data->instructions, protected_instructions, | |
64 num_protected_instructions * sizeof(ProtectedInstructionData)); | |
65 | |
66 return data; | |
67 } | |
68 | |
69 void UpdateCodePointer(int index, void* base) { | |
70 TRACE("Updating code pointer at index %d\n", index); | |
71 MetadataLock lock; | |
72 if (static_cast<size_t>(index) >= gNumCodeObjects) { | |
73 TRACE("Out of bounds\n"); | |
74 abort(); | |
75 } | |
76 CodeProtectionInfo* data = gCodeObjects[index]; | |
77 data->base = base; | |
78 } | |
79 | |
80 int RegisterHandlerData(void* base, size_t size, | |
81 size_t num_protected_instructions, | |
82 ProtectedInstructionData* protected_instructions) { | |
83 // TODO(eholk): in debug builds, make sure this data isn't already registered. | |
84 | |
85 CodeProtectionInfo* data = CreateHandlerData( | |
86 base, size, num_protected_instructions, protected_instructions); | |
87 | |
88 if (data == nullptr) { | |
89 TRACE("Could not allocate handler data\n"); | |
90 abort(); | |
91 } | |
92 | |
93 MetadataLock lock; | |
94 | |
95 size_t i; | |
96 for (i = 0; i < gNumCodeObjects; ++i) { | |
titzer
2017/02/20 09:50:08
Oh, this is kinda bad. It's gonna be linear time t
Eric Holk
2017/02/23 02:16:56
Good call. This basically makes instantiation quad
| |
97 if (gCodeObjects[i] == nullptr) { | |
98 break; | |
99 } | |
100 } | |
101 | |
102 // We didn't find an opening in the available space, so grow. | |
103 if (i == gNumCodeObjects) { | |
104 size_t new_size = gNumCodeObjects > 0 | |
105 ? gNumCodeObjects * kCodeObjectGrowthFactor | |
106 : kInitialCodeObjectSize; | |
107 gCodeObjects = static_cast<CodeProtectionInfo**>( | |
108 realloc(gCodeObjects, sizeof(*gCodeObjects) * new_size)); | |
109 | |
110 if (gCodeObjects == nullptr) { | |
111 abort(); | |
112 } | |
113 | |
114 memset(gCodeObjects + gNumCodeObjects, 0, | |
115 sizeof(*gCodeObjects) * (new_size - gNumCodeObjects)); | |
116 gNumCodeObjects = new_size; | |
117 } | |
118 | |
119 gCodeObjects[i] = data; | |
120 TRACE("Registered handler data %p at index %zu\n", data, i); | |
121 return static_cast<int>(i); | |
Mark Seaborn
2017/02/17 21:41:12
Please check that this doesn't overflow/wrap, as w
Eric Holk
2017/02/23 02:16:57
Done.
I also changed the new_size calculation abo
| |
122 } | |
123 | |
124 void ReleaseHandlerData(int index) { | |
125 // Remove the data from the global list if it's there. | |
126 | |
127 MetadataLock lock; | |
128 | |
129 CodeProtectionInfo* data = gCodeObjects[index]; | |
130 gCodeObjects[index] = nullptr; | |
131 | |
132 TRACE("Released handler data %p at index %d\n", data, index); | |
133 | |
134 // TODO(eholk): on debug builds, ensure there are no more copies in | |
135 // the list. | |
136 free(data); | |
Mark Seaborn
2017/02/17 21:41:12
You could do this outside of the lock.
Eric Holk
2017/02/23 02:16:56
Done.
| |
137 } | |
138 | |
139 void SetThreadInWasm() { | |
140 TRACE("Transitioning to Wasm\n"); | |
141 g_thread_in_wasm_code = true; | |
Mark Seaborn
2017/02/17 21:41:12
This could first assert that g_thread_in_wasm_code
Eric Holk
2017/02/23 02:16:56
Done.
| |
142 } | |
143 | |
144 void ClearThreadInWasm() { | |
145 TRACE("Transitioning from Wasm\n"); | |
146 g_thread_in_wasm_code = false; | |
147 } | |
148 | |
149 bool IsThreadInWasm() { return g_thread_in_wasm_code; } | |
150 | |
151 V8_EXPORT_PRIVATE bool ShouldEnableTrapHandler() { | |
152 return FLAG_wasm_trap_handler && kTrapHandlerSupported; | |
153 } | |
154 | |
155 bool RegisterDefaultSignalHandler() { | |
156 #if V8_TRAP_HANDLER_SUPPORTED | |
157 struct sigaction action; | |
158 action.sa_sigaction = HandleSignal; | |
159 action.sa_flags = SA_SIGINFO; | |
160 sigemptyset(&action.sa_mask); | |
161 if (sigaction(SIGSEGV, &action, nullptr) != 0) { | |
ahaas
2017/02/20 09:27:24
Could you add a comment for this code?
Eric Holk
2017/02/23 02:16:56
Done.
| |
162 return false; | |
163 } | |
164 | |
165 return true; | |
166 #else | |
167 return false; | |
168 #endif | |
169 } | |
170 | |
171 } // namespace trap_handler | |
172 } // namespace internal | |
173 } // namespace v8 | |
OLD | NEW |