diff options
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | binparse/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | binparse/parse.cpp | 8 | ||||
| -rw-r--r-- | emulate/emulator.cpp | 12 | ||||
| -rw-r--r-- | le/le_object_page_table.cpp | 4 | ||||
| -rw-r--r-- | le/le_pages.cpp | 4 | ||||
| -rw-r--r-- | le/le_parse_util.cpp | 75 | ||||
| -rw-r--r-- | le/le_parse_util.hpp | 4 | ||||
| -rw-r--r-- | le/le_resource_table.cpp | 4 |
9 files changed, 73 insertions, 48 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index eeac074..7406478 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,9 @@ list(APPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules) project(openwar) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + include(sanitizers) add_subdirectory(fusion-utils) @@ -13,3 +16,4 @@ add_subdirectory(mz) add_subdirectory(le) add_subdirectory(disasm) add_subdirectory(emulate) +add_subdirectory(run) diff --git a/binparse/CMakeLists.txt b/binparse/CMakeLists.txt index e436331..6c396e3 100644 --- a/binparse/CMakeLists.txt +++ b/binparse/CMakeLists.txt @@ -11,10 +11,6 @@ target_include_directories(binparse INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} ) -target_compile_options(binparse - PUBLIC "-std=c++14" -) - target_link_libraries(binparse PRIVATE fusion-utils -)
\ No newline at end of file +) diff --git a/binparse/parse.cpp b/binparse/parse.cpp index de0f04d..6887f43 100644 --- a/binparse/parse.cpp +++ b/binparse/parse.cpp @@ -1,12 +1,14 @@ #include "parse.hpp" +#include <istream> + namespace binparse { UnexpectedEOS::UnexpectedEOS() : std::runtime_error("Unexpected end of stream.") {} -UnexpectedEOS::UnexpectedEOS(std::__cxx11::string location) +UnexpectedEOS::UnexpectedEOS(std::string location) : std::runtime_error("Unexpected end of stream after " + location) {} @@ -80,7 +82,7 @@ Offset16 parse<Offset16>(std::istream& is, std::string name) { } template<> -Value24 parse<Value24>(std::istream& is, std::__cxx11::string name) +Value24 parse<Value24>(std::istream& is, std::string name) { return Value24(parse<std::array<uint8_t, 3>>(is, name)); } @@ -147,4 +149,4 @@ void dump_bytes(std::istream& is, std::vector<uint8_t>& buffer, std::string name } } -}
\ No newline at end of file +} diff --git a/emulate/emulator.cpp b/emulate/emulator.cpp index d30081e..e767446 100644 --- a/emulate/emulator.cpp +++ b/emulate/emulator.cpp @@ -435,8 +435,8 @@ void Emulator::handle_I_PUSH(_DInst inst) { switch(inst.ops[0].size) { case 8: { - auto value = static_cast<uint8_t>(boost::apply_visitor(return_visitor{}, register_getters.at(inst.ops[0].index)())); - auto stack_offset = static_cast<uint8_t>(boost::apply_visitor(return_visitor{}, register_getters.at(R_ESP)())); + auto value = static_cast<uint8_t>(boost::apply_visitor(return_visitor(), register_getters.at(inst.ops[0].index)())); + auto stack_offset = static_cast<uint8_t>(boost::apply_visitor(return_visitor(), register_getters.at(R_ESP)())); uint8_t& stack_var = *reinterpret_cast<uint8_t*>(&memory[stack_offset]); stack_var = value; @@ -444,8 +444,8 @@ void Emulator::handle_I_PUSH(_DInst inst) break; } case 16: { - auto value = static_cast<uint16_t>(boost::apply_visitor(return_visitor{}, register_getters.at(inst.ops[0].index)())); - auto stack_offset = static_cast<uint16_t>(boost::apply_visitor(return_visitor{}, register_getters.at(R_ESP)())); + auto value = static_cast<uint16_t>(boost::apply_visitor(return_visitor(), register_getters.at(inst.ops[0].index)())); + auto stack_offset = static_cast<uint16_t>(boost::apply_visitor(return_visitor(), register_getters.at(R_ESP)())); uint16_t& stack_var = *reinterpret_cast<uint16_t*>(&memory[stack_offset]); stack_var = value; @@ -453,8 +453,8 @@ void Emulator::handle_I_PUSH(_DInst inst) break; } case 32: { - auto value = static_cast<uint32_t>(boost::apply_visitor(return_visitor{}, register_getters.at(inst.ops[0].index)())); - auto stack_offset = static_cast<uint32_t>(boost::apply_visitor(return_visitor{}, register_getters.at(R_ESP)())); + auto value = static_cast<uint32_t>(boost::apply_visitor(return_visitor(), register_getters.at(inst.ops[0].index)())); + auto stack_offset = static_cast<uint32_t>(boost::apply_visitor(return_visitor(), register_getters.at(R_ESP)())); uint32_t& stack_var = *reinterpret_cast<uint32_t*>(&memory[stack_offset]); stack_var = value; diff --git a/le/le_object_page_table.cpp b/le/le_object_page_table.cpp index 9843689..f2acc5e 100644 --- a/le/le_object_page_table.cpp +++ b/le/le_object_page_table.cpp @@ -5,6 +5,8 @@ #include <boost/fusion/adapted/struct.hpp> +#include <istream> + BOOST_FUSION_ADAPT_STRUCT( le::ObjectPageTable::Entry, (binparse::Value16, high) @@ -43,4 +45,4 @@ std::ostream&operator<<(std::ostream& os, const ObjectPageTable& table) return binparse::operator<<(os, table.entries); } -}
\ No newline at end of file +} diff --git a/le/le_pages.cpp b/le/le_pages.cpp index ed8de86..627bc25 100644 --- a/le/le_pages.cpp +++ b/le/le_pages.cpp @@ -4,6 +4,8 @@ #include <algorithm> +#include <istream> + namespace le { Pages parse_pages(std::istream& is, binparse::Offset32 offset, binparse::Value32 nr_pages, binparse::Value32 page_size) @@ -30,4 +32,4 @@ std::ostream&operator<<(std::ostream& os, const Pages& table) return binparse::operator<<(os, table.map); } -}
\ No newline at end of file +} diff --git a/le/le_parse_util.cpp b/le/le_parse_util.cpp index ab2d70d..003c953 100644 --- a/le/le_parse_util.cpp +++ b/le/le_parse_util.cpp @@ -1,5 +1,7 @@ #include "le_parse_util.hpp" +#include <boost/assert.hpp> + #include "parse.hpp" std::vector<uint8_t> read_file_part(std::istream& is, std::streamsize offset, size_t length) { @@ -32,7 +34,7 @@ le::File parse_file(std::istream& is) return file; } -void relocate(std::vector<le::FixupRecordTable::Entry> fixups, std::vector<uint8_t>& binary, binparse::Value32 page_nr, le::File const& file) { +void relocate(std::vector<le::FixupRecordTable::Entry> fixups, uint8_t* binary, binparse::Value32 page_nr, le::File const& file) { binparse::Offset32 page_offset; for(auto&& object : file.object_table.entries) { if(page_nr >= object.second.page_table_index && page_nr < object.second.page_table_index + object.second.nr_page_table_entries) { @@ -59,41 +61,54 @@ void relocate(std::vector<le::FixupRecordTable::Entry> fixups, std::vector<uint8 } dest_offset += file.object_table.entries.at(target_object).reloc_base_address; for(int i = 0; i < 4; ++i) { - uint8_t& byte = *(binary.data() + binary_offset + i); + uint8_t& byte = *(binary + binary_offset + i); byte = ((dest_offset >> (i * 8)) & 255); } } } -std::vector<uint8_t> load_binary(le::File file) +size_t determine_binary_size(le::File const& file) { + size_t binary_size = 0; + + for(auto&& object : file.object_table.entries) { + auto furthest_object_point = object.second.reloc_base_address + (object.second.nr_page_table_entries * file.le_header.page_size); + if (furthest_object_point > binary_size) { + binary_size = furthest_object_point; + } + } + + return binary_size; +} + +static void load_binary_into(le::File const& file, uint8_t* buffer, size_t buffer_size) { + for(auto&& entry : file.object_table.entries) { + auto&& object = entry.second; + auto index = object.page_table_index; + for(binparse::Value32 i = index ; i < index + object.nr_page_table_entries; ++i) { + auto page = file.pages.map.at(i); + + binparse::Offset32 dest_offset = binparse::Offset32(object.reloc_base_address + (i-index) * file.le_header.page_size); + + BOOST_ASSERT_MSG(dest_offset < buffer_size, "buffer too small for binary loading"); + std::copy(page.begin(), page.end(), buffer + dest_offset); + } + } + + for(auto&& entry : file.fixup_record_table.entries) { + auto&& relocation = entry.second; + relocate(relocation, buffer, entry.first, file); + } +} + +std::vector<uint8_t> load_binary(le::File const& file) { - size_t binary_size = 0; - - for(auto&& object : file.object_table.entries) { - auto furthest_object_point = object.second.reloc_base_address + (object.second.nr_page_table_entries * file.le_header.page_size); - if (furthest_object_point > binary_size) { - binary_size = furthest_object_point; - } - } - + size_t binary_size = determine_binary_size(file); std::vector<uint8_t> binary(binary_size, 0x90); - - for(auto&& entry : file.object_table.entries) { - auto&& object = entry.second; - auto index = object.page_table_index; - for(binparse::Value32 i = index ; i < index + object.nr_page_table_entries; ++i) { - auto page = file.pages.map[i]; - - binparse::Offset32 dest_offset = binparse::Offset32(object.reloc_base_address + (i-index) * file.le_header.page_size); - - std::copy(page.begin(), page.end(), binary.data() + dest_offset); - } - } - - for(auto&& entry : file.fixup_record_table.entries) { - auto&& relocation = entry.second; - relocate(relocation, binary, entry.first, file); - } - + + load_binary_into(file, binary.data(), binary.size()); return binary; } + +void load_binary(le::File const& file, uint8_t* buffer, size_t buffer_size) { + load_binary_into(file, buffer, buffer_size); +} diff --git a/le/le_parse_util.hpp b/le/le_parse_util.hpp index 77bcaf1..aea5e6e 100644 --- a/le/le_parse_util.hpp +++ b/le/le_parse_util.hpp @@ -11,4 +11,6 @@ std::vector<uint8_t> read_file_part(std::istream& is, std::streamsize offset, si std::vector<uint8_t> read_object(std::istream& is, le::File file, binparse::Value32 object_id); std::vector<uint8_t> relocate(le::File& file, std::vector<uint8_t> page, size_t index); -std::vector<uint8_t> load_binary(le::File file);
\ No newline at end of file +size_t determine_binary_size(le::File const& file); +std::vector<uint8_t> load_binary(le::File const& file); +void load_binary(le::File const& file, uint8_t* buffer, size_t buffer_size); diff --git a/le/le_resource_table.cpp b/le/le_resource_table.cpp index 8b69733..8a06770 100644 --- a/le/le_resource_table.cpp +++ b/le/le_resource_table.cpp @@ -5,6 +5,8 @@ #include <boost/fusion/adapted/struct.hpp> +#include <istream> + BOOST_FUSION_ADAPT_STRUCT( le::ResourceTable::Entry, (binparse::Value16, type_id) @@ -49,4 +51,4 @@ std::ostream&operator<<(std::ostream& os, const ResourceTable& table) return binparse::operator<<(os, table.entries); } -}
\ No newline at end of file +} |
