From 28008a746a31abb7909dd86cb0cd413ac8943b0b Mon Sep 17 00:00:00 2001 From: jmpoep Date: Thu, 7 Dec 2023 16:51:07 +0800 Subject: first commit --- unit-tests/testfile.h | 273 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 unit-tests/testfile.h (limited to 'unit-tests/testfile.h') diff --git a/unit-tests/testfile.h b/unit-tests/testfile.h new file mode 100644 index 0000000..7100d9e --- /dev/null +++ b/unit-tests/testfile.h @@ -0,0 +1,273 @@ +#ifndef TESTFILE_H +#define TESTFILE_H + +template class TestSegmentListT; + +template +class TestSegmentT : public TTestConfig::Segment +{ +public: + explicit TestSegmentT(typename TTestConfig::SegmentList *owner, uint64_t address, uint32_t size, const char *name, uint32_t type) + : TTestConfig::Segment(owner), address_(address), size_(size), name_(name), type_(type), physical_size_(0), physical_offset_(0) {} + virtual uint64_t address() const { return address_; } + virtual uint64_t size() const { return size_; } + virtual uint32_t physical_offset() const { return physical_offset_; } + virtual uint32_t physical_size() const { return physical_size_; } + virtual std::string name() const { return name_; } + virtual uint32_t memory_type() const { return type_; } + void set_physical_size(uint32_t physical_size) { physical_size_ = physical_size; } + void set_physical_offset(uint32_t physical_offset) { physical_offset_ = physical_offset; } + virtual void update_type(uint32_t mt) { } + virtual uint32_t flags() const { return 0; } + virtual void Rebase(uint64_t delta_base) { address_ += delta_base; } + virtual TestSegmentT *Clone(ISectionList *owner) const { return new TestSegmentT(dynamic_cast(owner), address_, size_, name_.c_str(), type_); } +private: + uint64_t address_; + uint32_t size_; + std::string name_; + uint32_t type_; + uint32_t physical_size_; + uint32_t physical_offset_; +}; + +template +class TestSegmentListT : public TTestConfig::SegmentList +{ +public: + explicit TestSegmentListT(typename TTestConfig::Architecture *owner) + : TTestConfig::SegmentList(owner) {} + + TestSegmentT *Add(uint64_t address, uint32_t size, const char *name, uint32_t type) + { + TestSegmentT *seg = new TestSegmentT(this, address, size, name, type); + this->AddObject(seg); + return seg; + } +}; + +template +class TestExportListT : public TTestConfig::ExportList +{ +public: + explicit TestExportListT(typename TTestConfig::Architecture *owner) + : TTestConfig::ExportList(owner) {} + virtual std::string name() const { return ""; } +protected: + virtual typename TTestConfig::Export *Add(uint64_t /*address*/) { return NULL; } +}; + +template +class TestFixupT : public TTestConfig::Fixup +{ +public: + explicit TestFixupT(typename TTestConfig::FixupList *owner); + virtual uint64_t address() const { return 0; } + virtual FixupType type() const { return ftUnknown; } + virtual OperandSize size() const { return osDWord; } + virtual void set_address(uint64_t /*address*/) { return; } + virtual void Rebase(IArchitecture & /*file*/, uint64_t /*delta_base*/) { return; } + virtual TestFixupT *Clone(IFixupList *owner) const { return new TestFixupT(reinterpret_cast(owner)); } +}; + +template +class TestFixupListT : public TTestConfig::FixupList +{ +public: + explicit TestFixupListT() + : TTestConfig::FixupList() {} + virtual IFixup *AddDefault(OperandSize /*cpu_address_size*/, bool /*is_code*/) + { + TestFixupT *fixup = new TestFixupT(this); + this->AddObject(fixup); + return fixup; + } +}; + +template +class TestImportListT : public TTestConfig::ImportList +{ +public: + explicit TestImportListT(typename TTestConfig::Architecture *owner) + : TTestConfig::ImportList(owner) {} +protected: + virtual typename TTestConfig::Import *AddSDK() { return NULL; } +}; + +class TestMapFile : public MapFile +{ +public: + bool ParseEx(const char *file_name, const std::vector &segments, uint64_t time_stamp) + { + bool res = MapFile::Parse(file_name, segments); + set_time_stamp(time_stamp); + return res; + } +}; + +template +class TestArchitectureT : public TTestConfig::Architecture +{ +public: + explicit TestArchitectureT(typename TTestConfig::File *owner, OperandSize cpu_address_size) + : TTestConfig::Architecture(owner, 0, -1), function_list_(NULL), cpu_address_size_(cpu_address_size), virtual_machine_list_(NULL) + { + segment_list_ = new TestSegmentListT(this); + export_list_ = new TestExportListT(this); + fixup_list_ = new TestFixupListT(); + import_list_ = new TestImportListT(this); + time_stamp_ = 1; + + function_list_ = new typename TTestConfig::FunctionList(this); + runtime_function_list_ = new typename TTestConfig::RuntimeFunctionList(); + virtual_machine_list_ = new typename TTestConfig::VirtualMachineList(); + } + + virtual ~TestArchitectureT() + { + delete segment_list_; + delete export_list_; + delete function_list_; + delete fixup_list_; + delete import_list_; + delete virtual_machine_list_; + delete runtime_function_list_; + }; + + virtual std::string format_name() const { return "TEST"; } + virtual std::string name() const { return "TEST"; } + virtual uint32_t type() const { return 0; } + virtual OperandSize cpu_address_size() const { return cpu_address_size_; } + virtual uint64_t entry_point() const { return 0; }; + virtual uint32_t segment_alignment() const { return 0x1000; } + virtual TestSegmentListT *segment_list() const { return segment_list_; } + virtual typename TTestConfig::SectionList *section_list() const { return NULL; } + virtual TestImportListT *import_list() const { return import_list_; } + virtual TestExportListT *export_list() const { return export_list_; } + virtual TestFixupListT *fixup_list() const { return fixup_list_; } + virtual typename TTestConfig::RelocationList *relocation_list() const { return NULL; } + virtual typename TTestConfig::ResourceList *resource_list() const { return NULL; } + virtual IFunctionList *function_list() const { return function_list_; } + virtual IVirtualMachineList *virtual_machine_list() const { return virtual_machine_list_; } + virtual typename TTestConfig::SEHandlerList *seh_handler_list() const { return NULL; } + virtual typename TTestConfig::RuntimeFunctionList *runtime_function_list() const { return runtime_function_list_; } + virtual uint64_t image_base() const { return 0; } + virtual CallingConvention calling_convention() const { return ccStdcall; } + virtual uint64_t time_stamp() const { return time_stamp_; } + + void ReadTestMapFile(const char *file_name) + { + TestMapFile map_file; + std::vector segments; + for (size_t i = 0; i < segment_list()->count(); i++) { + segments.push_back(segment_list()->item(i)->address()); + } + if (std::find(segments.begin(), segments.end(), 0) == segments.end()) + segments.insert(segments.begin(), 0); + if (map_file.ParseEx(file_name, segments, time_stamp())) + this->ReadMapFile(map_file); + this->map_function_list()->ReadFromFile(*this); + }; + virtual void Save(CompileContext & /*c*/) + { + ISection *last_section = segment_list_->item(0); + uint64_t address = AlignValue(last_section->address() + last_section->size(), segment_alignment()); + uint64_t pos = this->size(); + auto *vmp_section = segment_list_->Add(address, -1, ".vmp", mtReadable | mtExecutable); + vmp_section->set_physical_size(-1); + vmp_section->set_physical_offset(static_cast(pos)); + + for (size_t i = 0; i < function_list_->count(); i++) { + function_list_->item(i)->WriteToFile(*this); + } + }; + + bool Prepare(CompileContext &ctx) + { + ISectionList *seg_list = segment_list(); + if (seg_list->count() == 0) + return false; + + ISection *section = seg_list->item(seg_list->count() - 1); + ctx.manager->Add(AlignValue(section->address() + section->size(), segment_alignment()), -1, mtReadable | mtExecutable | mtWritable | mtNotPaged); + + return true; + }; +protected: + virtual bool ReadHeader(uint32_t /*open_mode*/) { return true; } +private: + TestSegmentListT *segment_list_; + TestExportListT *export_list_; + IFunctionList *function_list_; + TestFixupListT *fixup_list_; + TestImportListT *import_list_; + OperandSize cpu_address_size_; + IVirtualMachineList *virtual_machine_list_; + typename TTestConfig::RuntimeFunctionList *runtime_function_list_; + uint64_t time_stamp_; + + // no copy ctr or assignment op + TestArchitectureT(const TestArchitectureT &); + TestArchitectureT &operator =(const TestArchitectureT &); +}; + +template +class TestFileT : public TTestConfig::File +{ +public: + explicit TestFileT(OperandSize cpu_address_size) + : TTestConfig::File(NULL) + { + Add(cpu_address_size); + } + + explicit TestFileT(const typename TTestConfig::File &src, const char *file_name) + : TTestConfig::File(src, file_name) {} + + void OpenFromMemory(const void *buf, uint32_t len) + { + this->CloseStream(); + this->stream_ = new MemoryStream; + /*size_t res = */this->stream_->Write(buf, len); + + ISection *segment = item(0)->segment_list()->item(0); + uint8_t b = 0xcc; + for (size_t i = len; i < segment->physical_size(); i++) { + this->stream_->Write(&b, sizeof(b)); + } + + typename TTestConfig::FileHelper helper; + helper.Parse(*item(0)); + } + + TestArchitectureT *item(size_t index) const { return reinterpret_cast *>(TTestConfig::File::item(index)); } + + IArchitecture *Add(OperandSize cpu_address_size) + { + auto arch = new TestArchitectureT(this, cpu_address_size); + this->AddObject(arch); + return arch; + } + + TestFileT *Clone(const char *file_name) const + { + TestFileT *file = new TestFileT(*this, file_name); + return file; + } + +protected: + virtual OpenStatus ReadHeader(uint32_t /*open_mode*/) { return osSuccess; }; + virtual IFile *runtime() const { return NULL; } +private: + std::string map_file_name_; +}; + +class TestLog: public ILog +{ +public: + virtual void AddMessage(MessageType /*type*/, IObject * /*sender*/, const std::string & /*message*/) { return; } + virtual void StartProgress(const std::string & /*caption*/, unsigned long long /*max*/) { return; } + virtual void StepProgress(unsigned long long /*value*/ = 1ull, bool /*is_project*/ = false) { return; } + virtual void EndProgress() { return; } +}; + +#endif \ No newline at end of file -- cgit v1.2.3