From 22231518b9c2c0b7f73c72a6ca834df659c63c7f Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Wed, 22 Jun 2016 00:15:08 +0200 Subject: Reduces the amount of boilerplate neccesary to parse the binary format. --- binparse/CMakeLists.txt | 7 +- binparse/binparse.cpp | 177 ------------------------------------------- binparse/binparse.hpp | 66 ---------------- binparse/output.cpp | 61 +++++++++++++++ binparse/output.hpp | 57 ++++++++++++++ binparse/parse.cpp | 137 +++++++++++++++++++++++++++++++++ binparse/parse.hpp | 75 ++++++++++++++++++ le/CMakeLists.txt | 2 + le/le_file.cpp | 46 +++-------- le/le_file.hpp | 21 ++--- le/le_header.cpp | 35 ++------- le/le_header.hpp | 14 ++-- le/le_object_table.cpp | 23 ++++++ le/le_object_table.hpp | 17 +++++ le/le_object_table_entry.cpp | 31 ++++++++ le/le_object_table_entry.hpp | 42 ++++++++++ mz/mz_header.cpp | 38 ++-------- mz/mz_header.hpp | 12 +-- 18 files changed, 506 insertions(+), 355 deletions(-) delete mode 100644 binparse/binparse.cpp delete mode 100644 binparse/binparse.hpp create mode 100644 binparse/output.cpp create mode 100644 binparse/output.hpp create mode 100644 binparse/parse.cpp create mode 100644 binparse/parse.hpp create mode 100644 le/le_object_table.cpp create mode 100644 le/le_object_table.hpp create mode 100644 le/le_object_table_entry.cpp create mode 100644 le/le_object_table_entry.hpp diff --git a/binparse/CMakeLists.txt b/binparse/CMakeLists.txt index 00fc246..cbc83b5 100644 --- a/binparse/CMakeLists.txt +++ b/binparse/CMakeLists.txt @@ -1,7 +1,8 @@ add_library(binparse STATIC types.hpp - binparse.hpp binparse.cpp + parse.hpp parse.cpp + output.hpp output.cpp ) target_include_directories(binparse @@ -10,4 +11,8 @@ target_include_directories(binparse 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/binparse.cpp b/binparse/binparse.cpp deleted file mode 100644 index eae6143..0000000 --- a/binparse/binparse.cpp +++ /dev/null @@ -1,177 +0,0 @@ - -#include "binparse.hpp" - -namespace binparse { - -UnexpectedEOS::UnexpectedEOS() -: std::runtime_error("Unexpected end of stream.") -{} - -UnexpectedEOS::UnexpectedEOS(std::__cxx11::string location) -: std::runtime_error("Unexpected end of stream after " + location) -{} - -template<> -uint8_t parse(std::istream& is, std::string name) { - if(!is) { - throw UnexpectedEOS(); - } - char data = 0; - is.read(&data, 1); - if(!is) { - throw UnexpectedEOS(name); - } - - return (unsigned char) data; -} - -template<> -uint16_t parse(std::istream& is, std::string name) { - if(!is) { - throw UnexpectedEOS(); - } - char data[2] = {0, 0}; - is.read(data, 2); - if(!is) { - throw UnexpectedEOS(name); - } - - return ( - ((unsigned char) data[1]) << 8) - | (unsigned char) data[0]; -} - -template<> -uint32_t parse(std::istream& is, std::string name) { - if(!is) { - throw UnexpectedEOS(); - } - char data[4] = {0, 0}; - is.read(data, sizeof(data)); - if(!is) { - throw UnexpectedEOS(name); - } - - return ( - ((unsigned char) data[3]) << 24 - | ((unsigned char) data[2]) << 16 - | ((unsigned char) data[1]) << 8 - | ((unsigned char) data[0]) - ); -} - -template<> -Value8 parse(std::istream& is, std::string name) { - return Value8(parse(is, name)); -} - -template<> -Value16 parse(std::istream& is, std::string name) { - return Value16(parse(is, name)); -} - -template<> -Magic16 parse(std::istream& is, std::string name) { - return Magic16(parse(is, name)); -} - -template<> -Offset16 parse(std::istream& is, std::string name) { - return Offset16(parse(is, name)); -} - -template<> -Value32 parse(std::istream& is, std::string name) { - return Value32(parse(is, name)); -} - -template<> -Offset32 parse(std::istream& is, std::string name) { - return Offset32(parse(is, name)); -} - -template<> -std::array parse>(std::istream& is, std::string name) { - if(!is) { - throw UnexpectedEOS(); - } - - std::array buffer; - is.read(reinterpret_cast(buffer.data()), buffer.size()); - - if(!is) { - throw UnexpectedEOS(name); - } - - return buffer; -} - -template<> -std::array parse>(std::istream& is, std::string name) { - if(!is) { - throw UnexpectedEOS(); - } - - std::array buffer; - is.read(reinterpret_cast(buffer.data()), buffer.size()); - - if(!is) { - throw UnexpectedEOS(name); - } - - return buffer; -} - -void dump_bytes(std::istream& is, std::vector& buffer, std::string name) -{ - if(!is) { - throw UnexpectedEOS(); - } - - is.read(reinterpret_cast(buffer.data()), buffer.size()); - - if(!is) { - throw UnexpectedEOS(name); - } -} - -std::string to_string(Magic16 magic) { - char* c = reinterpret_cast(&magic); - return std::string(c, sizeof(Magic16)); -} - -std::ostream& operator<<(std::ostream& os, uint8_t i) { - return os << (unsigned int) i; -} - -std::ostream& operator<<(std::ostream& os, Value8 v) -{ - return os << std::dec << static_cast(v); -} - -std::ostream& operator<<(std::ostream& os, Offset8 o) -{ - return os << std::hex << std::setw(2) << std::setfill('0') << static_cast(o); -} - -std::ostream& operator<<(std::ostream& os, Magic16 m) { - return os << std::hex << std::setw(4) << std::setfill('0') << static_cast(m) << " (" << to_string(m) << ")"; -} - -std::ostream& operator<<(std::ostream& os, Value16 v) { - return os << std::dec << static_cast(v); -} - -std::ostream& operator<<(std::ostream& os, Offset16 o) { - return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast(o); -} - -std::ostream& operator<<(std::ostream& os, Value32 v) { - return os << std::dec << static_cast(v); -} - -std::ostream& operator<<(std::ostream& os, Offset32 o) { - return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast(o); -} - -} \ No newline at end of file diff --git a/binparse/binparse.hpp b/binparse/binparse.hpp deleted file mode 100644 index e649ce7..0000000 --- a/binparse/binparse.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "types.hpp" - -#include -#include -#include -#include - -namespace binparse { - -struct UnexpectedEOS : public std::runtime_error { - UnexpectedEOS(); - - UnexpectedEOS(std::string location); -}; - -template -T parse(std::istream& is, std::string name); - -template<> -uint8_t parse(std::istream& is, std::string name); - -template<> -uint16_t parse(std::istream& is, std::string name); - -template<> -uint32_t parse(std::istream& is, std::string name); - -template<> -Magic16 parse(std::istream& is, std::string name); - -template<> -Value16 parse(std::istream& is, std::string name); - -template<> -Offset16 parse(std::istream& is, std::string name); - -template<> -Value32 parse(std::istream& is, std::string name); - -template<> -Offset32 parse(std::istream& is, std::string name); - -template<> -std::array parse>(std::istream& is, std::string name); - -template<> -std::array parse>(std::istream& is, std::string name); - -void dump_bytes(std::istream& is, std::vector& buffer, std::string name); - -std::string to_string(Magic16 magic); - -//overload inside this namespace to output unsigned char as value not as characters. -std::ostream& operator<<(std::ostream& os, uint8_t); - -std::ostream& operator<<(std::ostream& os, Value8 v); -std::ostream& operator<<(std::ostream& os, Offset8 o); - -std::ostream& operator<<(std::ostream& os, Magic16 m); -std::ostream& operator<<(std::ostream& os, Value16 v); -std::ostream& operator<<(std::ostream& os, Offset16 o); - -std::ostream& operator<<(std::ostream& os, Value32 v); -std::ostream& operator<<(std::ostream& os, Offset32 o); - -} \ No newline at end of file diff --git a/binparse/output.cpp b/binparse/output.cpp new file mode 100644 index 0000000..78babd8 --- /dev/null +++ b/binparse/output.cpp @@ -0,0 +1,61 @@ +#include "output.hpp" + +#include + +namespace binparse { + +std::string to_string(Magic16 magic) { + char* c = reinterpret_cast(&magic); + return std::string(c, sizeof(Magic16)); +} + +std::ostream& operator<<(std::ostream& os, uint8_t i) { + return os << (unsigned int) i; +} + +std::ostream& operator<<(std::ostream& os, Value8 v) +{ + return os << std::dec << static_cast(v); +} + +std::ostream& operator<<(std::ostream& os, Offset8 o) +{ + return os << std::hex << std::setw(2) << std::setfill('0') << static_cast(o); +} + +std::ostream& operator<<(std::ostream& os, Magic16 m) { + return os << std::hex << std::setw(4) << std::setfill('0') << static_cast(m) << " (" << to_string(m) << ")"; +} + +std::ostream& operator<<(std::ostream& os, Value16 v) { + return os << std::dec << static_cast(v); +} + +std::ostream& operator<<(std::ostream& os, Offset16 o) { + return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast(o); +} + +std::ostream& operator<<(std::ostream& os, Value32 v) { + return os << std::dec << static_cast(v); +} + +std::ostream& operator<<(std::ostream& os, Offset32 o) { + return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast(o); +} + +std::ostream&operator<<(std::ostream& os, std::array a) +{ + return os; +} + +std::ostream&operator<<(std::ostream& os, std::array a) +{ + return os; +} + +std::ostream&operator<<(std::ostream& os, std::vector vec) +{ + return os; +} + +} diff --git a/binparse/output.hpp b/binparse/output.hpp new file mode 100644 index 0000000..b16dd89 --- /dev/null +++ b/binparse/output.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include "types.hpp" + +#include "index_list.hpp" + +#include +#include +#include + +#include +#include + +namespace binparse { + +std::string to_string(Magic16 magic); + +//overload inside this namespace to output unsigned char as value not as characters. +std::ostream& operator<<(std::ostream& os, uint8_t); + +std::ostream& operator<<(std::ostream& os, Value8 v); +std::ostream& operator<<(std::ostream& os, Offset8 o); + +std::ostream& operator<<(std::ostream& os, Magic16 m); +std::ostream& operator<<(std::ostream& os, Value16 v); +std::ostream& operator<<(std::ostream& os, Offset16 o); + +std::ostream& operator<<(std::ostream& os, Value32 v); +std::ostream& operator<<(std::ostream& os, Offset32 o); + +std::ostream& operator<<(std::ostream& os, std::array a); +std::ostream& operator<<(std::ostream& os, std::array a); + +std::ostream& operator<<(std::ostream& os, std::vector vec); + +template ::value>::type* = nullptr> +std::ostream& operator<<(std::ostream&, T const&); + +template +std::ostream& output_impl(std::ostream& os, T const&, indices<>) { + return os; +} + +template +std::ostream& output_impl(std::ostream& os, T const& t, indices) { + os << boost::fusion::extension::struct_member_name::call() << ": " << boost::fusion::at_c(t) << std::endl; + return output_impl(os, t, indices{}); +} + +template ::value>::type*> +std::ostream& operator<<(std::ostream& os, T const& t) { + typedef typename build_indices::value>::type indices; + + return output_impl(os, t, indices{}); +} + +} \ No newline at end of file diff --git a/binparse/parse.cpp b/binparse/parse.cpp new file mode 100644 index 0000000..cf7c0be --- /dev/null +++ b/binparse/parse.cpp @@ -0,0 +1,137 @@ +#include "parse.hpp" + +namespace binparse { + +UnexpectedEOS::UnexpectedEOS() +: std::runtime_error("Unexpected end of stream.") +{} + +UnexpectedEOS::UnexpectedEOS(std::__cxx11::string location) +: std::runtime_error("Unexpected end of stream after " + location) +{} + +template<> +uint8_t parse(std::istream& is, std::string name) { + if(!is) { + throw UnexpectedEOS(); + } + char data = 0; + is.read(&data, 1); + if(!is) { + throw UnexpectedEOS(name); + } + + return (unsigned char) data; +} + +template<> +uint16_t parse(std::istream& is, std::string name) { + if(!is) { + throw UnexpectedEOS(); + } + char data[2] = {0, 0}; + is.read(data, 2); + if(!is) { + throw UnexpectedEOS(name); + } + + return ( + ((unsigned char) data[1]) << 8) + | (unsigned char) data[0]; +} + +template<> +uint32_t parse(std::istream& is, std::string name) { + if(!is) { + throw UnexpectedEOS(); + } + char data[4] = {0, 0}; + is.read(data, sizeof(data)); + if(!is) { + throw UnexpectedEOS(name); + } + + return ( + ((unsigned char) data[3]) << 24 + | ((unsigned char) data[2]) << 16 + | ((unsigned char) data[1]) << 8 + | ((unsigned char) data[0]) + ); +} + +template<> +Value8 parse(std::istream& is, std::string name) { + return Value8(parse(is, name)); +} + +template<> +Value16 parse(std::istream& is, std::string name) { + return Value16(parse(is, name)); +} + +template<> +Magic16 parse(std::istream& is, std::string name) { + return Magic16(parse(is, name)); +} + +template<> +Offset16 parse(std::istream& is, std::string name) { + return Offset16(parse(is, name)); +} + +template<> +Value32 parse(std::istream& is, std::string name) { + return Value32(parse(is, name)); +} + +template<> +Offset32 parse(std::istream& is, std::string name) { + return Offset32(parse(is, name)); +} + +template<> +std::array parse>(std::istream& is, std::string name) { + if(!is) { + throw UnexpectedEOS(); + } + + std::array buffer; + is.read(reinterpret_cast(buffer.data()), buffer.size()); + + if(!is) { + throw UnexpectedEOS(name); + } + + return buffer; +} + +template<> +std::array parse>(std::istream& is, std::string name) { + if(!is) { + throw UnexpectedEOS(); + } + + std::array buffer; + is.read(reinterpret_cast(buffer.data()), buffer.size()); + + if(!is) { + throw UnexpectedEOS(name); + } + + return buffer; +} + +void dump_bytes(std::istream& is, std::vector& buffer, std::string name) +{ + if(!is) { + throw UnexpectedEOS(); + } + + is.read(reinterpret_cast(buffer.data()), buffer.size()); + + if(!is) { + throw UnexpectedEOS(name); + } +} + +} \ No newline at end of file diff --git a/binparse/parse.hpp b/binparse/parse.hpp new file mode 100644 index 0000000..8015ba3 --- /dev/null +++ b/binparse/parse.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include "types.hpp" + +#include "index_list.hpp" + +#include +#include +#include + +#include +#include +#include + +namespace binparse { + +struct UnexpectedEOS : public std::runtime_error { + UnexpectedEOS(); + + UnexpectedEOS(std::string location); +}; + +template::value>::type* = nullptr> +T parse(std::istream& is, std::string name); + +template<> +uint8_t parse(std::istream& is, std::string name); + +template<> +uint16_t parse(std::istream& is, std::string name); + +template<> +uint32_t parse(std::istream& is, std::string name); + +template<> +Magic16 parse(std::istream& is, std::string name); + +template<> +Value16 parse(std::istream& is, std::string name); + +template<> +Offset16 parse(std::istream& is, std::string name); + +template<> +Value32 parse(std::istream& is, std::string name); + +template<> +Offset32 parse(std::istream& is, std::string name); + +template<> +std::array parse>(std::istream& is, std::string name); + +template<> +std::array parse>(std::istream& is, std::string name); + +template ::value>::type* = nullptr> +T parse(std::istream& is); + +template +T parse_impl(std::istream& is, indices) { + + return {parse::type>::type>(is, boost::fusion::extension::struct_member_name::call())...}; + +} + +template ::value>::type*> +T parse(std::istream& is) { + typedef typename build_indices::value>::type indices; + + return parse_impl(is, indices{}); +} + +void dump_bytes(std::istream& is, std::vector& buffer, std::string name); + +} \ No newline at end of file diff --git a/le/CMakeLists.txt b/le/CMakeLists.txt index 5d849b3..c41d730 100644 --- a/le/CMakeLists.txt +++ b/le/CMakeLists.txt @@ -2,6 +2,8 @@ add_library(le STATIC le_header.hpp le_header.cpp le_file.hpp le_file.cpp + le_object_table.hpp le_object_table.cpp + le_object_table_entry.hpp le_object_table_entry.cpp ) target_include_directories(le diff --git a/le/le_file.cpp b/le/le_file.cpp index 3cec50c..b01f13e 100644 --- a/le/le_file.cpp +++ b/le/le_file.cpp @@ -1,6 +1,7 @@ #include "le_file.hpp" -#include "index_list.hpp" +#include "parse.hpp" +#include "output.hpp" #include @@ -8,20 +9,22 @@ typedef std::array A1; typedef std::array A2; BOOST_FUSION_ADAPT_STRUCT( - le::LEFile, - (mz::MZHeader, mz_header) + le::File, + (mz::Header, mz_header) (A1, unused_1) (binparse::Value16, OEM_id) (A2, OEM_info) (binparse::Offset32, le_offset) (std::vector, dos_exe) - (le::LEHeader, le_header) - (std::vector, le_exe) + (le::Header, le_header) + (le::ObjectTable, object_table) ) namespace le { -LEFile parse_file(std::istream& is) { +File parse_file(std::istream& is) { + using binparse::parse; + auto mz_h = mz::parse_header(is); auto unused = parse>(is, "unused_1"); auto OEM_id = parse(is, "OEM_id"); @@ -33,8 +36,6 @@ LEFile parse_file(std::istream& is) { binparse::dump_bytes(is, dos_exe, "dos_exe"); auto le_h = le::parse_header(is); - std::string str(std::istreambuf_iterator(is), {}); - std::vector le_exe(str.begin(), str.end()); return { mz_h, @@ -44,37 +45,12 @@ LEFile parse_file(std::istream& is) { le_offset, dos_exe, le_h, - le_exe }; } -std::ostream& operator<<(std::ostream& os, std::array const& array) { - return os; -} - -std::ostream& operator<<(std::ostream& os, std::array const& array) { - return os; -} - -std::ostream& operator<<(std::ostream& os, std::vector vec) { - return os; -} - -std::ostream& output_impl(std::ostream& os, LEFile const&, indices<>) { - return os; -} - -template -std::ostream& output_impl(std::ostream& os, const LEFile& file, indices) { - os << boost::fusion::extension::struct_member_name::call() << ": " << boost::fusion::at_c(file) << std::endl; - return output_impl(os, file, indices{}); -} - -std::ostream&operator<<(std::ostream& os, LEFile const& file) +std::ostream&operator<<(std::ostream& os, File const& file) { - typedef build_indices::value>::type indices; - - return output_impl(os, file, indices{}); + return binparse::operator<<(os, file); } } \ No newline at end of file diff --git a/le/le_file.hpp b/le/le_file.hpp index 010c49b..56857c5 100644 --- a/le/le_file.hpp +++ b/le/le_file.hpp @@ -1,8 +1,10 @@ #pragma once -#include "binparse.hpp" +#include "types.hpp" + #include "mz_header.hpp" #include "le_header.hpp" +#include "le_object_table.hpp" #include #include @@ -12,22 +14,23 @@ namespace le { -using namespace binparse; +using binparse::Value16; +using binparse::Offset32; -struct LEFile +struct File { - mz::MZHeader mz_header; + mz::Header mz_header; std::array unused_1; Value16 OEM_id; std::array OEM_info; Offset32 le_offset; std::vector dos_exe; - LEHeader le_header; - std::vector le_exe; + Header le_header; + ObjectTable object_table; }; -LEFile parse_file(std::istream& is); +File parse_file(std::istream& is); -std::ostream& operator<<(std::ostream& os, LEFile const& file); +std::ostream& operator<<(std::ostream& os, File const& file); -} +} \ No newline at end of file diff --git a/le/le_header.cpp b/le/le_header.cpp index f28cc4d..b2bd7bd 100644 --- a/le/le_header.cpp +++ b/le/le_header.cpp @@ -1,13 +1,13 @@ #include "le_header.hpp" -#include "index_list.hpp" -#include "binparse.hpp" +#include "parse.hpp" +#include "output.hpp" #include BOOST_FUSION_ADAPT_STRUCT( - le::LEHeader, + le::Header, (binparse::Magic16, magic) (binparse::Value8, B_ord) (binparse::Value8, W_ord) @@ -58,35 +58,16 @@ BOOST_FUSION_ADAPT_STRUCT( namespace le { -template -LEHeader parse_header_impl(std::istream& is, indices) { - - return {parse::type>::type>(is, boost::fusion::extension::struct_member_name::call())...}; +Header parse_header(std::istream& is) { + using binparse::parse; + return parse
(is); } -LEHeader parse_header(std::istream& is) { - - typedef build_indices::value>::type indices; - - return parse_header_impl(is, indices{}); -} -std::ostream& output_impl(std::ostream& os, LEHeader const&, indices<>) { - return os; -} - -template -std::ostream& output_impl(std::ostream& os, const LEHeader& header, indices) { - os << boost::fusion::extension::struct_member_name::call() << ": " << boost::fusion::at_c(header) << std::endl; - return output_impl(os, header, indices{}); -} - -std::ostream& operator<<(std::ostream& os, LEHeader const& header) +std::ostream& operator<<(std::ostream& os, Header const& header) { - typedef build_indices::value>::type indices; - - return output_impl(os, header, indices{}); + return binparse::operator<<(os, header); } } \ No newline at end of file diff --git a/le/le_header.hpp b/le/le_header.hpp index 5d070b6..656b6b4 100644 --- a/le/le_header.hpp +++ b/le/le_header.hpp @@ -5,8 +5,6 @@ namespace le { -using namespace binparse; - struct NotALEFileException : public std::runtime_error { NotALEFileException(); }; @@ -51,7 +49,13 @@ enum class module_flags { per_process_library_temrination = 0x40000000, }; -struct LEHeader { +using binparse::Magic16; +using binparse::Value8; +using binparse::Value16; +using binparse::Value32; +using binparse::Offset32; + +struct Header { Magic16 magic; Value8 B_ord; Value8 W_ord; @@ -100,8 +104,8 @@ struct LEHeader { Value32 heapsize; }; -LEHeader parse_header(std::istream& is); +Header parse_header(std::istream& is); -std::ostream& operator<<(std::ostream& os, LEHeader const& header); +std::ostream& operator<<(std::ostream& os, Header const& header); } \ No newline at end of file diff --git a/le/le_object_table.cpp b/le/le_object_table.cpp new file mode 100644 index 0000000..1155c35 --- /dev/null +++ b/le/le_object_table.cpp @@ -0,0 +1,23 @@ +#include "le_object_table.hpp" + +namespace le { + +ObjectTable parse_object_table(std::istream& is, Offset32 offset, Value32 nr_objects) +{ + is.seekg(0, std::ios::beg); + is.ignore(offset); + + ObjectTable table; + + for(Value32 i = Value32(0); i < nr_objects; i++) { + table.entries.emplace(i+1, parse_object_table_entry(is)); + } + return table; +} + +std::ostream& operator<<(std::ostream& os, const ObjectTable& table) +{ + return os; +} + +} \ No newline at end of file diff --git a/le/le_object_table.hpp b/le/le_object_table.hpp new file mode 100644 index 0000000..8c57c60 --- /dev/null +++ b/le/le_object_table.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "le_object_table_entry.hpp" + +#include + +namespace le { + +struct ObjectTable { + std::map entries; +}; + +ObjectTable parse_object_table(std::istream& is, Offset32 offset, Value32 nr_objects); + +std::ostream& operator<<(std::ostream& os, ObjectTable const& table); + +} \ No newline at end of file diff --git a/le/le_object_table_entry.cpp b/le/le_object_table_entry.cpp new file mode 100644 index 0000000..92810aa --- /dev/null +++ b/le/le_object_table_entry.cpp @@ -0,0 +1,31 @@ +#include "le_object_table_entry.hpp" + +#include "parse.hpp" +#include "output.hpp" + +#include + +BOOST_FUSION_ADAPT_STRUCT( + le::ObjectTableEntry, + (binparse::Value32, virtual_size) + (binparse::Offset32, reloc_base_address) + (binparse::Value32, ojbect_flags) + (binparse::Value32, page_table_index) + (binparse::Value32, nr_page_table_entries) + (binparse::Value32, reserved) +) + +namespace le { + +ObjectTableEntry parse_object_table_entry(std::istream& is) { + using binparse::parse; + + return parse(is); +} + +std::ostream& operator<<(std::ostream& os, const ObjectTableEntry& entry) +{ + return binparse::operator<<(os, entry); +} + +} diff --git a/le/le_object_table_entry.hpp b/le/le_object_table_entry.hpp new file mode 100644 index 0000000..7b97873 --- /dev/null +++ b/le/le_object_table_entry.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "types.hpp" + +namespace le { + +using binparse::Value32; +using binparse::Offset32; + +enum class ObjectFlags { + readable = 0x1, + writable = 0x2, + executable = 0x4, + resource = 0x8, + discardable = 0x10, + shared = 0x20, + has_preload_pages = 0x40, + has_invalid_pages = 0x80, + has_zero_filled_pages = 0x100, + is_resident = 0x200, + is_resident_and_contiguous = 0x300, + is_resident_and_long_lockable = 0x400, + alias_16_16_required = 0x1000, + big_bit_setting = 0x2000, + is_conforming_for_code = 0x4000, + IO_privilege_level = 0x8000, +}; + +struct ObjectTableEntry { + Value32 virtual_size; + Offset32 reloc_base_address; + Value32 ojbect_flags; + Value32 page_table_index; + Value32 nr_page_table_entries; + Value32 reserved; +}; + +ObjectTableEntry parse_object_table_entry(std::istream& is); + +std::ostream& operator<<(std::ostream& os, ObjectTableEntry const& entry); + +} diff --git a/mz/mz_header.cpp b/mz/mz_header.cpp index 02241cf..c33270f 100644 --- a/mz/mz_header.cpp +++ b/mz/mz_header.cpp @@ -1,18 +1,16 @@ #include "mz_header.hpp" -#include "index_list.hpp" - -#include "binparse.hpp" +#include "parse.hpp" +#include "output.hpp" #include -#include #include #include BOOST_FUSION_ADAPT_STRUCT( - mz::MZHeader, + mz::Header, (binparse::Magic16, magic) (binparse::Value16, bytes_in_last_block) (binparse::Value16, blocks_in_file) @@ -35,35 +33,15 @@ NotAMZFileException::NotAMZFileException() : std::runtime_error("This stream does not contain a valid MZ executable") {} -template -MZHeader parse_header_impl(std::istream& is, indices) { - - return {parse::type>::type>(is, boost::fusion::extension::struct_member_name::call())...}; - -} - -MZHeader parse_header(std::istream& is) { - - typedef build_indices::value>::type indices; +Header parse_header(std::istream& is) { + using binparse::parse; - return parse_header_impl(is, indices{}); + return parse
(is); } -std::ostream& output_impl(std::ostream& os, MZHeader const&, indices<>) { - return os; -} - -template -std::ostream& output_impl(std::ostream& os, const MZHeader& header, indices) { - os << boost::fusion::extension::struct_member_name::call() << ": " << boost::fusion::at_c(header) << std::endl; - return output_impl(os, header, indices{}); -} - -std::ostream& operator<<(std::ostream& os, MZHeader const& header) +std::ostream& operator<<(std::ostream& os, Header const& header) { - typedef build_indices::value>::type indices; - - return output_impl(os, header, indices{}); + return binparse::operator<<(os, header); } } diff --git a/mz/mz_header.hpp b/mz/mz_header.hpp index 9bef928..c783335 100644 --- a/mz/mz_header.hpp +++ b/mz/mz_header.hpp @@ -10,8 +10,6 @@ namespace mz { -using namespace binparse; - struct NotAMZFileException : public std::runtime_error { NotAMZFileException(); }; @@ -22,7 +20,11 @@ struct UnexpectedEOS : public std::runtime_error { UnexpectedEOS(std::string location); }; -struct MZHeader { +using binparse::Magic16; +using binparse::Value16; +using binparse::Offset16; + +struct Header { Magic16 magic; Value16 bytes_in_last_block; Value16 blocks_in_file; @@ -39,8 +41,8 @@ struct MZHeader { Value16 overlay_number; }; -MZHeader parse_header(std::istream& is); +Header parse_header(std::istream& is); -std::ostream& operator<<(std::ostream& os, MZHeader const& header); +std::ostream& operator<<(std::ostream& os, Header const& header); } -- cgit v1.2.3-70-g09d2