30 #include "src/trap-handler/trap-handler-internal.h" 31 #include "src/trap-handler/trap-handler.h" 34 size_t gNextCodeObject = 0;
37 constexpr
bool kEnableDebug =
true;
39 constexpr
bool kEnableDebug =
false;
45 namespace trap_handler {
47 constexpr
size_t kInitialCodeObjectSize = 1024;
48 constexpr
size_t kCodeObjectGrowthFactor = 2;
50 constexpr
size_t HandlerDataSize(
size_t num_protected_instructions) {
51 return offsetof(CodeProtectionInfo, instructions) +
52 num_protected_instructions *
sizeof(ProtectedInstructionData);
57 bool IsDisjoint(
const CodeProtectionInfo* a,
const CodeProtectionInfo* b) {
58 if (a ==
nullptr || b ==
nullptr) {
61 return a->base >= b->base + b->size || b->base >= a->base + a->size;
67 void VerifyCodeRangeIsDisjoint(
const CodeProtectionInfo* code_info) {
68 for (
size_t i = 0;
i < gNumCodeObjects; ++
i) {
69 DCHECK(IsDisjoint(code_info, gCodeObjects[
i].code_info));
73 void ValidateCodeObjects() {
75 for (
unsigned i = 0;
i < gNumCodeObjects; ++
i) {
76 const auto* data = gCodeObjects[
i].code_info;
78 if (data ==
nullptr)
continue;
81 for (
unsigned i = 0;
i < data->num_protected_instructions; ++
i) {
82 DCHECK_GE(data->instructions[
i].instr_offset, 0);
83 DCHECK_LT(data->instructions[
i].instr_offset, data->size);
84 DCHECK_GE(data->instructions[
i].landing_offset, 0);
85 DCHECK_LT(data->instructions[
i].landing_offset, data->size);
86 DCHECK_GT(data->instructions[
i].landing_offset,
87 data->instructions[
i].instr_offset);
92 size_t free_count = 0;
93 for (
size_t i = gNextCodeObject;
i != gNumCodeObjects;
94 i = gCodeObjects[
i].next_free) {
95 DCHECK_LT(
i, gNumCodeObjects);
98 DCHECK_LE(free_count, gNumCodeObjects);
102 size_t free_count2 = 0;
103 for (
size_t i = 0;
i < gNumCodeObjects; ++
i) {
104 if (gCodeObjects[
i].code_info ==
nullptr) {
108 DCHECK_EQ(free_count, free_count2);
112 CodeProtectionInfo* CreateHandlerData(
113 Address base,
size_t size,
size_t num_protected_instructions,
114 const ProtectedInstructionData* protected_instructions) {
115 const size_t alloc_size = HandlerDataSize(num_protected_instructions);
116 CodeProtectionInfo* data =
117 reinterpret_cast<CodeProtectionInfo*
>(malloc(alloc_size));
119 if (data ==
nullptr) {
125 data->num_protected_instructions = num_protected_instructions;
127 memcpy(data->instructions, protected_instructions,
128 num_protected_instructions *
sizeof(ProtectedInstructionData));
133 int RegisterHandlerData(
134 Address base,
size_t size,
size_t num_protected_instructions,
135 const ProtectedInstructionData* protected_instructions) {
137 CodeProtectionInfo* data = CreateHandlerData(
138 base, size, num_protected_instructions, protected_instructions);
140 if (data ==
nullptr) {
147 VerifyCodeRangeIsDisjoint(data);
150 size_t i = gNextCodeObject;
156 const size_t int_max = std::numeric_limits<int>::max();
159 if (
i == gNumCodeObjects) {
160 size_t new_size = gNumCodeObjects > 0
161 ? gNumCodeObjects * kCodeObjectGrowthFactor
162 : kInitialCodeObjectSize;
166 if (new_size > int_max) {
169 if (new_size == gNumCodeObjects) {
171 return kInvalidIndex;
176 gCodeObjects =
static_cast<CodeProtectionInfoListEntry*
>(
177 realloc(gCodeObjects,
sizeof(*gCodeObjects) * new_size));
179 if (gCodeObjects ==
nullptr) {
183 memset(gCodeObjects + gNumCodeObjects, 0,
184 sizeof(*gCodeObjects) * (new_size - gNumCodeObjects));
185 for (
size_t j = gNumCodeObjects; j < new_size; ++j) {
186 gCodeObjects[j].next_free = j + 1;
188 gNumCodeObjects = new_size;
191 DCHECK(gCodeObjects[
i].code_info ==
nullptr);
194 gNextCodeObject = gCodeObjects[
i].next_free;
197 gCodeObjects[
i].code_info = data;
200 ValidateCodeObjects();
203 return static_cast<int>(
i);
206 return kInvalidIndex;
210 void ReleaseHandlerData(
int index) {
211 if (index == kInvalidIndex) {
217 CodeProtectionInfo* data =
nullptr;
221 data = gCodeObjects[index].code_info;
222 gCodeObjects[index].code_info =
nullptr;
224 gCodeObjects[index].next_free = gNextCodeObject;
225 gNextCodeObject = index;
228 ValidateCodeObjects();
233 DCHECK_NOT_NULL(data);
237 size_t GetRecoveredTrapCount() {
238 return gRecoveredTrapCount.load(std::memory_order_relaxed);
241 #if !V8_TRAP_HANDLER_SUPPORTED 245 bool RegisterDefaultTrapHandler() {
return false; }
247 void RemoveTrapHandler() {}
250 bool g_is_trap_handler_enabled;
252 bool EnableTrapHandler(
bool use_v8_handler) {
253 if (!V8_TRAP_HANDLER_SUPPORTED) {
256 if (use_v8_handler) {
257 g_is_trap_handler_enabled = RegisterDefaultTrapHandler();
258 return g_is_trap_handler_enabled;
260 g_is_trap_handler_enabled =
true;