RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
peexe.h
1#ifndef PEEXE_H
2#define PEEXE_H
3
4#include <array>
5#include "../common.h"
6#include "../dumper/dumper.h"
7#include "../linker/options.h"
8#include "../linker/segment_manager.h"
9#include "coff.h"
10#include "mzexe.h"
11#include "neexe.h"
12
13namespace Microsoft
14{
19 {
20 public:
21 std::array<char, 4> pe_signature;
22
25 {
26 uint16_t major, minor;
27 };
28
31 {
32 public:
34 static constexpr uint16_t ROM32 = 0x0107;
36 static constexpr uint16_t EXE32 = 0x010B;
38 static constexpr uint16_t EXE64 = 0x020B;
39
41 static constexpr offset_t Win32Base = 0x00400000;
43 static constexpr offset_t Dll32Base = 0x10000000;
45 static constexpr offset_t WinCEBase = 0x00010000;
47 static constexpr offset_t Win64Base = 0x140000000;
49 static constexpr offset_t Dll64Base = 0x180000000;
50
54 offset_t image_base = 0;
58 uint32_t section_align = 0;
62 uint32_t file_align = 0;
78 uint32_t win32_version = 0;
82 uint32_t total_image_size = 0;
86 uint32_t total_headers_size = 0;
90 uint32_t checksum = 0;
92 enum SubsystemType : uint16_t
93 {
94 Unknown = 0,
95 Native = 1,
96 WindowsGUI = 2,
97 WindowsCUI = 3,
98 OS2CUI = 5,
99 POSIXCUI = 7,
100 NativeWin95 = 8,
101 WinCEGUI = 9,
102 EFIApplication = 10,
103 EFIBootServiceDriver = 11,
104 EFIRuntimeDriver = 12,
105 EFIROM = 13,
106 Xbox = 14,
107 WindowsBootApplication = 16,
108 };
116 uint16_t flags = 0;
128 offset_t reserved_heap_size = 0;
136 uint32_t loader_flags = 0;
137
140 {
141 uint32_t address = 0, size = 0;
142 };
143
144 enum
145 {
146 DirExportTable,
147 DirImportTable,
148 DirResourceTable,
149 DirExceptionTable,
150 DirCertificateTable,
151 DirBaseRelocationTable,
152 DirDebug,
153 DirArchitecture, // reserved
154 DirGlobalPointer,
155 DirTLSTable,
156 DirLoadConfigTable,
157 DirBoundImport,
158 DirIAT,
159 DirDelayImportDescriptor,
160 DirCLRRuntimeHeader,
161 DirReserved,
162 DirTotalCount,
163 };
164
168 std::vector<DataDirectory> data_directories;
169
171 bool Is64Bit() const;
172
174 : AOutHeader()
175 {
176 }
177
178 uint32_t GetSize() const override;
179
180 void ReadFile(Linker::Reader& rd) override;
181
182 void WriteFile(Linker::Writer& wr) const override;
183
184 offset_t CalculateValues(COFFFormat& coff) override;
185
187 uint32_t AddressToRVA(offset_t address) const;
189 offset_t RVAToAddress(uint32_t rva, bool suppress_on_zero = false) const;
190
191 protected:
192 void DumpFields(const COFFFormat& coff, Dumper::Dumper& dump, Dumper::Region& header_region) const override;
193 };
194
196 PEOptionalHeader& GetOptionalHeader();
198 const PEOptionalHeader& GetOptionalHeader() const;
199
201 bool Is64Bit() const;
202
204 uint32_t AddressToRVA(offset_t address) const;
206 offset_t RVAToAddress(uint32_t rva, bool suppress_on_zero = false) const;
208 offset_t RVAToFileOffset(uint32_t rva) const;
209
212 {
213 public:
214 // TODO: other flags
216 static constexpr uint32_t DISCARDABLE = 0x02000000;
218 static constexpr uint32_t EXECUTE = 0x20000000;
220 static constexpr uint32_t READ = 0x40000000;
222 static constexpr uint32_t WRITE = 0x80000000;
223
224 Section(uint32_t flags = 0, std::shared_ptr<Linker::Contents> image = nullptr)
225 : COFFFormat::Section(flags, image)
226 {
227 }
228
230 constexpr offset_t& virtual_size() { return physical_address; }
232 constexpr const offset_t& virtual_size() const { return physical_address; }
233
234 void ReadSectionData(Linker::Reader& rd, const COFFFormat& coff_format) override;
235 void WriteSectionData(Linker::Writer& wr, const COFFFormat& coff_format) const override;
236 uint32_t ImageSize(const COFFFormat& coff_format) const override;
237 void Dump(Dumper::Dumper& dump, const COFFFormat& format, unsigned section_index) const override;
238
240 virtual void ReadSectionData(Linker::Reader& rd, const PEFormat& fmt);
242 virtual void WriteSectionData(Linker::Writer& wr, const PEFormat& fmt) const;
244 virtual uint32_t ImageSize(const PEFormat& fmt) const;
246 virtual uint32_t MemorySize(const PEFormat& fmt) const;
247
248 size_t ReadData(size_t bytes, size_t offset, void * buffer) const;
249 };
250
253 {
254 const PEFormat * pe;
255 struct iterator
256 {
257 std::vector<std::shared_ptr<COFFFormat::Section>>::iterator coff_iterator;
258 bool operator !=(const iterator& other) const;
259 iterator& operator++();
260 std::shared_ptr<PEFormat::Section> operator*() const;
261 };
263 {
264 std::vector<std::shared_ptr<COFFFormat::Section>>::const_iterator coff_iterator;
265 bool operator !=(const const_iterator& other) const;
266 const_iterator& operator++();
267 std::shared_ptr<const PEFormat::Section> operator*() const;
268 };
270 {
271 std::vector<std::shared_ptr<COFFFormat::Section>>::const_reference coff_reference;
272 PEFormat::Section * get() const;
273 PEFormat::Section * operator->() const;
274 };
275 iterator begin();
276 const_iterator begin() const;
277 iterator end();
278 const_iterator end() const;
279 size_t size() const;
280 const_reference back() const;
281 };
282
284 const PESections Sections() const;
287
300 size_t MapRVAToSectionData(uint32_t rva, size_t bytes, std::shared_ptr<Section>& found_section, size_t& section_offset) const;
301
303 size_t ReadData(size_t bytes, uint32_t rva, void * buffer) const;
305 uint64_t ReadUnsigned(size_t bytes, uint32_t rva, ::EndianType endiantype) const;
307 uint64_t ReadSigned(size_t bytes, uint32_t rva, ::EndianType endiantype) const;
309 std::string ReadASCII(uint32_t rva, char terminator, size_t maximum = size_t(-1)) const;
311 std::string ReadData(uint32_t rva, size_t count) const;
312
313 class MemoryPortionImage : public virtual Linker::Image
314 {
315 public:
316 const PEFormat& fmt;
317 uint32_t rva;
318 uint32_t size;
319
320 MemoryPortionImage(const PEFormat& fmt, uint32_t rva, uint32_t size)
321 : fmt(fmt), rva(rva), size(size)
322 {
323 }
324
325 offset_t ImageSize() const override;
327 offset_t WriteFile(Linker::Writer& wr, offset_t count, offset_t offset = 0) const override;
328 size_t ReadData(size_t bytes, offset_t offset, void * buffer) const override;
329 };
330
333 {
334 public:
336 typedef std::variant<std::string, uint32_t> Identifier;
337
339 static constexpr size_t Level_Type = 0;
341 static constexpr size_t Level_Name = 1;
343 static constexpr size_t Level_Language = 2;
345 static constexpr size_t Level_Count = 3;
346
348 static void DumpIdentifier(std::vector<Identifier> full_identifier, Dumper::Container& container);
349
351 std::vector<Identifier> full_identifier;
353 uint32_t data_rva = 0;
355 uint32_t size = 0;
357 uint32_t codepage = 0;
359 uint32_t reserved = 0;
360
362 std::shared_ptr<Linker::Section> section = nullptr;
363
364 Resource(const std::vector<Resource::Identifier>& full_identifier)
366 {
367 }
368
370 size_t ParseResourceData(const PEFormat& fmt, uint32_t rva);
372 void DumpResource(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t rva) const;
374 uint32_t AssignAddress(PEFormat& fmt, uint32_t rva);
376 void WriteDirectories(Linker::Writer& wr, const PEFormat& fmt, uint32_t section_pointer) const;
378 offset_t WriteResource(Linker::Writer& wr, const PEFormat& fmt, uint32_t rva_to_offset) const;
379 };
380
381 class ResourcesSection;
382
384 {
385 public:
386 class Name
387 {
388 public:
389 std::string name;
390 uint32_t offset = 0;
391
392 Name(std::string name = "")
393 : name(name)
394 {
395 }
396 };
397
399 template <typename Key>
400 class Entry
401 {
402 public:
406 std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourceDirectory>> content;
408 uint32_t content_offset = 0;
409
410 bool IsSubdirectory() const { return std::get_if<std::shared_ptr<ResourceDirectory>>(&content); }
411 };
412
414 uint32_t flags = 0;
415 uint32_t timestamp = 0;
416 version_type version = { };
418 std::vector<Entry<Name>> name_entries;
420 std::vector<Entry<uint32_t>> id_entries;
421
427 void AddResource(std::shared_ptr<Resource>& resource, size_t level = 0);
428
430 size_t ParseResourceDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t rva, const std::vector<Resource::Identifier>& partial_identifier);
432 void DumpResourceDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t rva, const std::vector<Resource::Identifier>& partial_identifier, size_t dump_level) const;
434 uint32_t CalculateDirectoryOffsets(PEFormat& fmt, uint32_t offset, size_t level_deeper);
436 void CollectSubdirectoryStrings(PEFormat& fmt, ResourcesSection& rsrc, size_t level_deeper);
438 uint32_t CollectResourceData(PEFormat& fmt, uint32_t rva, size_t level_deeper);
440 void WriteDirectories(Linker::Writer& wr, const PEFormat& fmt, uint32_t section_pointer) const;
442 offset_t WriteResources(Linker::Writer& wr, const PEFormat& fmt, uint32_t rva_to_offset) const;
443 };
444
447 {
448 public:
450 : Section(DATA | READ)
451 {
452 name = ".rsrc";
453 }
454
455 size_t max_depth = 0;
456 protected:
457 std::vector<std::string> string_table;
458 std::map<std::string, uint32_t> string_table_map;
459 uint32_t string_table_offset = 0;
460 uint32_t string_table_end_offset = 0;
461 public:
462 uint32_t FetchString(std::string s);
463
464 using Section::ReadSectionData;
465 using Section::WriteSectionData;
466 using Section::ImageSize;
467
468 bool IsPresent() const;
469 void Generate(PEFormat& fmt);
470 void ReadSectionData(Linker::Reader& rd, const PEFormat& fmt) override;
471 void WriteSectionData(Linker::Writer& wr, const PEFormat& fmt) const override;
472 uint32_t ImageSize(const PEFormat& fmt) const override;
473 uint32_t MemorySize(const PEFormat& fmt) const override;
474
476 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
478 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
479 };
480
482 std::shared_ptr<ResourcesSection> resources = std::make_shared<ResourcesSection>();
483
486 {
487 public:
488 typedef uint16_t Ordinal;
489
491 class Name
492 {
493 public:
495 uint16_t hint;
497 std::string name = "";
499 uint32_t rva = 0;
500
501 Name(std::string name, uint16_t hint = 0)
502 : hint(hint), name(name)
503 {
504 }
505 };
506
508 typedef std::variant<Ordinal, Name> ImportTableEntry;
509
511 uint32_t lookup_table_rva = 0;
513 uint32_t address_table_rva = 0;
514 uint32_t timestamp = 0;
515 uint32_t forwarder_chain = 0;
517 std::string name;
519 uint32_t name_rva = 0;
520
522 std::vector<ImportTableEntry> import_table;
524 std::map<std::string, size_t> imports_by_name;
526 std::map<Ordinal, size_t> imports_by_ordinal;
527
529 void AddImportByName(std::string entry_name, uint16_t hint);
531 void AddImportByOrdinal(uint16_t ordinal);
532
534 offset_t GetImportByNameAddress(const PEFormat& fmt, std::string name);
536 offset_t GetImportByOrdinalAddress(const PEFormat& fmt, uint16_t ordinal);
537
538 ImportedLibrary(std::string name)
539 : name(name)
540 {
541 }
542 };
543
545 class ImportsSection : public Section
546 {
547 public:
549 std::vector<ImportedLibrary> libraries;
551 std::map<std::string, size_t> library_indexes;
552
557
559 : Section(DATA | READ | WRITE)
560 {
561 name = ".idata";
562 }
563
564 using Section::ReadSectionData;
565 using Section::WriteSectionData;
566 using Section::ImageSize;
567
568 bool IsPresent() const;
569 void Generate(PEFormat& fmt);
570 void ReadSectionData(Linker::Reader& rd, const PEFormat& fmt) override;
571 void WriteSectionData(Linker::Writer& wr, const PEFormat& fmt) const override;
572 uint32_t ImageSize(const PEFormat& fmt) const override;
573 uint32_t MemorySize(const PEFormat& fmt) const override;
574
576 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
578 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
579 };
580
582 std::shared_ptr<ImportsSection> imports = std::make_shared<ImportsSection>();
583
586 {
587 public:
594 {
595 public:
597 std::string dll_name;
599 std::variant<std::string, uint32_t> reference;
601 std::string reference_name;
603 uint32_t rva;
604 };
605
607 class Name
608 {
609 public:
611 std::string name;
613 uint32_t rva = 0;
614
615 Name(std::string name)
616 : name(name)
617 {
618 }
619 };
620
622 std::variant<uint32_t, Forwarder> value;
624 std::optional<Name> name;
625
626 ExportedEntry(uint32_t rva)
627 : value(rva), name()
628 {
629 }
630
631 ExportedEntry(uint32_t rva, std::string name)
632 : value(rva), name(name)
633 {
634 }
635
636 ExportedEntry(Forwarder fwd)
637 : value(fwd), name()
638 {
639 }
640 };
641
643 class ExportsSection : public Section
644 {
645 public:
646 uint32_t flags = 0;
647 uint32_t timestamp = 0;
648 version_type version = { };
650 std::string dll_name;
652 uint32_t dll_name_rva = 0;
654 uint32_t ordinal_base = 1;
658 uint32_t address_table_rva = 0;
660 uint32_t name_table_rva = 0;
662 uint32_t ordinal_table_rva = 0;
664 std::map<uint32_t, std::shared_ptr<ExportedEntry>> entries;
666 std::map<std::string, uint32_t> named_exports;
667
669 void SetEntry(PEFormat& fmt, uint32_t ordinal, std::shared_ptr<ExportedEntry> entry);
671 void AddEntry(PEFormat& fmt, std::shared_ptr<ExportedEntry> entry);
672
674 : Section(DATA | READ)
675 {
676 name = ".edata";
677 // TODO: flags and other fields
678 }
679
680 using Section::ReadSectionData;
681 using Section::WriteSectionData;
682 using Section::ImageSize;
683
684 bool IsPresent() const;
685 void Generate(PEFormat& fmt);
686 void ReadSectionData(Linker::Reader& rd, const PEFormat& fmt) override;
687 void WriteSectionData(Linker::Writer& wr, const PEFormat& fmt) const override;
688 uint32_t ImageSize(const PEFormat& fmt) const override;
689 uint32_t MemorySize(const PEFormat& fmt) const override;
690
692 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
694 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
695 };
696
698 std::shared_ptr<ExportsSection> exports = std::make_shared<ExportsSection>();
699
750
753 {
754 public:
756 static constexpr uint32_t PAGE_SIZE = 0x1000;
758 uint32_t page_rva;
760 uint32_t block_size;
762 std::vector<BaseRelocation> relocations_list;
764 std::map<uint16_t, BaseRelocation> relocations_map;
765
766 BaseRelocationBlock(uint32_t page_rva = 0)
767 : page_rva(page_rva & ~(PAGE_SIZE - 1))
768 {
769 }
770 };
771
774 {
775 public:
777 std::vector<std::shared_ptr<BaseRelocationBlock>> blocks_list;
779 std::map<uint32_t, std::shared_ptr<BaseRelocationBlock>> blocks_map;
780
783 {
784 name = ".reloc";
785 }
786
787 using Section::ReadSectionData;
788 using Section::WriteSectionData;
789 using Section::ImageSize;
790
791 bool IsPresent() const;
792 void Generate(PEFormat& fmt);
793 void ReadSectionData(Linker::Reader& rd, const PEFormat& fmt) override;
794 void WriteSectionData(Linker::Writer& wr, const PEFormat& fmt) const override;
795 uint32_t ImageSize(const PEFormat& fmt) const override;
796 uint32_t MemorySize(const PEFormat& fmt) const override;
797
799 void ParseDirectoryData(const PEFormat& fmt, uint32_t directory_rva, uint32_t directory_size);
801 void DumpDirectory(const PEFormat& fmt, Dumper::Dumper& dump, uint32_t directory_rva, uint32_t directory_size) const;
802 };
803
805 std::shared_ptr<BaseRelocationsSection> base_relocations = std::make_shared<BaseRelocationsSection>();
806
813 void AddBaseRelocation(uint32_t rva, BaseRelocation::relocation_type type, uint16_t low_ref = 0);
814
815 mutable MZStubWriter stub;
816
817 void ReadFile(Linker::Reader& rd) override;
818
819 ::EndianType GetMachineEndianType() const;
820 void CalculateValues() override;
821
823 offset_t WriteFile(Linker::Writer& wr) const override;
824 void Dump(Dumper::Dumper& dump) const override;
825
839
840 compatibility_type compatibility = CompatibleNone;
841
844 {
852 TargetMacintosh, // TODO: not supported
856 TargetTNT, // TODO: not supported
858 TargetEFI, // TODO: not supported
860 TargetDotNET, // TODO: not supported
862 TargetXbox, // TODO: not supported
863 //TargetBeOS, // TODO: possible target
864 //TargetSkyOS, // TODO: possible target
865 //TargetHXDOS, // TODO: possible target
866 };
869
880 /*** @brief Whether to generate an executable, library or system file */
881 output_type output = OUTPUT_EXE;
882
883 PEFormat(target_type target = TargetWinNT, PEOptionalHeader::SubsystemType subsystem = PEOptionalHeader::WindowsGUI, output_type output = OUTPUT_EXE)
884 : COFFFormat(WINDOWS, PECOFF, ::LittleEndian), target(target), output(output)
885 {
886 optional_header = std::make_unique<PEOptionalHeader>();
887 GetOptionalHeader().subsystem = subsystem;
888 }
889
890 public:
891 /* * * Writer members * * */
892
895
898
901
904
906 bool option_debug_info = false;
907
910
912 std::shared_ptr<Linker::Segment> import_thunk_segment = nullptr;
913
914 Linker::Module * current_module = nullptr;
915 std::map<std::pair<std::string, std::string>, uint32_t> import_thunks_by_name;
916 std::map<std::pair<std::string, uint16_t>, uint32_t> import_thunks_by_ordinal;
917
919 {
920 public:
921 class TargetEnumeration : public Linker::Enumeration<target_type>
922 {
923 public:
925 : Enumeration(
926 "WIN9X", TargetWin9x,
927 "WINNT", TargetWinNT,
928 "WINCE", TargetWinCE,
929 "MACINTOSH", TargetMacintosh,
930 "WIN32S", TargetWin32s,
931 "TNT", TargetTNT,
932 "EFI", TargetEFI,
933 "DOTNET", TargetDotNET,
934 "XBOX", TargetXbox)
935 {
936 descriptions = {
937 { TargetWin9x, "targets Windows 95/98/ME" },
938 { TargetWinNT, "targets Windows NT" },
939 { TargetWinCE, "targets Windows CE/Windows Phone/Windows Mobile (pre-8)" },
940 { TargetMacintosh, "targets the Windows Portability Library on Macintosh (not implemented)" },
941 { TargetWin32s, "targets the Win32s layer for Windows 3.11" },
942 { TargetTNT, "targets the Phar Lap TNT DOS Extender (not implemented)" },
943 { TargetEFI, "targets EFI/UEFI (not implemented)" },
944 { TargetDotNET, "targets the .NET environment (not implemented)" },
945 { TargetXbox, "targets Xbox (not implemented)" },
946 //{ TargetBeOS, "targets BeOS x86 up to Release 3.2" },
947 //{ TargetSkyOS, "targets SkyOS" },
948 //{ TargetHXDOS, "targets the HX-DOS DOS extender" },
949 };
950 }
951 };
952
953 enum subsystem_determination
954 {
955 Subsystem_Windows = 1,
956 Subsystem_Console,
957 Subsystem_Native,
958 Subsystem_OS2,
959 Subsystem_POSIX,
960 Subsystem_EFIApplication,
961 Subsystem_EFIBootServiceDriver,
962 Subsystem_EFIRuntimeDriver,
963 Subsystem_EFI_ROM,
964 Subsystem_BootApplication,
965 };
966
967 class SubsystemEnumeration : public Linker::Enumeration<subsystem_determination>
968 {
969 public:
971 : Enumeration(
972 "WINDOWS", Subsystem_Windows,
973 "CONSOLE", Subsystem_Console,
974 "NATIVE", Subsystem_Native,
975 "OS2", Subsystem_OS2,
976 "POSIX", Subsystem_POSIX,
977 "EFI_APPLICATION", Subsystem_EFIApplication,
978 "EFI_BOOT_SERVICE_DRIVER", Subsystem_EFIBootServiceDriver,
979 "EFI_RUNTIME_DRIVER", Subsystem_EFIRuntimeDriver,
980 "EFI_ROM", Subsystem_EFI_ROM,
981 "BOOT_APPLICATION", Subsystem_BootApplication)
982 {
983 descriptions = {
984 { Subsystem_Windows, "creates a graphical program" },
985 { Subsystem_Console, "creates a console (text mode) program" },
986 { Subsystem_Native, "creates a native Windows NT kernel program" },
987 { Subsystem_OS2, "creates a program that uses the OS/2 personality" },
988 { Subsystem_POSIX, "creates a program that uses the POSIX personality" },
989 { Subsystem_EFIApplication, "creates an EFI application" },
990 { Subsystem_EFIBootServiceDriver, "creates an EFI boot service driver" },
991 { Subsystem_EFIRuntimeDriver, "creates an EFI run-time driver" },
992 { Subsystem_EFI_ROM, "creates an EFI ROM image" },
993 { Subsystem_BootApplication, "creates a Windows boot application" },
994 };
995 }
996 };
997
998 class OutputTypeEnumeration : public Linker::Enumeration<output_type>
999 {
1000 public:
1002 : Enumeration(
1003 "EXE", OUTPUT_EXE,
1004 "DLL", OUTPUT_DLL,
1005 "SYS", OUTPUT_SYS)
1006 {
1007 descriptions = {
1008 { OUTPUT_EXE, "creates an executable" },
1009 { OUTPUT_DLL, "creates a dynamic linking library (DLL)" },
1010 { OUTPUT_SYS, "creates a system program" }
1011 };
1012 }
1013 };
1014
1015 class CompatibilityEnumeration : public Linker::Enumeration<compatibility_type>
1016 {
1017 public:
1019 : Enumeration(
1020 "NONE", CompatibleNone,
1021 "WATCOM", CompatibleWatcom,
1022 "MS", CompatibleMicrosoft,
1023 "BORLAND", CompatibleBorland,
1024 "GNU", CompatibleGNU)
1025 {
1026 descriptions = {
1027 { CompatibleNone, "default operation" },
1028 { CompatibleWatcom, "mimics the Watcom linker (not implemented)" },
1029 { CompatibleMicrosoft, "mimics the Microsoft linker (not implemented)" },
1030 { CompatibleBorland, "mimics the Borland linker (not implemented)" },
1031 { CompatibleGNU, "mimics the GNU (MinGW) linker (not implemented)" },
1032 };
1033 }
1034 };
1035
1036 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
1037 Linker::Option<Linker::ItemOf<TargetEnumeration>> target{"target", "Windows target type"};
1038 Linker::Option<Linker::ItemOf<SubsystemEnumeration>> subsystem{"subsystem", "Windows subsystem to target"};
1039 Linker::Option<Linker::ItemOf<OutputTypeEnumeration>> output{"output", "Output types"};
1040 Linker::Option<Linker::ItemOf<CompatibilityEnumeration>> compat{"compat", "Mimics the behavior of another linker"};
1041 Linker::Option<offset_t> image_base{"base", "Base address of image, used for calculating relative virtual addresses"};
1042 Linker::Option<offset_t> section_align{"section_align", "Section alignment"};
1043 Linker::Option<bool> import_thunks{"import_thunks", "Create thunk procedures for imported names"};
1044 // TODO: make stack size a parameter
1045
1046 PEOptionCollector()
1047 {
1048 InitializeFields(stub, target, subsystem, output, compat, image_base, section_align, import_thunks);
1049 }
1050 };
1051
1052 static std::shared_ptr<PEFormat> CreateConsoleApplication(target_type target = TargetWinNT, PEOptionalHeader::SubsystemType subsystem = PEOptionalHeader::WindowsCUI);
1053
1054 static std::shared_ptr<PEFormat> CreateGUIApplication(target_type target = TargetWinNT, PEOptionalHeader::SubsystemType subsystem = PEOptionalHeader::WindowsGUI);
1055
1056 static std::shared_ptr<PEFormat> CreateLibraryModule(target_type target = TargetWinNT);
1057
1058 static std::shared_ptr<PEFormat> CreateDeviceDriver(target_type target = TargetWinNT);
1059
1060 std::shared_ptr<PEFormat> SimulateLinker(compatibility_type compatibility);
1061
1062 bool FormatSupportsLibraries() const override;
1063
1064 bool FormatSupportsResources() const override;
1065
1066 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
1067
1068 std::shared_ptr<Resource>& AddResource(std::shared_ptr<Resource>& resource);
1069
1070 ImportedLibrary& FetchImportLibrary(std::string library_name, bool create_if_not_present = false);
1071 void AddImportByName(std::string library_name, std::string entry_name, uint16_t hint);
1072 void AddImportByOrdinal(std::string library_name, uint16_t ordinal);
1073
1074 static std::vector<Linker::OptionDescription<void> *> ParameterNames;
1075 std::vector<Linker::OptionDescription<void> *> GetLinkerScriptParameterNames() override;
1076 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
1077
1079 enum
1080 {
1082 FLAG_NO_RELOCATIONS = 0x0001, // already defined in COFF
1084 FLAG_EXECUTABLE = 0x0002, // already defined in COFF
1086 FLAG_NO_LINE_NUMBERS = 0x0004, // already defined in COFF
1088 FLAG_NO_SYMBOLS = 0x0008, // already defined in COFF
1096 FLAG_32BIT = 0x0100,
1104 FLAG_SYSTEM = 0x1000,
1111 };
1112
1113 void SetOptions(std::map<std::string, std::string>& options) override;
1114 void AllocateSymbols(Linker::Module& module) const override;
1115 void OnCallDirective(std::string identifier) override;
1116 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
1117 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
1118 void Link(Linker::Module& module);
1119
1127 offset_t GenerateResourceSection(Linker::Module& module, offset_t image_end);
1128
1136 offset_t GenerateImportSection(Linker::Module& module, offset_t image_end);
1137
1145 offset_t GenerateExportSection(Linker::Module& module, offset_t image_end);
1146
1154 offset_t GenerateBaseRelocationSection(Linker::Module& module, offset_t image_end);
1155
1159 void ProcessRelocations(Linker::Module& module);
1160
1164 void FixupImportThunk(Linker::Module& module, offset_t offset, offset_t address);
1165
1166 offset_t GetMemoryImageEnd() const;
1167 void ProcessModule(Linker::Module& module) override;
1168 void GenerateFile(std::string filename, Linker::Module& module) override;
1170 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
1171
1175 class RVADisplay : public Dumper::Display<offset_t>
1176 {
1177 public:
1178 const PEFormat * pe;
1179 unsigned width;
1180 RVADisplay(const PEFormat * pe, unsigned width)
1181 : pe(pe), width(width)
1182 {
1183 }
1184
1185 void DisplayValue(Dumper::Dumper& dump, std::tuple<offset_t> values) override;
1186 };
1187
1188 std::shared_ptr<RVADisplay> MakeRVADisplay(unsigned width = 8) const;
1189 };
1190
1191 class NTResourceFile : public virtual Linker::Format
1192 {
1193 public:
1194 typedef ResourceFile::Identifier Identifier;
1195
1196 static void ReadIdentifier(Linker::Reader& rd, Identifier& id);
1197 static void WriteIdentifier(Linker::Writer& wr, const Identifier& id);
1198 static offset_t GetIdentifierSize(const Identifier& id);
1199
1201 {
1202 public:
1203 uint32_t header_size;
1204 uint32_t data_version;
1205 uint16_t language_id;
1206 uint32_t version;
1207 uint32_t characteristics;
1208 };
1209
1210 offset_t file_offset;
1211 std::vector<Resource> resources;
1212
1213 void ReadFile(Linker::Reader& rd) override;
1214 void ReadFile(Linker::Reader& rd, offset_t size);
1215 void CalculateValues();
1217 offset_t WriteFile(Linker::Writer& wr) const override;
1218 void Dump(Dumper::Dumper& dump) const override;
1219
1221 };
1222}
1223
1224#endif /* PEEXE_H */
A standard 28 byte a.out optional header, used by DJGPP.
Definition coff.h:1303
A COFF section.
Definition coff.h:914
std::string name
The name of the section (COFF name: s_name)
Definition coff.h:919
static constexpr uint32_t DATA
COFF section flag: Section contains initialized data (COFF name: STYP_DATA)
Definition coff.h:977
offset_t physical_address
The physical address of the section (expected to be identical to the virtual address) (COFF name: s_p...
Definition coff.h:925
uint32_t flags
COFF section flags, determines the type of the section (text, data, bss, etc.) (COFF name: s_flags)
Definition coff.h:957
std::shared_ptr< Linker::Contents > image
The stored image data.
Definition coff.h:966
The UNIX COFF file format.
Definition coff.h:28
@ PECOFF
Microsoft PE/COFF variant.
Definition coff.h:253
@ WINDOWS
Windows Portable Executable (used only by PE)
Definition coff.h:1818
format_type type
A representation of the format to generate.
Definition coff.h:1823
::EndianType endiantype
The byte order.
Definition coff.h:1711
offset_t ImageSize() const override
Retrieves size of stored data.
Definition coff.cc:2177
std::unique_ptr< OptionalHeader > optional_header
The optional header instance used for reading/writing the COFF file.
Definition coff.h:1257
A record whose values should be displayed together, as a collection.
Definition dumper.h:566
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 record that represents a region within the file.
Definition dumper.h:666
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
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.
Definition image.h:43
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
Helper class that contains the options interpreted by the format.
Definition options.h:474
Documents and handles command line options.
Definition options.h:306
virtual std::string GetDefaultExtension(Module &module, std::string filename) const
Appends a default extension to the filename.
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:20
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
Definition mzexe.h:305
Definition peexe.h:1192
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition peexe.cc:4170
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition peexe.cc:4198
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition peexe.cc:4152
A block of base relocations, corresponding to a single page in the image.
Definition peexe.h:753
std::vector< BaseRelocation > relocations_list
Sequence of relocations in this block, filled in by the linker once all the relocations have been col...
Definition peexe.h:762
static constexpr uint32_t PAGE_SIZE
Pages are 4 KiB long.
Definition peexe.h:756
std::map< uint16_t, BaseRelocation > relocations_map
Collection of relocations, accessed via their page offset.
Definition peexe.h:764
uint32_t page_rva
The relative virtual address of the page this block corresponds to, with the least significant 12 bit...
Definition peexe.h:758
uint32_t block_size
Number of bytes in this block, including the initial 8 bytes for the relative virtual address of the ...
Definition peexe.h:760
Represents a base relocation, as stored in the image.
Definition peexe.h:702
size_t GetRelocationSize(const PEFormat *format) const
The number of bytes impacted by this relocation (typically 2 or 4 or 8)
Definition peexe.cc:1775
relocation_type type
The type of the relocation, stored as the 4 most significant bits of a 16-bit base relocation entry.
Definition peexe.h:739
uint16_t parameter
For relocation type HighAdj, the 16-bit value stored in the following base relocation entry.
Definition peexe.h:743
size_t GetEntryCount(const PEFormat *format) const
The number of base relocation entries required to store this base relocation, typically 1.
Definition peexe.cc:1764
relocation_type
The type of the relocation, partly dependent on the current CPU.
Definition peexe.h:706
@ RelRISCVHigh20
RISC-V specific.
Definition peexe.h:722
@ RelLow
The least significant 16 bits of the address.
Definition peexe.h:712
@ RelAbsolute
No relocation.
Definition peexe.h:708
@ RelLoongArch64MarkLA
LoongArch specific.
Definition peexe.h:732
@ RelThumbMov32
Thumb (ARM) specific.
Definition peexe.h:724
@ RelDir64
A full 64-bit address.
Definition peexe.h:736
@ RelLoongArch32MarkLA
LoongArch specific.
Definition peexe.h:730
@ RelRISCVLow12I
RISC-V specific.
Definition peexe.h:726
@ RelHigh
The most significant 16 bits of the address.
Definition peexe.h:710
@ RelMIPSJmpAddr16
MIPS specific.
Definition peexe.h:734
@ RelHighAdj
The most significant 16 bits of the address, with the currently assumed least significant 16 bits sto...
Definition peexe.h:716
@ RelMIPSJmpAddr
MIPS specific.
Definition peexe.h:718
@ RelRISCVLow12S
RISC-V specific.
Definition peexe.h:728
@ RelHighLow
A full 32-bit address.
Definition peexe.h:714
@ RelARMMov32
ARM specific.
Definition peexe.h:720
uint16_t offset
The offset of the relocation within the page corresponding to this base relocation block,...
Definition peexe.h:741
Represents a .reloc section for the base relocations for the binary.
Definition peexe.h:774
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:1924
void ReadSectionData(Linker::Reader &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:1886
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:1961
void WriteSectionData(Linker::Writer &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:1891
std::map< uint32_t, std::shared_ptr< BaseRelocationBlock > > blocks_map
Collection of relocation blocks, accessed via the relative virtual address of the page.
Definition peexe.h:779
std::vector< std::shared_ptr< BaseRelocationBlock > > blocks_list
Sequence of relocation blocks, filled in by the linker once all the relocations have been collected.
Definition peexe.h:777
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:1929
Encompasses the information necessary to encode a forwarder exported reference.
Definition peexe.h:594
std::variant< std::string, uint32_t > reference
The name or ordinal to the entry that is being reexported, this field will not appear directly in the...
Definition peexe.h:599
std::string reference_name
A string representation of the forwarder, to appear in the image.
Definition peexe.h:601
uint32_t rva
The relative virtual address of the reference name.
Definition peexe.h:603
std::string dll_name
The name of the library whose entry is being reexported, this field will not appear directly in the i...
Definition peexe.h:597
Represents a name by which an exported entry is identified.
Definition peexe.h:608
uint32_t rva
The relative virtual address of the name string.
Definition peexe.h:613
std::string name
The name, as a string.
Definition peexe.h:611
Represents a single exported entry in the file.
Definition peexe.h:586
std::optional< Name > name
An optional name by which the exported entry is identified, otherwise its position in the export tabl...
Definition peexe.h:624
std::variant< uint32_t, Forwarder > value
Represents the associated value of the entry: either the relative virtual address of the object being...
Definition peexe.h:622
Represents an .edata section for the exported entries in the binary.
Definition peexe.h:644
void WriteSectionData(Linker::Writer &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:1523
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:1701
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:1628
void AddEntry(PEFormat &fmt, std::shared_ptr< ExportedEntry > entry)
Adds an entry to an unused ordinal (for speed, we access the highest taken ordinal and assign this en...
Definition peexe.cc:1409
std::string dll_name
The name of this library.
Definition peexe.h:650
std::map< uint32_t, std::shared_ptr< ExportedEntry > > entries
Sequence of entries, the first entry corresponds to ordinal_base.
Definition peexe.h:664
uint32_t ordinal_base
The starting ordinal for the export table.
Definition peexe.h:654
uint32_t address_table_rva
Relative virtual address of the export address table, containing the exported entries for each succes...
Definition peexe.h:658
uint32_t name_table_rva
Relative virtual address of the name pointer table, containing the relative virtual addresses of the ...
Definition peexe.h:660
std::map< std::string, uint32_t > named_exports
A collection of exports by name, with each string being associated with its ordinal.
Definition peexe.h:666
uint32_t dll_name_rva
The relative virtual address of the library name string.
Definition peexe.h:652
void ReadSectionData(Linker::Reader &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:1518
void SetEntry(PEFormat &fmt, uint32_t ordinal, std::shared_ptr< ExportedEntry > entry)
Sets a specific entry, corresponding to some ordinal.
Definition peexe.cc:1390
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:1633
uint32_t ordinal_table_rva
Relative virtual address of the ordinal table, containing the ordinals for each entry exported by nam...
Definition peexe.h:662
uint32_t first_allowed_ordinal
A hint for AddEntry to start looking for free ordinals.
Definition peexe.h:656
Represents an entry in the hint-name table, corresponding to imports by name.
Definition peexe.h:492
uint32_t rva
The relative virtual address of the name of the entry.
Definition peexe.h:499
std::string name
The name by which the entry is identified.
Definition peexe.h:497
uint16_t hint
The hint (ordinal) corresponding to this entry.
Definition peexe.h:495
A collection of the imported names for a specific dynamic linking library.
Definition peexe.h:486
std::map< Ordinal, size_t > imports_by_ordinal
A convenience field to quickly access the imported entry index via its ordinal (only for import by or...
Definition peexe.h:526
std::variant< Ordinal, Name > ImportTableEntry
Represents a single entry in the import directory, either an ordinal or a name.
Definition peexe.h:508
offset_t GetImportByNameAddress(const PEFormat &fmt, std::string name)
Retrieves the virtual address of an already registered entry that is imported by name.
Definition peexe.cc:2683
void AddImportByOrdinal(uint16_t ordinal)
Adds a new imported entry by ordinal, unless an entry by the same ordinal already exists,...
Definition peexe.cc:2672
uint32_t name_rva
Relative virtual address of the name.
Definition peexe.h:519
std::vector< ImportTableEntry > import_table
List of imported entries.
Definition peexe.h:522
void AddImportByName(std::string entry_name, uint16_t hint)
Adds a new imported entry by name and hint, unless an entry by the same name already exists,...
Definition peexe.cc:2662
offset_t GetImportByOrdinalAddress(const PEFormat &fmt, uint16_t ordinal)
Retrieves the virtual address of an already registered entry that is imported by ordinal.
Definition peexe.cc:2694
std::map< std::string, size_t > imports_by_name
A convenience field to quickly access the imported entry index via its name, must be kept synchronize...
Definition peexe.h:524
uint32_t lookup_table_rva
Relative virtual address for the lookup table, preserved during execution time.
Definition peexe.h:511
uint32_t address_table_rva
Relative virtual address for the address table, used to access the imported functions,...
Definition peexe.h:513
std::string name
Name of the dynamic linking library included.
Definition peexe.h:517
Represents an .idata section for imported DLLs in the binary.
Definition peexe.h:546
std::map< std::string, size_t > library_indexes
A convenience field to access the DLL index by its name.
Definition peexe.h:551
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:1282
void ReadSectionData(Linker::Reader &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:1146
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:1277
std::vector< ImportedLibrary > libraries
The sequence of all import directories, one for each DLL.
Definition peexe.h:549
void WriteSectionData(Linker::Writer &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:1151
uint32_t address_table_size
Size of the import address table, to be stored in the optional header.
Definition peexe.h:556
uint32_t address_table_rva
Relative virtual address of the import address table, to be stored in the optional header.
Definition peexe.h:554
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:1339
size_t ReadData(size_t bytes, offset_t offset, void *buffer) const override
Attempts to fill a buffer with data.
Definition peexe.cc:412
offset_t ImageSize() const override
Retrieves size of stored data.
Definition peexe.cc:401
offset_t WriteFile(Linker::Writer &wr, offset_t count, offset_t offset=0) const override
Writes data of non-zero filled sections.
Definition peexe.cc:406
The PE optional header as specified by Microsoft.
Definition peexe.h:31
version_type image_version
Binary image version.
Definition peexe.h:70
uint16_t flags
DLL flags (in PE terminology, characteristics)
Definition peexe.h:116
version_type os_version
Required operating system version.
Definition peexe.h:66
uint32_t win32_version
Reserved value.
Definition peexe.h:78
uint32_t loader_flags
Reserved.
Definition peexe.h:136
static constexpr offset_t Win32Base
Conventional image base for 32-bit Windows executables.
Definition peexe.h:41
uint32_t section_align
Section alignment.
Definition peexe.h:58
uint32_t file_align
File alignment.
Definition peexe.h:62
uint32_t checksum
Checksum.
Definition peexe.h:90
offset_t RVAToAddress(uint32_t rva, bool suppress_on_zero=false) const
Converts an image base relative virtual address into a virtual address.
Definition peexe.cc:33
static constexpr offset_t Dll32Base
Conventional image base for 32-bit Windows dynamic linking libraries.
Definition peexe.h:43
std::vector< DataDirectory > data_directories
PE specific areas in the file, each one has a specific purpose.
Definition peexe.h:168
static constexpr uint16_t EXE64
Magic number for 64-bit binaries, also signifies 8-byte entries in the file (PE32+)
Definition peexe.h:38
static constexpr offset_t WinCEBase
Conventional image base for Windows CE executables.
Definition peexe.h:45
static constexpr offset_t Win64Base
Conventional image base for 64-bit Windows executables.
Definition peexe.h:47
bool Is64Bit() const
Whether the file is in the PE32+ (64-bit) format.
Definition peexe.cc:9
offset_t reserved_stack_size
How much of stack should be reserved at launch.
Definition peexe.h:120
uint32_t total_headers_size
Cumulative size of all the headers, including the MZ stub.
Definition peexe.h:86
offset_t committed_stack_size
How many pages of stack are actually available at launch.
Definition peexe.h:124
static constexpr uint16_t EXE32
Magic number for 32-bit binaries, also signifies 4-byte entries in the file (PE32)
Definition peexe.h:36
offset_t image_base
Preferred base address of image, all relative virtual addresses are calculate relative to this value.
Definition peexe.h:54
SubsystemType subsystem
The Windows subsystem this program runs on.
Definition peexe.h:112
offset_t reserved_heap_size
How much of heap should be reserved at launch.
Definition peexe.h:128
uint32_t total_image_size
Size of the entire image, including headers.
Definition peexe.h:82
static constexpr offset_t Dll64Base
Conventional image base for 64-bit Windows dynamic linking libraries.
Definition peexe.h:49
offset_t committed_heap_size
How many pages of heap are actually available at launch.
Definition peexe.h:132
uint32_t AddressToRVA(offset_t address) const
Converts a virtual address into an image base relative virtual address.
Definition peexe.cc:19
uint32_t GetSize() const override
Returns size of optional header.
Definition peexe.cc:14
static constexpr uint16_t ROM32
Magic number for ROM images, according to Microsoft.
Definition peexe.h:34
version_type subsystem_version
Version of the subsystem.
Definition peexe.h:74
Represents a field that displays a relative virtual address and file offset pair.
Definition peexe.h:1176
Represents a single entry in the resource directory.
Definition peexe.h:401
Key identifier
The value that identifiers the resource at the current level.
Definition peexe.h:404
std::variant< std::shared_ptr< Resource >, std::shared_ptr< ResourceDirectory > > content
The contents at this level, either the resource itself, or another level of resource directory.
Definition peexe.h:406
uint32_t content_offset
The offset of the contents within the section.
Definition peexe.h:408
offset_t WriteResources(Linker::Writer &wr, const PEFormat &fmt, uint32_t rva_to_offset) const
Recursively writes all the resources, returns the file offset after the last written byte.
Definition peexe.cc:933
size_t ParseResourceDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t rva, const std::vector< Resource::Identifier > &partial_identifier)
Parses the contents of the directory at the current level, after all the section data for the file is...
Definition peexe.cc:622
std::vector< Entry< Name > > name_entries
Entries that are identified via a string.
Definition peexe.h:418
void CollectSubdirectoryStrings(PEFormat &fmt, ResourcesSection &rsrc, size_t level_deeper)
Registers all strings occuring in the directory and its subdirectories at the specified relative leve...
Definition peexe.cc:808
void AddResource(std::shared_ptr< Resource > &resource, size_t level=0)
Inserts a resource into the directory.
Definition peexe.cc:546
uint32_t CollectResourceData(PEFormat &fmt, uint32_t rva, size_t level_deeper)
Calculates the relative virtual addresses of each individual resource at the specified relative level...
Definition peexe.cc:839
uint32_t CalculateDirectoryOffsets(PEFormat &fmt, uint32_t offset, size_t level_deeper)
Fills in the offsets for all subdirectories at the specified relative level.
Definition peexe.cc:774
void DumpResourceDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t rva, const std::vector< Resource::Identifier > &partial_identifier, size_t dump_level) const
Displays the directory contents.
Definition peexe.cc:692
std::vector< Entry< uint32_t > > id_entries
Entries that are identified via a number.
Definition peexe.h:420
uint32_t flags
Resource directory characteristics.
Definition peexe.h:414
void WriteDirectories(Linker::Writer &wr, const PEFormat &fmt, uint32_t section_pointer) const
Recursively writes the directory table and all those of all of its subdirectories and leaves.
Definition peexe.cc:885
Represents a resource inside the image.
Definition peexe.h:333
uint32_t codepage
Codepage of the resource.
Definition peexe.h:357
uint32_t reserved
Reserved entry in the resource table.
Definition peexe.h:359
uint32_t data_rva
The relative virtual address of the resource data.
Definition peexe.h:353
std::vector< Identifier > full_identifier
The sequence of IDs that identifies this resource, conventionally corresponding to the resource type,...
Definition peexe.h:351
static constexpr size_t Level_Name
The second level of the resource tree corresponds to the resource name.
Definition peexe.h:341
offset_t WriteResource(Linker::Writer &wr, const PEFormat &fmt, uint32_t rva_to_offset) const
Writes the actual resource, returns the file offset after the last written byte.
Definition peexe.cc:535
static constexpr size_t Level_Type
The first level of the resource tree corresponds to the resource type.
Definition peexe.h:339
std::variant< std::string, uint32_t > Identifier
Represents a resource identifier, either a string or a 32-bit value.
Definition peexe.h:336
uint32_t AssignAddress(PEFormat &fmt, uint32_t rva)
Assigns the relative virtual addresses and returns the relative virtual address of the end of the res...
Definition peexe.cc:517
size_t ParseResourceData(const PEFormat &fmt, uint32_t rva)
Parses the contents of the resource, after all the section data for the file is loaded,...
Definition peexe.cc:419
uint32_t size
The size of the resource data.
Definition peexe.h:355
void WriteDirectories(Linker::Writer &wr, const PEFormat &fmt, uint32_t section_pointer) const
Writes the directory entry for this resource.
Definition peexe.cc:527
static constexpr size_t Level_Count
Total number of levels used.
Definition peexe.h:345
static constexpr size_t Level_Language
The third level of the resource tree corresponds to the language (locale) for the resource.
Definition peexe.h:343
void DumpResource(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t rva) const
Displays the resource contents.
Definition peexe.cc:467
std::shared_ptr< Linker::Section > section
The section containing the resource, only used for generating images.
Definition peexe.h:362
static void DumpIdentifier(std::vector< Identifier > full_identifier, Dumper::Container &container)
Adds fields to the container that describe the identifier.
Definition peexe.cc:428
Represents an .rsrc resource section in the binary.
Definition peexe.h:447
void DumpDirectory(const PEFormat &fmt, Dumper::Dumper &dump, uint32_t directory_rva, uint32_t directory_size) const
Displays the directory contents.
Definition peexe.cc:1050
void WriteSectionData(Linker::Writer &wr, const PEFormat &fmt) const override
Writes the contents of the section to the file.
Definition peexe.cc:1011
void ReadSectionData(Linker::Reader &rd, const PEFormat &fmt) override
Reads the contents of the section in the file.
Definition peexe.cc:1006
void ParseDirectoryData(const PEFormat &fmt, uint32_t directory_rva, uint32_t directory_size)
Parses the contents of the directory, after all the section data for the file is loaded.
Definition peexe.cc:1044
uint32_t MemorySize(const PEFormat &fmt) const override
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:1039
A section, with the PE extensions.
Definition peexe.h:212
static constexpr uint32_t WRITE
The section contents are writable to the program.
Definition peexe.h:222
static constexpr uint32_t READ
The section contents are readable to the program.
Definition peexe.h:220
static constexpr uint32_t DISCARDABLE
The section is discardable.
Definition peexe.h:216
virtual uint32_t MemorySize(const PEFormat &fmt) const
Retrieves the size of the section, as loaded into memory.
Definition peexe.cc:391
constexpr const offset_t & virtual_size() const
The COFF s_paddr field is redefined to contain the size of the section as loaded into memory.
Definition peexe.h:232
static constexpr uint32_t EXECUTE
The section contains executable code.
Definition peexe.h:218
constexpr offset_t & virtual_size()
The COFF s_paddr field is redefined to contain the size of the section as loaded into memory.
Definition peexe.h:230
Microsoft PE .EXE portable executable file format.
Definition peexe.h:19
target_type target
The expected target system, only used for setting up default values.
Definition peexe.h:868
offset_t GenerateImportSection(Linker::Module &module, offset_t image_end)
Creates an import section and attaches it to the end of the file.
Definition peexe.cc:3447
compatibility_type
Definition peexe.h:827
@ CompatibleMicrosoft
Attempts to mimic the output of the Microsoft linker (TODO: unimplemented)
Definition peexe.h:833
@ CompatibleGNU
Attempts to mimic the output of the GNU (MinGW) linker, this is undefined for the LE output.
Definition peexe.h:837
@ CompatibleWatcom
Attempts to mimic the output of the Watcom linker.
Definition peexe.h:831
@ CompatibleNone
No emulation is attempted.
Definition peexe.h:829
@ CompatibleBorland
Attempts to mimic the output of the Borland linker (TODO: unimplemented)
Definition peexe.h:835
bool option_coff_local_symbols
Include COFF local symbols (TODO: not implemented)
Definition peexe.h:903
uint32_t AddressToRVA(offset_t address) const
Converts a virtual address into an image base relative virtual address.
Definition peexe.cc:2016
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 peexe.cc:3021
offset_t GenerateResourceSection(Linker::Module &module, offset_t image_end)
Creates a resource section and attaches it to the end of the file.
Definition peexe.cc:3435
output_type
Represents the target image type.
Definition peexe.h:872
@ OUTPUT_EXE
An executable image, conventionally taking the suffix .exe
Definition peexe.h:874
@ OUTPUT_SYS
A system file or driver, conventionally taking the suffix .sys
Definition peexe.h:878
@ OUTPUT_DLL
A dynamically linked library, conventionally taking the suffix .dll
Definition peexe.h:876
size_t ReadData(size_t bytes, uint32_t rva, void *buffer) const
Loads a sequence of bytes from the filled section data.
Definition peexe.cc:2132
std::shared_ptr< Linker::Segment > import_thunk_segment
Holds the segment that contains the import thinks.
Definition peexe.h:912
std::shared_ptr< BaseRelocationsSection > base_relocations
The collection of base relocations.
Definition peexe.h:805
bool option_debug_info
Include debug information (TODO: not implemented)
Definition peexe.h:906
std::shared_ptr< ImportsSection > imports
The collection of imports in the file.
Definition peexe.h:582
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition peexe.cc:3890
std::string ReadASCII(uint32_t rva, char terminator, size_t maximum=size_t(-1)) const
Loads a sequence of bytes terminated by a specific character from the filled section data.
Definition peexe.cc:2170
std::shared_ptr< ExportsSection > exports
The collection of exported symbols.
Definition peexe.h:698
void AddBaseRelocation(uint32_t rva, BaseRelocation::relocation_type type, uint16_t low_ref=0)
Adds a base relocation at the specified relative virtual address.
Definition peexe.cc:2188
void OnCallDirective(std::string identifier) override
Callback function for the CALL directive.
Definition peexe.cc:3086
@ FLAG_ON_REMOVABLE
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP.
Definition peexe.h:1100
@ FLAG_NO_LINE_NUMBERS
(deprecated) IMAGE_FILE_LINE_NUMS_STRIPPED (F_LNNO)
Definition peexe.h:1086
@ FLAG_32BIT
IMAGE_FILE_32BIT_MACHINE (redefined from COFF F_AR32WR)
Definition peexe.h:1096
@ FLAG_LIBRARY
IMAGE_FILE_DLL.
Definition peexe.h:1106
@ FLAG_LITTLE_ENDIAN
(deprecated) IMAGE_FILE_BYTES_REVERSED_LO (redefined from COFF F_AR16WR)
Definition peexe.h:1094
@ FLAG_NO_DEBUG
IMAGE_FILE_DEBUG_STRIPPED (redefined from COFF F_AR32W)
Definition peexe.h:1098
@ FLAG_SYSTEM
IMAGE_FILE_SYSTEM.
Definition peexe.h:1104
@ FLAG_BIG_ENDIAN
(deprecated) IMAGE_FILE_BYTES_REVERSED_HI
Definition peexe.h:1110
@ FLAG_ON_NETWORK
IMAGE_FILE_NET_RUN_FROM_SWAP.
Definition peexe.h:1102
@ FLAG_EXECUTABLE
IMAGE_FILE_EXECUTABLE_IMAGE (F_EXEC)
Definition peexe.h:1084
@ FLAG_NO_SYMBOLS
(deprecated) IMAGE_FILE_LOCAL_SYMS_STRIPPED (F_LSYMS)
Definition peexe.h:1088
@ FLAG_TRIM_WORKING_SET
(deprecated) IMAGE_FILE_AGGRESSIVE_WS_TRIM (no COFF meaning)
Definition peexe.h:1090
@ FLAG_NO_RELOCATIONS
IMAGE_FILE_RELOCS_STRIPPED (F_RELFLG)
Definition peexe.h:1082
@ FLAG_UNIPROCESSOR_ONLY
IMAGE_FILE_UP_SYSTEM_ONLY.
Definition peexe.h:1108
@ FLAG_LARGE_ADDRESS
IMAGE_FILE_LARGE_ADDRESS_AWARE (no COFF meaning)
Definition peexe.h:1092
void AllocateSymbols(Linker::Module &module) const override
Instructs the module to allocate any unallocated local symbols.
Definition peexe.cc:3016
size_t MapRVAToSectionData(uint32_t rva, size_t bytes, std::shared_ptr< Section > &found_section, size_t &section_offset) const
Attempts to find the section:offset pair that encompasses this memory range.
Definition peexe.cc:2036
void ProcessRelocations(Linker::Module &module)
Processes relocations present in the module and stores them as base relocations and imports.
Definition peexe.cc:3488
bool option_include_deprecated_flags
Certain header flags are deprecated and should be zero, this option sets them if applicable (TODO: ex...
Definition peexe.h:897
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition peexe.cc:4034
PEOptionalHeader & GetOptionalHeader()
Retrieves the optional header.
Definition peexe.cc:2001
std::shared_ptr< ResourcesSection > resources
The resources in this file.
Definition peexe.h:482
uint64_t ReadSigned(size_t bytes, uint32_t rva, ::EndianType endiantype) const
Loads a signed word from the filled section data.
Definition peexe.cc:2162
bool Is64Bit() const
Whether the file is in the PE32+ (64-bit) format.
Definition peexe.cc:2011
bool option_coff_line_numbers
Include COFF line numbers (TODO: not implemented)
Definition peexe.h:900
bool option_relocatable
Make generated image relocatable (TODO: expose as command line option)
Definition peexe.h:894
offset_t GenerateExportSection(Linker::Module &module, offset_t image_end)
Creates an export section and attaches it to the end of the file.
Definition peexe.cc:3464
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition peexe.cc:2730
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition peexe.cc:2209
offset_t GenerateBaseRelocationSection(Linker::Module &module, offset_t image_end)
Creates a base relocation section and attaches it to the end of the file.
Definition peexe.cc:3476
uint64_t ReadUnsigned(size_t bytes, uint32_t rva, ::EndianType endiantype) const
Loads an unsigned word from the filled section data.
Definition peexe.cc:2154
std::vector< Linker::OptionDescription< void > * > GetLinkerScriptParameterNames() override
Returns a list of the parameters used in the linker scripts, used for documentation.
Definition peexe.cc:2720
target_type
Represents settings and assumptions about the target.
Definition peexe.h:844
@ TargetWin32s
Win32s compatibility library for Windows 3.1.
Definition peexe.h:854
@ TargetEFI
EFI and UEFI firmware.
Definition peexe.h:858
@ TargetWin9x
Windows 95/98/ME.
Definition peexe.h:846
@ TargetTNT
Phar Lap TNT DOS Extender.
Definition peexe.h:856
@ TargetXbox
Xbox.
Definition peexe.h:862
@ TargetWinNT
Windows NT kernel.
Definition peexe.h:848
@ TargetMacintosh
Windows Portability Library.
Definition peexe.h:852
@ TargetDotNET
.NET environment
Definition peexe.h:860
@ TargetWinCE
Windows CE kernel.
Definition peexe.h:850
const PESections Sections() const
Access the sections as PEFormat::Section.
Definition peexe.cc:2122
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition peexe.cc:2725
void FixupImportThunk(Linker::Module &module, offset_t offset, offset_t address)
Adjust addresses in the text section where the indirect jumps appear.
Definition peexe.cc:3664
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition peexe.cc:3713
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition peexe.cc:2281
bool FormatSupportsResources() const override
Whether the format supports resources.
Definition peexe.cc:2625
bool option_import_thunks
By default, imported labels address the import address table directly.
Definition peexe.h:909
offset_t RVAToFileOffset(uint32_t rva) const
Converts an image base relative virtual address into a file offset.
Definition peexe.cc:2026
bool FormatSupportsLibraries() const override
Whether the format supports libraries.
Definition peexe.cc:2620
offset_t RVAToAddress(uint32_t rva, bool suppress_on_zero=false) const
Converts an image base relative virtual address into a virtual address.
Definition peexe.cc:2021
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition peexe.cc:2377
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition peexe.cc:2367
Definition neexe.h:875
A data directory entry.
Definition peexe.h:140
Wrapper around COFFFormat::sections to return PEFormat::Section pointers instead of COFFFormat::Secti...
Definition peexe.h:253
Represents a version entry with major and minor versions.
Definition peexe.h:25