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::Image> 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
107 class PageSet : public Linker::Image
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(const std::shared_ptr<Linker::Writer>& wr, offset_t count, offset_t offset = 0) const override;
123 size_t ReadData(size_t bytes, offset_t offset, void * buffer) const override;
124 };
125
133 {
134 public:
135 std::shared_ptr<Linker::Image> image;
136 offset_t offset = 0;
137 offset_t size = 0;
138
139 SegmentPage(std::shared_ptr<Linker::Image> image, offset_t offset, offset_t size)
140 : image(image), offset(offset), size(size)
141 {
142 }
143
144 offset_t ImageSize() const override;
146 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr, offset_t count, offset_t offset = 0) const override;
147 size_t ReadData(size_t bytes, offset_t offset, void * buffer) const override;
148 std::shared_ptr<const Linker::Image> AsImage() const override;
149 };
150
155 {
156 public:
158 {
159 uint16_t count = 0;
160 std::vector<uint8_t> data;
161 };
162 std::vector<IterationRecord> records;
163
164 offset_t ImageSize() const override;
166 static std::shared_ptr<IteratedPage> ReadFromFile(const std::shared_ptr<Linker::Reader>& rd, uint16_t size);
167 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr, offset_t count, offset_t offset = 0) const override;
168 size_t ReadData(size_t bytes, offset_t offset, void * buffer) const override;
169
173 class View : public Linker::Image
174 {
175 public:
176 IteratedPage& iterated_page;
177 size_t size;
178
179 View(IteratedPage& iterated_page, size_t size)
180 : iterated_page(iterated_page), size(size)
181 {
182 }
183
184 size_t ReadData(size_t bytes, offset_t offset, void * buffer) const override;
185
186 offset_t ImageSize() const override;
187 };
188 };
189
191 class Page
192 {
193 public:
196 {
197 Preload = 0,
198 Iterated = 1,
199 Invalid = 2,
200 ZeroFilled = 3,
201 Range = 4,
202 Compressed = 5,
203 };
204
211 uint32_t offset = 0;
212
218 uint16_t size = 0;
219
225 uint16_t type = 0;
226
227 page_type GetPageType(const LEFormat& fmt) const;
228
230 uint32_t fixup_offset = 0;
231
234 {
235 public:
236 enum source_type
237 {
238 Offset8 = 0,
239 Selector16 = 2,
240 Pointer32 = 3,
241 Offset16 = 5,
242 Pointer48 = 6,
243 Offset32 = 7,
244 Relative32 = 8,
245
246 SourceTypeMask = 0x0F,
247
248 Alias = 0x10,
249 SourceList = 0x20,
250 };
251 source_type type = source_type(0);
252 enum flag_type
253 {
254 Internal = 0,
255 ImportOrdinal = 1,
256 ImportName = 2,
257 Entry = 3,
258
259 FlagTypeMask = 3,
260
261 Additive = 4,
262 Chained = 8,
263 Target32 = 0x10,
264 Additive32 = 0x20,
265 Module16 = 0x40,
266 Ordinal8 = 0x80,
267 };
268 flag_type flags = flag_type(0);
269 uint16_t module = 0;
270 uint32_t target = 0;
271 uint32_t addition = 0;
272
273 // informational purposes
275 std::string module_name;
277 std::string import_name;
279 uint16_t actual_object = 0;
281 uint32_t actual_offset = 0;
282
283 Relocation()
284 {
285 }
286
287 Relocation(unsigned type, unsigned flags, uint16_t offset, uint16_t module, uint32_t target = 0, uint32_t addition = 0)
288 : 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(const std::shared_ptr<Linker::Reader>& rd, Page& page);
347 void WriteFile(const std::shared_ptr<Linker::Writer>& wr) const;
348 };
349 std::map<uint16_t, Relocation> relocations;
350 uint32_t checksum = 0;
351 std::shared_ptr<Linker::Image> 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
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 {
446 }
447
448 Entry(unsigned type)
449 : type(entry_type(type))
450 {
451 }
452
453 Entry(unsigned type, uint16_t object, unsigned flags, uint32_t offset)
454 : type(entry_type(type)), object(object), flags(flag_type(flags)), offset(offset)
455 {
456 }
457
458 mutable bool same_bundle = false; // mutable because this isn't actually part of the entry state but the entire entry table
459
460 bool SameBundle(const Entry& other) const;
461
462 offset_t GetEntryHeadSize() const;
463
464 offset_t GetEntryBodySize() const;
465
466 static Entry ReadEntryHead(const std::shared_ptr<Linker::Reader>& rd, uint8_t type);
467 static Entry ReadEntry(const std::shared_ptr<Linker::Reader>& rd, uint8_t type, LEFormat::Entry& head);
468
469 void WriteEntryHead(const std::shared_ptr<Linker::Writer>& wr) const;
470
471 void WriteEntryBody(const std::shared_ptr<Linker::Writer>& wr) const;
472 };
473
476 {
477 public:
478 enum directive_number : uint16_t
479 {
480 VerifyRecordDirective = 0x8001,
481 LanguageInformationDirective = 0x0002,
482 CoProcessorRequiredSupportTable = 0x0003,
483 ThreadStateInitializationDirective = 0x0004,
484 CSetBrowseInformation = 0x0005,
485 };
486 static constexpr uint16_t ResidentFlagMask = 0x8000;
487 directive_number directive = directive_number(0);
488 uint16_t length = 0;
489 offset_t offset = 0;
490
491 bool IsResident() const;
492 };
493
494 ::EndianType endiantype = ::LittleEndian;
495
497 std::array<char, 2> signature{'L', 'E'};
498
499 bool IsExtendedFormat() const;
500
501 uint32_t format_level = 0;
502
503 /* https://faydoc.tripod.com/formats/exe-LE.htm */
504 enum cpu_type
505 {
506 I286 = 0x01,
507 I386 = 0x02, /* only value used */
508 I486 = 0x03,
509 I586 = 0x04,
510 I860_N10 = 0x20,
511 I860_N11 = 0x21,
512 MIPS1 = 0x40,
513 MIPS2 = 0x41,
514 MIPS3 = 0x42,
515 };
516 cpu_type cpu = I386;
517
534 system_type system = system_type(0);
535
550 /*** @brief Whether to generate an executable or a library */
551 output_type output;
552
553 uint32_t module_version = 0;
554
555 enum
556 {
557 PreProcessInitialization = 0x00000004,
558 NoInternalFixup = 0x00000010,
559 NoExternalFixup = 0x00000020,
560 FullScreen = 0x00000100,
561 GUIAware = 0x00000200,
562 GUI = 0x00000300,
563 ErrorInImage = 0x00002000,
564 Library = 0x00008000,
565 ProtectedMemoryLibrary = 0x00018000,
566 PhysicalDriver = 0x00020000,
567 VirtualDriver = 0x00028000,
568 PerProcessTermination = 0x40000000,
569 };
570 uint32_t module_flags = 0;
571
572 uint32_t page_count = 0, page_size = 0x1000;
573 uint32_t eip_object = 0, eip_value = 0, esp_object = 0, esp_value = 0;
574 union
575 {
576 uint32_t last_page_size; /* LE */
577 uint32_t page_offset_shift; /* LX */
578 };
579 uint32_t fixup_section_size = 0, fixup_section_checksum = 0;
580 uint32_t loader_section_size = 0, loader_section_checksum = 0;
581 uint32_t object_table_offset = 0, object_page_table_offset = 0, object_iterated_pages_offset = 0;
582 uint32_t resource_table_offset = 0, resource_table_entry_count = 0, resident_name_table_offset = 0;
583 uint32_t entry_table_offset = 0, module_directives_offset = 0, fixup_page_table_offset = 0, fixup_record_table_offset = 0;
584 uint32_t imported_module_table_offset = 0, imported_procedure_table_offset = 0;
585 uint32_t per_page_checksum_offset = 0;
586 uint32_t data_pages_offset = 0, preload_page_count = 0;
587 uint32_t nonresident_name_table_offset = 0, nonresident_name_table_size = 0, nonresident_name_table_checksum = 0;
588 uint32_t automatic_data = 0;
589 uint32_t debug_info_offset = 0, debug_info_size = 0, instance_preload_page_count = 0, instance_demand_page_count = 0;
590 uint32_t stack_size = 0, heap_size = 0;
591
592 uint32_t vxd_version_info_resource_offset = 0;
593 uint32_t vxd_version_info_resource_length = 0;
594 ResourceFile vxd_version_info_resource = ResourceFile(ResourceFile::System_Windows_3x);
595 uint16_t vxd_device_id = 0;
596 uint16_t vxd_ddk_version = 0;
597
598 std::vector<Object> objects;
599 std::vector<ModuleDirective> module_directives;
600
603 {
604 private:
605 std::vector<Page> pages;
606 public:
607 typedef std::vector<Page>::iterator iterator;
608 typedef std::vector<Page>::const_iterator const_iterator;
609 typedef std::vector<Page>::reference reference;
610 typedef std::vector<Page>::const_reference const_reference;
612
613 Page& operator[](PhysicalPageNumber physical_page_number);
614 const Page& operator[](PhysicalPageNumber physical_page_number) const;
615
616 iterator begin();
617 const_iterator begin() const;
618 iterator end();
619 const_iterator end() const;
620
621 reference front();
622 const_reference front() const;
623 reference back();
624 const_reference back() const;
625
626 void push_back(const Page& page);
627
628 size_type size() const;
629 };
630
631 PhysicalPages pages;
632
639 std::vector<std::tuple<PhysicalPageNumber, Page::page_type>> page_map_table;
640
641 PhysicalPageNumber ObjectPageToPhysicalPage(uint32_t index) const;
642
643 std::map<std::tuple<uint16_t, uint16_t>, Resource> resources;
644 std::vector<Name> resident_names, nonresident_names;
645 std::vector<Entry> entries;
646 std::vector<std::string> imported_modules, imported_procedures;
647
648 offset_t file_size = offset_t(-1);
649
651 void SetTargetDefaults();
652
653 explicit LEFormat()
654 : last_page_size(0)
655 {
656 }
657
658 LEFormat(bool extended_format)
659 : last_page_size(0)
660 {
661 if(extended_format)
662 signature[1] = 'X';
663 }
664
665 LEFormat(system_type system, output_type output)
666 : system(system_type(system)), output(output), last_page_size(0)
667 {
668 }
669
670 LEFormat(system_type system, output_type output, bool extended_format)
671 : system(system_type(system)), output(output), last_page_size(0)
672 {
673 if(extended_format)
674 signature[1] = 'X';
675 }
676
677 bool IsLibrary() const;
678
679 bool IsDriver() const;
680
681 bool IsOS2() const;
682
683 bool MayHaveStack() const;
684
685 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
686
687 offset_t ImageSize() const override;
688
690 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
691 void Dump(Dumper::Dumper& dump) const override;
692
693 offset_t GetPageOffset(PhysicalPageNumber physical_page_number) const;
694 offset_t GetPageSize(PhysicalPageNumber physical_page_number) const;
695
696 /* * * Writer members * * */
697
699 {
700 public:
701 class SystemEnumeration : public Linker::Enumeration<system_type>
702 {
703 public:
705 : Enumeration(
706 "OS2", OS2,
707 "WINDOWS", Windows,
708 "DOS", MSDOS4,
709 "WIN386", Windows386,
710 "WINDOWS386", Windows386,
711 "VXD", Windows386,
712 "IBM", Neutral,
713 "DOS4G", DOS4G,
714 "DOS4GW", DOS4G)
715 {
716 descriptions = {
717 { OS2, "OS/2 2.0+" },
718 { Windows, "Reserved for Windows (not supported)" },
719 { MSDOS4, "Reserved for Multitasking MS-DOS 4.0 (not supported)" },
720 { Windows386, "Windows 386 (virtual device driver only)" },
721 { Neutral, "IBM Microkernel Personality Neutral (not supported)" },
722 { DOS4G, "Rational Systems (Tenberry Software) DOS/4G or DOS/4GW executable" },
723 };
724 }
725 };
726
727 class OutputTypeEnumeration : public Linker::Enumeration<output_type>
728 {
729 public:
731 : Enumeration(
732 "GUI", OUTPUT_GUI,
733 "PM", OUTPUT_GUI,
734 "WINDOWS", OUTPUT_GUI,
735 "CONSOLE", OUTPUT_CON,
736 "DLL", OUTPUT_DLL,
737 "PDD", OUTPUT_PDD,
738 "SYS", OUTPUT_PDD,
739 "VDD", OUTPUT_VDD,
740 "VXD", OUTPUT_VDD)
741 {
742 descriptions = {
743 { OUTPUT_GUI, "creates a graphical executable (Presentation Manager for OS/2)" },
744 { OUTPUT_CON, "creates a console (text mode) executable" },
745 { OUTPUT_DLL, "creates a dynamic linking library (DLL)" },
746 { OUTPUT_PDD, "creates a physical device driver" },
747 { OUTPUT_VDD, "creates a virtual device driver" },
748 };
749 }
750 };
751
752 class CompatibilityEnumeration : public Linker::Enumeration<compatibility_type>
753 {
754 public:
756 : Enumeration(
757 "NONE", CompatibleNone,
758 "WATCOM", CompatibleWatcom,
760 "BORLAND", CompatibleBorland)
761 //"GNU", CompatibleGNU
762 {
763 descriptions = {
764 { CompatibleNone, "default operation" },
765 { CompatibleWatcom, "mimics the Watcom linker (not implemented)" },
766 { CompatibleMicrosoft, "mimics the Microsoft linker (not implemented)" },
767 { CompatibleBorland, "mimics the Borland linker (not implemented)" },
768 /*{ CompatibleGNU, "mimics the GNU linker (not implemented)" },*/
769 };
770 }
771 };
772
773 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
774 Linker::Option<Linker::ItemOf<SystemEnumeration>> system{"system", "Target system type"};
775 Linker::Option<Linker::ItemOf<OutputTypeEnumeration>> type{"type", "Type of binary"};
776 Linker::Option<Linker::ItemOf<CompatibilityEnumeration>> compat{"compat", "Mimics the behavior of another linker"};
777 Linker::Option<std::optional<offset_t>> stack{"stack", "Specify the stack size"};
778 Linker::Option<offset_t> heap{"heap", "Specify the heap size"};
779 Linker::Option<bool> le{"le", "Original linear executable (LE)"};
780 Linker::Option<bool> lx{"lx", "Extended linear executable (LX)"};
781
782 LEOptionCollector()
783 {
784 InitializeFields(stub, system, type, compat, stack, heap, le, lx);
785 }
786 };
787
788 static std::shared_ptr<LEFormat> CreateConsoleApplication(system_type system = OS2);
789
790 static std::shared_ptr<LEFormat> CreateGUIApplication(system_type system = OS2);
791
792 static std::shared_ptr<LEFormat> CreateLibraryModule(system_type system = OS2);
793
794 static std::shared_ptr<LEFormat> CreateDeviceDriver(system_type system = OS2, bool virtual_device_driver = true);
795
796 std::shared_ptr<LEFormat> SimulateLinker(compatibility_type compatibility);
797
798 mutable MZStubWriter stub;
799
800 compatibility_type compatibility = CompatibleNone;
801
802 /*std::string stub_file;*/
803 std::string program_name, module_name;
804
805 bool FormatSupportsSegmentation() const override;
806
807 bool FormatSupportsLibraries() const override;
808
809 bool FormatSupportsResources() const override;
810
811 bool FormatSupportsEntryTable() const override; // TODO: not yet implemented
812
813 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
814
815 Resource& AddResource(Resource resource);
816
817 void GetRelocationOffset(Object& object, size_t offset, PhysicalPageNumber& page_index, uint16_t& page_offset);
818 void AddRelocation(Object& object, unsigned type, unsigned flags, size_t offset, uint16_t module, uint32_t target = 0, uint32_t addition = 0);
819
820 std::shared_ptr<Linker::Segment> stack, heap;
821 std::map<std::shared_ptr<Linker::Segment>, size_t> object_index;
822 std::map<std::string, uint32_t> imported_procedure_name_offsets;
823 offset_t imported_procedure_names_length = 0;
824
825 unsigned GetDefaultObjectFlags() const;
826 void AddObject(const Object& object);
827 uint16_t FetchImportedModuleName(std::string name);
828 uint16_t FetchImportedProcedureName(std::string name);
829 uint16_t MakeEntry(Linker::Position value);
830 uint16_t MakeEntry(uint16_t index, Linker::Position value);
831 uint8_t CountBundles(size_t entry_index) const;
832
833 static std::vector<Linker::OptionDescription<void> *> ParameterNames;
834 std::vector<Linker::OptionDescription<void> *> GetLinkerScriptParameterNames() override;
835 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
836 void SetOptions(std::map<std::string, std::string>& options) override;
837 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
838 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
839 void Link(Linker::Module& module);
840 void ProcessModule(Linker::Module& module) override;
841 void CalculateValues() override;
842 void GenerateFile(std::string filename, Linker::Module& module) override;
844 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
845
846 };
847
848}
849
850#endif /* LEEXE_H */
A region within a file that can be dumped, decompiled, and it may contain fixups.
Definition dumper.h:941
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:1009
A record that represents a region within the file.
Definition dumper.h:902
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(const std::shared_ptr< Writer > &wr) const override=0
Stores data in memory to file.
Definition image.h:41
virtual offset_t WriteFile(const std::shared_ptr< Writer > &wr, offset_t count, offset_t offset=0) const
Writes data of non-zero filled sections.
Definition image.cc:68
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:499
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 representation of a value within some binary data that has to be fixed up once the exact position o...
Definition relocation.h:28
A helper class to collect sections into segments.
Definition segment_manager.h:32
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:174
size_t ReadData(size_t bytes, offset_t offset, void *buffer) const override
Attempts to fill a buffer with data.
Definition leexe.cc:138
offset_t ImageSize() const override
Retrieves the offset of the byte after the last one belonging to this format from the first one.
Definition leexe.cc:167
A data structure to represent an LE/LX iterated page, consisting of data produced from a repetition o...
Definition leexe.h:155
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr, offset_t count, offset_t offset=0) const override
Writes data of non-zero filled sections.
Definition leexe.cc:126
offset_t ImageSize() const override
Retrieves the offset of the byte after the last one belonging to this format from the first one.
Definition leexe.cc:95
size_t ReadData(size_t bytes, offset_t offset, void *buffer) const override
Attempts to fill a buffer with data.
Definition leexe.cc:132
Stores a module directive in the module directive table.
Definition leexe.h:476
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
size_t ReadData(size_t bytes, offset_t offset, void *buffer) const override
Attempts to fill a buffer with data.
Definition leexe.cc:54
offset_t ImageSize() const override
Retrieves the offset of the byte after the last one belonging to this format from the first one.
Definition leexe.cc:11
offset_t WriteFile(const std::shared_ptr< 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:234
uint16_t actual_object
Convenience field that stores the actual object number for an entry, not used for generation.
Definition leexe.h:279
std::string module_name
Convenience field that stores the module name, not used for generation.
Definition leexe.h:275
uint32_t actual_offset
Convenience field that stores the actual offset for an entry, not used for generation.
Definition leexe.h:281
std::string import_name
Convenience field that stores the imported procedure name, if imported by name, also the name for an ...
Definition leexe.h:277
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:192
page_type
LX (and presumably LE) page types.
Definition leexe.h:196
uint32_t offset
(LX only) Offset of the page within the file
Definition leexe.h:211
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:230
uint16_t size
(LX only) The size of the page as stored in the file
Definition leexe.h:218
uint16_t type
The type of the page.
Definition leexe.h:225
Typesafe wrapper around std::vector<Page> to only access elements via physical pages.
Definition leexe.h:603
Stores an OS/2 resource.
Definition leexe.h:378
An image instance for a single page within a complete object image.
Definition leexe.h:133
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr, offset_t count, offset_t offset=0) const override
Writes data of non-zero filled sections.
Definition leexe.cc:64
offset_t ImageSize() const override
Retrieves the offset of the byte after the last one belonging to this format from the first one.
Definition leexe.cc:59
size_t ReadData(size_t bytes, offset_t offset, void *buffer) const override
Attempts to fill a buffer with data.
Definition leexe.cc:78
std::shared_ptr< const Linker::Image > AsImage() const override
Retrieves a randomly accessible image.
Definition leexe.cc:83
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:1879
std::vector< std::tuple< PhysicalPageNumber, Page::page_type > > page_map_table
(LE only) The object page map table contents
Definition leexe.h:639
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition leexe.cc:2971
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:2524
void ReadFile(const std::shared_ptr< Linker::Reader > &rd) override
Loads file into memory.
Definition leexe.cc:1104
std::vector< Linker::OptionDescription< void > * > GetLinkerScriptParameterNames() override
Returns a list of the parameters used in the linker scripts, used for documentation.
Definition leexe.cc:2514
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr) const override
Stores data in memory to file.
Definition leexe.cc:1595
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:2519
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition leexe.cc:3103
offset_t ImageSize() const override
Retrieves the offset of the byte after the last one belonging to this format from the first one.
Definition leexe.cc:1590
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition leexe.cc:3119
bool FormatSupportsResources() const override
Whether the format supports resources.
Definition leexe.cc:2351
bool FormatSupportsSegmentation() const override
Whether the format supports multiple segments.
Definition leexe.cc:2341
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition leexe.cc:2704
bool FormatSupportsEntryTable() const override
Whether the format supports a structure containing addresses of methods.
Definition leexe.cc:2356
std::array< char, 2 > signature
The signature, almost always "LE" or "LX".
Definition leexe.h:497
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:2589
void SetTargetDefaults()
Configures the values for system/output type.
Definition leexe.cc:949
output_type
Represents the target image type.
Definition leexe.h:538
@ OUTPUT_VDD
A virtual device driver, conventionally taking the suffix .sys
Definition leexe.h:548
@ OUTPUT_DLL
A dynamically linked library, conventionally taking the suffix .dll
Definition leexe.h:544
@ OUTPUT_PDD
A physical device driver, conventionally taking the suffix .sys
Definition leexe.h:546
@ OUTPUT_GUI
A graphical executable image, conventionally taking the suffix .exe
Definition leexe.h:540
@ OUTPUT_CON
A console executable image, conventionally taking the suffix .exe
Definition leexe.h:542
bool FormatSupportsLibraries() const override
Whether the format supports libraries.
Definition leexe.cc:2346
system_type
Definition leexe.h:519
@ DOS4G
Used by DOS/4G, the numerical value is chosen so that it gets stored as OS/2 in the binary.
Definition leexe.h:532
@ Windows
Reserved for Windows, unimplemented.
Definition leexe.h:523
@ MSDOS4
Reserved for DOS 4.x, unimplemented.
Definition leexe.h:525
@ OS2
Runs on OS/2 2.0+.
Definition leexe.h:521
@ Neutral
IBM Microkernel Personality Neutral, unimplemented.
Definition leexe.h:529
@ Windows386
Windows 386 (only virtual device drivers supported)
Definition leexe.h:527
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