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

Side by Side Diff: src/trap-handler/trap-handler.cc

Issue 2371833007: [wasm] Initial signal handler (Closed)
Patch Set: Addressing some of Jochen's feedback Created 3 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
(Empty)
1 // Copyright 2016 the V8 project authors. All rights reserved.
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!
6 //
7 // This file implements the out of bounds signal handler for
8 // WebAssembly. Signal handlers are notoriously difficult to get
9 // right, and getting it wrong can lead to security
10 // vulnerabilities. In order to minimize this risk, here are some
11 // rules to follow.
12 //
13 // 1. Do not introduce any new external dependencies. This file needs
14 // to be self contained so it is easy to audit everything that a
15 // signal handler might do.
16 //
17 // 2. Any changes must be reviewed by someone from the crash reporting
18 // or security team.
19
20 // This file contains general support code for trap handling, and is mostly
21 // used by other parts of V8. For the code that runs in the signal handler
22 // itself, see signal-handler.cc.
23
24 #include <signal.h>
25 #include <stddef.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <atomic>
31
32 #include "src/flags.h"
33 #include "src/trap-handler/trap-handler-internal.h"
34 #include "src/trap-handler/trap-handler.h"
35
36 #define TRACE(...)
37 // #define TRACE(...) fprintf(stderr, __VA_ARGS__)
38
39 namespace v8 {
40 namespace internal {
41 namespace trap_handler {
42
43 __thread bool g_thread_in_wasm_code = false;
44
45 const size_t kInitialCodeObjectSize = 1024;
46 const size_t kCodeObjectGrowthFactor = 2;
47 size_t gNumCodeObjects = 0;
48 CodeObjectData **gCodeObjects = nullptr;
49
50 std::atomic_flag MetadataLock::spinlock_ = ATOMIC_FLAG_INIT;
51
52 constexpr size_t HandlerDataSize(size_t num_protected_instructions) {
53 return sizeof(CodeObjectData) +
54 num_protected_instructions * sizeof(ProtectedInstructionData);
55 }
56
57 CodeObjectData *CreateHandlerData(
58 void *base, size_t size, size_t num_protected_instructions,
59 ProtectedInstructionData *protected_instructions) {
60 const size_t alloc_size = HandlerDataSize(num_protected_instructions);
61 CodeObjectData *data = reinterpret_cast<CodeObjectData *>(malloc(alloc_size));
62
63 if (data == nullptr) {
64 return nullptr;
65 }
66
67 data->base = base;
68 data->size = size;
69 data->num_protected_instructions = num_protected_instructions;
70
71 memcpy(data->instructions, protected_instructions,
72 num_protected_instructions * sizeof(ProtectedInstructionData));
73
74 return data;
75 }
76
77 CodeObjectData *CloneHandlerData(CodeObjectData *data) {
78 const size_t alloc_size = HandlerDataSize(data->num_protected_instructions);
79 CodeObjectData *new_data =
80 reinterpret_cast<CodeObjectData *>(malloc(alloc_size));
81
82 memcpy(new_data, data, alloc_size);
83 return new_data;
84 }
85
86 void UpdateCodePointer(int index, void *base) {
87 MetadataLock _;
titzer 2017/01/09 09:26:56 Can we name this little temporary locks "lock"?
Eric Holk 2017/01/10 23:10:48 Done. I thought I had fixed this already but I gu
88 CodeObjectData *data = gCodeObjects[index];
89 data->base = base;
90 }
91
92 int RegisterHandlerData(CodeObjectData *data) {
93 // TODO(eholk): in debug builds, make sure this data isn't already registered.
94 MetadataLock _;
95
96 size_t i;
97 for (i = 0; i < gNumCodeObjects; ++i) {
98 if (gCodeObjects[i] == nullptr) {
99 break;
100 }
101 }
102
103 // We didn't find an opening in the available space, so grow.
104 if (i == gNumCodeObjects) {
105 size_t new_size = gNumCodeObjects > 0
106 ? gNumCodeObjects * kCodeObjectGrowthFactor
107 : kInitialCodeObjectSize;
108 gCodeObjects = static_cast<CodeObjectData **>(
109 realloc(gCodeObjects, sizeof(*gCodeObjects) * new_size));
110
111 if (gCodeObjects == nullptr) {
112 return -1;
113 }
114
115 memset(gCodeObjects + gNumCodeObjects, 0,
116 sizeof(*gCodeObjects) * (new_size - gNumCodeObjects));
117 gNumCodeObjects = new_size;
118 }
119
120 gCodeObjects[i] = data;
121 TRACE("Registered handler data %p at index %d\n", data, i);
122 return static_cast<int>(i);
123 }
124
125 void ReleaseHandlerData(int index) {
126 // Remove the data from the global list if it's there.
127
128 MetadataLock _;
129
130 CodeObjectData *data = gCodeObjects[index];
131 gCodeObjects[index] = nullptr;
132
133 TRACE("Released handler data %p at index %d\n", data, index);
134
135 // TODO(eholk): on debug builds, ensure there are no more copies in
136 // the list.
137 free(data);
138 }
139
140 void SetThreadInWasm() {
141 TRACE("Transitioning to Wasm\n");
142 g_thread_in_wasm_code = true;
143 }
144
145 void ClearThreadInWasm() {
146 TRACE("Transitioning from Wasm\n");
147 g_thread_in_wasm_code = false;
148 }
149
150 bool IsThreadInWasm() { return g_thread_in_wasm_code; }
151
152 bool EnableTrapHandler() {
153 return FLAG_wasm_trap_handler && kTrapHandlerSupported;
154 }
155
156 } // namespace trap_handler
157 } // namespace internal
158 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698