RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
leexe.h
1#ifndef LEEXE_H
2#define LEEXE_H
3
4#include <array>
5#include <vector>
6#include "mzexe.h"
7#include "neexe.h"
8#include "../common.h"
9#include "../dumper/dumper.h"
10#include "../linker/module.h"
11#include "../linker/options.h"
12#include "../linker/segment.h"
13#include "../linker/segment_manager.h"
14#include "../linker/writer.h"
15
16namespace Microsoft
17{
29 class LEFormat : public virtual Linker::SegmentManager, public std::enable_shared_from_this<LEFormat>
30 {
31 public:
32 /* * * General members * * */
33
35 {
44 // /** @brief Attempts to mimic the output of the GNU linker, this is undefined for the LE output */
45 // CompatibleGNU,
46 };
47
50 {
51 uint32_t number;
52 explicit PhysicalPageNumber() : number(0) { }
53 explicit PhysicalPageNumber(uint32_t number) : number(number) { }
54 operator uint32_t() const { return number; }
55 PhysicalPageNumber operator +(int value) const { return PhysicalPageNumber{number + value}; }
56 PhysicalPageNumber operator -(int value) const { return PhysicalPageNumber{number - value}; }
57 PhysicalPageNumber& operator++(int) { number++; return *this; }
58 };
59
61 class Object
62 {
63 public:
64 std::shared_ptr<Linker::Contents> image;
65 enum flag_type
66 {
67 Readable = 0x0001,
68 Writable = 0x0002,
69 Executable = 0x0004,
70 Resource = 0x0008,
71 Discardable = 0x0010,
72 Shared = 0x0020,
73 PreloadPages = 0x0040,
74 InvalidPages = 0x0080,
75 ZeroFilledPages = 0x0100,
76 Resident = 0x0200,
77 ResidentContiguous = 0x0300,
78 ResidentLongLockable = 0x0400,
79 Alias16_16 = 0x1000, /* x86 */
80 BigSegment = 0x2000, /* x86 */
81 Conforming = 0x4000, /* x86 */
82 IOPrivilege = 0x8000, /* x86 */
83 };
84 uint32_t size = 0;
85 uint32_t address = 0;
86 flag_type flags = flag_type(0);
87 uint32_t page_table_index = 0;
88 uint32_t page_entry_count = 0;
89 uint32_t data_pages_offset = 0;
90
91 Object()
92 {
93 }
94
95 Object(std::shared_ptr<Linker::Segment> segment, unsigned flags)
96 : image(segment), flags(flag_type(flags))
97 {
98 }
99 };
100
108 {
109 public:
110 std::shared_ptr<LEFormat> file;
111 std::vector<PhysicalPageNumber> pages;
112
113 PageSet() = delete;
114
115 PageSet(std::shared_ptr<LEFormat> file)
116 : file(file)
117 {
118 }
119
120 offset_t ImageSize() const override;
122 offset_t WriteFile(Linker::Writer& wr, offset_t count, offset_t offset = 0) const override;
123 };
124
132 {
133 public:
134 std::shared_ptr<Linker::Contents> image;
135 offset_t offset = 0;
136 offset_t size = 0;
137
138 SegmentPage(std::shared_ptr<Linker::Contents> image, offset_t offset, offset_t size)
139 : image(image), offset(offset), size(size)
140 {
141 }
142
143 offset_t ImageSize() const override;
145 offset_t WriteFile(Linker::Writer& wr, offset_t count, offset_t offset = 0) const override;
146 std::shared_ptr<const Linker::Image> AsImage() const override;
147 };
148
153 {
154 public:
156 {
157 uint16_t count = 0;
158 std::vector<uint8_t> data;
159 };
160 std::vector<IterationRecord> records;
161
162 offset_t ImageSize() const override;
164 static std::shared_ptr<IteratedPage> ReadFromFile(Linker::Reader& rd, uint16_t size);
165 offset_t WriteFile(Linker::Writer& wr, offset_t count, offset_t offset = 0) const override;
166
170 class View : public Linker::Image
171 {
172 public:
173 IteratedPage& iterated_page;
174 size_t size;
175
176 View(IteratedPage& iterated_page, size_t size)
177 : iterated_page(iterated_page), size(size)
178 {
179 }
180
181 size_t ReadData(size_t bytes, offset_t offset, void * buffer) const override;
182
183 offset_t ImageSize() const override;
185 offset_t WriteFile(Linker::Writer& wr, offset_t count, offset_t offset = 0) const override;
186 };
187 };
188
190 class Page
191 {
192 public:
195 {
196 Preload = 0,
197 Iterated = 1,
198 Invalid = 2,
199 ZeroFilled = 3,
200 Range = 4,
201 Compressed = 5,
202 };
203
210 uint32_t offset = 0;
211
217 uint16_t size = 0;
218
224 uint16_t type = 0;
225
226 page_type GetPageType(const LEFormat& fmt) const;
227
229 uint32_t fixup_offset = 0;
230
233 {
234 public:
235 enum source_type
236 {
237 Offset8 = 0,
238 Selector16 = 2,
239 Pointer32 = 3,
240 Offset16 = 5,
241 Pointer48 = 6,
242 Offset32 = 7,
243 Relative32 = 8,
244
245 SourceTypeMask = 0x0F,
246
247 Alias = 0x10,
248 SourceList = 0x20,
249 };
250 source_type type = source_type(0);
251 enum flag_type
252 {
253 Internal = 0,
254 ImportOrdinal = 1,
255 ImportName = 2,
256 Entry = 3,
257
258 FlagTypeMask = 3,
259
260 Additive = 4,
261 Chained = 8,
262 Target32 = 0x10,
263 Additive32 = 0x20,
264 Module16 = 0x40,
265 Ordinal8 = 0x80,
266 };
267 flag_type flags = flag_type(0);
268 uint16_t module = 0;
269 uint32_t target = 0;
270 uint32_t addition = 0;
271
272 // informational purposes
274 std::string module_name;
276 std::string import_name;
278 uint16_t actual_object = 0;
280 uint32_t actual_offset = 0;
281
282 Relocation()
283 : Writer(::LittleEndian)
284 {
285 }
286
287 Relocation(unsigned type, unsigned flags, uint16_t offset, uint16_t module, uint32_t target = 0, uint32_t addition = 0)
288 : Writer(::LittleEndian), type(source_type(type)), flags(flag_type(flags)), module(module), target(target), addition(addition)
289 {
290 sources.push_back(Chain{offset});
291 }
292
293 static source_type GetType(Linker::Relocation& rel);
294
295 bool IsExternal() const;
296
297 bool IsSelectorOrOffset() const;
298
299 bool ComesBefore() const;
300
301 size_t GetSourceSize() const;
302
305 {
306 uint32_t target = 0;
307 uint16_t source = 0;
308 };
309
316 struct Chain
317 {
319 uint16_t source = 0;
321 uint32_t base_address = 0;
323 std::vector<ChainLink> chains;
324 };
325
327 std::vector<Chain> sources;
328
329 /* do not call this */
330 void DecrementSingleSourceOffset(size_t amount);
331
332 bool IsSelector() const;
333 bool IsSourceList() const;
334 bool IsAdditive() const;
335 size_t GetTargetSize() const;
336 size_t GetAdditiveSize() const;
337 size_t GetModuleSize() const;
338 size_t GetOrdinalSize() const;
339
340 uint16_t GetFirstSource() const;
341
342 void CalculateSizes(compatibility_type compatibility);
343
344 size_t GetSize() const;
345
346 static Relocation ReadFile(Linker::Reader& rd, Page& page);
347 void WriteFile(Linker::Writer& wr) const;
348 };
349 std::map<uint16_t, Relocation> relocations;
350 uint32_t checksum = 0;
351 std::shared_ptr<Linker::Contents> image;
352
353 Page()
354 {
355 }
356
357 static Page LEPage(uint8_t type);
358
359 static Page LXPage(uint32_t offset, uint16_t size, uint8_t type);
360
361 protected:
362 void FillDumpRegion(Dumper::Dumper& dump, Dumper::Region& page_region, const LEFormat& fmt, uint32_t object_number, PhysicalPageNumber page_index) const;
363 void FillDumpRelocations(Dumper::Dumper& dump, Dumper::Block& page_block, const LEFormat& fmt) const;
364 void DumpPhysicalPage(Dumper::Dumper& dump, const LEFormat& fmt, uint32_t object_number, PhysicalPageNumber page_index) const;
365 void DumpIteratedPage(Dumper::Dumper& dump, const LEFormat& fmt, uint32_t object_number, PhysicalPageNumber page_index) const;
366 void DumpInvalidPage(Dumper::Dumper& dump, const LEFormat& fmt, uint32_t object_number, PhysicalPageNumber page_index) const;
367 void DumpZeroFilledPage(Dumper::Dumper& dump, const LEFormat& fmt, uint32_t object_number, PhysicalPageNumber page_index) const;
368 void DumpPageRange(Dumper::Dumper& dump, const LEFormat& fmt, uint32_t object_number, PhysicalPageNumber page_index) const;
369 void DumpCompressedPage(Dumper::Dumper& dump, const LEFormat& fmt, uint32_t object_number, PhysicalPageNumber page_index) const;
370 void DumpUnknownPage(Dumper::Dumper& dump, const LEFormat& fmt, uint32_t object_number, PhysicalPageNumber page_index) const;
371
372 public:
373 void Dump(Dumper::Dumper& dump, const LEFormat& fmt, PhysicalPageNumber page_index) const;
374 };
375
378 {
379 public:
380 uint16_t type_id = 0, name_id = 0;
381 uint32_t size = 0;
382 uint16_t object = 0;
383 uint32_t offset = 0;
384
385 Resource() = default;
386
387 Resource(uint16_t type_id, uint16_t name_id, uint32_t size, uint16_t object = 0, uint32_t offset = 0)
388 : type_id(type_id), name_id(name_id), size(size), object(object), offset(offset)
389 {
390 }
391 };
392
394 struct Name
395 {
396 public:
397 std::string name;
398 uint16_t ordinal = 0;
399 };
400
402 class Entry : public Linker::Writer
403 {
404 public:
405 enum entry_type
406 {
407 Unused,
408 Entry16,
409 CallGate286,
410 Entry32,
411 Forwarder,
412 };
413 entry_type type = Unused;
414 uint16_t object = 0;
415 enum flag_type
416 {
417 Exported = 1,
418 SharedData = 2,
419
420 ForwarderByOrdinal = 1,
421 };
422 flag_type flags = flag_type(0);
423 uint32_t offset = 0;
424
425 // informational purposes
438 std::string entry_name;
440 std::string module_name;
442 std::string import_name;
443
444 Entry()
445 : Writer(::LittleEndian)
446 {
447 }
448
449 Entry(unsigned type)
450 : Writer(::LittleEndian), type(entry_type(type))
451 {
452 }
453
454 Entry(unsigned type, uint16_t object, unsigned flags, uint32_t offset)
455 : Writer(::LittleEndian), type(entry_type(type)), object(object), flags(flag_type(flags)), offset(offset)
456 {
457 }
458
459 mutable bool same_bundle = false; // mutable because this isn't actually part of the entry state but the entire entry table
460
461 bool SameBundle(const Entry& other) const;
462
463 offset_t GetEntryHeadSize() const;
464
465 offset_t GetEntryBodySize() const;
466
467 static Entry ReadEntryHead(Linker::Reader& rd, uint8_t type);
468 static Entry ReadEntry(Linker::Reader& rd, uint8_t type, LEFormat::Entry& head);
469
470 void WriteEntryHead(Linker::Writer& wr) const;
471
472 void WriteEntryBody(Linker::Writer& wr) const;
473 };
474
477 {
478 public:
479 enum directive_number : uint16_t
480 {
481 VerifyRecordDirective = 0x8001,
482 LanguageInformationDirective = 0x0002,
483 CoProcessorRequiredSupportTable = 0x0003,
484 ThreadStateInitializationDirective = 0x0004,
485 CSetBrowseInformation = 0x0005,
486 };
487 static constexpr uint16_t ResidentFlagMask = 0x8000;
488 directive_number directive = directive_number(0);
489 uint16_t length = 0;
490 offset_t offset = 0;
491
492 bool IsResident() const;
493 };
494
495 ::EndianType endiantype = ::LittleEndian;
496
498 std::array<char, 2> signature{'L', 'E'};
499
500 bool IsExtendedFormat() const;
501
502 uint32_t format_level = 0;
503
504 /* https://faydoc.tripod.com/formats/exe-LE.htm */
505 enum cpu_type
506 {
507 I286 = 0x01,
508 I386 = 0x02, /* only value used */
509 I486 = 0x03,
510 I586 = 0x04,
511 I860_N10 = 0x20,
512 I860_N11 = 0x21,
513 MIPS1 = 0x40,
514 MIPS2 = 0x41,
515 MIPS3 = 0x42,
516 };
517 cpu_type cpu = I386;
518
535 system_type system = system_type(0);
536
551 /*** @brief Whether to generate an executable or a library */
552 output_type output;
553
554 uint32_t module_version = 0;
555
556 enum
557 {
558 PreProcessInitialization = 0x00000004,
559 NoInternalFixup = 0x00000010,
560 NoExternalFixup = 0x00000020,
561 FullScreen = 0x00000100,
562 GUIAware = 0x00000200,
563 GUI = 0x00000300,
564 ErrorInImage = 0x00002000,
565 Library = 0x00008000,
566 ProtectedMemoryLibrary = 0x00018000,
567 PhysicalDriver = 0x00020000,
568 VirtualDriver = 0x00028000,
569 PerProcessTermination = 0x40000000,
570 };
571 uint32_t module_flags = 0;
572
573 uint32_t page_count = 0, page_size = 0x1000;
574 uint32_t eip_object = 0, eip_value = 0, esp_object = 0, esp_value = 0;
575 union
576 {
577 uint32_t last_page_size; /* LE */
578 uint32_t page_offset_shift; /* LX */
579 };
580 uint32_t fixup_section_size = 0, fixup_section_checksum = 0;
581 uint32_t loader_section_size = 0, loader_section_checksum = 0;
582 uint32_t object_table_offset = 0, object_page_table_offset = 0, object_iterated_pages_offset = 0;
583 uint32_t resource_table_offset = 0, resource_table_entry_count = 0, resident_name_table_offset = 0;
584 uint32_t entry_table_offset = 0, module_directives_offset = 0, fixup_page_table_offset = 0, fixup_record_table_offset = 0;
585 uint32_t imported_module_table_offset = 0, imported_procedure_table_offset = 0;
586 uint32_t per_page_checksum_offset = 0;
587 uint32_t data_pages_offset = 0, preload_page_count = 0;
588 uint32_t nonresident_name_table_offset = 0, nonresident_name_table_size = 0, nonresident_name_table_checksum = 0;
589 uint32_t automatic_data = 0;
590 uint32_t debug_info_offset = 0, debug_info_size = 0, instance_preload_page_count = 0, instance_demand_page_count = 0;
591 uint32_t stack_size = 0, heap_size = 0;
592
593 uint32_t vxd_version_info_resource_offset = 0;
594 uint32_t vxd_version_info_resource_length = 0;
595 ResourceFile vxd_version_info_resource = ResourceFile(ResourceFile::System_Windows_3x);
596 uint16_t vxd_device_id = 0;
597 uint16_t vxd_ddk_version = 0;
598
599 std::vector<Object> objects;
600 std::vector<ModuleDirective> module_directives;
601
604 {
605 private:
606 std::vector<Page> pages;
607 public:
608 typedef std::vector<Page>::iterator iterator;
609 typedef std::vector<Page>::const_iterator const_iterator;
610 typedef std::vector<Page>::reference reference;
611 typedef std::vector<Page>::const_reference const_reference;
613
614 Page& operator[](PhysicalPageNumber physical_page_number);
615 const Page& operator[](PhysicalPageNumber physical_page_number) const;
616
617 iterator begin();
618 const_iterator begin() const;
619 iterator end();
620 const_iterator end() const;
621
622 reference front();
623 const_reference front() const;
624 reference back();
625 const_reference back() const;
626
627 void push_back(const Page& page);
628
629 size_type size() const;
630 };
631
632 PhysicalPages pages;
633
640 std::vector<std::tuple<PhysicalPageNumber, Page::page_type>> page_map_table;
641
642 PhysicalPageNumber ObjectPageToPhysicalPage(uint32_t index) const;
643
644 std::map<std::tuple<uint16_t, uint16_t>, Resource> resources;
645 std::vector<Name> resident_names, nonresident_names;
646 std::vector<Entry> entries;
647 std::vector<std::string> imported_modules, imported_procedures;
648
649 offset_t file_size = offset_t(-1);
650
652 void SetTargetDefaults();
653
654 explicit LEFormat()
655 : last_page_size(0)
656 {
657 }
658
659 LEFormat(bool extended_format)
660 : last_page_size(0)
661 {
662 if(extended_format)
663 signature[1] = 'X';
664 }
665
666 LEFormat(system_type system, output_type output)
667 : system(system_type(system)), output(output), last_page_size(0)
668 {
669 }
670
671 LEFormat(system_type system, output_type output, bool extended_format)
672 : system(system_type(system)), output(output), last_page_size(0)
673 {
674 if(extended_format)
675 signature[1] = 'X';
676 }
677
678 bool IsLibrary() const;
679
680 bool IsDriver() const;
681
682 bool IsOS2() const;
683
684 bool MayHaveStack() const;
685
686 void ReadFile(Linker::Reader& rd) override;
687
688 offset_t ImageSize() const override;
689
691 offset_t WriteFile(Linker::Writer& wr) const override;
692 void Dump(Dumper::Dumper& dump) const override;
693
694 offset_t GetPageOffset(PhysicalPageNumber physical_page_number) const;
695 offset_t GetPageSize(PhysicalPageNumber physical_page_number) const;
696
697 /* * * Writer members * * */
698
700 {
701 public:
702 class SystemEnumeration : public Linker::Enumeration<system_type>
703 {
704 public:
706 : Enumeration(
707 "OS2", OS2,
708 "WINDOWS", Windows,
709 "DOS", MSDOS4,
710 "WIN386", Windows386,
711 "WINDOWS386", Windows386,
712 "VXD", Windows386,
713 "IBM", Neutral,
714 "DOS4G", DOS4G,
715 "DOS4GW", DOS4G)
716 {
717 descriptions = {
718 { OS2, "OS/2 2.0+" },
719 { Windows, "Reserved for Windows (not supported)" },
720 { MSDOS4, "Reserved for Multitasking MS-DOS 4.0 (not supported)" },
721 { Windows386, "Windows 386 (virtual device driver only)" },
722 { Neutral, "IBM Microkernel Personality Neutral (not supported)" },
723 { DOS4G, "Rational Systems (Tenberry Software) DOS/4G or DOS/4GW executable" },
724 };
725 }
726 };
727
728 class OutputTypeEnumeration : public Linker::Enumeration<output_type>
729 {
730 public:
732 : Enumeration(
733 "GUI", OUTPUT_GUI,
734 "PM", OUTPUT_GUI,
735 "WINDOWS", OUTPUT_GUI,
736 "CONSOLE", OUTPUT_CON,
737 "DLL", OUTPUT_DLL,
738 "PDD", OUTPUT_PDD,
739 "SYS", OUTPUT_PDD,
740 "VDD", OUTPUT_VDD,
741 "VXD", OUTPUT_VDD)
742 {
743 descriptions = {
744 { OUTPUT_GUI, "creates a graphical executable (Presentation Manager for OS/2)" },
745 { OUTPUT_CON, "creates a console (text mode) executable" },
746 { OUTPUT_DLL, "creates a dynamic linking library (DLL)" },
747 { OUTPUT_PDD, "creates a physical device driver" },
748 { OUTPUT_VDD, "creates a virtual device driver" },
749 };
750 }
751 };
752
753 class CompatibilityEnumeration : public Linker::Enumeration<compatibility_type>
754 {
755 public:
757 : Enumeration(
758 "NONE", CompatibleNone,
759 "WATCOM", CompatibleWatcom,
761 "BORLAND", CompatibleBorland)
762 //"GNU", CompatibleGNU
763 {
764 descriptions = {
765 { CompatibleNone, "default operation" },
766 { CompatibleWatcom, "mimics the Watcom linker (not implemented)" },
767 { CompatibleMicrosoft, "mimics the Microsoft linker (not implemented)" },
768 { CompatibleBorland, "mimics the Borland linker (not implemented)" },
769 /*{ CompatibleGNU, "mimics the GNU linker (not implemented)" },*/
770 };
771 }
772 };
773
774 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
775 Linker::Option<Linker::ItemOf<SystemEnumeration>> system{"system", "Target system type"};
776 Linker::Option<Linker::ItemOf<OutputTypeEnumeration>> type{"type", "Type of binary"};
777 Linker::Option<Linker::ItemOf<CompatibilityEnumeration>> compat{"compat", "Mimics the behavior of another linker"};
778 Linker::Option<std::optional<offset_t>> stack{"stack", "Specify the stack size"};
779 Linker::Option<offset_t> heap{"heap", "Specify the heap size"};
780 Linker::Option<bool> le{"le", "Original linear executable (LE)"};
781 Linker::Option<bool> lx{"lx", "Extended linear executable (LX)"};
782
783 LEOptionCollector()
784 {
785 InitializeFields(stub, system, type, compat, stack, heap, le, lx);
786 }
787 };
788
789 static std::shared_ptr<LEFormat> CreateConsoleApplication(system_type system = OS2);
790
791 static std::shared_ptr<LEFormat> CreateGUIApplication(system_type system = OS2);
792
793 static std::shared_ptr<LEFormat> CreateLibraryModule(system_type system = OS2);
794
795 static std::shared_ptr<LEFormat> CreateDeviceDriver(system_type system = OS2, bool virtual_device_driver = true);
796
797 std::shared_ptr<LEFormat> SimulateLinker(compatibility_type compatibility);
798
799 mutable MZStubWriter stub;
800
801 compatibility_type compatibility = CompatibleNone;
802
803 /*std::string stub_file;*/
804 std::string program_name, module_name;
805
806 bool FormatSupportsSegmentation() const override;
807
808 bool FormatSupportsLibraries() const override;
809
810 bool FormatSupportsResources() const override;
811
812 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
813
814 Resource& AddResource(Resource resource);
815
816 void GetRelocationOffset(Object& object, size_t offset, PhysicalPageNumber& page_index, uint16_t& page_offset);
817 void AddRelocation(Object& object, unsigned type, unsigned flags, size_t offset, uint16_t module, uint32_t target = 0, uint32_t addition = 0);
818
819 std::shared_ptr<Linker::Segment> stack, heap;
820 std::map<std::shared_ptr<Linker::Segment>, size_t> object_index;
821 std::map<std::string, uint32_t> imported_procedure_name_offsets;
822 offset_t imported_procedure_names_length = 0;
823
824 unsigned GetDefaultObjectFlags() const;
825 void AddObject(const Object& object);
826 uint16_t FetchImportedModuleName(std::string name);
827 uint16_t FetchImportedProcedureName(std::string name);
828 uint16_t MakeEntry(Linker::Position value);
829 uint16_t MakeEntry(uint16_t index, Linker::Position value);
830 uint8_t CountBundles(size_t entry_index) const;
831
832 static std::vector<Linker::OptionDescription<void> *> ParameterNames;
833 std::vector<Linker::OptionDescription<void> *> GetLinkerScriptParameterNames() override;
834 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
835 void SetOptions(std::map<std::string, std::string>& options) override;
836 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
837 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
838 void Link(Linker::Module& module);
839 void ProcessModule(Linker::Module& module) override;
840 void CalculateValues() override;
841 void GenerateFile(std::string filename, Linker::Module& module) override;
843 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
844
845 };
846
847}
848
849#endif /* LEEXE_H */
A region within a file that can be dumped, decompiled, and it may contain fixups.
Definition dumper.h:705
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:773
A record that represents a region within the file.
Definition dumper.h:666
Represents abstract data contents whose data can be written to a file.
Definition image.h:17
virtual offset_t WriteFile(Writer &wr, offset_t count, offset_t offset=0) const =0
Writes data of non-zero filled sections.
A representation of an enumeration with associated string representations for each value.
Definition options.h:15
std::map< value_type, std::string > descriptions
An empty dictionary that explains the value types in detail.
Definition options.h:20
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.
Stores an absolute address along with the containing segment or address space.
Definition position.h:17
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:20
A representation of a value within some binary data that has to be fixed up once the exact position o...
Definition relocation.h:27
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
Represents an entry into the binary, typically DLL exported procedures.
Definition leexe.h:403
export_type export_state
Whether the entry is exported. This is not actually stored in the entry table and its value is ignore...
Definition leexe.h:436
std::string import_name
Convenience field that stores the imported procedure name for a forwarder entry, if imported by name,...
Definition leexe.h:442
std::string entry_name
The name of an exported entry. This is not actually stored in the entry table and its value is ignore...
Definition leexe.h:438
export_type
Definition leexe.h:427
@ NotExported
The entry is not exported, the Exported bit is not set.
Definition leexe.h:429
@ ExportByName
The entry is exported by name, it is referenced in the resident name table.
Definition leexe.h:431
@ ExportByOrdinal
The entry is exported by ordinal, it is referenced in the nonresident name table.
Definition leexe.h:433
std::string module_name
Convenience field that stores the module name for a forwarder entry, not used for generation.
Definition leexe.h:440
An image instance where the iterated page data can be accessed as the series of bytes it generates.
Definition leexe.h:171
offset_t WriteFile(Linker::Writer &wr, offset_t count, offset_t offset=0) const override
Writes data of non-zero filled sections.
Definition leexe.cc:156
size_t ReadData(size_t bytes, offset_t offset, void *buffer) const override
Attempts to fill a buffer with data.
Definition leexe.cc:122
offset_t ImageSize() const override
Retrieves size of stored data.
Definition leexe.cc:151
A data structure to represent an LE/LX iterated page, consisting of data produced from a repetition o...
Definition leexe.h:153
offset_t ImageSize() const override
Retrieves size of stored data.
Definition leexe.cc:85
offset_t WriteFile(Linker::Writer &wr, offset_t count, offset_t offset=0) const override
Writes data of non-zero filled sections.
Definition leexe.cc:116
Stores a module directive in the module directive table.
Definition leexe.h:477
Represents an LE/LX object (a relocatable section of memory) as stored in the object table,...
Definition leexe.h:62
An image instance that is a collection of other images, conceptually pages.
Definition leexe.h:108
offset_t ImageSize() const override
Retrieves size of stored data.
Definition leexe.cc:11
offset_t WriteFile(Linker::Writer &wr, offset_t count, offset_t offset=0) const override
Writes data of non-zero filled sections.
Definition leexe.cc:21
Represents a relocation record associated to this page.
Definition leexe.h:233
uint16_t actual_object
Convenience field that stores the actual object number for an entry, not used for generation.
Definition leexe.h:278
std::string module_name
Convenience field that stores the module name, not used for generation.
Definition leexe.h:274
uint32_t actual_offset
Convenience field that stores the actual offset for an entry, not used for generation.
Definition leexe.h:280
std::string import_name
Convenience field that stores the imported procedure name, if imported by name, also the name for an ...
Definition leexe.h:276
std::vector< Chain > sources
The sequence of sources corresponding to the same relocation record.
Definition leexe.h:327
Represents a page (usually of 4 KiB) within an LE/LX object.
Definition leexe.h:191
page_type
LX (and presumably LE) page types.
Definition leexe.h:195
uint32_t offset
(LX only) Offset of the page within the file
Definition leexe.h:210
uint32_t fixup_offset
The offset to the first fixup from the fixup record table, as stored in the fixup page table.
Definition leexe.h:229
uint16_t size
(LX only) The size of the page as stored in the file
Definition leexe.h:217
uint16_t type
The type of the page.
Definition leexe.h:224
Typesafe wrapper around std::vector<Page> to only access elements via physical pages.
Definition leexe.h:604
Stores an OS/2 resource.
Definition leexe.h:378
An image instance for a single page within a complete object image.
Definition leexe.h:132
offset_t WriteFile(Linker::Writer &wr, offset_t count, offset_t offset=0) const override
Writes data of non-zero filled sections.
Definition leexe.cc:59
offset_t ImageSize() const override
Retrieves size of stored data.
Definition leexe.cc:54
std::shared_ptr< const Linker::Image > AsImage() const override
Retrieves a randomly accessible image.
Definition leexe.cc:73
LE/LX .EXE linear executable file format.
Definition leexe.h:30
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition leexe.cc:1860
std::vector< std::tuple< PhysicalPageNumber, Page::page_type > > page_map_table
(LE only) The object page map table contents
Definition leexe.h:640
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition leexe.cc:2947
compatibility_type
Definition leexe.h:35
@ CompatibleMicrosoft
Attempts to mimic the output of the Microsoft linker (TODO: unimplemented)
Definition leexe.h:41
@ CompatibleNone
No emulation is attempted.
Definition leexe.h:37
@ CompatibleBorland
Attempts to mimic the output of the Borland linker (TODO: unimplemented)
Definition leexe.h:43
@ CompatibleWatcom
Attempts to mimic the output of the Watcom linker.
Definition leexe.h:39
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition leexe.cc:2500
std::vector< Linker::OptionDescription< void > * > GetLinkerScriptParameterNames() override
Returns a list of the parameters used in the linker scripts, used for documentation.
Definition leexe.cc:2490
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition leexe.cc:2495
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition leexe.cc:3079
offset_t ImageSize() const override
Retrieves size of stored data.
Definition leexe.cc:1571
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition leexe.cc:3095
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition leexe.cc:1094
bool FormatSupportsResources() const override
Whether the format supports resources.
Definition leexe.cc:2332
bool FormatSupportsSegmentation() const override
Whether the format supports multiple segments.
Definition leexe.cc:2322
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition leexe.cc:2680
std::array< char, 2 > signature
The signature, almost always "LE" or "LX".
Definition leexe.h:498
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition leexe.cc:1576
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 leexe.cc:2565
void SetTargetDefaults()
Configures the values for system/output type.
Definition leexe.cc:939
output_type
Represents the target image type.
Definition leexe.h:539
@ OUTPUT_VDD
A virtual device driver, conventionally taking the suffix .sys
Definition leexe.h:549
@ OUTPUT_DLL
A dynamically linked library, conventionally taking the suffix .dll
Definition leexe.h:545
@ OUTPUT_PDD
A physical device driver, conventionally taking the suffix .sys
Definition leexe.h:547
@ OUTPUT_GUI
A graphical executable image, conventionally taking the suffix .exe
Definition leexe.h:541
@ OUTPUT_CON
A console executable image, conventionally taking the suffix .exe
Definition leexe.h:543
bool FormatSupportsLibraries() const override
Whether the format supports libraries.
Definition leexe.cc:2327
system_type
Definition leexe.h:520
@ DOS4G
Used by DOS/4G, the numerical value is chosen so that it gets stored as OS/2 in the binary.
Definition leexe.h:533
@ Windows
Reserved for Windows, unimplemented.
Definition leexe.h:524
@ MSDOS4
Reserved for DOS 4.x, unimplemented.
Definition leexe.h:526
@ OS2
Runs on OS/2 2.0+.
Definition leexe.h:522
@ Neutral
IBM Microkernel Personality Neutral, unimplemented.
Definition leexe.h:530
@ Windows386
Windows 386 (only virtual device drivers supported)
Definition leexe.h:528
A name and ordinal pair, as used for resident and non-resident names.
Definition leexe.h:395
A source location entry in the relocation record.
Definition leexe.h:317
uint32_t base_address
If the relocations are chained, this contains the base address to which other fields are relocated to...
Definition leexe.h:321
std::vector< ChainLink > chains
If the relocations are chained, this contains the following link entries.
Definition leexe.h:323
uint16_t source
Offset within page where relocation should be applied to.
Definition leexe.h:319
Type safe wrapper for an uint32_t to access physical pages.
Definition leexe.h:50