2#include <cppunit/extensions/HelperMacros.h>
3#include <cppunit/TestFixture.h>
5#include "../../src/format/mzexe.h"
8using namespace Microsoft;
16 CPPUNIT_TEST(testCreateEXE);
17 CPPUNIT_TEST(testEXEFileSize);
18 CPPUNIT_TEST(testEXEHeaderValues);
19 CPPUNIT_TEST(testEXERelocations);
20 CPPUNIT_TEST(testEXEHeaderSize);
21 CPPUNIT_TEST_SUITE_END();
24 std::shared_ptr<Section> code;
28 void testEXEFileSize();
29 void testEXEHeaderValues();
30 void testEXERelocations();
31 void testEXEHeaderSize();
34 void load(std::string data);
36 std::string generate_image(
size_t size);
37 void set_image(std::string data);
38 void test_image(std::string data);
40 std::vector<MZFormat::Relocation> generate_relocations(
size_t count);
41 void test_relocations(std::vector<MZFormat::Relocation>& relocations);
47void TestMZFormat::testCreateEXE()
50 std::string image = store();
53 CPPUNIT_ASSERT(exe.GetHeaderSize() >= 0x20);
57void TestMZFormat::testEXEFileSize()
61 data = generate_image(1);
67 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
72 data = generate_image(511 - 0x20);
78 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
81 data = generate_image(512 - 0x20);
87 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
90 data = generate_image(513 - 0x20);
96 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
99 data = generate_image(1023 - 0x20);
105 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
108 data = generate_image(1024 - 0x20);
114 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
117 data = generate_image(1025 - 0x20);
123 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
131 data = generate_image((0xFFFF << 9) - 0x20);
137 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
141void TestMZFormat::testEXEHeaderValues()
145 static const uint16_t min_extra_paras = 0x1234;
146 static const uint16_t max_extra_paras = 0x5678;
147 static const uint16_t cs = 0x0102;
148 static const uint16_t ip = 0x0304;
149 static const uint16_t ss = 0x0506;
150 static const uint16_t sp = 0x0506;
151 static const uint16_t overlay_number = 0xABCD;
155 data = generate_image((cs << 4) + ip + 1 - 0x20);
160 exe.
extra_paras = max_extra_paras - min_extra_paras;
169 CPPUNIT_ASSERT(exe.GetHeaderSize() == 0x20);
174 CPPUNIT_ASSERT_EQUAL(cs, exe.
cs);
175 CPPUNIT_ASSERT_EQUAL(ip, exe.
ip);
176 CPPUNIT_ASSERT_EQUAL(ss, exe.
ss);
177 CPPUNIT_ASSERT_EQUAL(sp, exe.
sp);
180void TestMZFormat::testEXERelocations()
182 std::vector<MZFormat::Relocation> relocations;
185 relocations = generate_relocations(1);
186 data = generate_image(2);
195 test_relocations(relocations);
200 static const uint16_t relocation_offset1 = 0x56;
214 static const uint16_t relocation_offset2 = 0x03;
215 relocations = generate_relocations(1);
226 test_relocations(relocations);
231 relocations = generate_relocations(0x3FF8);
239 static const uint16_t relocation_offset3 = 0xFFFF;
240 relocations = generate_relocations(1);
247void TestMZFormat::testEXEHeaderSize()
249 std::vector<MZFormat::Relocation> relocations;
254 offset_t normal_header_size;
256 data = generate_image(4);
257 relocations = generate_relocations(4);
266 test_relocations(relocations);
269 normal_header_size = exe.GetHeaderSize();
271 offset_t header_align = 0x10;
272 while(header_align <= normal_header_size)
277 data = generate_image(4);
278 relocations = generate_relocations(4);
288 CPPUNIT_ASSERT((exe.GetHeaderSize() & (header_align - 1)) == 0);
289 test_relocations(relocations);
293void TestMZFormat::setUp()
296 code = std::make_shared<Linker::Section>(
".code");
299void TestMZFormat::tearDown()
305std::string TestMZFormat::store()
308 std::ostringstream out;
309 Writer wr(::Undefined, &out);
314void TestMZFormat::load(std::string data)
316 std::istringstream in(data);
317 Reader rd(::Undefined, &in);
318 CPPUNIT_ASSERT_NO_THROW(exe.
ReadFile(rd));
321std::string TestMZFormat::generate_image(
size_t size)
324 std::ostringstream out;
325 for(
size_t i = 0; i < size; i++)
328 size_t inc = (i >> 7) | 1;
329 out.put(
char(inc * off));
334void TestMZFormat::set_image(std::string data)
337 code->Append(data.c_str(), data.size());
338 std::shared_ptr<Linker::Segment> segment = std::make_shared<Linker::Segment>(
".code");
339 segment->Append(code);
346void TestMZFormat::test_image(std::string data)
348 uint32_t file_size = exe.GetHeaderSize() + data.size();
349 CPPUNIT_ASSERT_EQUAL(file_size & 0x1FF, (uint32_t)exe.
last_block_size);
350 CPPUNIT_ASSERT_EQUAL((file_size + 0x1FF) >> 9, (uint32_t)exe.
file_size_blocks);
351 CPPUNIT_ASSERT_EQUAL(file_size, exe.GetFileSize());
352 std::shared_ptr<Linker::Buffer> buffer = std::dynamic_pointer_cast<Linker::Buffer>(exe.
image);
353 assert(buffer !=
nullptr);
354 CPPUNIT_ASSERT_EQUAL(data.size(), buffer->ActualDataSize());
355 for(uint32_t i = 0; i < data.size(); i++)
357 CPPUNIT_ASSERT_EQUAL(data[i] & 0xFF, buffer->GetByte(i) & 0xFF);
361std::vector<MZFormat::Relocation> TestMZFormat::generate_relocations(
size_t count)
363 std::vector<MZFormat::Relocation> relocations;
364 for(
size_t i = 0; i < count; i++)
367 size_t inc = (i >> 7) | 1;
368 off = (off * inc) & 0xFF;
374void TestMZFormat::test_relocations(std::vector<MZFormat::Relocation>& relocations)
377 CPPUNIT_ASSERT_EQUAL(relocations.size(), exe.
relocations.size());
378 for(
size_t i = 0; i < relocations.size(); i++)
380 CPPUNIT_ASSERT(relocations[i] == exe.
relocations[i]);
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15