Showing the changes to src/vm/module_reader.cpp (1 of 31 files). Show all
Unified · Split
| @@ -18,9 +18,33 @@ · 17 unmodified lines | |||
| 18 | #include <module_reader.h> | 18 | #include <module_reader.h> |
| 19 | #include "buffered_reader.h" | 19 | #include "buffered_reader.h" |
| 20 | 20 | ||
| 21 | using namespace disvm; | 21 | using disvm::opcode_t; |
| 22 | using namespace disvm::runtime; | 22 | |
| 23 | using namespace disvm::format; | 23 | using disvm::format::operand_t; |
| 24 | |||
| 25 | using disvm::runtime::addr_code_t; | ||
| 26 | using disvm::runtime::address_mode_t; | ||
| 27 | using disvm::runtime::address_mode_middle_t; | ||
| 28 | using disvm::runtime::big_t; | ||
| 29 | using disvm::runtime::byte_t; | ||
| 30 | using disvm::runtime::word_t; | ||
| 31 | using disvm::runtime::real_t; | ||
| 32 | using disvm::runtime::pointer_t; | ||
| 33 | using disvm::runtime::runtime_flags_t; | ||
| 34 | using disvm::runtime::type_descriptor_t; | ||
| 35 | using disvm::runtime::vm_module_t; | ||
| 36 | using disvm::runtime::vm_alloc_t; | ||
| 37 | using disvm::runtime::vm_array_t; | ||
| 38 | using disvm::runtime::vm_string_t; | ||
| 39 | using disvm::runtime::vm_pc_t; | ||
| 40 | using disvm::runtime::import_function_t; | ||
| 41 | using disvm::runtime::export_function_t; | ||
| 42 | using disvm::runtime::import_vm_module_t; | ||
| 43 | using disvm::runtime::handler_entry_t; | ||
| 44 | using disvm::runtime::exception_entry_t; | ||
| 45 | using disvm::runtime::vm_instruction_t; | ||
| 46 | using disvm::runtime::vm_module_exception; | ||
| 47 | using disvm::runtime::module_reader_exception; | ||
| 24 | 48 | ||
| 25 | namespace | 49 | namespace |
| 26 | { | 50 | { |
| @@ -49,7 +73,7 @@ namespace · 22 unmodified lines | |||
| 49 | }; | 73 | }; |
| 50 | 74 | ||
| 51 | // Read the next operand as defined in the Dis VM specification. | 75 | // Read the next operand as defined in the Dis VM specification. |
| 52 | std::tuple<bool, operand_t> read_next_operand(util::buffered_reader_t &reader) | 76 | std::tuple<bool, operand_t> read_next_operand(disvm::util::buffered_reader_t &reader) |
| 53 | { | 77 | { |
| 54 | operand_t result; | 78 | operand_t result; |
| 55 | 79 | ||
| @@ -111,7 +135,7 @@ namespace · 55 unmodified lines | |||
| 111 | } | 135 | } |
| 112 | 136 | ||
| 113 | // Read the next word as defined in the Dis VM specification. | 137 | // Read the next word as defined in the Dis VM specification. |
| 114 | std::tuple<bool, word_t> read_next_word(util::buffered_reader_t &reader) | 138 | std::tuple<bool, word_t> read_next_word(disvm::util::buffered_reader_t &reader) |
| 115 | { | 139 | { |
| 116 | auto result = word_t{}; | 140 | auto result = word_t{}; |
| 117 | 141 | ||
| @@ -141,7 +165,7 @@ namespace · 23 unmodified lines | |||
| 141 | return r; | 165 | return r; |
| 142 | } | 166 | } |
| 143 | 167 | ||
| 144 | byte_t *read_8byte_segments(util::buffered_reader_t &reader, datum_type_t type, uint32_t segment_count, byte_t *dest) | 168 | byte_t *read_8byte_segments(disvm::util::buffered_reader_t &reader, datum_type_t type, uint32_t segment_count, byte_t *dest) |
| 145 | { | 169 | { |
| 146 | assert(type == datum_type_t::value_real64 || type == datum_type_t::value_bit64); | 170 | assert(type == datum_type_t::value_real64 || type == datum_type_t::value_bit64); |
| 147 | 171 | ||
| @@ -190,7 +214,7 @@ namespace · 42 unmodified lines | |||
| 190 | } | 214 | } |
| 191 | 215 | ||
| 192 | // See header format definition in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) | 216 | // See header format definition in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) |
| 193 | void read_header(util::buffered_reader_t &reader, vm_module_t &modobj) | 217 | void read_header(disvm::util::buffered_reader_t &reader, vm_module_t &modobj) |
| 194 | { | 218 | { |
| 195 | auto success = bool{}; | 219 | auto success = bool{}; |
| 196 | auto &header = modobj.header; | 220 | auto &header = modobj.header; |
| @@ -200,7 +224,7 @@ namespace · 3 unmodified lines | |||
| 200 | throw module_reader_exception{ "Failed to read magic number" }; | 224 | throw module_reader_exception{ "Failed to read magic number" }; |
| 201 | 225 | ||
| 202 | // If the object file is signed, read in the signature. | 226 | // If the object file is signed, read in the signature. |
| 203 | if (header.magic_number == magic_number_constants::smagic) | 227 | if (header.magic_number == disvm::format::magic_number_constants::smagic) |
| 204 | { | 228 | { |
| 205 | std::tie(success, header.Signature.length) = read_next_operand(reader); | 229 | std::tie(success, header.Signature.length) = read_next_operand(reader); |
| 206 | if (!success) throw module_reader_exception{ "Failed to read signature length" }; | 230 | if (!success) throw module_reader_exception{ "Failed to read signature length" }; |
| @@ -209,7 +233,7 @@ namespace · 2 unmodified lines | |||
| 209 | const auto bytesRead = reader.get_next_bytes(header.Signature.length, header.Signature.signature.get()); | 233 | const auto bytesRead = reader.get_next_bytes(header.Signature.length, header.Signature.signature.get()); |
| 210 | if (bytesRead != header.Signature.length) throw module_reader_exception{ "Failed to read full signature" }; | 234 | if (bytesRead != header.Signature.length) throw module_reader_exception{ "Failed to read full signature" }; |
| 211 | } | 235 | } |
| 212 | else if (header.magic_number == magic_number_constants::xmagic) | 236 | else if (header.magic_number == disvm::format::magic_number_constants::xmagic) |
| 213 | { | 237 | { |
| 214 | header.Signature.length = word_t{ 0 }; | 238 | header.Signature.length = word_t{ 0 }; |
| 215 | } | 239 | } |
| @@ -248,7 +272,7 @@ namespace · 32 unmodified lines | |||
| 248 | } | 272 | } |
| 249 | 273 | ||
| 250 | // See code section layout in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) | 274 | // See code section layout in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) |
| 251 | void read_code_section(util::buffered_reader_t &reader, vm_module_t &modobj) | 275 | void read_code_section(disvm::util::buffered_reader_t &reader, vm_module_t &modobj) |
| 252 | { | 276 | { |
| 253 | auto success = bool{}; | 277 | auto success = bool{}; |
| 254 | const auto instruction_count = modobj.header.code_size; | 278 | const auto instruction_count = modobj.header.code_size; |
| @@ -320,7 +344,7 @@ namespace · 65 unmodified lines | |||
| 320 | } | 344 | } |
| 321 | 345 | ||
| 322 | // See type section layout in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) | 346 | // See type section layout in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) |
| 323 | void read_type_section(util::buffered_reader_t &reader, vm_module_t &modobj) | 347 | void read_type_section(disvm::util::buffered_reader_t &reader, vm_module_t &modobj) |
| 324 | { | 348 | { |
| 325 | auto success = bool{}; | 349 | auto success = bool{}; |
| 326 | const auto type_count = modobj.header.type_size; | 350 | const auto type_count = modobj.header.type_size; |
| @@ -356,7 +380,7 @@ namespace · 29 unmodified lines | |||
| 356 | } | 380 | } |
| 357 | 381 | ||
| 358 | // See data section layout in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) | 382 | // See data section layout in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) |
| 359 | void read_data_section(util::buffered_reader_t &reader, vm_module_t &modobj) | 383 | void read_data_section(disvm::util::buffered_reader_t &reader, vm_module_t &modobj) |
| 360 | { | 384 | { |
| 361 | if (modobj.header.data_size != 0) | 385 | if (modobj.header.data_size != 0) |
| 362 | { | 386 | { |
| @@ -496,7 +520,7 @@ namespace · 133 unmodified lines | |||
| 496 | } | 520 | } |
| 497 | 521 | ||
| 498 | // See module name in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) | 522 | // See module name in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) |
| 499 | void read_module_name(util::buffered_reader_t &reader, vm_module_t &modobj) | 523 | void read_module_name(disvm::util::buffered_reader_t &reader, vm_module_t &modobj) |
| 500 | { | 524 | { |
| 501 | auto string_buffer = std::vector<uint8_t>{}; | 525 | auto string_buffer = std::vector<uint8_t>{}; |
| 502 | if (!reader.get_bytes_until(0, string_buffer)) | 526 | if (!reader.get_bytes_until(0, string_buffer)) |
| @@ -507,7 +531,7 @@ namespace · 4 unmodified lines | |||
| 507 | } | 531 | } |
| 508 | 532 | ||
| 509 | // See link section in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) | 533 | // See link section in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) |
| 510 | void read_link_section(util::buffered_reader_t &reader, vm_module_t &modobj) | 534 | void read_link_section(disvm::util::buffered_reader_t &reader, vm_module_t &modobj) |
| 511 | { | 535 | { |
| 512 | auto success = bool{}; | 536 | auto success = bool{}; |
| 513 | const auto export_count = modobj.header.export_size; | 537 | const auto export_count = modobj.header.export_size; |
| @@ -543,7 +567,7 @@ namespace · 29 unmodified lines | |||
| 543 | // See import section in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) | 567 | // See import section in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) |
| 544 | // [SPEC] The specification does not seem to match what is observed in an actual module. | 568 | // [SPEC] The specification does not seem to match what is observed in an actual module. |
| 545 | // The function is modeled after the disassembler (dis.b and libinterp/load.c) instead. | 569 | // The function is modeled after the disassembler (dis.b and libinterp/load.c) instead. |
| 546 | void read_import_section(util::buffered_reader_t &reader, vm_module_t &modobj) | 570 | void read_import_section(disvm::util::buffered_reader_t &reader, vm_module_t &modobj) |
| 547 | { | 571 | { |
| 548 | auto success = bool{}; | 572 | auto success = bool{}; |
| 549 | auto module_import_count = operand_t{}; | 573 | auto module_import_count = operand_t{}; |
| @@ -592,7 +616,7 @@ namespace · 42 unmodified lines | |||
| 592 | } | 616 | } |
| 593 | 617 | ||
| 594 | // See handler section in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) | 618 | // See handler section in Dis VM specification (http://www.vitanuova.com/inferno/man/6/dis.html) |
| 595 | void read_handler_section(util::buffered_reader_t &reader, vm_module_t &modobj) | 619 | void read_handler_section(disvm::util::buffered_reader_t &reader, vm_module_t &modobj) |
| 596 | { | 620 | { |
| 597 | auto success = bool{}; | 621 | auto success = bool{}; |
| 598 | auto handler_count = operand_t{}; | 622 | auto handler_count = operand_t{}; |
| @@ -604,7 +628,7 @@ namespace · 5 unmodified lines | |||
| 604 | for (auto c = operand_t{ 0 }; c < handler_count; ++c) | 628 | for (auto c = operand_t{ 0 }; c < handler_count; ++c) |
| 605 | { | 629 | { |
| 606 | // Read in single handler | 630 | // Read in single handler |
| 607 | handler_t handler{}; | 631 | handler_entry_t handler{}; |
| 608 | 632 | ||
| 609 | std::tie(success, handler.exception_offset) = read_next_operand(reader); | 633 | std::tie(success, handler.exception_offset) = read_next_operand(reader); |
| 610 | if (!success) throw module_reader_exception{ "Failed to read exception offset" }; | 634 | if (!success) throw module_reader_exception{ "Failed to read exception offset" }; |
| @@ -643,7 +667,7 @@ namespace · 32 unmodified lines | |||
| 643 | for (auto k = operand_t{ 0 }; k < total_count; ++k) | 667 | for (auto k = operand_t{ 0 }; k < total_count; ++k) |
| 644 | { | 668 | { |
| 645 | // Read in single exception | 669 | // Read in single exception |
| 646 | exception_t except{}; | 670 | exception_entry_t except{}; |
| 647 | 671 | ||
| 648 | auto string_buffer = std::vector<uint8_t>{}; | 672 | auto string_buffer = std::vector<uint8_t>{}; |
| 649 | if (!reader.get_bytes_until(0, string_buffer)) | 673 | if (!reader.get_bytes_until(0, string_buffer)) |
| @@ -658,7 +682,7 @@ namespace · 8 unmodified lines | |||
| 658 | } | 682 | } |
| 659 | 683 | ||
| 660 | // Read in wildcard exception | 684 | // Read in wildcard exception |
| 661 | exception_t wildcard_exception{}; | 685 | exception_entry_t wildcard_exception{}; |
| 662 | std::tie(success, wildcard_exception.pc) = read_next_operand(reader); | 686 | std::tie(success, wildcard_exception.pc) = read_next_operand(reader); |
| 663 | if (!success) throw module_reader_exception{ "Failed to read wildcard exception pc" }; | 687 | if (!success) throw module_reader_exception{ "Failed to read wildcard exception pc" }; |
| 664 | 688 | ||
| @@ -705,19 +729,19 @@ import_vm_module_t::import_vm_module_t(import_vm_module_t &&other) · 40 unmodified lines | |||
| 705 | { | 729 | { |
| 706 | } | 730 | } |
| 707 | 731 | ||
| 708 | exception_t::exception_t(exception_t &&other) | 732 | exception_entry_t::exception_entry_t(exception_entry_t &&other) |
| 709 | : pc{ other.pc } | 733 | : pc{ other.pc } |
| 710 | , name{ std::move(other.name) } | 734 | , name{ std::move(other.name) } |
| 711 | { | 735 | { |
| 712 | } | 736 | } |
| 713 | 737 | ||
| 714 | exception_t::~exception_t() | 738 | exception_entry_t::~exception_entry_t() |
| 715 | { | 739 | { |
| 716 | if (name != nullptr) | 740 | if (name != nullptr) |
| 717 | name->release(); | 741 | name->release(); |
| 718 | } | 742 | } |
| 719 | 743 | ||
| 720 | handler_t::handler_t(handler_t &&other) | 744 | handler_entry_t::handler_entry_t(handler_entry_t &&other) |
| 721 | : exception_offset{ other.exception_offset } | 745 | : exception_offset{ other.exception_offset } |
| 722 | , begin_pc{ other.begin_pc } | 746 | , begin_pc{ other.begin_pc } |
| 723 | , end_pc{ other.end_pc } | 747 | , end_pc{ other.end_pc } |
| @@ -736,15 +760,15 @@ vm_module_t::~vm_module_t() · 12 unmodified lines | |||
| 736 | original_mp->release(); | 760 | original_mp->release(); |
| 737 | } | 761 | } |
| 738 | 762 | ||
| 739 | std::unique_ptr<runtime::vm_module_t> disvm::read_module(std::istream &data) | 763 | std::unique_ptr<vm_module_t> disvm::read_module(std::istream &data) |
| 740 | { | 764 | { |
| 741 | util::buffered_reader_t reader{ data }; | 765 | disvm::util::buffered_reader_t reader{ data }; |
| 742 | 766 | ||
| 743 | auto modobj = std::make_unique<vm_module_t>(); | 767 | auto modobj = std::make_unique<vm_module_t>(); |
| 744 | 768 | ||
| 745 | read_header(reader, *modobj); | 769 | read_header(reader, *modobj); |
| 746 | 770 | ||
| 747 | if (util::has_flag(modobj->header.runtime_flag, runtime_flags_t::has_import_deprecated)) | 771 | if (disvm::util::has_flag(modobj->header.runtime_flag, runtime_flags_t::has_import_deprecated)) |
| 748 | throw module_reader_exception{ "Obsolete module" }; | 772 | throw module_reader_exception{ "Obsolete module" }; |
| 749 | 773 | ||
| 750 | read_code_section(reader, *modobj); | 774 | read_code_section(reader, *modobj); |
| @@ -753,14 +777,14 @@ std::unique_ptr<runtime::vm_module_t> disvm::read_module(std::istream &data) · 2 unmodified lines | |||
| 753 | read_module_name(reader, *modobj); | 777 | read_module_name(reader, *modobj); |
| 754 | read_link_section(reader, *modobj); | 778 | read_link_section(reader, *modobj); |
| 755 | 779 | ||
| 756 | if (util::has_flag(modobj->header.runtime_flag, runtime_flags_t::has_import)) | 780 | if (disvm::util::has_flag(modobj->header.runtime_flag, runtime_flags_t::has_import)) |
| 757 | read_import_section(reader, *modobj); | 781 | read_import_section(reader, *modobj); |
| 758 | 782 | ||
| 759 | if (util::has_flag(modobj->header.runtime_flag, runtime_flags_t::has_handler)) | 783 | if (disvm::util::has_flag(modobj->header.runtime_flag, runtime_flags_t::has_handler)) |
| 760 | read_handler_section(reader, *modobj); | 784 | read_handler_section(reader, *modobj); |
| 761 | 785 | ||
| 762 | // [TODO] Native code generation - runtime_flags_t::must_compile | 786 | // [TODO] Native code generation - runtime_flags_t::must_compile |
| 763 | assert(!util::has_flag(modobj->header.runtime_flag, runtime_flags_t::must_compile)); | 787 | assert(!disvm::util::has_flag(modobj->header.runtime_flag, runtime_flags_t::must_compile)); |
| 764 | 788 | ||
| 765 | return modobj; | 789 | return modobj; |
| 766 | } | 790 | } |