RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
pharlap.h
1#ifndef PHARLAP_H
2#define PHARLAP_H
3
4#include "../common.h"
5#include "../dumper/dumper.h"
6#include "../linker/options.h"
7#include "../linker/segment_manager.h"
8#include "mzexe.h"
9
10namespace PharLap
11{
15 class MPFormat : public virtual Linker::SegmentManager
16 {
17 public:
19 {
20 public:
21 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
22 Linker::Option<offset_t> stack{"stack", "Specify the stack size"};
23
25 {
26 InitializeFields(stub, stack);
27 }
28 };
29
30 void ReadFile(Linker::Reader& rd) override;
31
32 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
33
34 bool has_relocations;
35
36 std::shared_ptr<Linker::Contents> image;
37
38 static const uint32_t REL32 = 0x80000000;
40 {
41 struct
42 {
43 uint32_t offset : 31, rel32 : 1;
44 };
45 uint32_t value;
46
47 Relocation(uint32_t offset, unsigned rel32)
48 : offset(offset), rel32(rel32)
49 {
50 }
51
52 explicit Relocation(uint32_t offset)
53 : value(offset)
54 {
55 }
56
57 bool operator ==(const Relocation& other) const;
58
59 bool operator <(const Relocation& other) const;
60 };
61
62 offset_t image_size = 0;
63 std::vector<Relocation> relocations;
64 offset_t header_size = 0;
65 offset_t min_extra_pages = 0;
66 offset_t max_extra_pages = 0;
67 uint32_t esp = 0;
68 uint32_t eip = 0;
69 uint16_t checksum = 0; // TODO
70 offset_t relocation_offset = 0;
71 uint16_t relocation_count = 0;
73 uint32_t stack_size = 0;
74 mutable Microsoft::MZStubWriter stub;
75
76 MPFormat(bool has_relocations = false)
77 : has_relocations(has_relocations)
78 {
79 }
80
81 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
82
83 void SetOptions(std::map<std::string, std::string>& options) override;
84
85 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
86
87 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
88
89 void Link(Linker::Module& module);
90
91 void ProcessModule(Linker::Module& module) override;
92
93 void CalculateValues() override;
94
96 offset_t WriteFile(Linker::Writer& wr) const override;
97 void Dump(Dumper::Dumper& dump) const override;
98
100 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
101 };
102
106 class P3Format : public virtual Linker::SegmentManager
107 {
108 public:
110 {
111 public:
112 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
113 Linker::Option<offset_t> stack{"stack", "Specify the stack size"};
114
116 {
117 InitializeFields(stub, stack);
118 }
119 };
120
121 void ReadFile(Linker::Reader& rd) override;
122
123 bool FormatSupportsSegmentation() const override;
124
125 bool FormatIs16bit() const override;
126
127 bool FormatIsProtectedMode() const override;
128
129#if 0
130 bool FormatSupportsStackSection() const override;
131#endif
132
133 bool is_multisegmented;
134 bool is_32bit;
135
136 uint16_t header_size = 0;
137 uint32_t file_size = 0;
138 uint16_t checksum16 = 0; // TODO
139 uint32_t checksum32 = 0; // TODO
140
141 uint32_t runtime_parameters_offset = 0;
142 uint32_t runtime_parameters_size = 0;
143 uint32_t relocation_table_offset = 0;
144 uint32_t relocation_table_size = 0;
145 uint32_t segment_information_table_offset = 0;
146 uint32_t segment_information_table_size = 0;
147 uint16_t segment_information_table_entry_size = 0;
148 uint32_t load_image_offset = 0;
149 uint32_t load_image_size = 0;
150 uint32_t symbol_table_offset = 0;
151 uint32_t symbol_table_size = 0;
152 uint32_t gdt_address = 0;
153 uint32_t gdt_size = 0;
154 uint32_t ldt_address = 0;
155 uint32_t ldt_size = 0;
156 uint32_t idt_address = 0;
157 uint32_t idt_size = 0;
158 uint32_t tss_address = 0;
159 uint32_t tss_size = 0;
160 uint32_t minimum_extra = 0;
161 uint32_t maximum_extra = 0;
162 uint32_t base_load_offset = 0;
163 uint32_t esp = 0;
164 uint16_t ss = 0;
165 uint32_t eip = 0;
166 uint16_t cs = 0;
167 uint16_t ldtr = 0;
168 uint16_t tr = 0;
169 uint16_t flags = 0;
170 uint32_t memory_requirements = 0;
171 uint32_t stack_size = 0;
172
173 mutable Microsoft::MZStubWriter stub;
174
175 P3Format(bool is_multisegmented = true, bool is_32bit = true)
176 : is_multisegmented(is_multisegmented), is_32bit(is_32bit)
177 {
178 }
179
186 {
187 public:
188 uint32_t address = 0;
189 virtual ~AbstractSegment();
190 virtual uint32_t GetStoredSize() const = 0;
191 virtual uint32_t GetLoadedSize() const = 0;
192 virtual void WriteFile(Linker::Writer& wr) const = 0;
193 };
194
197 {
198 public:
200 std::weak_ptr<AbstractSegment> image = std::weak_ptr<AbstractSegment>();
201
202 enum
203 {
204 TSS16 = 0x00008100,
205 LDT = 0x00008200,
206 TSS32 = 0x00008900,
207 Code16 = 0x00009A00,
208 Code32 = 0x00409A00,
209 Data16 = 0x00009200,
210 Data32 = 0x00409200,
211
212 DESC_X = 0x00000800,
213 DESC_S = 0x00001000,
214 DESC_G = 0x00800000,
215 };
216 uint32_t access = 0;
217
218 // only for segments
219 uint32_t limit = 0;
220 uint32_t base = 0;
221 // only for gates
222 uint32_t offset = 0;
223 uint16_t selector = 0;
224
225 explicit Descriptor() = default;
226
227 static Descriptor FromSegment(uint32_t access, std::weak_ptr<AbstractSegment> image = std::weak_ptr<AbstractSegment>());
228 static Descriptor ReadEntry(Linker::Image& image, offset_t offset);
229
230 bool IsSegment() const;
231 bool IsGate() const;
232
233 void CalculateValues();
234
235 void WriteEntry(Linker::Writer& wr) const;
236
237 void FillEntry(Dumper::Entry& entry) const;
238 };
239
242 {
243 public:
244 std::vector<Descriptor> descriptors;
245
246 uint32_t GetStoredSize() const override;
247
248 uint32_t GetLoadedSize() const override;
249
250 void WriteFile(Linker::Writer& wr) const override;
251
252 void CalculateValues();
253 };
254
257 {
258 public:
259 bool is_32bit;
260
261 uint32_t esp0 = 0, esp1 = 0, esp2 = 0;
262 uint32_t cr3 = 0, eip = 0, eflags = 0, eax = 0, ecx = 0, edx = 0, ebx = 0, esp = 0, ebp = 0, esi = 0, edi = 0;
263 uint16_t ss0 = 0, ss1 = 0, ss2 = 0, es = 0, cs = 0, ss = 0, ds = 0, fs = 0, gs = 0, ldtr = 0, iopb = 0;
264 uint16_t link = 0;
265
266 TaskStateSegment(bool is_32bit = true)
267 : is_32bit(is_32bit)
268 {
269 }
270
271 uint32_t GetStoredSize() const override;
272
273 uint32_t GetLoadedSize() const override;
274
275 void WriteFile(Linker::Writer& wr) const override;
276 void ReadImage(Linker::Image& image, offset_t offset);
277 void FillEntries(Dumper::Region& region) const;
278 };
279
282 {
283 public:
284 uint16_t selector = 0;
285 uint16_t flags = 0;
286 uint32_t base_offset = 0; /* TODO??? */
287 uint32_t zero_fill = 0; /* only used for reading */
288
289 SITEntry(uint16_t selector = 0)
290 : selector(selector)
291 {
292 }
293
294 uint32_t GetStoredSize() const override;
295
296 virtual uint32_t GetZeroSize() const;
297
298 uint32_t GetLoadedSize() const override;
299
300 void WriteSITEntry(Linker::Writer& wr) const;
301
302 void WriteFile(Linker::Writer& wr) const override;
303
304 static std::shared_ptr<SITEntry> ReadSITEntry(Linker::Reader& rd);
305 };
306
312 class Segment : public SITEntry
313 {
314 public:
315 /* Segment members */
316 std::shared_ptr<Linker::Segment> segment;
317
318 uint32_t access;
319
320 Segment(std::shared_ptr<Linker::Segment> segment, uint32_t access, uint16_t selector)
321 : SITEntry(selector), segment(segment), access(access)
322 {
323 }
324
325 uint32_t GetStoredSize() const override;
326
327 uint32_t GetZeroSize() const override;
328
329 void WriteFile(Linker::Writer& wr) const override;
330 };
331
334 {
335 public:
336 uint16_t selector;
337 uint32_t offset;
338
339 Relocation(uint16_t selector, uint32_t offset)
340 : selector(selector), offset(offset)
341 {
342 }
343
344 bool operator ==(const Relocation& other) const;
345
346 bool operator <(const Relocation& other) const;
347
348 void WriteFile(Linker::Writer& wr) const;
349 };
350
352 {
353 public:
354 uint16_t min_realmode_param = 0, max_realmode_param = 0, min_int_buffer_size_kb = 0, max_int_buffer_size_kb = 0, int_stack_count = 0, int_stack_size_kb = 0;
355 uint32_t realmode_area_end = 0;
356 uint16_t call_buffer_size_kb = 0, flags = 0, ring = 0;
357
358 void ReadFile(Linker::Reader& rd);
359
360 void CalculateValues();
361
362 void WriteFile(Linker::Writer& wr) const;
363 };
364
365 // not needed for flat binaries
366 std::vector<std::shared_ptr<AbstractSegment>> segments;
367
368 // not needed for flat binaries
369 std::vector<Relocation> relocations;
370
371 RunTimeParameterBlock runtime_parameters;
372
373 // not needed for multi segment binaries
374 std::shared_ptr<Linker::Image> image;
375
376 // not needed for flat binaries
377 std::shared_ptr<DescriptorTable> gdt = std::make_shared<DescriptorTable>();
378 // not needed for flat binaries
379 std::shared_ptr<DescriptorTable> idt = std::make_shared<DescriptorTable>();
380 // not needed for flat binaries
381 std::shared_ptr<DescriptorTable> ldt = std::make_shared<DescriptorTable>();
382 // not needed for flat binaries
383 std::shared_ptr<TaskStateSegment> tss = std::make_shared<TaskStateSegment>();
384
385 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
386
387 void SetOptions(std::map<std::string, std::string>& options) override;
388
390 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
391
392 void WriteHeader(Linker::Writer& wr) const;
394 offset_t WriteFile(Linker::Writer& wr) const override;
395 void Dump(Dumper::Dumper& dump) const override;
396
397 class Flat;
398 class MultiSegmented;
399 class External;
400 };
401
404 {
405 public:
406 Flat(bool is_32bit = true)
407 : P3Format(false, is_32bit)
408 {
409 }
410
411 std::shared_ptr<Linker::Segment> GetSegment();
412 std::shared_ptr<const Linker::Segment> GetSegment() const;
413
414 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
415
416 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
417
418 void Link(Linker::Module& module);
419
420 void ProcessModule(Linker::Module& module) override;
421
422 void CalculateValues() override;
423
425 offset_t WriteFile(Linker::Writer& wr) const override;
426 };
427
430 {
431 public:
432 MultiSegmented(bool is_32bit = true)
433 : P3Format(true, is_32bit)
434 {
435 }
436
437 std::map<std::shared_ptr<Linker::Segment>, uint16_t> segment_associations;
438 std::shared_ptr<Segment> code;
439 std::shared_ptr<Segment> data;
440
441 void OnNewSegment(std::shared_ptr<Linker::Segment> linker_segment) override;
442
443 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
444
445 void Link(Linker::Module& module);
446
447 void ProcessModule(Linker::Module& module) override;
448
449 void CalculateValues() override;
450
452 offset_t WriteFile(Linker::Writer& wr) const override;
453 };
454}
455
456#endif /* PHARLAP_H */
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:773
A brief record, such as a relocation or imported library.
Definition dumper.h:687
A record that represents a region within the file.
Definition dumper.h:666
offset_t WriteFile(Writer &wr) const override=0
Stores data in memory to file.
Definition image.h:43
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:474
Documents and handles command line options.
Definition options.h:306
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:20
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
Definition mzexe.h:305
Phar Lap "MP" .exp and "MQ" .rex file.
Definition pharlap.h:16
uint32_t stack_size
Stack size requested at the command line.
Definition pharlap.h:73
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition pharlap.cc:243
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition pharlap.cc:10
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition pharlap.cc:195
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition pharlap.cc:62
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 pharlap.cc:75
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition pharlap.cc:289
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition pharlap.cc:67
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition pharlap.cc:207
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition pharlap.cc:120
Represents a section of data in the image.
Definition pharlap.h:186
An array of descriptors, used for GDT, LDT and IDT.
Definition pharlap.h:242
An entry in a GDT, LDT or IDT image.
Definition pharlap.h:197
std::weak_ptr< AbstractSegment > image
Reference to a segment in the file.
Definition pharlap.h:200
Class used for generating flat P3 binaries.
Definition pharlap.h:404
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition pharlap.cc:1471
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition pharlap.cc:1427
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition pharlap.cc:1342
Class used for generating multisegmented P3 binaries.
Definition pharlap.h:430
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition pharlap.cc:1574
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition pharlap.cc:1782
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition pharlap.cc:1704
Definition pharlap.h:110
A relocation entry in the relocation table.
Definition pharlap.h:334
Corresponds to an entry in the Segment Information Table.
Definition pharlap.h:282
A segment that appears in the Segment Information Table.
Definition pharlap.h:313
An Intel x86 task state segment structure, stored in the image.
Definition pharlap.h:257
Phar Lap "P2"/"P3" .exp file.
Definition pharlap.h:107
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition pharlap.cc:568
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition pharlap.cc:307
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition pharlap.cc:560
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition pharlap.cc:634
bool FormatSupportsSegmentation() const override
Whether the format supports multiple segments.
Definition pharlap.cc:490
bool FormatIs16bit() const override
Whether the format is 16-bit or not.
Definition pharlap.cc:495
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition pharlap.cc:555
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition pharlap.cc:627
bool FormatIsProtectedMode() const override
Whether the format is in protected mode or not (x86 only)
Definition pharlap.cc:500
Definition pharlap.h:40