RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
mzexe.h
1#ifndef MZEXE_H
2#define MZEXE_H
3
4#include <iomanip>
5#include <set>
6#include <string>
7#include <vector>
8#include "../common.h"
9#include "../linker/format.h"
10#include "../linker/module.h"
11#include "../linker/options.h"
12#include "../linker/reader.h"
13#include "../linker/section.h"
14#include "../linker/segment.h"
15#include "../linker/segment_manager.h"
16#include "../linker/writer.h"
17#include "../dumper/dumper.h"
18
19namespace Microsoft
20{
35 class MZFormat : public virtual Linker::SegmentManager
36 {
37 public:
38 /* * * General members * * */
39
50
52 char signature[2] = { 'M', 'Z' }; /* TODO: make parameter */
53
55 uint16_t last_block_size = 0;
57 uint16_t file_size_blocks = 0; /* TODO: consider making file size a parameter */
58
59 offset_t ImageSize() const override;
60
62 uint16_t relocation_count = 0;
64 uint16_t header_size_paras = 0; /* TODO: make header size a parameter */
66 uint16_t min_extra_paras = 0;
68 uint16_t max_extra_paras = 0;
70 uint16_t ss = 0;
72 uint16_t sp = 0;
74 uint16_t checksum = 0; /* TODO: fill when writing */
76 uint16_t ip = 0;
78 uint16_t cs = 0;
80 uint16_t relocation_offset = 0; /* TODO: make parameter */
81
83 uint16_t overlay_number = 0;
85 uint16_t data_segment = 0;
86
93 {
95 uint16_t segment;
97 uint16_t offset;
98
99 Relocation(uint16_t segment, uint16_t offset)
101 {
102 }
103
104 static Relocation FromLinear(uint32_t address);
105
106 uint32_t GetOffset() const;
107
108 bool operator ==(const Relocation& other) const;
109
110 bool operator <(const Relocation& other) const;
111 };
112
114 std::vector<Relocation> relocations;
115
117 struct PIF
118 {
119 static constexpr uint32_t MAGIC_BEGIN = 0x0013EDC1;
120 static constexpr uint32_t MAGIC_END = 0xEDC10013;
121 static constexpr size_t SIZE = 19;
122
123 /* TODO: requires testing */
124 uint16_t maximum_extra_paragraphs;
125 uint16_t minimum_extra_paragraphs;
126 uint8_t flags;
127 uint8_t lowest_used_interrupt;
128 uint8_t highest_used_interrupt;
129 uint8_t com_port_usage;
130 uint8_t lpt_port_usage;
131 uint8_t screen_usage;
132
133 void SetDefaults();
134
135 void ReadFile(Linker::Reader& rd);
136
137 void WriteFile(Linker::Writer& wr) const;
138
139 void Dump(Dumper::Dumper& dump, offset_t file_offset) const;
140 };
141
143 std::unique_ptr<PIF> pif;
144
146 std::shared_ptr<Linker::Image> image;
147
148 magic_type GetSignature() const;
149
150 void SetSignature(magic_type magic);
151
152 void Clear() override;
153
154 ~MZFormat()
155 {
156 Clear();
157 }
158
159 void SetFileSize(uint32_t size);
160
161 uint32_t GetHeaderSize() const;
162
163 uint32_t GetPifOffset() const;
164
165 void ReadFile(Linker::Reader& rd) override;
166
168 offset_t WriteFile(Linker::Writer& wr) const override;
169
170 void Dump(Dumper::Dumper& dump) const override;
171
172 void CalculateValues() override;
173
174 /* * * Writer members * * */
175
177 {
178 public:
179 Linker::Option<std::optional<offset_t>> header_align{"header_align", "Aligns the end of the header to a specific boundary, must be power of 2"};
180 Linker::Option<std::optional<offset_t>> file_align{"file_align", "Aligns the end of the file to a specific boundary, must be power of 2"};
181
183 {
184 InitializeFields(header_align, file_align);
185 }
186 };
187
204
205 /* filled in automatically */
207 uint16_t extra_paras = 0;
208
210 uint32_t zero_fill = 0;
211
213 uint32_t option_header_align = 0x10;
214
216 uint32_t option_file_align = 1;
217
218 bool FormatSupportsSegmentation() const override;
219
220 bool FormatIs16bit() const override;
221
222 bool FormatIsProtectedMode() const override;
223
224 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
225
226 static std::vector<Linker::OptionDescription<void>> MemoryModelNames;
227
228 std::vector<Linker::OptionDescription<void>> GetMemoryModelNames() override;
229
230 void SetModel(std::string model) override;
231
232 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
233
234 void SetOptions(std::map<std::string, std::string>& options) override;
235
236 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
237
243
244 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
245
249 void Link(Linker::Module& module);
250
251#if 0
255 void LinkLarge(Linker::Module& module);
256#endif
257
258 void ProcessModule(Linker::Module& module) override;
259
260 uint32_t GetDataSize() const;
261
262 void GenerateFile(std::string filename, Linker::Module& module) override;
263
265 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
266 };
267
269 {
270 public:
271 std::string filename;
272 bool valid = true;
273 std::ifstream stream;
274
275 MZSimpleStubWriter(std::string filename = "")
276 : filename(filename)
277 {
278 }
279
280 offset_t size = -1;
281
282 bool OpenAndCheckValidFile();
283
284 offset_t GetStubImageSize();
285
286 void WriteStubImage(std::ostream& out);
287
288 void WriteStubImage(Linker::Writer& wr);
289
291 {
292 if(stream.is_open())
293 {
294 stream.close();
295 }
296 }
297 };
298
300 {
301 public:
302 std::string filename;
303 bool valid = true;
304 std::ifstream stream;
305
306 MZStubWriter(std::string filename = "")
307 : filename(filename)
308 {
309 }
310
311 uint32_t original_file_size = -1;
312 uint32_t stub_file_size = 0;
313 uint16_t stub_reloc_count = 0;
314 uint32_t original_header_size = 0;
315 uint32_t stub_header_size = 0;
316 uint16_t original_reloc_offset = 0;
317 uint16_t stub_reloc_offset = 0;
318
319 bool OpenAndCheckValidFile();
320
321 offset_t GetStubImageSize();
322
323 void WriteStubImage(std::ostream& out);
324
325 void WriteStubImage(Linker::Writer& wr);
326
328 {
329 if(stream.is_open())
330 {
331 stream.close();
332 }
333 }
334 };
335
336}
337
338#endif /* MZEXE_H */
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:586
offset_t WriteFile(Writer &wr) const override=0
Stores data in memory to file.
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
Helper class that contains the options interpreted by the format.
Definition options.h:308
Documents and handles command line options.
Definition options.h:196
virtual std::string GetDefaultExtension(Module &module, std::string filename) const
Appends a default extension to the filename.
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
A helper class to collect sections into segments.
Definition segment_manager.h:32
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
MZ .EXE format for MS-DOS.
Definition mzexe.h:36
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition mzexe.cc:245
void CreateDefaultSegments()
Create the required segments, if they have not already been allocated. The MZ format uses a single se...
Definition mzexe.cc:500
offset_t ImageSize() const override
Retrieves size of stored data.
Definition mzexe.cc:10
uint16_t relocation_offset
Offset to first relocation. Updated by CalculateValues.
Definition mzexe.h:80
uint16_t cs
Initial value for the code segment (CS)
Definition mzexe.h:78
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition mzexe.cc:176
uint16_t min_extra_paras
Minimum required extra memory, in paragraphs.
Definition mzexe.h:66
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition mzexe.cc:461
magic_type
Type of magic number, usually "MZ".
Definition mzexe.h:42
@ MAGIC_DL
HP 100LX/200LX System Manager modules (.exm) use the magic number "DL".
Definition mzexe.h:48
@ MAGIC_ZM
According to some sources such as Ralf Brown's interrupt list, some early excutables started with the...
Definition mzexe.h:46
@ MAGIC_MZ
The most common magic number "MZ".
Definition mzexe.h:44
void OnNewSegment(std::shared_ptr< Linker::Segment > segment) override
Callback function when allocating a new segment When the linker script runs, it creates segments cons...
Definition mzexe.cc:480
void Link(Linker::Module &module)
Link application according to script or memory model.
Definition mzexe.cc:584
uint16_t checksum
Checksum.
Definition mzexe.h:74
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition mzexe.cc:721
uint16_t last_block_size
Size of last 512 byte block, 0 if full. Set by CalculateValues.
Definition mzexe.h:55
bool FormatSupportsSegmentation() const override
Whether the format supports multiple segments.
Definition mzexe.cc:386
uint16_t extra_paras
Required maximum extra paragraphs after bss.
Definition mzexe.h:207
uint32_t option_file_align
User provided alignment value for file align.
Definition mzexe.h:216
uint16_t header_size_paras
Size of MZ header. Updated by CalculateValues.
Definition mzexe.h:64
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition mzexe.cc:334
uint16_t file_size_blocks
Size of MZ image in 512 blocks, rounded up. Set by CalculateValues.
Definition mzexe.h:57
void SetModel(std::string model) override
Sets the way memory is organized, typically modifying a built-in script.
Definition mzexe.cc:432
std::vector< Linker::OptionDescription< void > > GetMemoryModelNames() override
Returns a list of the supported memory models, used for documentation.
Definition mzexe.cc:427
uint32_t zero_fill
Total size of bss and stack.
Definition mzexe.h:210
bool FormatIsProtectedMode() const override
Whether the format is in protected mode or not (x86 only)
Definition mzexe.cc:396
uint16_t relocation_count
Number of relocations. Updated by CalculateValues.
Definition mzexe.h:62
void Clear() override
Resets all fields to their default values, deallocate memory.
Definition mzexe.cc:150
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition mzexe.cc:282
uint16_t data_segment
Starting paragraph of program data, only required for .exm files.
Definition mzexe.h:85
memory_model_t
Represents the memory model of the running executable, which is the way in which the segments are set...
Definition mzexe.h:190
@ MODEL_LARGE
Large model, every section is a separate segment.
Definition mzexe.h:200
@ MODEL_SMALL
Small model, separate code and data segments.
Definition mzexe.h:196
@ MODEL_DEFAULT
Default model, same as small.
Definition mzexe.h:192
@ MODEL_TINY
Tiny model, code and data segment are the same.
Definition mzexe.h:194
@ MODEL_COMPACT
Compact model, separate code and multiple data segments.
Definition mzexe.h:198
uint16_t ip
Entry point initial value for IP.
Definition mzexe.h:76
memory_model_t memory_model
Memory model of generated executable.
Definition mzexe.h:203
uint16_t sp
Initial value for the stack (SP)
Definition mzexe.h:72
char signature[2]
The magic number at the start of the executable file, usually "MZ".
Definition mzexe.h:52
std::vector< Relocation > relocations
Address relocation offsets to paragraph fixups.
Definition mzexe.h:114
uint32_t option_header_align
User provided alignment value for header size.
Definition mzexe.h:213
bool FormatIs16bit() const override
Whether the format is 16-bit or not.
Definition mzexe.cc:391
uint16_t ss
Initial value for the stack segment (SS)
Definition mzexe.h:70
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition mzexe.cc:731
std::shared_ptr< Linker::Image > image
The program image, placed after the MZ header.
Definition mzexe.h:146
uint16_t overlay_number
Overlay number, should be 0 for main programs, not used for .exm files.
Definition mzexe.h:83
uint16_t max_extra_paras
Maximum required extra memory, in paragraphs. Set by CalculateValues using extra_paras.
Definition mzexe.h:68
std::unique_ptr< PIF > pif
Concurrent DOS program information entry, allocated only if present.
Definition mzexe.h:143
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition mzexe.cc:625
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition mzexe.cc:466
Definition mzexe.h:269
Definition mzexe.h:300
Concurrent DOS embedded program information, produced by PIFED.
Definition mzexe.h:118
Represents a relocation entry in the header, as a pair of 16-bit words.
Definition mzexe.h:93
uint16_t segment
Segment of relocation.
Definition mzexe.h:95
uint16_t offset
Offset of relocation within segment.
Definition mzexe.h:97