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

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

Issue 2371833007: [wasm] Initial signal handler (Closed)
Patch Set: Try to fix android compile 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
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 sizeof(CodeProtectionInfo) +
Mark Seaborn 2017/01/24 07:14:39 I think this should be offsetof(CodeProtectionInfo
Eric Holk 2017/01/26 01:33:37 Done.
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 MetadataLock lock;
79 CodeProtectionInfo *data = gCodeObjects[index];
80 data->base = base;
81 }
82
83 int RegisterHandlerData(void *base, size_t size,
84 size_t num_protected_instructions,
85 ProtectedInstructionData *protected_instructions) {
86 // TODO(eholk): in debug builds, make sure this data isn't already registered.
87
88 CodeProtectionInfo *data = CreateHandlerData(
89 base, size, num_protected_instructions, protected_instructions);
90
91 MetadataLock lock;
92
93 size_t i;
94 for (i = 0; i < gNumCodeObjects; ++i) {
95 if (gCodeObjects[i] == nullptr) {
96 break;
97 }
98 }
99
100 // We didn't find an opening in the available space, so grow.
101 if (i == gNumCodeObjects) {
102 size_t new_size = gNumCodeObjects > 0
103 ? gNumCodeObjects * kCodeObjectGrowthFactor
104 : kInitialCodeObjectSize;
105 gCodeObjects = static_cast<CodeProtectionInfo **>(
106 realloc(gCodeObjects, sizeof(*gCodeObjects) * new_size));
107
108 if (gCodeObjects == nullptr) {
Mark Seaborn 2017/01/24 07:14:40 If this happens, then we've just set gCodeObjects
Eric Holk 2017/01/26 01:33:37 Yikes! Good catch.
109 return -1;
110 }
111
112 memset(gCodeObjects + gNumCodeObjects, 0,
113 sizeof(*gCodeObjects) * (new_size - gNumCodeObjects));
114 gNumCodeObjects = new_size;
115 }
116
117 gCodeObjects[i] = data;
118 TRACE("Registered handler data %p at index %d\n", data, i);
119 return static_cast<int>(i);
Mark Seaborn 2017/01/24 07:14:39 It's probably safer to make the return type a size
Eric Holk 2017/01/26 01:33:37 Good point. At the moment, this immediately gets
120 }
121
122 void ReleaseHandlerData(int index) {
123 // Remove the data from the global list if it's there.
124
125 MetadataLock lock;
126
127 CodeProtectionInfo *data = gCodeObjects[index];
128 gCodeObjects[index] = nullptr;
129
130 TRACE("Released handler data %p at index %d\n", data, index);
131
132 // TODO(eholk): on debug builds, ensure there are no more copies in
133 // the list.
134 free(data);
135 }
136
137 void SetThreadInWasm() {
138 TRACE("Transitioning to Wasm\n");
139 g_thread_in_wasm_code = true;
140 }
141
142 void ClearThreadInWasm() {
143 TRACE("Transitioning from Wasm\n");
144 g_thread_in_wasm_code = false;
145 }
146
147 bool IsThreadInWasm() { return g_thread_in_wasm_code; }
148
149 bool EnableTrapHandler() {
150 return FLAG_wasm_trap_handler && kTrapHandlerSupported;
151 }
152
153 } // namespace trap_handler
154 } // namespace internal
155 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698