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

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

Issue 2371833007: [wasm] Initial signal handler (Closed)
Patch Set: Handler signal handler registration failure Created 3 years, 10 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
Mark Seaborn 2017/02/09 16:44:36 The naming of the files as "trap-handler.cc" and "
Eric Holk 2017/02/15 02:02:45 Done.
5 // PLEASE READ BEFORE CHANGING THIS FILE!
6 //
7 // This file implements the out of bounds signal handler for
Mark Seaborn 2017/02/09 16:44:36 Can you drop this sentence? *This* file doesn't i
Eric Holk 2017/02/15 02:02:45 Done.
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
Mark Seaborn 2017/02/09 16:44:36 This reason doesn't apply for the outside-the-trap
Eric Holk 2017/02/15 02:02:45 I softened the wording a bit to say "avoid adding
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
38 namespace v8 {
39 namespace internal {
40 namespace trap_handler {
41
42 THREAD_LOCAL bool g_thread_in_wasm_code = false;
43
44 const size_t kInitialCodeObjectSize = 1024;
45 const size_t kCodeObjectGrowthFactor = 2;
46 size_t gNumCodeObjects = 0;
47 CodeProtectionInfo** gCodeObjects = nullptr;
48
49 std::atomic_flag MetadataLock::spinlock_ = ATOMIC_FLAG_INIT;
50
51 constexpr size_t HandlerDataSize(size_t num_protected_instructions) {
52 return offsetof(CodeProtectionInfo, instructions) +
53 num_protected_instructions * sizeof(ProtectedInstructionData);
54 }
55
56 CodeProtectionInfo* CreateHandlerData(
57 void* base, size_t size, size_t num_protected_instructions,
58 ProtectedInstructionData* protected_instructions) {
59 const size_t alloc_size = HandlerDataSize(num_protected_instructions);
60 CodeProtectionInfo* data =
61 reinterpret_cast<CodeProtectionInfo*>(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 void UpdateCodePointer(int index, void* base) {
78 TRACE("Updating code pointer at index %d\n", index);
79 MetadataLock lock;
80 if (static_cast<size_t>(index) >= gNumCodeObjects) {
81 TRACE("Out of bounds\n");
82 abort();
83 }
84 CodeProtectionInfo* data = gCodeObjects[index];
85 data->base = base;
86 }
87
88 int RegisterHandlerData(void* base, size_t size,
89 size_t num_protected_instructions,
90 ProtectedInstructionData* protected_instructions) {
91 // TODO(eholk): in debug builds, make sure this data isn't already registered.
92
93 CodeProtectionInfo* data = CreateHandlerData(
94 base, size, num_protected_instructions, protected_instructions);
95
96 if (data == nullptr) {
97 TRACE("Could not allocate handler data\n");
98 abort();
99 }
100
101 MetadataLock lock;
102
103 size_t i;
104 for (i = 0; i < gNumCodeObjects; ++i) {
105 if (gCodeObjects[i] == nullptr) {
106 break;
107 }
108 }
109
110 // We didn't find an opening in the available space, so grow.
111 if (i == gNumCodeObjects) {
112 size_t new_size = gNumCodeObjects > 0
113 ? gNumCodeObjects * kCodeObjectGrowthFactor
114 : kInitialCodeObjectSize;
115 gCodeObjects = static_cast<CodeProtectionInfo**>(
116 realloc(gCodeObjects, sizeof(*gCodeObjects) * new_size));
117
118 if (gCodeObjects == nullptr) {
119 abort();
120 }
121
122 memset(gCodeObjects + gNumCodeObjects, 0,
123 sizeof(*gCodeObjects) * (new_size - gNumCodeObjects));
124 gNumCodeObjects = new_size;
125 }
126
127 gCodeObjects[i] = data;
128 TRACE("Registered handler data %p at index %zu\n", data, i);
129 return static_cast<int>(i);
130 }
131
132 void ReleaseHandlerData(int index) {
133 // Remove the data from the global list if it's there.
134
135 MetadataLock lock;
136
137 CodeProtectionInfo* data = gCodeObjects[index];
138 gCodeObjects[index] = nullptr;
139
140 TRACE("Released handler data %p at index %d\n", data, index);
141
142 // TODO(eholk): on debug builds, ensure there are no more copies in
143 // the list.
144 free(data);
145 }
146
147 void SetThreadInWasm() {
148 TRACE("Transitioning to Wasm\n");
149 g_thread_in_wasm_code = true;
150 }
151
152 void ClearThreadInWasm() {
153 TRACE("Transitioning from Wasm\n");
154 g_thread_in_wasm_code = false;
155 }
156
157 bool IsThreadInWasm() { return g_thread_in_wasm_code; }
158
159 bool EnableTrapHandler() {
160 return FLAG_wasm_trap_handler && kTrapHandlerSupported;
161 }
162
163 } // namespace trap_handler
164 } // namespace internal
165 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698