OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/macro-assembler.h" | 5 #include "src/macro-assembler.h" |
6 #include "src/objects.h" | 6 #include "src/objects.h" |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/wasm/decoder.h" | 9 #include "src/wasm/decoder.h" |
10 #include "src/wasm/module-decoder.h" | 10 #include "src/wasm/module-decoder.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 int length; | 150 int length; |
151 uint32_t data_segments_count = u32v(&length, "data segments count"); | 151 uint32_t data_segments_count = u32v(&length, "data segments count"); |
152 module->data_segments->reserve(SafeReserve(data_segments_count)); | 152 module->data_segments->reserve(SafeReserve(data_segments_count)); |
153 // Decode data segments. | 153 // Decode data segments. |
154 for (uint32_t i = 0; i < data_segments_count; i++) { | 154 for (uint32_t i = 0; i < data_segments_count; i++) { |
155 if (failed()) break; | 155 if (failed()) break; |
156 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 156 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
157 static_cast<int>(pc_ - start_)); | 157 static_cast<int>(pc_ - start_)); |
158 module->data_segments->push_back({0, 0, 0}); | 158 module->data_segments->push_back({0, 0, 0}); |
159 WasmDataSegment* segment = &module->data_segments->back(); | 159 WasmDataSegment* segment = &module->data_segments->back(); |
160 DecodeDataSegmentInModule(segment); | 160 DecodeDataSegmentInModule(module, segment); |
161 } | 161 } |
162 break; | 162 break; |
163 } | 163 } |
164 case kDeclFunctionTable: { | 164 case kDeclFunctionTable: { |
165 // An indirect function table requires functions first. | 165 // An indirect function table requires functions first. |
166 CheckForPreviousSection(sections, kDeclFunctions, true); | 166 CheckForPreviousSection(sections, kDeclFunctions, true); |
167 int length; | 167 int length; |
168 uint32_t function_table_count = u32v(&length, "function table count"); | 168 uint32_t function_table_count = u32v(&length, "function table count"); |
169 module->function_table->reserve(SafeReserve(function_table_count)); | 169 module->function_table->reserve(SafeReserve(function_table_count)); |
170 // Decode function table. | 170 // Decode function table. |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 "expected %d bytes for function body, fell off end", size); | 338 "expected %d bytes for function body, fell off end", size); |
339 } | 339 } |
340 function->code_start_offset = static_cast<uint32_t>(pc_ - start_); | 340 function->code_start_offset = static_cast<uint32_t>(pc_ - start_); |
341 function->code_end_offset = function->code_start_offset + size; | 341 function->code_end_offset = function->code_start_offset + size; |
342 TRACE(" +%d %-20s: (%d bytes)\n", static_cast<int>(pc_ - start_), | 342 TRACE(" +%d %-20s: (%d bytes)\n", static_cast<int>(pc_ - start_), |
343 "function body", size); | 343 "function body", size); |
344 pc_ += size; | 344 pc_ += size; |
345 } | 345 } |
346 } | 346 } |
347 | 347 |
| 348 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { |
| 349 if (offset > limit) return false; |
| 350 if ((offset + size) < offset) return false; // overflow |
| 351 return (offset + size) <= limit; |
| 352 } |
| 353 |
348 // Decodes a single data segment entry inside a module starting at {pc_}. | 354 // Decodes a single data segment entry inside a module starting at {pc_}. |
349 void DecodeDataSegmentInModule(WasmDataSegment* segment) { | 355 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { |
350 segment->dest_addr = | 356 segment->dest_addr = u32("destination"); |
351 u32("destination"); // TODO(titzer): check it's within the memory size. | |
352 segment->source_offset = offset("source offset"); | 357 segment->source_offset = offset("source offset"); |
353 segment->source_size = | 358 segment->source_size = u32("source size"); |
354 u32("source size"); // TODO(titzer): check the size is reasonable. | |
355 segment->init = u8("init"); | 359 segment->init = u8("init"); |
| 360 |
| 361 // Validate the data is in the module. |
| 362 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); |
| 363 if (!IsWithinLimit(module_limit, segment->source_offset, |
| 364 segment->source_size)) { |
| 365 error(pc_ - sizeof(uint32_t), "segment out of bounds of module"); |
| 366 } |
| 367 |
| 368 // Validate that the segment will fit into the (minimum) memory. |
| 369 uint32_t memory_limit = |
| 370 1 << (module ? module->min_mem_size_log2 : WasmModule::kMaxMemSize); |
| 371 if (!IsWithinLimit(memory_limit, segment->dest_addr, |
| 372 segment->source_size)) { |
| 373 error(pc_ - sizeof(uint32_t), "segment out of bounds of memory"); |
| 374 } |
356 } | 375 } |
357 | 376 |
358 // Verifies the body (code) of a given function. | 377 // Verifies the body (code) of a given function. |
359 void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv, | 378 void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv, |
360 WasmFunction* function) { | 379 WasmFunction* function) { |
361 if (FLAG_trace_wasm_decode_time) { | 380 if (FLAG_trace_wasm_decode_time) { |
362 // TODO(titzer): clean me up a bit. | 381 // TODO(titzer): clean me up a bit. |
363 OFStream os(stdout); | 382 OFStream os(stdout); |
364 os << "Verifying WASM function:"; | 383 os << "Verifying WASM function:"; |
365 if (function->name_offset > 0) { | 384 if (function->name_offset > 0) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 if (function_start > function_end) return FunctionError("start > end"); | 557 if (function_start > function_end) return FunctionError("start > end"); |
539 if (size > kMaxFunctionSize) | 558 if (size > kMaxFunctionSize) |
540 return FunctionError("size > maximum function size"); | 559 return FunctionError("size > maximum function size"); |
541 WasmFunction* function = new WasmFunction(); | 560 WasmFunction* function = new WasmFunction(); |
542 ModuleDecoder decoder(zone, function_start, function_end, false); | 561 ModuleDecoder decoder(zone, function_start, function_end, false); |
543 return decoder.DecodeSingleFunction(module_env, function); | 562 return decoder.DecodeSingleFunction(module_env, function); |
544 } | 563 } |
545 } // namespace wasm | 564 } // namespace wasm |
546 } // namespace internal | 565 } // namespace internal |
547 } // namespace v8 | 566 } // namespace v8 |
OLD | NEW |