From cea325b7451c1fb8dd22462ec2e7b5b88ea9b547 Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Sun, 19 Jun 2016 20:23:07 +0200 Subject: Adds an LE executable parser. Adds the binparse library that holds common components for the MZ and LE parsers. --- mz/mz_header.cpp | 103 +++++++++++++++---------------------------------------- 1 file changed, 28 insertions(+), 75 deletions(-) (limited to 'mz/mz_header.cpp') diff --git a/mz/mz_header.cpp b/mz/mz_header.cpp index e6d4461..323c9cd 100644 --- a/mz/mz_header.cpp +++ b/mz/mz_header.cpp @@ -1,110 +1,61 @@ + #include "mz_header.hpp" + #include "index_list.hpp" +#include "binparse.hpp" + #include #include #include #include -UnexpectedEOS::UnexpectedEOS() -: std::runtime_error("Unexpected end of stream.") -{} +BOOST_FUSION_ADAPT_STRUCT( + mz::MZHeader, + (binparse::Magic16, magic) + (binparse::Value16, bytes_in_last_block) + (binparse::Value16, blocks_in_file) + (binparse::Value16, num_relocs) + (binparse::Value16, header_paragraphs) + (binparse::Value16, min_extra_paragraphs) + (binparse::Value16, max_extra_paragraphs) + (binparse::Offset16, ss) + (binparse::Offset16, sp) + (binparse::Value16, checksum) + (binparse::Offset16, ip) + (binparse::Offset16, cs) + (binparse::Offset16, reloc_table_offset) + (binparse::Value16, overlay_number) +) -UnexpectedEOS::UnexpectedEOS(std::__cxx11::string location) -: std::runtime_error("Unexpected end of stream after " + location) -{} +namespace mz { NotAMZFileException::NotAMZFileException() : std::runtime_error("This stream does not contain a valid MZ executable") {} -BOOST_FUSION_ADAPT_STRUCT( - MZHeader, - (Magic, magic) - (uint16_t, bytes_in_last_block) - (uint16_t, blocks_in_file) - (uint16_t, num_relocs) - (uint16_t, header_paragraphs) - (uint16_t, min_extra_paragraphs) - (uint16_t, max_extra_paragraphs) - (uint16_t, ss) - (uint16_t, sp) - (uint16_t, checksum) - (uint16_t, ip) - (uint16_t, cs) - (uint16_t, reloc_table_offset) - (uint16_t, overlay_number) -) - -template -T parse(std::istream& is, std::string name); - -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<> -Magic parse(std::istream& is, std::string name) { - if(!is) { - throw UnexpectedEOS(); - } - char data[2]; - is.read(data, 2); - if(!is) { - throw UnexpectedEOS(name); - } - - return static_cast((data[1] << 8) | data[0]); -} - template -MZHeader parse_mz_file_impl(std::istream& is, indices) { +MZHeader parse_file_impl(std::istream& is, indices) { return {parse::type>::type>(is, boost::fusion::extension::struct_member_name::call())...}; } -MZHeader parse_mz_file(std::istream& is) { +MZHeader parse_file(std::istream& is) { typedef build_indices::value>::type indices; - return parse_mz_file_impl(is, indices{}); + return parse_file_impl(is, indices{}); } std::ostream& output_impl(std::ostream& os, MZHeader const&, indices<>) { return os; } -template -std::ostream& output(std::ostream& os, T rh) { - return os << std::hex << std::setw(sizeof(T) * 2) << std::setfill('0') << rh << std::endl; -} - -std::string to_string(Magic magic) { - char* c = reinterpret_cast(&magic); - return std::string(c, sizeof(Magic)); -} - -template <> -std::ostream& output(std::ostream& os, Magic m) { - return os << std::hex << std::setw(4) << std::setfill('0') << m << " (" << to_string(m) << ")" << std::endl; -} - template std::ostream& output_impl(std::ostream& os, const MZHeader& header, indices) { - os << boost::fusion::extension::struct_member_name::call() << ": "; - output(os, boost::fusion::at_c(header)); + os << boost::fusion::extension::struct_member_name::call() << ": " << boost::fusion::at_c(header) << std::endl; return output_impl(os, header, indices{}); } @@ -114,3 +65,5 @@ std::ostream& operator<<(std::ostream& os, MZHeader const& header) return output_impl(os, header, indices{}); } + +} -- cgit v1.2.3-70-g09d2