RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
neexe.h
1#ifndef NEEXE_H
2#define NEEXE_H
3
4#include <array>
5#include "mzexe.h"
6#include "../common.h"
7#include "../dumper/dumper.h"
8#include "../linker/module.h"
9#include "../linker/options.h"
10#include "../linker/segment.h"
11#include "../linker/segment_manager.h"
12#include "../linker/writer.h"
13
14namespace Microsoft
15{
16 namespace Windows
17 {
19 enum
20 {
21 RT_CURSOR = 0x0001,
22 RT_BITMAP = 0x0002,
23 RT_ICON = 0x0003,
24 RT_MENU = 0x0004,
25 RT_DIALOG = 0x0005,
26 RT_STRING = 0x0006,
27 RT_FONTDIR = 0x0007,
28 RT_FONT = 0x0008,
29 RT_ACCELERATOR = 0x0009,
30 RT_RCDATA = 0x000A,
31 RT_MESSAGETABLE = 0x000B,
32 RT_GROUP_CURSOR = 0x000C,
33 RT_GROUP_ICON = 0x000E,
34 RT_VERSION = 0x0010,
35 RT_DLGINCLUDE = 0x0011,
36 RT_PLUGPLAY = 0x0013,
37 RT_VXD = 0x0014,
38 RT_ANICURSOR = 0x0015,
39 RT_ANIICON = 0x0016,
40 RT_HTML = 0x0017,
41 RT_MANIFEST = 0x0018,
42 };
43
44 extern const std::map<offset_t, std::string> resource_type_id_descriptions;
45 }
46
47 namespace OS2
48 {
49 // based on OpenWatcom sources
50
52 enum
53 {
54 // cursor
55 RT_POINTER = 0x0001,
56 RT_BITMAP = 0x0002,
57 RT_MENU = 0x0003,
58 RT_DIALOG = 0x0004,
59 RT_STRING = 0x0005,
60 RT_FONTDIR = 0x0006,
61 RT_FONT = 0x0007,
62 RT_ACCELERATOR = 0x0008,
63 // binary data
64 RT_RCDATA = 0x0009,
65 // error message
66 RT_MESSAGE = 0x000A,
67 RT_DLGINCLUDE = 0x000B,
68 RT_VKEYTBL = 0x000C,
69 RT_KEYTBL = 0x000D,
70 RT_CHARTBL = 0x000E,
71 RT_DISPLAYINFO = 0x000F,
72 // function key area
73 RT_FKASHORT = 0x0010,
74 RT_FKALONG = 0x0011,
75 RT_HELPTABLE = 0x0012,
76 RT_HELPSUBTABLE = 0x0013,
77 RT_FDDIR = 0x0014,
78 RT_FD = 0x0015,
79 };
80
81 extern const std::map<offset_t, std::string> resource_type_id_descriptions;
82 }
83
93 class NEFormat : public virtual Linker::SegmentManager, public std::enable_shared_from_this<NEFormat>
94 {
95 public:
96 /* * * General members * * */
97
99 struct Name
100 {
101 public:
102 std::string name;
103 uint16_t ordinal = 0;
104 };
105
108 {
109 public:
110 std::shared_ptr<Linker::Contents> image;
111 offset_t data_offset = 0;
113 offset_t image_size = 0;
114 enum flag_type : uint16_t
115 {
116 Data = 1, Code = 0,
117 Allocated = 2,
118 Loaded = 4, /* RealMode = 4 */ /* TODO */
119 Iterated = 8, /* TODO */
120 Movable = 0x10, Fixed = 0,
121 Shareable = 0x20,
122 Preload = 0x40, LoadOnCall = 0,
123 ExecuteOnly = 0x80|Code, ReadOnly = 0x80|Data,
124 Relocations = 0x0100,
125 DebugInfo = 0x0200,
126 Discardable = 0x1000,
127 };
128 flag_type flags = flag_type(0);
130 uint32_t total_size = 0;
136
137 Segment()
138 {
139 }
140
141 Segment(std::shared_ptr<Linker::Segment> segment, unsigned flags)
142 : image(segment), flags(flag_type(flags))
143 {
144 }
145
146 enum
147 {
148 PrivilegeLevelShift = 10,
149 };
150
152 {
153 public:
197 std::vector<uint16_t> offsets;
199 uint16_t module = 0;
200 enum
201 {
202 FIARQQ = 1, FJARQQ = 1,
203 FISRQQ = 2, FJSRQQ = 2,
204 FICRQQ = 3, FJCRQQ = 3,
205 FIERQQ = 4,
206 FIDRQQ = 5,
207 FIWRQQ = 6,
208 };
211
213 std::string module_name;
215 std::string import_name;
217 uint8_t actual_segment = 0;
220
221 Relocation() = default;
222
223 Relocation(unsigned type, unsigned flags, uint16_t offset, uint16_t module, uint16_t target)
224 : type(source_type(type)), flags(flag_type(flags)), module(module), target(target)
225 {
226 offsets.push_back(offset);
227 }
228
229 static source_type GetType(Linker::Relocation& rel);
230 size_t GetSize() const;
231 };
232 std::vector<Relocation> relocations;
234 std::map<uint16_t, Relocation> relocations_map;
235
236 void AddRelocation(const Relocation& rel);
237 void Dump(Dumper::Dumper& dump, unsigned index, bool isos2) const;
238 };
239
244 class Resource : public Segment
245 {
246 public:
247 typedef std::variant<std::string, uint16_t> Identifier;
248
249 static Identifier ConvertIdentifier(Linker::ResourceIdentifier identifier);
250
255 uint16_t type_id = 0;
257 std::optional<std::string> type_id_name;
262 uint16_t id = 0;
264 std::optional<std::string> id_name;
266 uint16_t handle = 0;
268 uint16_t usage = 0;
269
270 Resource() = default;
271
272 Resource(const Identifier& type, const Identifier& name, std::shared_ptr<Linker::Segment> segment, unsigned flags)
273 : Segment(segment, flags)
274 {
275 if(auto name_p = std::get_if<std::string>(&type))
276 {
277 type_id_name = *name_p;
278 }
279 else if(auto id_p = std::get_if<uint16_t>(&type))
280 {
281 type_id = *id_p;
282 }
283
284 if(auto name_p = std::get_if<std::string>(&name))
285 {
286 id_name = *name_p;
287 }
288 else if(auto id_p = std::get_if<uint16_t>(&name))
289 {
290 id = *id_p;
291 }
292 }
293
294 Resource(const Linker::ResourceIdentifier& type, const Linker::ResourceIdentifier& name, std::shared_ptr<Linker::Segment> segment, unsigned flags)
295 : Resource(ConvertIdentifier(type), ConvertIdentifier(name), segment, flags)
296 {
297 }
298
299 Identifier GetTypeIdentifier() const
300 {
301 if(type_id_name)
302 {
303 return Identifier(type_id_name.value());
304 }
305 else
306 {
307 return Identifier(uint16_t(type_id & 0x7FFF));
308 }
309 }
310
311 Identifier GetNameIdentifier() const
312 {
313 if(id_name)
314 {
315 return Identifier(id_name.value());
316 }
317 else
318 {
319 return Identifier(uint16_t(id & 0x7FFF));
320 }
321 }
322
323 void Dump(Dumper::Dumper& dump, unsigned index, bool isos2) const;
324 };
325
328 {
329 public:
330 virtual ~ResourceType() = default;
331
332 uint16_t type_id = 0;
333 std::optional<std::string> type_id_name;
334 std::vector<std::shared_ptr<Resource>> resources;
335
336 ResourceType() = default;
337
338 ResourceType(const Resource::Identifier& type)
339 {
340 if(auto name_p = std::get_if<std::string>(&type))
341 {
342 type_id_name = *name_p;
343 }
344 else if(auto id_p = std::get_if<uint16_t>(&type))
345 {
346 type_id = *id_p;
347 }
348 }
349 };
350
352 class Entry
353 {
354 public:
368 uint8_t segment = 0;
370 static constexpr uint8_t CONSTANT_VALUE = 0xFE;
372 enum flag_type : uint8_t
373 {
378 };
379 flag_type flags = flag_type(0);
381 uint16_t offset = 0;
382
383 // informational purposes
396 std::string entry_name;
397
398 enum
399 {
400 WordCountShift = 3,
401
403 INT_3Fh = 0x3FCD,
404 };
405
407 mutable bool same_bundle = false; // mutable because this isn't actually part of the entry state but the entire entry table
408
409 Entry() = default;
410
411 Entry(unsigned type, uint8_t segment, unsigned flags, uint16_t offset)
413 {
414 }
415
417 offset_t GetEntrySize() const;
418
420 uint8_t GetIndicatorByte() const;
421
423 static Entry ReadEntry(Linker::Reader& rd, uint8_t indicator_byte);
425 void WriteEntry(Linker::Writer& wr) const;
426 };
427
430 {
431 public:
433 uint16_t name_offset = 0;
435 std::string name;
436
437 ModuleReference(uint16_t name_offset, std::string name = "")
439 {
440 }
441 };
442
444 std::array<char, 2> signature{'N', 'E'};
445
447 struct version
448 {
449 uint8_t major, minor;
450 };
453
454 uint32_t crc32 = 0;
455
456 enum program_flag_type : uint8_t
457 {
470
471 GLOBAL_INITIALIZATION = 4,
472 PROTECTED_MODE_ONLY = 8,
473 CPU_8086 = 0x10, /* this is not how all systems handle this */
474 CPU_80286 = 0x20,
475 CPU_80386 = 0x40,
476 CPU_8087 = 0x80,
477 };
480
482 {
494 GUI = 3,
495
496 FAMILY_APPLICATION = 8, /* first segment loads application */
497 ERROR_IN_IMAGE = 0x20,
498
500 LIBRARY = 0x80,
501 };
504
506 uint16_t automatic_data = 0;
507
509 uint16_t stack_size = 0;
511 uint16_t heap_size = 0;
512
513 uint16_t ip = 0, cs = 0, sp = 0, ss = 0;
514
515 // The following fields are listed in the order the parts appearing in the binary instead of the fields in the header
516
522
523 std::vector<std::shared_ptr<Segment>> segments;
524
530
531 uint16_t resource_count = 0;
532
534 uint16_t resource_shift = 0;
535
537 std::vector<std::shared_ptr<Resource>> resources;
538
540 std::vector<std::shared_ptr<ResourceType>> resource_types;
541
543 std::vector<std::string> resource_strings;
544
550
551 std::vector<Name> resident_names;
552
558
559 std::vector<ModuleReference> module_references;
560
566
567 std::vector<std::string> imported_names;
568
574 uint32_t nonresident_name_table_length = 0;
575
576 std::vector<Name> nonresident_names;
577
582 uint32_t entry_table_offset = 0;
583
585 uint32_t entry_table_length = 0;
586
589
590 std::vector<Entry> entries;
591
593 uint16_t sector_shift = 9;
594
595 enum system_type : uint8_t
596 {
598 OS2 = 1,
603 Windows386 = 4,
604 BorlandOSS = 5,
605 PharLap = 0x80,
606 };
607 system_type system = system_type(0);
608
609 enum additional_flag_type : uint8_t
610 {
611 SUPPORT_LONGFILENAME = 1,
612 WIN20_PROTECTED_MODE = 2,
613 WIN20_PROPORTIONAL_FONTS = 4,
614 FAST_LOAD_AREA = 8,
615 };
616 additional_flag_type additional_flags = additional_flag_type(0);
617
618 union
619 {
620 /* Windows */
621 uint16_t fast_load_area_offset;
622 /* OS/2 ? */
623 uint16_t return_thunks_offset;
624 };
625 union
626 {
627 /* Windows */
628 uint16_t fast_load_area_length;
629 /* OS/2 ? */
630 uint16_t segment_reference_thunks_offset;
631 };
632 uint16_t code_swap_area_length = 0;
633
634 version windows_version{0, 0};
635
636 offset_t file_size = offset_t(-1);
637
638 bool IsLibrary() const;
639
640 bool IsOS2() const;
641
642 void ReadFile(Linker::Reader& rd) override;
643
644 offset_t ImageSize() const override;
645
647 offset_t WriteFile(Linker::Writer& wr) const override;
648
649 void Dump(Dumper::Dumper& dump) const override;
650
661 /*** @brief Whether to generate an executable or a library */
662 output_type output;
663
665 void SetTargetDefaults();
666
667 explicit NEFormat()
668 {
669 }
670
671 NEFormat(system_type system, output_type output)
672 : system(system), fast_load_area_offset(0), fast_load_area_length(0), output(output)
673 {
674 }
675
676 /* * * Writer members * * */
677
679 {
688 // /** @brief Attempts to mimic the output of the GNU (MinGW) linker, this is undefined for the NE output */
689 // CompatibleGNU,
690 };
691 compatibility_type compatibility = CompatibleNone;
692
694 {
695 public:
696 class SystemEnumeration : public Linker::Enumeration<system_type>
697 {
698 public:
700 : Enumeration(
701 "OS2", OS2,
702 "WIN", Windows,
703 "WINDOWS", Windows,
704 "DOS", MSDOS4,
705 "MSDOS", MSDOS4,
706 "DOS4", MSDOS4,
707 "MSDOS4", MSDOS4,
708 "WIN386", Windows386,
709 "WINDOWS386", Windows386,
710 "BOSS", BorlandOSS,
711 "BORLAND", BorlandOSS,
712 "OS2+PHARLAP", system_type(OS2 + PharLap),
713 "WIN+PHARLAP", system_type(Windows + PharLap))
714 {
715 descriptions = {
716 { OS2, "OS/2 1.0 - 1.3" },
717 { Windows, "Windows 1.0 - 3.11" },
718 { MSDOS4, "Multitasking MS-DOS 4.0" },
719 { Windows386, "Windows 386 (not supported)" },
720 { BorlandOSS, "Borland Operating System Services (not supported)" },
721 { system_type(OS2 + PharLap), "Phar Lap 286|DOS-Extender, OS/2 personality (not supported)" },
722 { system_type(Windows + PharLap), "Phar Lap 286|DOS-Extender, Windows personality (not supported)" },
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 {
738 descriptions = {
739 { OUTPUT_GUI, "creates a graphical executable (for Windows, or Presentation Manager for OS/2)" },
740 { OUTPUT_CON, "creates a console (text mode) executable (for OS/2 or Multitasking MS-DOS 4.0)" },
741 { OUTPUT_DLL, "creates a dynamic linking library (DLL)" },
742 };
743 }
744 };
745
746 class CompatibilityEnumeration : public Linker::Enumeration<compatibility_type>
747 {
748 public:
750 : Enumeration(
751 "NONE", CompatibleNone,
752 "WATCOM", CompatibleWatcom,
754 "BORLAND", CompatibleBorland)
755 //"GNU", CompatibleGNU
756 {
757 descriptions = {
758 { CompatibleNone, "default operation" },
759 { CompatibleWatcom, "mimics the Watcom linker (not implemented)" },
760 { CompatibleMicrosoft, "mimics the Microsoft linker (not implemented)" },
761 { CompatibleBorland, "mimics the Borland linker (not implemented)" },
762 /*{ CompatibleGNU, "mimics the GNU linker (not implemented)" },*/
763 };
764 }
765 };
766
767 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
768 Linker::Option<Linker::ItemOf<SystemEnumeration>> system{"system", "Target system type"};
769 Linker::Option<Linker::ItemOf<OutputTypeEnumeration>> type{"type", "Type of binary"};
770 Linker::Option<Linker::ItemOf<CompatibilityEnumeration>> compat{"compat", "Mimics the behavior of another linker"};
771 Linker::Option<std::optional<offset_t>> stack{"stack", "Specify the stack size"};
772 // TODO: make heap, target windows version, font/memory support parameters
773
774 NEOptionCollector()
775 {
776 InitializeFields(stub, system, type, compat, stack);
777 }
778 };
779
780 mutable MZStubWriter stub;
781 std::shared_ptr<Linker::Segment> stack, heap;
782 std::map<std::shared_ptr<Linker::Segment>, size_t> segment_index;
783 std::map<std::string, uint16_t> module_reference_offsets;
784 std::map<std::string, uint16_t> imported_name_offsets;
785 uint16_t imported_names_length = 0;
786 std::map<std::string, uint16_t> resource_name_offsets;
787 uint16_t resource_table_size = 4; // alignment + resource type table terminator (without string table terminator 0 byte)
788
789 /*std::string stub_file;*/
790 std::string module_name;
791 std::string program_name;
792
793 bool option_capitalize_names = false; /* TODO: parametrize */
794 enum memory_model_t
795 {
796 MODEL_SMALL,
797 MODEL_LARGE,
798 };
799 memory_model_t memory_model = MODEL_SMALL;
800
801 bool FormatSupportsSegmentation() const override;
802
803 bool FormatIs16bit() const override;
804
805 bool FormatIsProtectedMode() const override;
806
807 bool FormatSupportsLibraries() const override;
808
809 bool FormatSupportsResources() const override;
810
811 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
812
813 std::shared_ptr<NEFormat> SimulateLinker(compatibility_type compatibility);
814
815 static std::shared_ptr<NEFormat> CreateConsoleApplication(system_type system = Windows);
816
817 static std::shared_ptr<NEFormat> CreateGUIApplication(system_type system = Windows);
818
819 static std::shared_ptr<NEFormat> CreateLibraryModule(system_type system = Windows);
820
822 std::map<std::tuple<Resource::Identifier, Resource::Identifier>, std::shared_ptr<Resource>> resources_map;
823
824 unsigned GetCodeSegmentFlags() const;
825 unsigned GetDataSegmentFlags() const;
826 unsigned GetResourceFlags() const;
827 void AddResource(std::shared_ptr<Resource> resource);
828 void AddSegment(std::shared_ptr<Segment> segment);
829 uint16_t FetchModule(std::string name);
830 uint16_t FetchImportedName(std::string name);
831 uint16_t FetchResourceName(std::string name);
832 std::string MakeProcedureName(std::string name);
833 uint16_t MakeEntry(Linker::Position value);
834 uint16_t MakeEntry(uint16_t ordinal, Linker::Position value);
835 uint8_t CountBundles(size_t entry_index) const;
836
837 void SetModel(std::string model) override;
838 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
839 void SetOptions(std::map<std::string, std::string>& options) override;
840 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
841 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
842 void Link(Linker::Module& module);
843 void ProcessModule(Linker::Module& module) override;
844 void CalculateValues() override;
845 void GenerateFile(std::string filename, Linker::Module& module) override;
847 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
848 };
849
850 class ResourceFile : public virtual Linker::Format
851 {
852 public:
853 enum system_type
854 {
855 System_Unspecified,
856 System_Windows,
857 System_Windows_1x,
858 System_Windows_3x,
859 System_OS2,
860 };
861 system_type system;
862
863 ResourceFile(system_type system = System_Unspecified)
864 : system(system)
865 {
866 }
867
868 typedef std::variant<uint16_t, std::string> Identifier;
869
870 static void ReadIdentifier(Linker::Reader& rd, Identifier& id);
871 static void WriteIdentifier(Linker::Writer& wr, const Identifier& id);
872 static offset_t GetIdentifierSize(const Identifier& id);
873
875 {
876 public:
877 Identifier type;
878 Identifier name;
879 uint16_t flags;
880 std::shared_ptr<Linker::Contents> image;
881 };
882
883 offset_t file_offset;
884 std::vector<Resource> resources;
885
886 void ReadFile(Linker::Reader& rd) override;
887 void ReadFile(Linker::Reader& rd, offset_t size);
889 offset_t WriteFile(Linker::Writer& wr) const override;
890 void Dump(Dumper::Dumper& dump) const override;
891
892 class IdDisplay : public Dumper::Display<Identifier>
893 {
894 public:
895 std::map<offset_t, std::string> names;
896
897 IdDisplay()
898 {
899 }
900
901 IdDisplay(const std::map<offset_t, std::string>& names)
902 : names(names)
903 {
904 }
905
906 void DisplayValue(Dumper::Dumper& dump, std::tuple<Identifier> values) override;
907 static std::shared_ptr<IdDisplay> Make();
908 static std::shared_ptr<IdDisplay> Make(const std::map<offset_t, std::string>& names);
909 };
910 };
911}
912
913#endif /* NEEXE_H */
This class represents an entry that can be displayed in a file dump.
Definition dumper.h:92
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:773
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
A class to encode a general file format.
Definition format.h:29
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: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 neexe.h:353
offset_t GetEntrySize() const
Returns the size of an entry as stored in the file, without the first two bytes of the bundle.
Definition neexe.cc:333
uint8_t segment
The number of the segment, 1 based.
Definition neexe.h:368
void WriteEntry(Linker::Writer &wr) const
Writes an entry within a bundle.
Definition neexe.cc:389
flag_type
Flags present in an entry.
Definition neexe.h:373
@ Exported
Set if the entry is exported.
Definition neexe.h:375
@ SharedData
Set if the data segment used by the entry is global, used in SINGLEDATA modules (libraries)
Definition neexe.h:377
bool same_bundle
Convenience field to signify this entry is part of the same bundle as the previous one.
Definition neexe.h:407
uint16_t offset
Offset within the segment.
Definition neexe.h:381
export_type export_state
Whether the entry is exported. This is not actually stored in the entry table and its value is ignore...
Definition neexe.h:394
static Entry ReadEntry(Linker::Reader &rd, uint8_t indicator_byte)
Reads an entry within a bundle.
Definition neexe.cc:364
uint8_t GetIndicatorByte() const
Retrieves the segment indicator byte. For Fixed entries, this the same as the segment number.
Definition neexe.cc:349
export_type
Definition neexe.h:385
@ NotExported
The entry is not exported, the Exported bit is not set.
Definition neexe.h:387
@ ExportByOrdinal
The entry is exported by ordinal, it is referenced in the nonresident name table.
Definition neexe.h:391
@ ExportByName
The entry is exported by name, it is referenced in the resident name table.
Definition neexe.h:389
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 neexe.h:396
@ INT_3Fh
Byte code for interrupt call that must be placed in the entry field.
Definition neexe.h:403
entry_type
This field represents the type of the entry.
Definition neexe.h:357
@ Fixed
The entry references a fixed segment.
Definition neexe.h:361
@ Movable
The entry references a movable segment.
Definition neexe.h:363
@ Unused
The entry is unused, the other fields are meaningless.
Definition neexe.h:359
static constexpr uint8_t CONSTANT_VALUE
Segment value to represent a constant in the module.
Definition neexe.h:370
entry_type type
The type of entry, based on the first byte in an entry bundle.
Definition neexe.h:366
Represents an imported module in the module reference table.
Definition neexe.h:430
std::string name
The name of the module, not actually used during program generation.
Definition neexe.h:435
uint16_t name_offset
Offset to the module name within the imported names table.
Definition neexe.h:433
Windows executables bundle their resources by resource type.
Definition neexe.h:328
Represents a resource entry.
Definition neexe.h:245
uint16_t handle
Reserved field, named so in Microsoft documentation.
Definition neexe.h:266
uint16_t usage
Reserved field, named so in Microsoft documentation.
Definition neexe.h:268
std::optional< std::string > type_id_name
Type name, used only by Windows.
Definition neexe.h:257
std::optional< std::string > id_name
Resource name, used only by Windows.
Definition neexe.h:264
uint16_t type_id
Type identifier, used by both Windows and OS/2.
Definition neexe.h:255
std::string import_name
Convenience field that stores the imported procedure name, if imported by name, also the name for an ...
Definition neexe.h:215
uint8_t actual_segment
Convenience field that stores the actual segment for an entry.
Definition neexe.h:217
flag_type flags
The type of target.
Definition neexe.h:195
source_type
The type of the field that needs to be updated in the binary image.
Definition neexe.h:156
@ Offset16
A 16-bit offset within its preferred segment.
Definition neexe.h:164
@ Selector16
A 16-bit segment selector value (or paragraph in real mode)
Definition neexe.h:160
@ Offset32
A 32-bit offset within its preferred segment.
Definition neexe.h:168
@ Pointer48
A 48-bit far pointer, 16-bit segment and 32-bit offset value.
Definition neexe.h:166
@ Offset8
Lower 8 bits of value.
Definition neexe.h:158
@ Pointer32
A 32-bit far pointer, 16-bit segment and 16-bit offset value.
Definition neexe.h:162
uint16_t target
This field is an offset or ordinal, depending on the flags.
Definition neexe.h:210
flag_type
Encodes what the type of the target is for this relocation.
Definition neexe.h:174
@ TargetTypeMask
Mask to get the type of the target.
Definition neexe.h:176
@ Internal
An internal segment:offset, or if segment is 0xFF, offset is the entry number.
Definition neexe.h:178
@ Additive
Whether the relocation has an added in the image or it is the first element in a relocation chain.
Definition neexe.h:192
@ ImportName
An imported module:offset where module is the module number and offset is an offset to the name.
Definition neexe.h:182
@ OSFixup
This is actually an 80x87 instruction sequence that needs to be fixed up for 80x87 emulation.
Definition neexe.h:184
@ ImportOrdinal
An imported module:ordinal where module is the module number.
Definition neexe.h:180
source_type type
The type of relocation.
Definition neexe.h:171
std::string module_name
Convenience field that stores the module name.
Definition neexe.h:213
std::vector< uint16_t > offsets
The offset to the relocation, or if the relocation is chained, a list of offsets (this is not possibl...
Definition neexe.h:197
uint16_t
This field is a segment (1 based) or module (1 based) or 80x87 instruction reference,...
Definition neexe.h:199
uint16_t actual_offset
Convenience field that stores the actual offset for an entry.
Definition neexe.h:219
Represents an NE segment as stored in the segment table and segment data.
Definition neexe.h:108
uint32_t total_size
Size of segment as stored in memory.
Definition neexe.h:130
offset_t image_size
Size of segment as stored in the file, only used during reading.
Definition neexe.h:113
std::map< uint16_t, Relocation > relocations_map
Used internally during output generation.
Definition neexe.h:234
uint16_t movable_entry_index
Entry number for movable segments (field not present in segment table)
Definition neexe.h:135
NE .EXE new executable file format.
Definition neexe.h:94
void SetTargetDefaults()
Configures the values for system/output type.
Definition neexe.cc:1300
uint32_t imported_names_table_offset
Offset of imported names table, containing the names of imported modules and procedures imported by n...
Definition neexe.h:565
output_type
Represents the target image type.
Definition neexe.h:653
@ OUTPUT_CON
A console executable image, conventionally taking the suffix .exe
Definition neexe.h:657
@ OUTPUT_DLL
A dynamically linked library, conventionally taking the suffix .dll
Definition neexe.h:659
@ OUTPUT_GUI
A graphical executable image, conventionally taking the suffix .exe
Definition neexe.h:655
uint32_t segment_table_offset
Offset of segment table.
Definition neexe.h:521
uint16_t heap_size
Size of initial heap, added to the size of the automatic data segment.
Definition neexe.h:511
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition neexe.cc:840
uint32_t resident_name_table_offset
Offset of resident name table, containing this module's name and the names and ordinals of procedures...
Definition neexe.h:549
program_flag_type
Definition neexe.h:457
@ MULTIPLEDATA
There is an automatic data segment for each task instance, used for applications (EXE)
Definition neexe.h:469
@ NODATA
There are no automatic data segments.
Definition neexe.h:459
@ SINGLEDATA
There is a single, shared automatic segment, used for libraries (DLL)
Definition neexe.h:464
program_flag_type program_flags
Properties of the program during execution.
Definition neexe.h:479
compatibility_type
Definition neexe.h:679
@ CompatibleWatcom
Attempts to mimic the output of the Watcom linker.
Definition neexe.h:683
@ CompatibleBorland
Attempts to mimic the output of the Borland linker (TODO: unimplemented)
Definition neexe.h:687
@ CompatibleMicrosoft
Attempts to mimic the output of the Microsoft linker (TODO: unimplemented)
Definition neexe.h:685
@ CompatibleNone
No emulation is attempted.
Definition neexe.h:681
application_flag_type
Definition neexe.h:482
@ GUI
Graphical application.
Definition neexe.h:494
@ GUI_AWARE
Application is well behaved when running in windowed mode.
Definition neexe.h:492
@ LIBRARY
Set for library modules (DLL)
Definition neexe.h:500
@ FULLSCREEN
Application can only run in full screen mode.
Definition neexe.h:487
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition neexe.cc:1646
bool FormatSupportsSegmentation() const override
Whether the format supports multiple segments.
Definition neexe.cc:1353
std::vector< std::shared_ptr< ResourceType > > resource_types
For non-OS/2 targets, the resources get organized according to their types.
Definition neexe.h:540
uint32_t resource_table_offset
Offset of resource table.
Definition neexe.h:529
uint16_t resource_shift
Specifies the shift count to get the actual offsets for the resource data.
Definition neexe.h:534
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition neexe.cc:2209
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition neexe.cc:1641
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition neexe.cc:2372
uint32_t entry_table_length
Size of entry table in bytes.
Definition neexe.h:585
uint16_t automatic_data
Automatic data segment number, starting from 1, only used for SINGLEDATA/MULTIPLEDATA.
Definition neexe.h:506
std::vector< std::shared_ptr< Resource > > resources
On OS/2, this is a sequence of resources, for non-OS/2 targets, this must be compiled into resource_t...
Definition neexe.h:537
uint16_t stack_size
Size of initial stack, added to the size of the automatic data segment.
Definition neexe.h:509
bool FormatIs16bit() const override
Whether the format is 16-bit or not.
Definition neexe.cc:1358
bool FormatIsProtectedMode() const override
Whether the format is in protected mode or not (x86 only)
Definition neexe.cc:1363
bool FormatSupportsResources() const override
Whether the format supports resources.
Definition neexe.cc:1374
version linker_version
Version of the linker.
Definition neexe.h:452
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition neexe.cc:418
application_flag_type application_flags
Properties of the application.
Definition neexe.h:503
std::map< std::tuple< Resource::Identifier, Resource::Identifier >, std::shared_ptr< Resource > > resources_map
Map from resource type/name to a resource, only used during binary generation.
Definition neexe.h:822
system_type
Definition neexe.h:596
@ OS2
Used for OS/2 1.0 - 1.3.
Definition neexe.h:598
@ MSDOS4
Signifies Multitasking MS-DOS 4.0.
Definition neexe.h:602
@ Windows
Used for Windows 1.0 - 3.11.
Definition neexe.h:600
uint16_t movable_entry_count
Number of movable entries in the entry table.
Definition neexe.h:588
offset_t ImageSize() const override
Retrieves size of stored data.
Definition neexe.cc:835
uint32_t entry_table_offset
Offset of entry table.
Definition neexe.h:582
std::array< char, 2 > signature
The signature, almost always "NE".
Definition neexe.h:444
bool FormatSupportsLibraries() const override
Whether the format supports libraries.
Definition neexe.cc:1369
std::vector< std::string > resource_strings
For non-OS/2 targets, this is a list of all the resource type strings and resource strings.
Definition neexe.h:543
void SetModel(std::string model) override
Sets the way memory is organized, typically modifying a built-in script.
Definition neexe.cc:2339
uint16_t sector_shift
Specifies the shift count to get the actual offsets of segments.
Definition neexe.h:593
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition neexe.cc:2356
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition neexe.cc:1895
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition neexe.cc:1042
uint32_t nonresident_name_table_offset
Offset of non-resident names table, containing this module's description and the names of procedures ...
Definition neexe.h:573
uint32_t module_reference_table_offset
Offset of module reference table, containing 16-bit offsets to the names of the imported modules in t...
Definition neexe.h:557
Definition neexe.h:875
Definition neexe.h:851
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition neexe.cc:2460
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition neexe.cc:2474
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition neexe.cc:2452
A name and ordinal pair, as used for resident and non-resident names.
Definition neexe.h:100
Version number.
Definition neexe.h:448