RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
omf.h
1#ifndef OMF_H
2#define OMF_H
3
4#include <array>
5#include <variant>
6#include "../common.h"
7#include "../dumper/dumper.h"
8#include "../linker/format.h"
9#include "../linker/reader.h"
10#include "../linker/writer.h"
11
12/* TODO: incomplete */
13
14/* Intel Object Module format (input only) */
15
16namespace OMF
17{
20 {
21 public:
22 Linker::Writer * wr;
23 uint8_t checksum = 0;
24
26 : wr(&wr)
27 {
28 }
29
30 void WriteWord(size_t bytes, uint64_t value)
31 {
32 wr->WriteWord(bytes, value);
33 for(size_t offset = 0; offset < bytes; offset++, value >>= 8)
34 {
35 checksum -= value;
36 }
37 }
38
39 size_t WriteData(const std::vector<uint8_t>& data)
40 {
41 size_t bytes = wr->WriteData(data);
42 for(size_t offset = 0; offset < bytes; offset++)
43 {
44 checksum -= data[offset];
45 }
46 return bytes;
47 }
48
49 size_t WriteData(std::string text)
50 {
51 wr->WriteData(text);
52 for(size_t offset = 0; offset < text.size(); offset++)
53 {
54 checksum -= text[offset];
55 }
56 return text.size();
57 }
58
59 void Skip(offset_t count)
60 {
61 wr->Skip(count);
62 }
63 };
64
68 class OMFFormat : public virtual Linker::Format
69 {
70 public:
71 virtual ~OMFFormat() = default;
72
74 static std::string ReadString(Linker::Reader& rd, size_t max_bytes = size_t(-1));
75
77 static void WriteString(ChecksumWriter& wr, std::string text);
78
80 typedef uint16_t index_t;
81
84
86 static void WriteIndex(ChecksumWriter& wr, index_t index);
87
89 static size_t IndexSize(index_t index);
90
97 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
98 class Record
99 {
100 public:
106 RecordTypeByte record_type;
107
108 Record(RecordTypeByte record_type = RecordTypeByte(0))
110 {
111 }
112
113 virtual ~Record() = default;
114
115 offset_t RecordEnd() const
116 {
117 return record_offset + record_length + 2;
118 }
119
121 virtual void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) = 0;
122
124 virtual uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const = 0;
125
127 virtual void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const = 0;
128
130 virtual void WriteRecord(FormatType * omf, ModuleType * mod, Linker::Writer& wr) const
131 {
132 ChecksumWriter ckswr(wr);
133 ckswr.WriteWord(1, record_type);
134 ckswr.WriteWord(2, GetRecordSize(omf, mod));
135 WriteRecordContents(omf, mod, ckswr);
136 wr.WriteWord(1, ckswr.checksum);
137 }
138
140 virtual void CalculateValues(FormatType * omf, ModuleType * mod)
141 {
142 record_offset = omf->file_size;
143 record_length = GetRecordSize(omf, mod);
145 }
146
148 virtual void ResolveReferences(FormatType * omf, ModuleType * mod)
149 {
150 }
151
152 virtual void DumpAddFields(Dumper::Dumper& dump, Dumper::Region& region, const FormatType * omf, const ModuleType * mod, size_t record_index) const
153 {
154 }
155
156 virtual void Dump(Dumper::Dumper& dump, const FormatType * omf, const ModuleType * mod, size_t record_index) const
157 {
158 Dumper::Region record_region("Record", record_offset, RecordEnd() + 1 - record_offset, 8);
159 record_region.InsertField(0, "Index", Dumper::DecDisplay::Make(), offset_t(record_index + 1));
160 record_region.AddField("Record type", Dumper::HexDisplay::Make(2), offset_t(record_type));
161 FormatType::DumpAddFields(this, dump, record_region, omf, mod, record_index);
162 DumpAddFields(dump, record_region, omf, mod, record_index);
163 record_region.Display(dump);
164 }
165
167 bool Is32Bit(FormatType * omf) const
168 {
169 return (record_type & 1) != 0;
170 }
171
173 size_t GetOffsetSize(FormatType * omf) const
174 {
175 return Is32Bit(omf) ? 4 : 2;
176 }
177 };
178
180 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
181 class UnknownRecord : public Record<RecordTypeByte, FormatType, ModuleType>
182 {
183 public:
185 std::vector<uint8_t> data;
186
187 UnknownRecord(RecordTypeByte record_type = RecordTypeByte(0))
188 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
189 {
190 }
191
192 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override
193 {
195 rd.ReadData(data);
196 }
197
198 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override
199 {
200 return data.size() + 1;
201 }
202
203 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override
204 {
205 wr.WriteData(data);
206 }
207 };
208
210 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
211 class EmptyRecord : public Record<RecordTypeByte, FormatType, ModuleType>
212 {
213 public:
214 EmptyRecord(RecordTypeByte record_type = RecordTypeByte(0))
216 {
217 }
218
219 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override
220 {
221 }
222
223 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override
224 {
225 return 1;
226 }
227
228 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override
229 {
230 }
231 };
232
237 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
238 class ContentRecord : public Record<RecordTypeByte, FormatType, ModuleType>
239 {
240 public:
241 uint8_t segment_id = 0;
242 uint16_t offset = 0;
243 std::vector<uint8_t> data;
244
245 ContentRecord(RecordTypeByte record_type = RecordTypeByte(0))
247 {
248 }
249
250 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
251 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
252 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
253 };
254
260 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
261 class LineNumbersRecord : public Record<RecordTypeByte, FormatType, ModuleType>
262 {
263 public:
265 {
266 public:
267 uint16_t line_number = 0;
268 uint16_t offset = 0;
269
270 static LineNumber Read(FormatType * omf, Linker::Reader& rd);
271 void Write(FormatType * omf, ChecksumWriter& wr) const;
272 };
273
274 uint8_t segment_id = 0;
275 std::vector<LineNumber> line_numbers;
276
277 LineNumbersRecord(RecordTypeByte record_type = RecordTypeByte(0))
278 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
279 {
280 }
281
282 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
283 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
284 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
285 };
286
288 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
289 class LibraryHeaderRecord : public Record<RecordTypeByte, FormatType, ModuleType>
290 {
291 public:
293 uint16_t module_count;
295 uint16_t block_number;
297 uint16_t byte_number;
298
299 LibraryHeaderRecord(RecordTypeByte record_type = RecordTypeByte(0))
300 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
301 {
302 }
303
304 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
305 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
306 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
307 };
308
310 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
311 class LibraryModuleNamesRecord : public Record<RecordTypeByte, FormatType, ModuleType>
312 {
313 public:
315 std::vector<std::string> names;
316
317 LibraryModuleNamesRecord(RecordTypeByte record_type = RecordTypeByte(0))
318 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
319 {
320 }
321
322 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
323 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
324 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
325 };
326
328 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
329 class LibraryModuleLocationsRecord : public Record<RecordTypeByte, FormatType, ModuleType>
330 {
331 public:
332 struct Location
333 {
334 public:
336 uint16_t block_number;
338 uint16_t byte_number;
339
340 static Location Read(Linker::Reader& rd);
341 void Write(ChecksumWriter& wr) const;
342 };
343
345 std::vector<Location> locations;
346
347 LibraryModuleLocationsRecord(RecordTypeByte record_type = RecordTypeByte(0))
348 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
349 {
350 }
351
352 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
353 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
354 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
355 };
356
358 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
359 class LibraryDictionaryRecord : public Record<RecordTypeByte, FormatType, ModuleType>
360 {
361 public:
362 class Group
363 {
364 public:
366 std::vector<std::string> names;
367
368 void Read(Linker::Reader& rd);
369 uint16_t Size() const;
370 void Write(ChecksumWriter& wr) const;
371 };
372
374 std::vector<Group> groups;
375
376 LibraryDictionaryRecord(RecordTypeByte record_type = RecordTypeByte(0))
377 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
378 {
379 }
380
381 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
382 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
383 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
384 };
385
387 static std::shared_ptr<OMFFormat> ReadOMFFile(Linker::Reader& rd);
388
390 offset_t file_size = 0;
391 };
392
396 class OMF86Format : public virtual OMFFormat, public virtual Linker::InputFormat
397 {
398 public:
399 class Module;
402
403 /* * * General members * * */
404
419
422
425 {
426 }
427
429 static constexpr unsigned int FlagIntel = 0x10;
431 static constexpr unsigned int FlagPharLap = 0x20;
433 static constexpr unsigned int FlagTIS = 0x30;
434
436 enum
437 {
452 };
453
455 typedef uint16_t FrameNumber;
456
458 struct UsesSource { };
459
461 struct UsesTarget { };
462
464 struct UsesAbsolute { };
465
468 {
469 public:
470 index_t index;
471 std::string text;
472
473 NameIndex(index_t index = 0)
474 : index(index)
475 {
476 }
477
478 void CalculateValues(OMF86Format * omf, Module * mod);
479 void ResolveReferences(OMF86Format * omf, Module * mod);
480 };
481
484 {
485 public:
486 index_t index;
487 std::shared_ptr<SegmentDefinitionRecord> record;
488
489 SegmentIndex(index_t index = 0)
490 : index(index)
491 {
492 }
493
494 void CalculateValues(OMF86Format * omf, Module * mod);
495 void ResolveReferences(OMF86Format * omf, Module * mod);
496 };
497
500 {
501 public:
502 index_t index;
503 std::shared_ptr<GroupDefinitionRecord> record;
504
505 GroupIndex(index_t index = 0)
506 : index(index)
507 {
508 }
509
510 void CalculateValues(OMF86Format * omf, Module * mod);
511 void ResolveReferences(OMF86Format * omf, Module * mod);
512 };
513
517
520 {
521 public:
522 index_t index;
523 std::shared_ptr<TypeDefinitionRecord> record;
524
525 TypeIndex(index_t index = 0)
526 : index(index)
527 {
528 }
529
530 void CalculateValues(OMF86Format * omf, Module * mod);
531 void ResolveReferences(OMF86Format * omf, Module * mod);
532 };
533
536 {
537 public:
538 index_t index;
539 std::shared_ptr<BlockDefinitionRecord> record;
540
541 BlockIndex(index_t index = 0)
542 : index(index)
543 {
544 }
545
546 void CalculateValues(OMF86Format * omf, Module * mod);
547 void ResolveReferences(OMF86Format * omf, Module * mod);
548 };
549
552 {
553 public:
554 index_t index;
555 std::shared_ptr<OverlayDefinitionRecord> record;
556
557 OverlayIndex(index_t index = 0)
558 : index(index)
559 {
560 }
561
562 void CalculateValues(OMF86Format * omf, Module * mod);
563 void ResolveReferences(OMF86Format * omf, Module * mod);
564 };
565
568 {
569 public:
571 enum common_type_t : uint8_t
572 {
575
578
580 FarCommon = 0x61,
581
584 };
585
587 bool local = false;
589 bool name_is_index = false;
592 TypeIndex type;
593 common_type_t common_type = External;
594
595 union
596 {
597 uint8_t segment_index;
598 struct
599 {
600 uint32_t length;
601 } near;
602 struct
603 {
604 uint32_t number;
605 uint32_t element_size;
606 } far;
607 } value;
608
610 {
611 value.far.number = value.far.element_size = 0;
612 }
613
615 static uint32_t ReadValue(OMF86Format * omf, Linker::Reader& rd);
617 static uint32_t ValueSize(OMF86Format * omf, uint32_t length);
619 static void WriteValue(OMF86Format * omf, ChecksumWriter& wr, uint32_t length);
620
622 static ExternalName ReadExternalName(OMF86Format * omf, Linker::Reader& rd, bool local);
624 static ExternalName ReadCommonName(OMF86Format * omf, Linker::Reader& rd, bool local);
626 static ExternalName ReadComdatExternalName(OMF86Format * omf, Linker::Reader& rd);
627
629 uint16_t GetExternalNameSize(OMF86Format * omf) const;
631 void WriteExternalName(OMF86Format * omf, ChecksumWriter& wr) const;
632
633 void CalculateValues(OMF86Format * omf, Module * mod);
634 void ResolveReferences(OMF86Format * omf, Module * mod);
635 };
636
639 {
640 public:
641 index_t index;
642 ExternalName name;
643
644 ExternalIndex(index_t index = 0)
645 : index(index)
646 {
647 }
648
649 void CalculateValues(OMF86Format * omf, Module * mod);
650 void ResolveReferences(OMF86Format * omf, Module * mod);
651 };
652
655 {
656 public:
658 struct Location
659 {
660 GroupIndex group;
661 SegmentIndex segment;
662 };
663
665 std::variant<Location, FrameNumber> location;
666
667 void Read(OMF86Format * omf, Linker::Reader& rd);
668 uint16_t Size(OMF86Format * omf) const;
669 void Write(OMF86Format * omf, ChecksumWriter& wr) const;
670
671 void CalculateValues(OMF86Format * omf, Module * mod);
672 void ResolveReferences(OMF86Format * omf, Module * mod);
673 };
674
677 {
678 public:
680 bool local;
682 std::string name;
684 uint32_t offset;
687
688 static SymbolDefinition Read(OMF86Format * omf, Linker::Reader& rd, bool local, bool is32bit);
689 uint16_t Size(OMF86Format * omf, bool is32bit) const;
690 void Write(OMF86Format * omf, ChecksumWriter& wr, bool is32bit) const;
691
692 void CalculateValues(OMF86Format * omf, Module * mod);
693 void ResolveReferences(OMF86Format * omf, Module * mod);
694 };
695
698 {
699 public:
701 uint16_t number;
703 uint32_t offset;
704
705 static LineNumber Read(OMF86Format * omf, Linker::Reader& rd, bool is32bit);
706 void Write(OMF86Format * omf, ChecksumWriter& wr, bool is32bit) const;
707 };
708
717 {
718 public:
720 uint16_t repeat_count;
721
723 typedef std::vector<std::shared_ptr<DataBlock>> Blocks;
725 typedef std::vector<uint8_t> Data;
726
728 std::variant<Data, Blocks> content;
729
731 static std::shared_ptr<DataBlock> ReadEnumeratedDataBlock(OMF86Format * omf, Linker::Reader& rd, uint16_t data_length);
733 uint16_t GetEnumeratedDataBlockSize(OMF86Format * omf) const;
736
738 static std::shared_ptr<DataBlock> ReadIteratedDataBlock(OMF86Format * omf, Linker::Reader& rd, bool is32bit);
740 uint16_t GetIteratedDataBlockSize(OMF86Format * omf, bool is32bit) const;
742 void WriteIteratedDataBlock(OMF86Format * omf, ChecksumWriter& wr, bool is32bit) const;
743 };
744
747 {
748 public:
750 typedef unsigned ThreadNumber;
751
753 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber> target = ThreadNumber(0);
755 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute> frame = ThreadNumber(0);
757 uint32_t displacement;
758
759 void Read(OMF86Format * omf, Linker::Reader& rd, size_t displacement_size);
760 uint16_t Size(OMF86Format * omf, bool is32bit) const;
761 void Write(OMF86Format * omf, ChecksumWriter& wr, bool is32bit) const;
762
763 void CalculateValues(OMF86Format * omf, Module * mod);
764 void ResolveReferences(OMF86Format * omf, Module * mod);
765 };
766
768 enum record_type_t : uint8_t
769 {
770 RHEADR = 0x6E, // Intel 4.0
771 REGINT = 0x70, // Intel 4.0
772 REDATA = 0x72, // Intel 4.0
773 RIDATA = 0x74, // Intel 4.0
774 OVLDEF = 0x76, // Intel 4.0
775 ENDREC = 0x78, // Intel 4.0
776 BLKDEF = 0x7A, // Intel 4.0
777 BLKEND = 0x7C, // Intel 4.0
778 DEBSYM = 0x7E, // Intel 4.0
779 THEADR = 0x80,
780 LHEADR = 0x82,
781 PEDATA = 0x84, // Intel 4.0
782 PIDATA = 0x86, // Intel 4.0
783 COMENT = 0x88,
784 MODEND16 = 0x8A,
785 MODEND = 0x8A,
786 MODEND32 = 0x8B, // TIS 1.1
787 EXTDEF = 0x8C,
788 TYPDEF = 0x8E, // Intel 4.0
789 PUBDEF16 = 0x90,
790 PUBDEF = 0x90,
791 PUBDEF32 = 0x91, // TIS 1.1
792 LOCSYM = 0x92, // Intel 4.0
793 LINNUM = 0x94, // Intel 4.0
794 LNAMES = 0x96,
795 SEGDEF = 0x98, // Intel 4.0
796 GRPDEF = 0x9A, // Intel 4.0
797 FIXUPP16 = 0x9C,
798 FIXUPP = 0x9C,
799 FIXUPP32 = 0x9D, // TIS 1.1
800 LEDATA16 = 0xA0,
801 LEDATA = 0xA0,
802 LEDATA32 = 0xA1, // TIS 1.1
803 LIDATA16 = 0xA2,
804 LIDATA = 0xA2,
805 LIDATA32 = 0xA3, // TIS 1.1
806 LIBHED = 0xA4, // Intel 4.0
807 LIBNAM = 0xA6, // Intel 4.0
808 LIBLOC = 0xA8, // Intel 4.0
809 LIBDIC = 0xAA, // Intel 4.0
810 COMDEF = 0xB0, // TIS 1.1, since Microsoft LINK 3.5
811 BAKPAT16 = 0xB2, // TIS 1.1, since Microsoft QuickC 1.0
812 BAKPAT = 0xB2, // TIS 1.1
813 BAKPAT32 = 0xB3, // TIS 1.1
814 LEXTDEF16 = 0xB4, // TIS 1.1, since Microsoft C 5.0
815 LEXTDEF = 0xB4, // TIS 1.1
816 LEXTDEF32 = 0xB5, // TIS 1.1
817 LPUBDEF16 = 0xB6, // TIS 1.1, since Microsoft C 5.0
818 LPUBDEF = 0xB6, // TIS 1.1
819 LPUBDEF32 = 0xB7, // TIS 1.1
820 LCOMDEF = 0xB8, // TIS 1.1, since Microsoft C 5.0
821 CEXTDEF = 0xBC, // TIS 1.1, since Microsoft C 7.0
822 COMDAT16 = 0xC2, // TIS 1.1, since Microsoft C 7.0
823 COMDAT = 0xC2, // TIS 1.1
824 COMDAT32 = 0xC3, // TIS 1.1
825 LINSYM16 = 0xC4, // TIS 1.1, since Microsoft C 7.0
826 LINSYM = 0xC4, // TIS 1.1
827 LINSYM32 = 0xC5, // TIS 1.1
828 ALIAS = 0xC6, // TIS 1.1, since Microsoft LINK 5.13
829 NBKPAT16 = 0xC8, // TIS 1.1, since Microsoft C 7.0
830 NBKPAT = 0xC8, // TIS 1.1
831 NBKPAT32 = 0xC9, // TIS 1.1
832 LLNAMES = 0xCA, // TIS 1.1, since Microsoft C 7.0
833 VERNUM = 0xCC, // TIS 1.1
834 VENDEXT = 0xCE, // TIS 1.1
835 LibraryHeader = 0xF0, // TIS 1.1
836 LibraryEnd = 0xF1, // TIS 1.1
837 };
838
839 static const std::map<offset_t, std::string> RecordTypeNames;
840
848
850 std::shared_ptr<Record> ReadRecord(Linker::Reader& rd);
851
854 {
855 public:
857 std::string name;
858
861 {
862 }
863
864 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
865 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
866 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
867 };
868
871 {
872 public:
875
877 enum module_type_t : uint8_t
878 {
879 AbsoluteModule = 0,
880 RelocatableModule = 1,
881 PICModule = 2,
882 LTLModule = 3,
883 };
884
894 uint32_t overlay_record_offset; // TODO: resolve record index
895
897 uint32_t static_size;
904
907 {
908 }
909
912 {
913 }
914
915 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
916 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
917 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
918 };
919
922 {
923 public:
925 std::vector<std::string> names;
929 uint16_t lname_count = 0;
930
933 {
934 }
935
936 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
937 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
938 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
939
940 void CalculateValues(OMF86Format * omf, Module * mod) override;
941 void ResolveReferences(OMF86Format * omf, Module * mod) override;
942 };
943
945 class SegmentDefinitionRecord : public Record, public std::enable_shared_from_this<SegmentDefinitionRecord>
946 {
947 public:
975
978
980 typedef uint32_t Absolute;
981
983 struct Relocatable { };
984
987 {
988 public:
989 bool group_member;
990 uint16_t maximum_segment_length;
991 uint16_t group_offset;
992 };
993
995 std::variant<Relocatable, Absolute, LoadTimeLocatable> location = Relocatable{};
996
998 enum combination_t : uint8_t
999 {
1006 Combination_Public = Combination_Append,
1009 Combination_Public4 = FlagTIS | 4,
1016 Combination_Common = FlagTIS | 6,
1019 Combination_Public7 = FlagTIS | 4,
1020 };
1021
1024
1026 bool page_resident = false; // Intel
1028 bool use32 = false;
1029
1036
1038 enum access_t : uint8_t
1039 {
1040 AccessReadOnly = 0,
1041 AccessExecuteOnly = 1,
1042 AccessExecuteRead = 2,
1043 AccessReadWrite = 3,
1044 };
1045
1047 std::optional<access_t> access;
1048
1051 {
1052 }
1053
1054 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1055 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1056 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1057
1058 void CalculateValues(OMF86Format * omf, Module * mod) override;
1059 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1060 };
1061
1063 class GroupDefinitionRecord : public Record, public std::enable_shared_from_this<GroupDefinitionRecord>
1064 {
1065 public:
1068 {
1069 public:
1072 {
1073 public:
1074 NameIndex segment_name;
1075 NameIndex class_name;
1076 NameIndex overlay_name;
1077 };
1078
1081 {
1082 public:
1083 uint32_t maximum_group_length;
1084 uint32_t group_length;
1085 };
1086
1088 typedef uint32_t Absolute;
1089
1091 static constexpr uint8_t Absolute_type = 0xFA;
1093 static constexpr uint8_t LoadTimeLocatable_type = 0xFB;
1095 static constexpr uint8_t SegmentClassOverlayNames_type = 0xFD;
1097 static constexpr uint8_t ExternalIndex_type = 0xFE;
1099 static constexpr uint8_t SegmentIndex_type = 0xFF;
1100
1102 std::variant<ExternalIndex, SegmentIndex, SegmentClassOverlayNames, LoadTimeLocatable, Absolute> component = ExternalIndex();
1103
1104 static Component Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1105 uint16_t Size(OMF86Format * omf, Module * mod) const;
1106 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1107
1108 void CalculateValues(OMF86Format * omf, Module * mod);
1109 void ResolveReferences(OMF86Format * omf, Module * mod);
1110 };
1111
1115 std::vector<Component> components;
1116
1119 {
1120 }
1121
1122 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1123 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1124 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1125
1126 void CalculateValues(OMF86Format * omf, Module * mod) override;
1127 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1128 };
1129
1137 class TypeDefinitionRecord : public Record, public std::enable_shared_from_this<TypeDefinitionRecord>
1138 {
1139 public:
1142 {
1143 public:
1145 bool nice;
1146
1148 struct Null { };
1150 struct Repeat { };
1151
1153 std::variant<uint32_t, int32_t, std::string, TypeIndex, Null, Repeat> leaf = Null();
1154
1156 static constexpr uint8_t NullLeaf = 0x80;
1158 static constexpr uint8_t StringLeaf = 0x82;
1160 static constexpr uint8_t IndexLeaf = 0x83;
1162 static constexpr uint8_t RepeatLeaf = 0x85;
1164 static constexpr uint8_t NumericLeaf16 = 0x81;
1166 static constexpr uint8_t NumericLeaf24 = 0x84;
1168 static constexpr uint8_t SignedNumericLeaf8 = 0x86;
1170 static constexpr uint8_t SignedNumericLeaf16 = 0x87;
1172 static constexpr uint8_t SignedNumericLeaf32 = 0x88;
1173
1174 static LeafDescriptor Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1175 uint16_t Size(OMF86Format * omf, Module * mod) const;
1176 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1177
1178 void CalculateValues(OMF86Format * omf, Module * mod);
1179 void ResolveReferences(OMF86Format * omf, Module * mod);
1180 };
1181
1183 std::string name;
1185 std::vector<LeafDescriptor> leafs;
1186
1187 enum
1188 {
1189 Far = 0x61, // Far(Array(...)) - Microsoft
1190 Near = 0x62, // Near(Array | Structure | Scalar, length in bits) - Microsoft
1191 Interrupt = 0x63,
1192 File = 0x64,
1193 Packed = 0x65,
1194 Unpacked = 0x66,
1195 Set = 0x67,
1196 Chameleon = 0x69,
1197 Boolean = 0x6A,
1198 True = 0x6B,
1199 False = 0x6C,
1200 Char = 0x6D,
1201 Integer = 0x6E,
1202 Const = 0x6F,
1203 Label = 0x71, // Label(nil, Short | Long)
1204 Long = 0x72,
1205 Short = 0x73,
1206 Procedure = 0x74, // Procedure(nil, @type, Short | Long, parameter count, @List(...))
1207 Parameter = 0x75, // Parameter(@type)
1208 Dimension = 0x76,
1209 Array = 0x77, // Array(length, @type)
1210 Structure = 0x79, // Structure(length, component count, @List(...))
1211 Pointer = 0x7A,
1212 Scalar = 0x7B, // Scalar(length, UnsignedInteger | SignedInteger | Real | @Pointer)
1213 UnsignedInteger = 0x7C,
1214 SignedInteger = 0x7D,
1215 Real = 0x7E,
1216 List = 0x7F, // List(...)
1217 };
1218
1221 {
1222 }
1223
1224 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1225 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1226 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1227
1228 void CalculateValues(OMF86Format * omf, Module * mod) override;
1229 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1230 };
1231
1234 {
1235 public:
1238
1240 std::vector<SymbolDefinition> symbols;
1241
1244 {
1245 }
1246
1247 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1248 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1249 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1250
1251 void CalculateValues(OMF86Format * omf, Module * mod) override;
1252 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1253 };
1254
1257 {
1258 public:
1262 uint16_t extdef_count = 0;
1263
1266 {
1267 }
1268
1269 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1270 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1271 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1272
1273 void CalculateValues(OMF86Format * omf, Module * mod) override;
1274 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1275 };
1276
1279 {
1280 public:
1283
1285 std::vector<LineNumber> lines;
1286
1289 {
1290 }
1291
1292 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1293 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1294 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1295
1296 void CalculateValues(OMF86Format * omf, Module * mod) override;
1297 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1298 };
1299
1301 class BlockDefinitionRecord : public Record, public std::enable_shared_from_this<BlockDefinitionRecord>
1302 {
1303 public:
1307 std::string name;
1309 uint16_t offset;
1311 uint16_t length;
1313 enum block_type_t : uint8_t
1314 {
1321 };
1325 uint16_t return_address_offset; // only for procedures
1328
1331 {
1332 }
1333
1334 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1335 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1336 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1337
1338 void CalculateValues(OMF86Format * omf, Module * mod) override;
1339 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1340 };
1341
1344 {
1345 public:
1346 enum frame_type_t : uint8_t
1347 {
1348 Location = 0x00,
1349 Frame16 = 0x80,
1350 Frame32 = 0xC0,
1351 };
1352 frame_type_t frame_type;
1353
1354 static constexpr uint8_t SymbolBaseMethod = 0x00;
1355 static constexpr uint8_t ExternalMethod = 0x01;
1356 static constexpr uint8_t BlockMethod = 0x02;
1357
1358 std::variant<BaseSpecification, ExternalIndex, BlockIndex> base = ExternalIndex();
1359
1360 std::vector<SymbolDefinition> names;
1361
1364 {
1365 }
1366
1367 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1368 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1369 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1370
1371 void CalculateValues(OMF86Format * omf, Module * mod) override;
1372 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1373 };
1374
1377 {
1378 public:
1382 uint16_t offset;
1384 std::shared_ptr<DataBlock> data;
1385
1388 {
1389 }
1390
1391 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1392 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1393 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1394
1395 void CalculateValues(OMF86Format * omf, Module * mod) override;
1396 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1397 };
1398
1401 {
1402 public:
1404 uint32_t address;
1406 std::shared_ptr<DataBlock> data;
1407
1410 {
1411 }
1412
1413 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1414 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1415 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1416 };
1417
1420 {
1421 public:
1425 uint32_t offset;
1427 std::shared_ptr<DataBlock> data;
1428
1431 {
1432 }
1433
1434 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1435 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1436 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1437
1438 void CalculateValues(OMF86Format * omf, Module * mod) override;
1439 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1440 };
1441
1443 class FixupRecord : public Record
1444 {
1445 public:
1448 {
1449 public:
1453 bool frame;
1455 std::variant<SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute> reference = FrameNumber(0);
1456
1457 static Thread Read(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint8_t leading_data_byte);
1458 uint16_t Size(OMF86Format * omf, Module * mod) const;
1459 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1460
1461 void CalculateValues(OMF86Format * omf, Module * mod);
1462 void ResolveReferences(OMF86Format * omf, Module * mod);
1463 };
1464
1465 class Fixup
1466 {
1467 public:
1470
1497
1501 uint16_t offset;
1504
1505 static Fixup Read(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint8_t leading_data_byte, bool is32bit);
1506 uint16_t Size(OMF86Format * omf, Module * mod, bool is32bit) const;
1507 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr, bool is32bit) const;
1508
1509 void CalculateValues(OMF86Format * omf, Module * mod);
1510 void ResolveReferences(OMF86Format * omf, Module * mod);
1511 };
1512
1514 std::vector<std::variant<Thread, Fixup>> fixup_data;
1515
1518 {
1519 }
1520
1521 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1522 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1523 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1524
1525 void CalculateValues(OMF86Format * omf, Module * mod) override;
1526 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1527 };
1528
1530 class OverlayDefinitionRecord : public Record, public std::enable_shared_from_this<OverlayDefinitionRecord>
1531 {
1532 public:
1534 std::string name;
1536 uint32_t location;
1540 std::optional<OverlayIndex> shared_overlay;
1542 std::optional<OverlayIndex> adjacent_overlay;
1543
1546 {
1547 }
1548
1549 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1550 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1551 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1552
1553 void CalculateValues(OMF86Format * omf, Module * mod) override;
1554 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1555 };
1556
1558 class EndRecord : public Record
1559 {
1560 public:
1562 enum block_type_t : uint8_t
1563 {
1564 Overlay = 0,
1565 Block = 1,
1566 };
1569
1572 {
1573 }
1574
1575 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1576 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1577 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1578 };
1579
1582 {
1583 public:
1586 {
1587 public:
1589 enum register_t : uint8_t
1590 {
1599 };
1600
1603 {
1604 public:
1608 uint16_t offset;
1609 };
1613 std::variant<Reference, InitialValue> value = Reference();
1614
1615 static Register Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1616 uint16_t Size(OMF86Format * omf, Module * mod) const;
1617 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1618
1619 void CalculateValues(OMF86Format * omf, Module * mod);
1620 void ResolveReferences(OMF86Format * omf, Module * mod);
1621 };
1622
1624 std::vector<Register> registers;
1625
1628 {
1629 }
1630
1631 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1632 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1633 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1634
1635 void CalculateValues(OMF86Format * omf, Module * mod) override;
1636 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1637 };
1638
1641 {
1642 public:
1646 std::optional<std::variant<Reference, std::tuple<uint16_t, uint16_t>>> start_address;
1647
1650 {
1651 }
1652
1653 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1654 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1655 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1656 };
1657
1660 {
1661 public:
1664 {
1665 public:
1667 uint32_t offset;
1669 uint32_t value;
1670 };
1671
1675 enum location_type_t : uint8_t
1676 {
1677 Location8bit = 0,
1678 Location16bit = 1,
1679 Location32bit = 2,
1680 Location32bit_IBM = 9,
1681 };
1683 uint8_t type;
1685 std::vector<OffsetValuePair> offset_value_pairs;
1686
1689 {
1690 }
1691
1692 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1693 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1694 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1695
1696 void CalculateValues(OMF86Format * omf, Module * mod) override;
1697 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1698 };
1699
1702 {
1703 public:
1706
1708 uint8_t type;
1711 std::vector<OffsetValuePair> offset_value_pairs;
1712
1715 {
1716 }
1717
1718 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1719 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1720 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1721
1722 void CalculateValues(OMF86Format * omf, Module * mod) override;
1723 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1724 };
1725
1728 {
1729 public:
1735 bool local;
1738
1739 // TODO: document further
1740
1741 enum selection_criterion_t : uint8_t
1742 {
1743 SelectNoMatch = 0x00,
1744 SelectPickAny = 0x10,
1745 SelectSameSize = 0x20,
1746 SelectExactMatch = 0x30,
1747 };
1748 static constexpr uint8_t SelectionCriterionMask = 0xF0;
1749 selection_criterion_t selection_criterion;
1750
1751 enum allocation_type_t : uint8_t
1752 {
1753 AllocateExplicit = 0x00,
1754 AllocateFarCode = 0x01,
1755 AllocateFarData = 0x02,
1756 AllocateCode32 = 0x03,
1757 AllocateData32 = 0x04,
1758 };
1759 static constexpr uint8_t AllocationTypeMask = 0x0F;
1760 allocation_type_t allocation_type;
1761
1764
1765 uint32_t offset;
1766 TypeIndex type;
1767 BaseSpecification base;
1768 NameIndex name;
1769 std::shared_ptr<DataBlock> data;
1770
1771 InitializedCommunalDataRecord(record_type_t record_type = record_type_t(0))
1772 : Record(record_type)
1773 {
1774 }
1775
1776 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1777 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1778 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1779
1780 void CalculateValues(OMF86Format * omf, Module * mod) override;
1781 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1782 };
1783
1786 {
1787 public:
1793 std::vector<LineNumber> line_numbers;
1794
1797 {
1798 }
1799
1800 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1801 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1802 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1803
1804 void CalculateValues(OMF86Format * omf, Module * mod) override;
1805 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1806 };
1807
1810 {
1811 public:
1814 {
1815 public:
1817 std::string alias_name;
1819 std::string substitute_name;
1820
1821 static AliasDefinition Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1822 uint16_t Size(OMF86Format * omf, Module * mod) const;
1823 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1824 };
1826 std::vector<AliasDefinition> alias_definitions;
1827
1830 {
1831 }
1832
1833 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1834 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1835 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1836 };
1837
1840 {
1841 public:
1843 std::string version;
1844
1847 {
1848 }
1849
1850 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1851 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1852 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1853 };
1854
1857 {
1858 public:
1862 std::vector<uint8_t> extension;
1863
1866 {
1867 }
1868
1869 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1870 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1871 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1872 };
1873
1874 // TODO: document
1875
1876 class CommentRecord : public Record
1877 {
1878 public:
1879 bool no_purge;
1880 bool no_list;
1881 enum comment_class_t : uint8_t
1882 {
1883 Translator = 0x00,
1884 IntelCopyright = 0x01,
1885 LibrarySpecifier = 0x81,
1886 MSDOSVersion = 0x9C,
1887 MemoryModel = 0x9D,
1888 DOSSEG = 0x9E,
1889 DefaultLibrarySearchName = 0x9F,
1890 OMFExtension = 0xA0,
1891 NewOMFExtension = 0xA1,
1892 LinkPassSeparator = 0xA2,
1893 LIBMOD = 0xA3,
1894 EXESTR = 0xA4,
1895 INCERR = 0xA6,
1896 NOPAD = 0xA7,
1897 WKEXT = 0xA8,
1898 LZEXT = 0xA9,
1899 Comment = 0xDA,
1900 Compiler = 0xDB,
1901 Date = 0xDC,
1902 TimeStamp = 0xDD,
1903 User = 0xDF,
1904 DependencyFile = 0xE9,
1905 CommandLine = 0xFF,
1906 };
1907 comment_class_t comment_class;
1908
1910 : Record(COMENT)
1911 {
1912 }
1913
1914 CommentRecord(comment_class_t comment_class = comment_class_t(0))
1915 : Record(COMENT), comment_class(comment_class)
1916 {
1917 }
1918
1919 virtual void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) = 0;
1920 virtual uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const = 0;
1921 virtual void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const = 0;
1922
1923 static std::shared_ptr<CommentRecord> ReadCommentRecord(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t record_length);
1924 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1925 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1926 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1927
1929 class EmptyCommentRecord;
1930 class TextCommentRecord;
1931 };
1932
1934 {
1935 public:
1936 std::vector<SegmentIndex> segments;
1937
1939 : CommentRecord(NOPAD)
1940 {
1941 }
1942
1943 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
1944 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
1945 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1946
1947 void CalculateValues(OMF86Format * omf, Module * mod) override;
1948 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1949 };
1950
1952 {
1953 public:
1955 {
1956 public:
1957 ExternalIndex definition;
1958 ExternalIndex default_resolution;
1959
1960 static ExternalAssociation Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1961 uint16_t Size(OMF86Format * omf, Module * mod) const;
1962 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1963
1964 void CalculateValues(OMF86Format * omf, Module * mod);
1965 void ResolveReferences(OMF86Format * omf, Module * mod);
1966 };
1967
1968 std::vector<ExternalAssociation> associations;
1969
1970 ExternalAssociationRecord(comment_class_t comment_class = comment_class_t(0))
1971 : CommentRecord(comment_class)
1972 {
1973 }
1974
1975 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
1976 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
1977 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1978
1979 void CalculateValues(OMF86Format * omf, Module * mod) override;
1980 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1981 };
1982
1984 {
1985 public:
1986 enum extension_type_t : uint8_t
1987 {
1988 IMPDEF = 0x01,
1989 EXPDEF = 0x02,
1990 INCDEF = 0x03,
1991 ProtectedModeLibrary = 0x04,
1992 LNKDIR = 0x05,
1993 BigEndian = 0x06,
1994 PRECOMP = 0x07,
1995 };
1996 extension_type_t subtype;
1997
1998 OMFExtensionRecord(extension_type_t subtype = extension_type_t(0))
1999 : CommentRecord(OMFExtension), subtype(subtype)
2000 {
2001 }
2002
2005 };
2006
2008 {
2009 public:
2010 std::string internal_name;
2011 std::string module_name;
2012 std::variant<std::string, uint16_t> entry_ident;
2013
2015 : OMFExtensionRecord(IMPDEF)
2016 {
2017 }
2018
2019 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2020 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2021 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2022 };
2023
2025 {
2026 public:
2027 bool resident_name;
2028 bool no_data;
2029 uint8_t parameter_count;
2030 std::string exported_name;
2031 std::string internal_name;
2032 std::optional<uint16_t> ordinal;
2033
2035 : OMFExtensionRecord(EXPDEF)
2036 {
2037 }
2038
2039 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2040 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2041 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2042 };
2043
2045 {
2046 public:
2047 uint16_t extdef_delta;
2048 uint16_t linnum_delta;
2049 uint16_t padding_byte_count;
2050
2052 : OMFExtensionRecord(INCDEF)
2053 {
2054 }
2055
2056 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2057 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2058 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2059 };
2060
2062 {
2063 public:
2064 bool new_executable;
2065 bool omit_codeview_publics;
2066 bool run_mpc;
2067 uint8_t pseudocode_version;
2068 uint8_t codeview_version;
2069
2070 static constexpr uint8_t FlagNewExecutable = 0x01;
2071 static constexpr uint8_t FlagOmitCodeViewPublics = 0x02;
2072 static constexpr uint8_t FlagRunMPC = 0x04;
2073
2075 : OMFExtensionRecord(LNKDIR)
2076 {
2077 }
2078
2079 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2080 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2081 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2082 };
2083
2085 {
2086 public:
2087 uint32_t dictionary_offset;
2088 uint16_t dictionary_size;
2089 bool case_sensitive;
2090
2093 {
2094 }
2095
2096 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
2097 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
2098 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2099
2100 void WriteRecord(OMF86Format * omf, Module * mod, Linker::Writer& wr) const override;
2101 };
2102
2104 {
2105 public:
2108 {
2109 }
2110
2111 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
2112 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
2113 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2114
2115 void WriteRecord(OMF86Format * omf, Module * mod, Linker::Writer& wr) const override;
2116 };
2117
2120 {
2121 public:
2123 size_t first_record = 0;
2125 size_t record_count = 0;
2126
2128 std::vector<std::string> lnames;
2130 std::vector<std::shared_ptr<SegmentDefinitionRecord>> segdefs;
2132 std::vector<std::shared_ptr<GroupDefinitionRecord>> grpdefs;
2134 std::vector<std::shared_ptr<TypeDefinitionRecord>> typdefs;
2136 std::vector<std::shared_ptr<BlockDefinitionRecord>> blkdefs;
2138 std::vector<std::shared_ptr<OverlayDefinitionRecord>> ovldefs;
2140 std::vector<ExternalName> extdefs; // also includes comdefs and cextdefs
2141 // TODO: CalculateValue/etc. for ExternalName
2142 };
2143
2145 std::vector<std::shared_ptr<Record>> records;
2146
2148 std::vector<Module> modules;
2149
2150 // TIS library fields
2151 uint16_t page_size;
2152
2154 static std::shared_ptr<OMF86Format> ReadOMFFile(Linker::Reader& rd);
2155
2156 static void DumpAddFields(const Record * record, Dumper::Dumper& dump, Dumper::Region& region, const OMF86Format * omf, const Module * mod, size_t record_index);
2157
2158 void ReadFile(Linker::Reader& rd) override;
2160 offset_t WriteFile(Linker::Writer& wr) const override;
2161 void Dump(Dumper::Dumper& dump) const override;
2163 void GenerateModule(Linker::Module& module) const override;
2164 /* TODO */
2165 };
2166
2168 {
2169 public:
2170 std::vector<uint8_t> data;
2171
2172 GenericCommentRecord(comment_class_t comment_class = comment_class_t(0))
2173 : CommentRecord(comment_class)
2174 {
2175 }
2176
2177 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2178 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2179 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2180 };
2181
2183 {
2184 public:
2185 EmptyCommentRecord(comment_class_t comment_class = comment_class_t(0))
2186 : CommentRecord(comment_class)
2187 {
2188 }
2189
2190 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2191 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2192 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2193 };
2194
2196 {
2197 public:
2198 std::string name;
2199
2200 TextCommentRecord(comment_class_t comment_class = comment_class_t(0))
2201 : CommentRecord(comment_class)
2202 {
2203 }
2204
2205 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2206 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2207 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2208 };
2209
2211 {
2212 public:
2213 std::vector<uint8_t> data;
2214
2215 GenericOMFExtensionRecord(extension_type_t extension_type = extension_type_t(0))
2216 : OMFExtensionRecord(extension_type)
2217 {
2218 }
2219
2220 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2221 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2222 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2223 };
2224
2226 {
2227 public:
2228 EmptyOMFExtensionRecord(extension_type_t extension_type = extension_type_t(0))
2229 : OMFExtensionRecord(extension_type)
2230 {
2231 }
2232
2233 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2234 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2235 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2236 };
2237
2241 class OMF80Format : public virtual OMFFormat, public virtual Linker::InputFormat
2242 {
2243 public:
2244 class Module;
2245
2246 enum record_type_t : uint8_t
2247 {
2248 ModuleHeader = 0x02,
2249 ModuleEnd = 0x04,
2250 Content = 0x06,
2251 LineNumbers = 0x08,
2252 EndOfFile = 0x0E,
2253 ModuleAncestor = 0x10,
2254 LocalSymbols = 0x12,
2255 PublicDefinitions = 0x16,
2256 ExternalDefinitions = 0x18,
2257 ExternalReferences = 0x20,
2258 Relocations = 0x22,
2259 InterSegmentReferences = 0x24,
2260 LibraryModuleLocations = 0x26,
2261 LibraryModuleNames = 0x28,
2262 LibraryDictionary = 0x2A,
2263 LibraryHeader = 0x2C,
2264 NamedCommonDefinitions = 0x2E,
2265 };
2266
2267 static const std::map<offset_t, std::string> RecordTypeNames;
2268
2278
2280 std::shared_ptr<Record> ReadRecord(Linker::Reader& rd);
2281
2287 typedef uint8_t segment_id_t;
2288
2290 static constexpr segment_id_t AbsoluteSegment = 0;
2292 static constexpr segment_id_t CodeSegment = 1;
2294 static constexpr segment_id_t DataSegment = 2;
2296 static constexpr segment_id_t StackSegment = 3;
2298 static constexpr segment_id_t MemorySegment = 4;
2302 static constexpr segment_id_t LastNamedCommonSegment = 254;
2304 static constexpr segment_id_t UnnamedCommonSegment = 255;
2305
2306 // TODO: document
2307
2308 enum alignment_t : uint8_t
2309 {
2310 // page is 256 bytes
2311 AlignFitsPage = 1,
2312 AlignPage = 2,
2313 AlignByte = 3,
2314 };
2315
2317 {
2318 public:
2319 uint16_t index;
2320 std::string external_name;
2321
2322 void CalculateValues(OMF80Format * omf, Module * mod);
2323 void ResolveReferences(OMF80Format * omf, Module * mod);
2324 };
2325
2327 {
2328 public:
2330 {
2331 public:
2332 segment_id_t segment_id = 0;
2333 uint16_t length = 0;
2334 alignment_t alignment = AlignByte;
2335
2336 static SegmentDefinition Read(OMF80Format * omf, Linker::Reader& rd);
2337 void Write(OMF80Format * omf, ChecksumWriter& wr) const;
2338 };
2339
2340 std::string name;
2341 std::vector<SegmentDefinition> segment_definitions;
2342
2343 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
2345 {
2346 }
2347
2348 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2349 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2350 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2351
2352 void CalculateValues(OMF80Format * omf, Module * mod) override;
2353 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2354 };
2355
2357 {
2358 public:
2359 bool main;
2360 segment_id_t start_segment_id;
2361 uint16_t start_offset;
2362 std::vector<uint8_t> info;
2363
2364 ModuleEndRecord(record_type_t record_type = record_type_t(0))
2366 {
2367 }
2368
2369 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2370 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2371 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2372
2373 void CalculateValues(OMF80Format * omf, Module * mod) override;
2374 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2375 };
2376
2378 {
2379 public:
2381 {
2382 public:
2383 segment_id_t segment_id;
2384 std::string common_name;
2385
2386 static NamedCommonDefinition ReadNamedCommonDefinition(OMF80Format * omf, Linker::Reader& rd);
2387 uint16_t GetNamedCommonDefinitionSize(OMF80Format * omf) const;
2388 void WriteNamedCommonDefinition(OMF80Format * omf, ChecksumWriter& wr) const;
2389 };
2390
2391 std::vector<NamedCommonDefinition> named_common_definitions;
2392
2393 NamedCommonDefinitionsRecord(record_type_t record_type = record_type_t(0))
2395 {
2396 }
2397
2398 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2399 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2400 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2401
2402 void CalculateValues(OMF80Format * omf, Module * mod) override;
2403 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2404 };
2405
2407 {
2408 public:
2409 Module * mod;
2410
2411 std::vector<std::string> external_names; // only used for generation
2412 uint16_t first_external_name;
2413 uint16_t external_name_count;
2414
2415 ExternalDefinitionsRecord(record_type_t record_type = record_type_t(0))
2417 {
2418 }
2419
2420 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2421 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2422 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2423
2424 void CalculateValues(OMF80Format * omf, Module * mod) override;
2425 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2426 };
2427
2429 {
2430 public:
2432 {
2433 public:
2434 uint16_t offset;
2435 std::string name;
2436
2437 static SymbolDefinition Read(OMF80Format * omf, Module * mod, Linker::Reader& rd);
2438 uint16_t Size(OMF80Format * omf, Module * mod) const;
2439 void Write(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const;
2440 };
2441
2442 uint8_t segment_id;
2443 std::vector<SymbolDefinition> public_definitions;
2444
2445 SymbolDefinitionsRecord(record_type_t record_type = record_type_t(0))
2447 {
2448 }
2449
2450 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2451 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2452 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2453
2454 void CalculateValues(OMF80Format * omf, Module * mod) override;
2455 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2456 };
2457
2458 enum relocation_type_t : uint8_t
2459 {
2460 RelocationLowByte = 1,
2461 RelocationHighByte = 2,
2462 RelocationWord = 3,
2463 };
2464
2466 {
2467 public:
2468 relocation_type_t relocation_type;
2469 std::vector<uint16_t> offsets;
2470
2471 RelocationsRecord(record_type_t record_type = record_type_t(0))
2473 {
2474 }
2475
2476 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2477 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2478 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2479
2480 void CalculateValues(OMF80Format * omf, Module * mod) override;
2481 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2482 };
2483
2485 {
2486 public:
2487 segment_id_t segment_id;
2488
2489 InterSegmentReferencesRecord(record_type_t record_type = record_type_t(0))
2491 {
2492 }
2493
2494 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2495 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2496 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2497
2498 void CalculateValues(OMF80Format * omf, Module * mod) override;
2499 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2500 };
2501
2503 {
2504 public:
2506 {
2507 public:
2508 ExternalNameIndex name_index;
2509 uint16_t offset;
2510 };
2511
2512 relocation_type_t relocation_type;
2513 std::vector<ExternalReference> external_references;
2514
2515 ExternalReferencesRecord(record_type_t record_type = record_type_t(0))
2517 {
2518 }
2519
2520 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2521 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2522 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2523
2524 void CalculateValues(OMF80Format * omf, Module * mod) override;
2525 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2526 };
2527
2529 {
2530 public:
2531 std::string name;
2532
2533 ModuleAncestorRecord(record_type_t record_type = record_type_t(0))
2535 {
2536 }
2537
2538 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2539 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2540 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2541
2542 void CalculateValues(OMF80Format * omf, Module * mod) override;
2543 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2544 };
2545
2547 {
2548 public:
2549 segment_id_t segment_id = 0;
2550 uint16_t length = 0;
2551 alignment_t alignment = AlignByte;
2552 std::string common_name;
2553
2555 {
2556 }
2557
2559 : segment_id(segment_definition.segment_id), length(segment_definition.length), alignment(segment_definition.alignment)
2560 {
2561 }
2562 };
2563
2565 {
2566 public:
2568 size_t first_record = 0;
2570 size_t record_count = 0;
2571
2572 std::map<segment_id_t, SegmentDefinition> segment_definitions;
2573 std::vector<std::string> external_names;
2574 };
2575
2577 std::vector<std::shared_ptr<Record>> records;
2578
2580 std::vector<Module> modules;
2581
2583 static std::shared_ptr<OMF80Format> ReadOMFFile(Linker::Reader& rd);
2584
2585 static void DumpAddFields(const Record * record, Dumper::Dumper& dump, Dumper::Region& region, const OMF80Format * omf, const Module * mod, size_t record_index);
2586
2587 void ReadFile(Linker::Reader& rd) override;
2589 offset_t WriteFile(Linker::Writer& wr) const override;
2590 void Dump(Dumper::Dumper& dump) const override;
2592 void GenerateModule(Linker::Module& module) const override;
2593 /* TODO */
2594 };
2595
2599 class OMF51Format : public virtual OMFFormat, public virtual Linker::InputFormat
2600 {
2601 public:
2602 class Module;
2603
2604 enum record_type_t : uint8_t
2605 {
2606 ModuleHeader = OMF80Format::ModuleHeader,
2607 ModuleEnd = OMF80Format::ModuleEnd,
2608 Content = OMF80Format::Content,
2609 Fixups = 0x08,
2610 SegmentDefinitions = 0x0E,
2611 ScopeDefinition = 0x10,
2612 DebugItems = 0x12,
2613 PublicDefinitions = OMF80Format::PublicDefinitions,
2614 ExternalDefinitions = OMF80Format::ExternalDefinitions,
2615 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
2616 LibraryModuleNames = OMF80Format::LibraryModuleNames,
2617 LibraryDictionary = OMF80Format::LibraryDictionary,
2618 LibraryHeader = OMF80Format::LibraryHeader,
2619 };
2620
2621 static const std::map<offset_t, std::string> RecordTypeNames;
2622
2631
2633 std::shared_ptr<Record> ReadRecord(Linker::Reader& rd);
2634
2635 // TODO: document record types
2636
2637 static constexpr uint8_t SegmentAbsolute = 0;
2638
2654
2670
2672 {
2673 public:
2674 bool overlayable;
2675 uint8_t register_bank;
2676 segment_type_t segment_type;
2677
2678 static constexpr uint8_t MaskSegmentType = 0x07;
2679 static constexpr uint8_t MaskRegisterBank = 0x18;
2680 static constexpr uint8_t ShiftRegisterBank = 3;
2681 static constexpr uint8_t FlagOverlayable = 0x20;
2682 static constexpr uint8_t FlagSegmentEmpty = 0x80;
2683
2684 void ReadSegmentInfo(OMF51Format * omf, Module * mod, uint8_t segment_info);
2685 uint8_t WriteSegmentInfo(OMF51Format * omf, Module * mod) const;
2686 };
2687
2689 {
2690 public:
2691 uint8_t segment_id;
2692 SegmentInfo info;
2693 alignment_t alignment;
2694 uint16_t base;
2695 uint32_t size;
2696 std::string name;
2697
2698 static SegmentDefinition Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2699 uint16_t Size(OMF51Format * omf, Module * mod) const;
2700 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2701 };
2702
2704 {
2705 public:
2706 bool indirectly_callable;
2707 bool variable;
2708 std::optional<unsigned> register_bank;
2709 segment_type_t usage;
2710
2711 static constexpr uint8_t MaskSegmentType = 0x07;
2712 static constexpr uint8_t MaskRegisterBank = 0x18;
2713 static constexpr uint8_t ShiftRegisterBank = 3;
2714 static constexpr uint8_t FlagRegisterBank = 0x20;
2715 static constexpr uint8_t FlagVariable = 0x40;
2716 static constexpr uint8_t FlagIndirectlyCallable = 0x80;
2717
2718 void Read(OMF51Format * omf, Module * mod, uint8_t segment_info);
2719 uint8_t Write(OMF51Format * omf, Module * mod) const;
2720 };
2721
2723 {
2724 public:
2725 uint8_t segment_id;
2726 SymbolInfo info;
2727 uint16_t offset;
2728 std::string name;
2729
2730 static SymbolDefinition Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2731 uint16_t Size(OMF51Format * omf, Module * mod) const;
2732 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2733 };
2734
2736 {
2737 public:
2738 uint8_t block_id = 2;
2739 uint8_t external_id;
2740 SymbolInfo info;
2741 std::string name;
2742
2743 static ExternalDefinition Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2744 uint16_t Size(OMF51Format * omf, Module * mod) const;
2745 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2746 };
2747
2749 {
2750 public:
2751 std::string name;
2752 enum translator_id_t : uint8_t
2753 {
2754 Assembler = 0xFD,
2755 PLMCompiler = 0xFE,
2756 Linker = 0xFF,
2757 };
2758 translator_id_t translator_id;
2759
2760 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
2762 {
2763 }
2764
2765 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2766 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2767 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2768 };
2769
2771 {
2772 public:
2773 std::string name;
2774 std::array<bool, 4> banks;
2775
2776 ModuleEndRecord(record_type_t record_type = record_type_t(0))
2778 {
2779 }
2780
2781 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2782 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2783 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2784 };
2785
2787 {
2788 public:
2789 std::vector<SegmentDefinition> segment_definitions;
2790
2791 SegmentDefinitionsRecord(record_type_t record_type = record_type_t(0))
2793 {
2794 }
2795
2796 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2797 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2798 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2799
2800 void CalculateValues(OMF51Format * omf, Module * mod) override;
2801 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2802 };
2803
2805 {
2806 public:
2807 std::vector<SymbolDefinition> symbol_definitions;
2808
2809 PublicSymbolsRecord(record_type_t record_type = record_type_t(0))
2811 {
2812 }
2813
2814 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2815 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2816 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2817
2818 void CalculateValues(OMF51Format * omf, Module * mod) override;
2819 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2820 };
2821
2823 {
2824 public:
2825 std::vector<ExternalDefinition> external_definitions;
2826
2827 ExternalDefinitionsRecord(record_type_t record_type = record_type_t(0))
2829 {
2830 }
2831
2832 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2833 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2834 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2835
2836 void CalculateValues(OMF51Format * omf, Module * mod) override;
2837 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2838 };
2839
2841 {
2842 public:
2843 enum block_type_t : uint8_t
2844 {
2845 ModuleBlock = 0,
2846 DoBlock = 1,
2847 ProcedureBlock = 2,
2848 EndModuleBlock = 3,
2849 EndDoBlock = 4,
2850 EndProcedureBlock = 5,
2851 };
2852
2853 block_type_t block_type;
2854 std::string name;
2855
2856 ScopeDefinitionRecord(record_type_t record_type = record_type_t(0))
2858 {
2859 }
2860
2861 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2862 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2863 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2864
2865 void CalculateValues(OMF51Format * omf, Module * mod) override;
2866 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2867 };
2868
2870 {
2871 public:
2873 {
2874 public:
2875 uint8_t segment_id;
2876 SymbolInfo info;
2877 uint16_t offset;
2878 std::string name;
2879
2880 static Symbol Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2881 uint16_t Size(OMF51Format * omf, Module * mod) const;
2882 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2883 };
2884
2886 {
2887 public:
2888 std::vector<Symbol> symbols;
2889 };
2890
2892 {
2893 public:
2894 std::vector<Symbol> symbols;
2895 };
2896
2898 {
2899 public:
2900 uint8_t segment_id;
2901 SegmentInfo info;
2902 uint16_t offset;
2903 std::string name;
2904
2905 static SegmentSymbol Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2906 uint16_t Size(OMF51Format * omf, Module * mod) const;
2907 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2908 };
2909
2911 {
2912 public:
2913 std::vector<SegmentSymbol> symbols;
2914 };
2915
2917 {
2918 public:
2919 uint8_t segment_id;
2920 uint16_t offset;
2921 uint16_t line_number;
2922
2923 static LineNumber Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2924 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2925 };
2926
2928 {
2929 public:
2930 std::vector<LineNumber> symbols;
2931 };
2932
2933 static constexpr uint8_t Type_LocalSymbols = 0;
2934 static constexpr uint8_t Type_PublicSymbols = 1;
2935 static constexpr uint8_t Type_SegmentSymbols = 2;
2936 static constexpr uint8_t Type_LineNumbers = 3;
2937
2938 std::variant<LocalSymbols, PublicSymbols, SegmentSymbols, LineNumbers> contents;
2939
2940 DebugItemsRecord(record_type_t record_type = record_type_t(0))
2942 {
2943 }
2944
2945 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2946 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2947 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2948
2949 void CalculateValues(OMF51Format * omf, Module * mod) override;
2950 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2951 };
2952
2953 class FixupRecord : public Record
2954 {
2955 public:
2956 enum relocation_type_t : uint8_t
2957 {
2958 RelocationLow8 = 0,
2959 RelocationByte8 = 1,
2960 RelocationRelative8 = 2,
2961 RelocationHigh8 = 3,
2962 RelocationWord16 = 4,
2963 RelocationAbsolute11 = 5,
2964 RelocationBit7 = 6,
2965 RelocationConv7 = 7,
2966 };
2967
2977
2978 class Fixup
2979 {
2980 public:
2981 uint16_t location;
2982 relocation_type_t relocation;
2983 reference_type_t reference;
2984 uint8_t id;
2985 uint16_t offset;
2986
2987 static Fixup Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2988 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2989 };
2990
2991 std::vector<Fixup> fixups;
2992
2993 FixupRecord(record_type_t record_type = record_type_t(0))
2995 {
2996 }
2997
2998 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2999 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
3000 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
3001
3002 void CalculateValues(OMF51Format * omf, Module * mod) override;
3003 void ResolveReferences(OMF51Format * omf, Module * mod) override;
3004 };
3005
3007 {
3008 public:
3010 size_t first_record = 0;
3012 size_t record_count = 0;
3013
3014 std::map<uint8_t, SegmentDefinition> segment_definitions;
3015 std::map<uint8_t, ExternalDefinition> external_definitions;
3016 };
3017
3019 std::vector<std::shared_ptr<Record>> records;
3020
3022 std::vector<Module> modules;
3023
3025 static std::shared_ptr<OMF51Format> ReadOMFFile(Linker::Reader& rd);
3026
3027 static void DumpAddFields(const Record * record, Dumper::Dumper& dump, Dumper::Region& region, const OMF51Format * omf, const Module * mod, size_t record_index);
3028
3029 void ReadFile(Linker::Reader& rd) override;
3031 offset_t WriteFile(Linker::Writer& wr) const override;
3032 void Dump(Dumper::Dumper& dump) const override;
3034 void GenerateModule(Linker::Module& module) const override;
3035 /* TODO */
3036 };
3037
3041 class OMF96Format : public virtual OMFFormat, public virtual Linker::InputFormat
3042 {
3043 public:
3044 class Module;
3045
3046 typedef uint16_t index_t;
3047
3048 enum record_type_t : uint8_t
3049 {
3050 ModuleHeader = OMF80Format::ModuleHeader,
3051 ModuleEnd = OMF80Format::ModuleEnd,
3052 Content = OMF80Format::Content,
3053 LineNumbers = OMF80Format::LineNumbers,
3054 BlockDefinition = 0x0A,
3055 BlockEnd = 0x0C,
3056 EndOfFile = OMF80Format::EndOfFile,
3057 ModuleAncestor = OMF80Format::ModuleAncestor,
3058 LocalSymbols = OMF80Format::LocalSymbols,
3059 TypeDefinition = 0x14,
3060 PublicDefinitions = OMF80Format::PublicDefinitions,
3061 ExternalDefinitions = OMF80Format::ExternalDefinitions,
3062 SegmentDefinitions = 0x20, // different from OMF51 number
3063 Relocations = OMF80Format::Relocations,
3064 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
3065 LibraryModuleNames = OMF80Format::LibraryModuleNames,
3066 LibraryDictionary = OMF80Format::LibraryDictionary,
3067 LibraryHeader = 0x2E, // different from OMF80 number
3068 };
3069
3070 static const std::map<offset_t, std::string> RecordTypeNames;
3071
3081
3083 std::shared_ptr<Record> ReadRecord(Linker::Reader& rd);
3084
3085 typedef uint8_t segment_id_t;
3086
3087 static constexpr segment_id_t CodeSegment = 0;
3088 static constexpr segment_id_t DataSegment = 1;
3089 static constexpr segment_id_t RegisterSegment = 2;
3090 static constexpr segment_id_t OverlaySegment = 3;
3091 static constexpr segment_id_t StackSegment = 4;
3092 static constexpr segment_id_t DynamicSymbol = 5;
3093 static constexpr segment_id_t NullSegment = 6;
3094 static constexpr segment_id_t SegmentTypeMask = 7;
3095
3096 static constexpr segment_id_t FlagBasedVariable = 0x40;
3097
3098 static constexpr segment_id_t FlagRelocatableSegment = 0x80;
3099
3100 enum alignment_t
3101 {
3102 AlignByte = 0,
3103 AlignWord = 1,
3104 AlignLong = 2,
3105 };
3106
3108 {
3109 public:
3110 segment_id_t segment_id;
3111 private:
3112 union
3113 {
3114 alignment_t alignment; // for RelocatableSegment
3115 uint16_t base_address;
3116 };
3117 public:
3118 uint16_t size;
3119
3120 bool IsRelocatable() const
3121 {
3122 return segment_id & FlagRelocatableSegment;
3123 }
3124
3125 bool IsAbsolute() const
3126 {
3127 return !IsRelocatable();
3128 }
3129
3130 alignment_t GetAlignment() const
3131 {
3132 return IsRelocatable() ? alignment : alignment_t(-1);
3133 }
3134
3135 uint16_t GetBaseAddress() const
3136 {
3137 return IsAbsolute() ? base_address : 0;
3138 }
3139
3140 void MakeRelocatable(alignment_t rel_alignment)
3141 {
3142 segment_id |= FlagRelocatableSegment;
3143 alignment = rel_alignment;
3144 }
3145
3146 void MakeAbsolute(uint16_t address)
3147 {
3148 segment_id &= ~FlagRelocatableSegment;
3149 base_address = address;
3150 }
3151
3152 static SegmentDefinition Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3153 uint16_t Size(OMF96Format * omf, Module * mod) const;
3154 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3155 };
3156
3158
3160 {
3161 public:
3162 index_t index;
3163 std::shared_ptr<TypeDefinitionRecord> record;
3164
3165 TypeIndex(index_t index = 0)
3166 : index(index)
3167 {
3168 }
3169
3170 void CalculateValues(OMF86Format * omf, Module * mod);
3171 void ResolveReferences(OMF86Format * omf, Module * mod);
3172 };
3173
3175 {
3176 public:
3177 std::string name;
3178 TypeIndex type;
3179
3180 static ExternalDefinition Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3181 uint16_t Size(OMF96Format * omf, Module * mod) const;
3182 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3183
3184 void CalculateValues(OMF96Format * omf, Module * mod);
3185 void ResolveReferences(OMF96Format * omf, Module * mod);
3186 };
3187
3189 {
3190 public:
3191 uint16_t offset;
3192 std::string name;
3193 TypeIndex type;
3194
3195 static SymbolDefinition Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3196 uint16_t Size(OMF96Format * omf, Module * mod) const;
3197 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3198
3199 void CalculateValues(OMF96Format * omf, Module * mod);
3200 void ResolveReferences(OMF96Format * omf, Module * mod);
3201 };
3202
3204 {
3205 public:
3206 std::string name;
3207 uint8_t translator_id;
3208 std::string date_time;
3209
3210 static constexpr uint8_t Version14 = 0xE0;
3211 static constexpr uint8_t Version20 = 0xE4;
3212 static constexpr uint8_t Translator = 0x00;
3213 static constexpr uint8_t Linker = 0x01;
3214
3215 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
3217 {
3218 }
3219
3220 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3221 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3222 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3223 };
3224
3226 {
3227 public:
3228 bool main;
3229 bool valid;
3230
3231 static constexpr uint8_t MainModule = 0x01;
3232 static constexpr uint8_t OtherModule = 0x00;
3233
3234 static constexpr uint8_t ValidModule = 0x00;
3235 static constexpr uint8_t ErroneousModule = 0x01;
3236
3237 ModuleEndRecord(record_type_t record_type = record_type_t(0))
3239 {
3240 }
3241
3242 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3243 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3244 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3245 };
3246
3248 {
3249 public:
3250 std::vector<SegmentDefinition> segment_definitions;
3251
3252 SegmentDefinitionsRecord(record_type_t record_type = record_type_t(0))
3254 {
3255 }
3256
3257 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3258 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3259 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3260
3261 void CalculateValues(OMF96Format * omf, Module * mod) override;
3262 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3263 };
3264
3265 class TypeDefinitionRecord : public Record, public std::enable_shared_from_this<TypeDefinitionRecord>
3266 {
3267 public:
3269 {
3270 public:
3271 bool nice; // easy if false
3272
3274 struct Null { };
3276 struct Repeat { };
3277 // TODO: document
3278 struct EndOfBranch { };
3279
3280 std::variant<Null, int32_t, std::string, TypeIndex, Repeat, EndOfBranch> leaf = Null();
3281
3283 static constexpr uint8_t NullLeaf = 0x64;
3285 static constexpr uint8_t SignedNumericLeaf16 = 0x65;
3287 static constexpr uint8_t SignedNumericLeaf32 = 0x66;
3289 static constexpr uint8_t StringLeaf = 0x67;
3291 static constexpr uint8_t IndexLeaf = 0x68;
3293 static constexpr uint8_t RepeatLeaf = 0x69;
3295 static constexpr uint8_t EndOfBranchLeaf = 0x6A;
3296
3297 static LeafDescriptor Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3298 uint16_t Size(OMF96Format * omf, Module * mod) const;
3299 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3300
3301 void CalculateValues(OMF96Format * omf, Module * mod);
3302 void ResolveReferences(OMF96Format * omf, Module * mod);
3303 };
3304
3306 std::vector<LeafDescriptor> leafs;
3307
3308 TypeDefinitionRecord(record_type_t record_type = record_type_t(0))
3310 {
3311 }
3312
3313 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3314 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3315 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3316
3317 void CalculateValues(OMF96Format * omf, Module * mod) override;
3318 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3319 };
3320
3322 {
3323 public:
3324 segment_id_t segment_id;
3325 std::vector<SymbolDefinition> symbol_definitions;
3326
3327 SymbolDefinitionsRecord(record_type_t record_type = record_type_t(0))
3329 {
3330 }
3331
3332 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3333 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3334 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3335
3336 void CalculateValues(OMF96Format * omf, Module * mod) override;
3337 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3338 };
3339
3341 {
3342 public:
3343 segment_id_t segment_id;
3344 std::vector<ExternalDefinition> external_definitions;
3345
3346 ExternalDefinitionsRecord(record_type_t record_type = record_type_t(0))
3348 {
3349 }
3350
3351 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3352 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3353 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3354
3355 void CalculateValues(OMF96Format * omf, Module * mod) override;
3356 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3357 };
3358
3360 {
3361 public:
3363 {
3364 public:
3365 typedef segment_id_t LocalReference;
3366 typedef uint16_t ExternalReference;
3367
3368 enum reference_type_t
3369 {
3370 RegisterSimple = 0,
3371 RegisterAutoIncrement = 1,
3372 ShiftCountImmediate = 2,
3373 ShiftCountRegister = 3,
3374 ByteConstant = 4,
3375 ShortJump = 6,
3376 MediumJump = 7,
3377 MediumCall = 8,
3378 LongJumpCall = 9,
3379 LongDirect = 10,
3380 };
3381
3382 static constexpr uint8_t FlagAddendInCode = 0x40;
3383 static constexpr uint8_t FlagExternal = 0x80;
3384
3385 uint16_t offset;
3386 std::variant<LocalReference, ExternalReference> reference = LocalReference(0);
3387 std::optional<uint16_t> addend;
3388 reference_type_t reference_type;
3389 alignment_t alignment;
3390
3391 static Relocation Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3392 uint16_t Size(OMF96Format * omf, Module * mod) const;
3393 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3394 };
3395
3396 std::vector<Relocation> relocations;
3397
3398 RelocationRecord(record_type_t record_type = record_type_t(0))
3400 {
3401 }
3402
3403 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3404 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3405 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3406
3407 void CalculateValues(OMF96Format * omf, Module * mod) override;
3408 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3409 };
3410
3412 {
3413 public:
3414 std::string name;
3415 std::optional<SegmentDefinition> segment_definition;
3416
3417 ModuleAncestorRecord(record_type_t record_type = record_type_t(0))
3419 {
3420 }
3421
3422 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3423 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3424 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3425
3426 void CalculateValues(OMF96Format * omf, Module * mod) override;
3427 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3428 };
3429
3431 {
3432 public:
3434 {
3435 public:
3436 std::string name;
3437 TypeIndex type;
3438 };
3439
3440 typedef segment_id_t LocalReference;
3441 typedef uint16_t ExternalReference;
3442
3444 {
3445 public:
3446 std::variant<LocalReference, ExternalReference> frame_pointer = LocalReference(0);
3447 uint16_t return_offset;
3448 uint8_t prologue_size;
3449 };
3450
3451 segment_id_t segment_id;
3452 uint16_t offset;
3453 uint16_t size;
3454 std::optional<BlockNameAndType> name_and_type;
3455 std::optional<ProcedureInformation> procedure_info;
3456
3457 BlockDefinitionRecord(record_type_t record_type = record_type_t(0))
3459 {
3460 }
3461
3462 static constexpr uint8_t FlagProcedure = 0x40;
3463 static constexpr uint8_t FlagExternal = 0x80;
3464
3465 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3466 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3467 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3468
3469 void CalculateValues(OMF96Format * omf, Module * mod) override;
3470 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3471 };
3472
3474 {
3475 public:
3477 size_t first_record = 0;
3479 size_t record_count = 0;
3480
3481 std::map<segment_id_t, SegmentDefinition> segment_definitions;
3482 std::vector<std::shared_ptr<TypeDefinitionRecord>> type_definitions;
3483 };
3484
3486 std::vector<std::shared_ptr<Record>> records;
3487
3489 std::vector<Module> modules;
3490
3492 static std::shared_ptr<OMF96Format> ReadOMFFile(Linker::Reader& rd);
3493
3494 static void DumpAddFields(const Record * record, Dumper::Dumper& dump, Dumper::Region& region, const OMF96Format * omf, const Module * mod, size_t record_index);
3495
3496 void ReadFile(Linker::Reader& rd) override;
3498 offset_t WriteFile(Linker::Writer& wr) const override;
3499 void Dump(Dumper::Dumper& dump) const override;
3501 void GenerateModule(Linker::Module& module) const override;
3502 /* TODO */
3503 };
3504
3506 {
3507 public:
3508 std::shared_ptr<OMFFormat> contents;
3509
3510 void ReadFile(Linker::Reader& rd) override;
3511
3513 void GenerateModule(Linker::Module& module) const override;
3514
3516 offset_t WriteFile(Linker::Writer& wr) const override;
3517
3518 offset_t ImageSize() const override;
3519
3520 void Dump(Dumper::Dumper& dump) const override;
3521 };
3522}
3523
3524#endif /* OMF_H */
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:586
A record that represents a region within the file.
Definition dumper.h:485
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.
A class that provides a general interface to loading a module.
Definition format.h:193
virtual void GenerateModule(ModuleCollector &linker, std::string file_name, bool is_library=false) const
Loads the information into a module object.
Definition format.cc:215
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
void ReadData(size_t count, void *data)
Read in a sequence of bytes.
Definition reader.cc:30
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
void WriteData(size_t count, const void *data)
Write out a sequence of bytes.
Definition writer.cc:7
void Skip(offset_t offset)
Jump to a distance in the output stream.
Definition writer.cc:104
void WriteWord(size_t bytes, uint64_t value, EndianType endiantype)
Read a word.
Definition writer.cc:67
Convenience class to calculate the checksum of a record while writing it.
Definition omf.h:20
Definition omf.h:2954
reference_type_t
Definition omf.h:2969
@ ReferenceSegmentStart
The starting address of the portion of the segment in the file.
Definition omf.h:2973
@ ReferenceExternal
An external reference.
Definition omf.h:2975
@ ReferenceSegmentBase
The starting address of the segment.
Definition omf.h:2971
Definition omf.h:3007
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:3010
size_t record_count
The number of records belonging to this module.
Definition omf.h:3012
Definition omf.h:2672
Definition omf.h:2704
Intel Relocatable Object Module for the Intel MCS-51.
Definition omf.h:2600
void GenerateModule(Linker::Module &module) const override
Loads the information into a module object, a convenience method when there is a single module genera...
Definition omf.cc:5622
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:3019
std::shared_ptr< Record > ReadRecord(Linker::Reader &rd)
Parses and returns an instance of the next record.
Definition omf.cc:5502
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:5596
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:5574
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:5589
static std::shared_ptr< OMF51Format > ReadOMFFile(Linker::Reader &rd)
Parses an OMF51 file.
Definition omf.cc:5562
alignment_t
Definition omf.h:2656
@ AlignFitsBlock
Must fit a 256 byte block.
Definition omf.h:2666
@ AlignFitsPage
Must fit a 256 byte page.
Definition omf.h:2664
@ AlignUnit
Byte or bit alignment for SegmentBit segments.
Definition omf.h:2660
@ AlignPage
Align to a 256 byte page boundary.
Definition omf.h:2668
@ AlignBitAddressable
Must be allocated within the bit addressable part of SegmentData.
Definition omf.h:2662
@ AlignAbsolute
Non-relocatable.
Definition omf.h:2658
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:3022
segment_type_t
Definition omf.h:2640
@ SegmentNone
Not a segment, but a symbol with this segment type is treated as a value.
Definition omf.h:2652
@ SegmentIData
256 B internal RAM that is accessible via indirect addressing, first 128 B shared with SegmentData
Definition omf.h:2648
@ SegmentBit
256 bit address space, part of SegmentData
Definition omf.h:2650
@ SegmentData
256 B internal RAM that is accessible via direct addressing, first 128 B shared with SegmentIData
Definition omf.h:2646
@ SegmentCode
64 KiB read-only memory
Definition omf.h:2642
@ SegmentXData
64 KiB read-write memory
Definition omf.h:2644
Definition omf.h:2565
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:2568
size_t record_count
The number of records belonging to this module.
Definition omf.h:2570
Intel Relocatable Object Module for the Intel 8080.
Definition omf.h:2242
static constexpr segment_id_t CodeSegment
Used for instructions and generally anything loaded into the ROM.
Definition omf.h:2292
static constexpr segment_id_t StackSegment
Used to specify size of segment.
Definition omf.h:2296
uint8_t segment_id_t
Represents one of the 256 segments.
Definition omf.h:2287
static constexpr segment_id_t UnnamedCommonSegment
The unnamed common segment.
Definition omf.h:2304
static constexpr segment_id_t DataSegment
Used for data and generally anything loaded into the RAM.
Definition omf.h:2294
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:2580
static constexpr segment_id_t LastNamedCommonSegment
The last segment number corresponding to a named common segment.
Definition omf.h:2302
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:4851
static constexpr segment_id_t AbsoluteSegment
The absolute segment, all offsets are absolute memory locations.
Definition omf.h:2290
void GenerateModule(Linker::Module &module) const override
Loads the information into a module object, a convenience method when there is a single module genera...
Definition omf.cc:4884
static constexpr segment_id_t MemorySegment
Used to specify the highest memory address available.
Definition omf.h:2298
static std::shared_ptr< OMF80Format > ReadOMFFile(Linker::Reader &rd)
Parses an OMF80 file.
Definition omf.cc:4824
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:2577
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:4858
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:4836
std::shared_ptr< Record > ReadRecord(Linker::Reader &rd)
Parses and returns an instance of the next record.
Definition omf.cc:4754
static constexpr segment_id_t FirstNamedCommonSegment
The first segment number corresponding to a named common segment.
Definition omf.h:2300
Represents a single substitution.
Definition omf.h:1814
std::string alias_name
Name used in references.
Definition omf.h:1817
std::string substitute_name
Name it should be substituted with.
Definition omf.h:1819
Record defining a replacement name for symbols, used for ALIAS (included in TIS)
Definition omf.h:1810
std::vector< AliasDefinition > alias_definitions
List of replacements.
Definition omf.h:1826
Represents a single fixup.
Definition omf.h:1664
uint32_t offset
The offset at which the fixup should happen.
Definition omf.h:1667
uint32_t value
The value to be added to the fixup location.
Definition omf.h:1669
A specialized relocation, used for BAKPAT (included in TIS)
Definition omf.h:1660
std::vector< OffsetValuePair > offset_value_pairs
The data for the relocations.
Definition omf.h:1685
location_type_t
Relocation type.
Definition omf.h:1676
SegmentIndex segment
Segment to which the relocations belong.
Definition omf.h:1673
uint8_t type
The type of the relocations.
Definition omf.h:1683
Specification for the group and segment of some reference, and the frame if both are 0.
Definition omf.h:655
std::variant< Location, FrameNumber > location
The actual location of the reference.
Definition omf.h:665
A record that defines a block, used for BLKDEF records (Intel only)
Definition omf.h:1302
block_type_t
Type of the block, if it is a procedure.
Definition omf.h:1314
@ NotProcedure
Block is not a procedure.
Definition omf.h:1316
@ NearProcedure
Block is a near procedure.
Definition omf.h:1318
@ FarProcedure
Block is a far procedure.
Definition omf.h:1320
block_type_t procedure
Whether this block is a procedure, and whether it is a near or far procedure.
Definition omf.h:1323
uint16_t length
Length of the block.
Definition omf.h:1311
TypeIndex type
Type of block or procedure, only used if name != "".
Definition omf.h:1327
std::string name
The name of the block or empty.
Definition omf.h:1307
uint16_t return_address_offset
Offset, relative to the frame pointer (BP), to the return address of the procedure in the calling fra...
Definition omf.h:1325
uint16_t offset
Offset to the first byte of the block.
Definition omf.h:1309
BaseSpecification base
The first byte of the segment containing the block.
Definition omf.h:1305
A rich container for indexes referring to a BLKDEF record.
Definition omf.h:536
Definition omf.h:1877
Represents a sequence of data, with optional repeated parts, used by RelocatableDataRecord,...
Definition omf.h:717
std::vector< std::shared_ptr< DataBlock > > Blocks
If the contents are a sequence of blocks (iterated only)
Definition omf.h:723
uint16_t repeat_count
Number of times the data should be appear. Should be 1 for enumerated data.
Definition omf.h:720
uint16_t GetIteratedDataBlockSize(OMF86Format *omf, bool is32bit) const
Gets the size of an encoded iterated record in bytes.
Definition omf.cc:807
void WriteIteratedDataBlock(OMF86Format *omf, ChecksumWriter &wr, bool is32bit) const
Writes the contents of an iterated record into a file.
Definition omf.cc:829
static std::shared_ptr< DataBlock > ReadIteratedDataBlock(OMF86Format *omf, Linker::Reader &rd, bool is32bit)
Parses the contents of an iterated record.
Definition omf.cc:777
static std::shared_ptr< DataBlock > ReadEnumeratedDataBlock(OMF86Format *omf, Linker::Reader &rd, uint16_t data_length)
Parses the contents of an enumerated record.
Definition omf.cc:766
void WriteEnumeratedDataBlock(OMF86Format *omf, ChecksumWriter &wr) const
Writes the contents of an enumerated record into a file.
Definition omf.cc:824
std::variant< Data, Blocks > content
The actual contents of the block, whether iterated or enumerated.
Definition omf.h:728
std::vector< uint8_t > Data
If the contents are a sequence of bytes (either iterated or enumerated)
Definition omf.h:725
uint16_t GetEnumeratedDataBlockSize(OMF86Format *omf) const
Gets the size of an encoded enumerated record in bytes.
Definition omf.cc:802
Record to store debug symbols, used for DEBSYM (Intel only)
Definition omf.h:1344
Record to signal termination of an overloay or block, used for ENDBLK (Intel only)
Definition omf.h:1559
block_type_t
Type of block that is terminated by an EndRecord.
Definition omf.h:1563
block_type_t block_type
Type of block this record terminates.
Definition omf.h:1568
A rich container for indexes referring to symbols in an EXTDEF, LEXTDEF, COMDEF, LCOMDEF,...
Definition omf.h:639
An external name declaration, appearing in an EXTDEF, LEXTDEF, COMDEF, LCOMDEF or CEXTDEF record.
Definition omf.h:568
static uint32_t ReadValue(OMF86Format *omf, Linker::Reader &rd)
Read a length value, for near or far elements.
Definition omf.cc:464
void WriteExternalName(OMF86Format *omf, ChecksumWriter &wr) const
Writes this entry to file.
Definition omf.cc:599
NameIndex name
Name of the symbol.
Definition omf.h:591
static uint32_t ValueSize(OMF86Format *omf, uint32_t length)
Determines the number of bytes needed for a length value, for near or far elements.
Definition omf.cc:483
static ExternalName ReadCommonName(OMF86Format *omf, Linker::Reader &rd, bool local)
Parse a COMDEF or LCOMDEF entry.
Definition omf.cc:528
static void WriteValue(OMF86Format *omf, ChecksumWriter &wr, uint32_t length)
Writes a length value, for near or far elements.
Definition omf.cc:495
bool local
Signals if a symbol is local.
Definition omf.h:587
bool name_is_index
Set if name.index contains a valid value, for CEXTDEF entries.
Definition omf.h:589
common_type_t
Type of a common symbol.
Definition omf.h:572
@ NearCommon
Near variable.
Definition omf.h:583
@ FarCommon
Far variable.
Definition omf.h:580
@ SegmentIndexCommon
Borland segment index.
Definition omf.h:577
@ External
Not a common symbol, appears in an EXTDEF, LEXTDEF or CEXTDEF record.
Definition omf.h:574
uint16_t GetExternalNameSize(OMF86Format *omf) const
Returns the number of bytes required to write this entry.
Definition omf.cc:571
static ExternalName ReadExternalName(OMF86Format *omf, Linker::Reader &rd, bool local)
Parse an EXTDEF or LEXTDEF entry.
Definition omf.cc:518
static ExternalName ReadComdatExternalName(OMF86Format *omf, Linker::Reader &rd)
Parse a CEXTDEF entry.
Definition omf.cc:561
A record defining several external or common symbols, used for EXTDEF, LEXTDEF, CEXTDEF,...
Definition omf.h:1257
ExternalIndex first_extdef
Index of first external or common symbol in module.
Definition omf.h:1260
uint16_t extdef_count
Number of external or common symbols defined in this record.
Definition omf.h:1262
uint16_t offset
Offset to value to be relocated, relative to the latest data block.
Definition omf.h:1501
relocation_type_t type
The type of the relocation value.
Definition omf.h:1499
relocation_type_t
Types for the value that needs to be relocated.
Definition omf.h:1473
@ RelocationOffset32_LoaderResolved
A 32-bit loader-resolved value (TIS assignment)
Definition omf.h:1495
@ RelocationHighByte
Most significant 8 bits of a 16-bit value.
Definition omf.h:1483
@ RelocationOffset16
A 16-bit value or the 16-bit offset portion of a far address.
Definition omf.h:1477
@ RelocationSegment
The segment portion of a far address.
Definition omf.h:1479
@ RelocationPointer32
A 32-bit far address, consisting of a 16-bit segment portion and a 16-bit offset portion.
Definition omf.h:1481
@ RelocationOffset32_PharLap
A 32-bit value or the 32-bit offset portion of a far address (Phar Lap assignment)
Definition omf.h:1487
@ RelocationLowByte
Least significant 8 bits of value.
Definition omf.h:1475
@ RelocationOffset16_LoaderResolved
A 16-bit loader-resolved value (TIS assignment)
Definition omf.h:1485
@ RelocationOffset32
A 32-bit value or the 32-bit offset portion of a far address (TIS assignment)
Definition omf.h:1491
@ RelocationPointer48
A 48-bit far address, consisting of a 16-bit segment portion and a 32-bit offset portion (TIS assignm...
Definition omf.h:1493
@ RelocationPointer48_PharLap
A 48-bit far address, consisting of a 16-bit segment portion and a 32-bit offset portion (Phar Lap as...
Definition omf.h:1489
Reference ref
Reference of this relocation.
Definition omf.h:1503
bool segment_relative
Set if segment relative, self relative otherwise.
Definition omf.h:1469
Threads are intermediary storage for relocation targets and frames, this class represents a thread as...
Definition omf.h:1448
unsigned thread_number
The thread number which gets assigned to, a value from 0 to 3.
Definition omf.h:1451
bool frame
Set if this is a frame thread, it is a target thread otherwise.
Definition omf.h:1453
std::variant< SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute > reference
The frame or target reference.
Definition omf.h:1455
A record containing relocation data, used for FIXUPP.
Definition omf.h:1444
std::vector< std::variant< Thread, Fixup > > fixup_data
Sequence of thread assignments and relocations.
Definition omf.h:1514
Represents the data required for a load-time locatable group (Intel only)
Definition omf.h:1081
Represents the data required for identifying a the segment by the name, class name and overlay name (...
Definition omf.h:1072
Represents a component of the group.
Definition omf.h:1068
static constexpr uint8_t SegmentIndex_type
The type prefix for a segment (the only type defined by TIS)
Definition omf.h:1099
static constexpr uint8_t Absolute_type
The type prefix for the address of the group (Intel only)
Definition omf.h:1091
static constexpr uint8_t SegmentClassOverlayNames_type
The type prefix for segment, class, overlay name triplets (Intel only)
Definition omf.h:1095
static constexpr uint8_t LoadTimeLocatable_type
The type prefix for a load time locatable group (Intel only)
Definition omf.h:1093
uint32_t Absolute
Represents the data required for an absolute group (Intel only)
Definition omf.h:1088
static constexpr uint8_t ExternalIndex_type
The type prefix for the segment of an external symbol (Intel only)
Definition omf.h:1097
std::variant< ExternalIndex, SegmentIndex, SegmentClassOverlayNames, LoadTimeLocatable, Absolute > component
The contents of the component.
Definition omf.h:1102
A record that defines a segment group, used for GRPDEF records.
Definition omf.h:1064
std::vector< Component > components
The components of the group, such as member segments or load address.
Definition omf.h:1115
NameIndex name
Name of the group.
Definition omf.h:1113
A rich container for indexes referring to a GRPDEF record.
Definition omf.h:500
Initialization data for common segments, used for COMDAT (included in TIS)
Definition omf.h:1728
bool iterated
Set if the format of the data is iterated, cleared for enumerated.
Definition omf.h:1733
bool local
Local common segment.
Definition omf.h:1735
bool continued
Set if this record is the continuation of a previous record, cleared if it is a new record.
Definition omf.h:1731
bool code_segment
Set if the data is to be placed in a code segment.
Definition omf.h:1737
Represents a line number, used by LineNumbersRecord and SymbolLineNumbersRecord.
Definition omf.h:698
uint32_t offset
The offset in memory where the line starts.
Definition omf.h:703
uint16_t number
The line number value.
Definition omf.h:701
Stores as debugging data the line number information, used for LINNUM.
Definition omf.h:1279
BaseSpecification base
The first byte of the segment containing the line.
Definition omf.h:1282
std::vector< LineNumber > lines
List of lines.
Definition omf.h:1285
A list of names to be referenced, used for LNAMES and LLNAMES records.
Definition omf.h:922
index_t first_lname
Index of the first name in the module.
Definition omf.h:927
std::vector< std::string > names
List of names (only needed for genering OMF files.
Definition omf.h:925
uint16_t lname_count
Number of names appearing in this record.
Definition omf.h:929
Logical enumerated or iterated data, used for LEDATA and LIDATA.
Definition omf.h:1420
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1427
SegmentIndex segment
Segment that contains this data.
Definition omf.h:1423
uint32_t offset
Offset within segment where the data starts.
Definition omf.h:1425
Terminates a module, used for MODEND.
Definition omf.h:1641
bool main_module
Set if this is a main module.
Definition omf.h:1644
std::optional< std::variant< Reference, std::tuple< uint16_t, uint16_t > > > start_address
Optional starting address, either a reference, or a segment:offset pair.
Definition omf.h:1646
A header record, used for THEADR and LHEADR.
Definition omf.h:854
std::string name
The name of the record.
Definition omf.h:857
Represents a single module inside the OMF file.
Definition omf.h:2120
std::vector< std::shared_ptr< BlockDefinitionRecord > > blkdefs
List of blocks declared in the module.
Definition omf.h:2136
std::vector< std::shared_ptr< GroupDefinitionRecord > > grpdefs
List of groups declared in the module.
Definition omf.h:2132
std::vector< ExternalName > extdefs
List of external symbols declared in the module.
Definition omf.h:2140
std::vector< std::string > lnames
List of names declared in the module.
Definition omf.h:2128
std::vector< std::shared_ptr< TypeDefinitionRecord > > typdefs
List of types declared in the module.
Definition omf.h:2134
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:2123
std::vector< std::shared_ptr< OverlayDefinitionRecord > > ovldefs
List of overlays declared in the module.
Definition omf.h:2138
std::vector< std::shared_ptr< SegmentDefinitionRecord > > segdefs
List of segments declared in the module.
Definition omf.h:2130
size_t record_count
The number of records belonging to this module.
Definition omf.h:2125
A rich container for indexes referring to a LNAME/LLNAME declaration.
Definition omf.h:468
A specialized relocation for named common segments, used for NBKPAT (included in TIS)
Definition omf.h:1702
uint8_t type
The type of the relocations.
Definition omf.h:1708
NameIndex name
The name of the common segment to which the relocations belong to.
Definition omf.h:1710
The version of the OMF format, used for VERNUM (included in TIS)
Definition omf.h:1840
std::string version
Textual representation of the version number.
Definition omf.h:1843
A record that defines an overlay, used for OVLDEF records.
Definition omf.h:1531
size_t first_data_record_index
Index of the first overlay data record within the file.
Definition omf.h:1538
std::optional< OverlayIndex > shared_overlay
Must be loaded at the same location as the shared overlay.
Definition omf.h:1540
std::string name
Name of the overlay.
Definition omf.h:1534
uint32_t location
Offset to the first overlay data record within the file.
Definition omf.h:1536
std::optional< OverlayIndex > adjacent_overlay
Must be loaded adjacent to the adjacent overlay.
Definition omf.h:1542
A rich container for indexes referring to a OVLDEF record.
Definition omf.h:552
Physical enumerated or iterated data, used for PEDATA and PIDATA (Intel only)
Definition omf.h:1401
uint32_t address
Physical address where data starts.
Definition omf.h:1404
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1406
A header record for an R-Module, used for RHEADR (not part of TIS OMF)
Definition omf.h:871
uint32_t maximum_dynamic_storage
Maximum memory size to allocate on load.
Definition omf.h:903
uint32_t dynamic_storage
Memory size to allocate on load.
Definition omf.h:901
module_type_t module_type
The type of the module.
Definition omf.h:886
uint16_t group_record_count
Number of group definition records in module.
Definition omf.h:890
module_type_t
Represents the type of the module.
Definition omf.h:878
uint32_t static_size
Total size of LTL segments.
Definition omf.h:897
uint16_t segment_record_count
Number of segment definition records in module.
Definition omf.h:888
uint32_t maximum_static_size
Maximum size needed for all LTL segments.
Definition omf.h:899
uint32_t overlay_record_offset
Offset to the first overlay definition record from the start of the file or 0.
Definition omf.h:894
uint16_t overlay_record_count
Number of overlay definition records in module.
Definition omf.h:892
Module * mod
The module object this record appears in.
Definition omf.h:874
Represents a reference for a relocation.
Definition omf.h:747
std::variant< ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute > frame
The frame for a reference, or a thread number.
Definition omf.h:755
unsigned ThreadNumber
A number between 0 and 3.
Definition omf.h:750
std::variant< ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber > target
The target for a reference, or a thread number.
Definition omf.h:753
uint32_t displacement
Displacement to be added to the value.
Definition omf.h:757
Used to initialize the register.
Definition omf.h:1603
uint16_t offset
An offset, needed for CS:IP and SS:SP.
Definition omf.h:1608
BaseSpecification base
The segment base.
Definition omf.h:1606
A single initialization entry.
Definition omf.h:1586
register_t
Register type that can be initialized.
Definition omf.h:1590
@ DS
The DS segment register, the default data segment.
Definition omf.h:1596
@ ES
The ES segment register.
Definition omf.h:1598
@ CS_IP
The CS and IP register pair, it signifies the starting address as a far pointer.
Definition omf.h:1592
@ SS_SP
The SS and SP register pair, it signifies the initial stack as a far pointer.
Definition omf.h:1594
std::variant< Reference, InitialValue > value
The initial value of the register.
Definition omf.h:1613
register_t reg_id
The register to initialize.
Definition omf.h:1611
Initialization values for registers, used for REGINT (Intel only)
Definition omf.h:1582
std::vector< Register > registers
List of registers to be initialized.
Definition omf.h:1624
Relocatable enumerated or iterated data, used for REDATA and RIDATA (Intel only)
Definition omf.h:1377
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1384
uint16_t offset
Offset within paragraph where data starts.
Definition omf.h:1382
BaseSpecification base
Reference to paragraph that contains this data.
Definition omf.h:1380
Additional data for LTL segment, not part of TIS.
Definition omf.h:987
A record that defines a segment, used for SEGDEF records.
Definition omf.h:946
combination_t
Describes how two segments of the same name and class name should be combined.
Definition omf.h:999
@ Combination_Join_High
Merges the two segments at their highest address, adds their sizes (Intel interpretation)
Definition omf.h:1011
@ Combination_Private
Do not combine segments, also known as Private.
Definition omf.h:1001
@ Combination_Stack
Same as Public, but for stack segments.
Definition omf.h:1013
@ Combination_Join_Low
Merges the two segments at their lowest address, adds their sizes (Intel interpretation)
Definition omf.h:1008
@ Combination_Merge_High
Merges the two segments at their highest address, their size is the maximum (Intel interpretation)
Definition omf.h:1018
@ Combination_Merge_Low
Merges the two segments at their lowest address, their size is the maximum (Intel interpretation)
Definition omf.h:1015
@ Combination_Append
Appends the segments, also known as Public.
Definition omf.h:1005
@ Combination_Merge_Highest
Like Combination_Merge_High, but also places the segment above all other segments (not used by TIS)
Definition omf.h:1003
NameIndex class_name
The name of the segment's class (not used for AlignUnnamed)
Definition omf.h:1033
NameIndex segment_name
The name of the segment (not used for AlignUnnamed)
Definition omf.h:1031
combination_t combination
How segments of the same type should be combined.
Definition omf.h:1023
alignment_t alignment
Alignment of segment.
Definition omf.h:977
bool use32
Set if the USE32 directive is used for the segment. The field appears in different places for Phar La...
Definition omf.h:1028
std::variant< Relocatable, Absolute, LoadTimeLocatable > location
Information on where the segment should be placed at runtime.
Definition omf.h:995
uint64_t segment_length
The length of the segment (maximum 0x100000000)
Definition omf.h:949
bool page_resident
Set if the segment should not cross a 256 byte page boundary (only Intel)
Definition omf.h:1026
access_t
Represents an additional field used by Phar Lap.
Definition omf.h:1039
NameIndex overlay_name
The name of the overlay the segment appears in (not used for AlignUnnamed)
Definition omf.h:1035
std::optional< access_t > access
Represents the value of a Phar Lap specific extension word.
Definition omf.h:1047
alignment_t
Alignment type for a segment.
Definition omf.h:952
@ Align16
Relocatable segment, paragraph (16-byte) aligned.
Definition omf.h:960
@ Align256
Relocatable segment, page (256-byte) aligned, as defined by Intel.
Definition omf.h:967
@ AlignLTL16
Load-time locatable or, if not part of a group, paragraph (16-byte) aligned (Intel only)
Definition omf.h:964
@ Align2
Relocatable segment, word (2-byte) aligned.
Definition omf.h:958
@ Align32
Relocatable segment, double word (4-byte) aligned, type 5 as defined by TIS.
Definition omf.h:973
@ Align4096
Relocatable segment, page (4096-byte) aligned, as used by IBM.
Definition omf.h:969
@ AlignUnnamed
Unnamed absolute portion of the memory address space, type 5 as defined by Intel.
Definition omf.h:971
@ AlignAbsolute
Absolute segment, its position in memory is fixed.
Definition omf.h:954
@ AlignPage
Relocatable segment, page aligned, exact size depends on OMF version.
Definition omf.h:962
@ Align1
Relocatable segment, byte aligned.
Definition omf.h:956
uint32_t Absolute
Additional data used for absolute segments, type 0 or 5 if Intel version is used.
Definition omf.h:980
A rich container for indexes referring to a SEGDEF record.
Definition omf.h:484
Represents a symbol definition, used by SymbolDefinitionsRecord and DebugSymbolsRecord.
Definition omf.h:677
std::string name
The name of the symbol.
Definition omf.h:682
bool local
Set to true if the symbol is local.
Definition omf.h:680
uint32_t offset
The offset (value) of the symbol.
Definition omf.h:684
TypeIndex type
The type of the symbol, or 0.
Definition omf.h:686
Line numbers for common segments, used by LINSYM (included in TIS)
Definition omf.h:1786
std::vector< LineNumber > line_numbers
The line numbers.
Definition omf.h:1793
bool continued
Set if this record is the continuation of a previous record, cleared if it is a new record.
Definition omf.h:1789
NameIndex name
The name of the common segment to which the line numbers belong to.
Definition omf.h:1791
A record that defines a symbol, used by PUBDEF, LPUBDEF, LOCSYM.
Definition omf.h:1234
std::vector< SymbolDefinition > symbols
A list of symbols.
Definition omf.h:1240
BaseSpecification base
The first byte of the segment containing the symbol.
Definition omf.h:1237
A single item in a type definition.
Definition omf.h:1142
static constexpr uint8_t RepeatLeaf
Type byte for a repeat leaf leaf.
Definition omf.h:1162
static constexpr uint8_t NumericLeaf24
Type byte for an unsigned 24-bit leaf.
Definition omf.h:1166
bool nice
Set to false if "easy", true if "nice".
Definition omf.h:1145
std::variant< uint32_t, int32_t, std::string, TypeIndex, Null, Repeat > leaf
The actual contents of the leaf.
Definition omf.h:1153
static constexpr uint8_t StringLeaf
Type byte for a string leaf.
Definition omf.h:1158
static constexpr uint8_t NullLeaf
Type byte for a null leaf.
Definition omf.h:1156
static constexpr uint8_t SignedNumericLeaf16
Type byte for an signed 16-bit leaf.
Definition omf.h:1170
static constexpr uint8_t NumericLeaf16
Type byte for an unsigned 16-bit leaf.
Definition omf.h:1164
static constexpr uint8_t SignedNumericLeaf32
Type byte for an signed 32-bit leaf.
Definition omf.h:1172
static constexpr uint8_t IndexLeaf
Type byte for an index leaf, usually a type index.
Definition omf.h:1160
static constexpr uint8_t SignedNumericLeaf8
Type byte for an signed 8-bit leaf.
Definition omf.h:1168
A record that defines a data type, used for TYPDEF records.
Definition omf.h:1138
std::vector< LeafDescriptor > leafs
The parameters of this type.
Definition omf.h:1185
std::string name
The name of this type.
Definition omf.h:1183
A rich container for indexes referring to a TYPDEF record.
Definition omf.h:520
Vendor specific extension to the OMF format, used for VENDEXT (included in TIS)
Definition omf.h:1857
uint16_t vendor_number
Assigned vendor identifier.
Definition omf.h:1860
std::vector< uint8_t > extension
Extension data.
Definition omf.h:1862
Intel Relocatable Object Module format, used by various 16/32-bit DOS based compilers and linkers,...
Definition omf.h:397
static constexpr unsigned int FlagIntel
Flag binary or'ed to certain values to mark Intel interpretation.
Definition omf.h:429
@ MethodGroup
References a group defined in a module, for either targets or frames.
Definition omf.h:441
@ MethodFrame
References a physical paragraph address in a module, for either targets or frames.
Definition omf.h:445
@ MethodAbsolute
No frame is provided, intended for Intel 8089, only the Intel version supports it,...
Definition omf.h:451
@ MethodExternal
References a external symbol declared in a module, for either targets or frames.
Definition omf.h:443
@ MethodSegment
References a segment defined in a module, for either targets or frames.
Definition omf.h:439
@ MethodSource
References the frame of the relocation source, only for frames.
Definition omf.h:447
@ MethodTarget
References the frame of the relocation target, only for frames.
Definition omf.h:449
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:4276
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:2148
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:4269
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:2145
std::shared_ptr< Record > ReadRecord(Linker::Reader &rd)
Parses and returns an instance of the next record.
Definition omf.cc:4081
static constexpr unsigned int FlagPharLap
Flag binary or'ed to certain values to mark Phar Lap interpretation.
Definition omf.h:431
static std::shared_ptr< OMF86Format > ReadOMFFile(Linker::Reader &rd)
Parses an OMF86 file.
Definition omf.cc:4242
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:4254
void GenerateModule(Linker::Module &module) const override
Loads the information into a module object, a convenience method when there is a single module genera...
Definition omf.cc:4302
static constexpr unsigned int FlagTIS
Flag binary or'ed to certain values to mark TIS interpretation.
Definition omf.h:433
omf_version_t
Represents the various variants of the OMF file format, some of them are incompatible.
Definition omf.h:407
@ OMF_VERSION_INTEL_40
The original Intel definition, version 4.0 (including any extensions that are compatible)
Definition omf.h:409
@ OMF_VERSION_TIS_11
Version 1.1 produced and consolidated by the Tool Interface Standard.
Definition omf.h:417
@ OMF_VERSION_PHARLAP
Phar Lap's extensions, mostly concerning 32-bit (partly incompatible with later versions)
Definition omf.h:411
@ OMF_VERSION_IBM
Format generated by IBM's tools (partly incompatible with other versions)
Definition omf.h:415
@ OMF_VERSION_MICROSOFT
Format generated by Microsoft's tools (partly incompatible with other versions)
Definition omf.h:413
record_type_t
The recognized record types in an OMF86 file.
Definition omf.h:769
uint16_t FrameNumber
Represents a MethodFrame value.
Definition omf.h:455
omf_version_t omf_version
The variant of the OMF format, needed to handle certain fields.
Definition omf.h:421
Definition omf.h:3474
size_t record_count
The number of records belonging to this module.
Definition omf.h:3479
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:3477
static constexpr uint8_t StringLeaf
Type byte for a string leaf.
Definition omf.h:3289
static constexpr uint8_t SignedNumericLeaf32
Type byte for an signed 32-bit leaf.
Definition omf.h:3287
static constexpr uint8_t NullLeaf
Type byte for a null leaf.
Definition omf.h:3283
static constexpr uint8_t EndOfBranchLeaf
Type byte for an end of branch leaf.
Definition omf.h:3295
static constexpr uint8_t SignedNumericLeaf16
Type byte for an signed 16-bit leaf.
Definition omf.h:3285
static constexpr uint8_t IndexLeaf
Type byte for an index leaf, usually a type index.
Definition omf.h:3291
static constexpr uint8_t RepeatLeaf
Type byte for a repeat leaf leaf.
Definition omf.h:3293
std::vector< LeafDescriptor > leafs
The parameters of this type.
Definition omf.h:3306
Definition omf.h:3160
Intel Relocatable Object Module for the Intel MCS-96.
Definition omf.h:3042
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:6462
std::shared_ptr< Record > ReadRecord(Linker::Reader &rd)
Parses and returns an instance of the next record.
Definition omf.cc:6353
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:6440
void GenerateModule(Linker::Module &module) const override
Loads the information into a module object, a convenience method when there is a single module genera...
Definition omf.cc:6488
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:3486
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:6455
static std::shared_ptr< OMF96Format > ReadOMFFile(Linker::Reader &rd)
Parses an OMF96 file.
Definition omf.cc:6428
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:3489
Definition omf.h:3506
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:6519
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:6509
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:6495
void GenerateModule(Linker::Module &module) const override
Loads the information into a module object, a convenience method when there is a single module genera...
Definition omf.cc:6500
offset_t ImageSize() const override
Retrieves size of stored data.
Definition omf.cc:6514
A record representing data to be loaded into a segment.
Definition omf.h:239
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.cc:144
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:150
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:135
A record type that has no contents, aside from the type, length and checksum, used for BLKEND.
Definition omf.h:212
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.h:228
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.h:223
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.h:219
std::vector< std::string > names
List of public symbols for one library module.
Definition omf.h:366
All public symbols of all modules, used for LIBDIC.
Definition omf.h:360
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:338
std::vector< Group > groups
List of public symbols, grouped by library modules.
Definition omf.h:374
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:359
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.cc:348
Library header record, used for LIBHED.
Definition omf.h:290
uint16_t block_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:295
uint16_t module_count
Number of modules contained.
Definition omf.h:293
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.cc:214
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:206
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:220
uint16_t byte_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:297
Library module offsets, used for LIBLOC.
Definition omf.h:330
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:279
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.cc:288
std::vector< Location > locations
List of starting locations, one for each library module.
Definition omf.h:345
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:294
Library module names, used for LIBNAM.
Definition omf.h:312
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:230
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:250
std::vector< std::string > names
List of module names.
Definition omf.h:315
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.cc:239
A record representing line number information.
Definition omf.h:262
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:194
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.cc:188
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:178
Base class representing OMF record types.
Definition omf.h:99
offset_t record_offset
Offset of record within the file.
Definition omf.h:102
virtual uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const =0
Calculates the required bytes to write the record, might be less than record_length.
size_t GetOffsetSize(FormatType *omf) const
The number of bytes in an offset appearing inside the record, 2 for 16-bit records,...
Definition omf.h:173
virtual void WriteRecord(FormatType *omf, ModuleType *mod, Linker::Writer &wr) const
Writes the full record.
Definition omf.h:130
bool Is32Bit(FormatType *omf) const
Records are 32-bit if the least significant bit of their record type is set (only meaningful for OMF8...
Definition omf.h:167
virtual void ResolveReferences(FormatType *omf, ModuleType *mod)
Resolves any fields read from an OMF module, should be called after inpnut.
Definition omf.h:148
virtual void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const =0
Writes the record contents, except for the type, length and checksum.
RecordTypeByte record_type
A byte value identifying the type of record.
Definition omf.h:106
virtual void CalculateValues(FormatType *omf, ModuleType *mod)
Updates all fields that will be used for writing an OMF module, should be called before output.
Definition omf.h:140
virtual void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd)=0
Reads the record contents, except for the type, length and checksum.
uint16_t record_length
Length of record body file, excluding the type byte and 2-byte length field.
Definition omf.h:104
An unparsed record type, if the format is not recognized.
Definition omf.h:182
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.h:203
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.h:192
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.h:198
std::vector< uint8_t > data
Contents of the record, without the type, length and checksum.
Definition omf.h:185
Base class for a family of Intel Relocatable Object formats.
Definition omf.h:69
offset_t file_size
Used to calculate record offsets when generating OMF file.
Definition omf.h:390
static std::shared_ptr< OMFFormat > ReadOMFFile(Linker::Reader &rd)
Attempts to parse an OMF file, whether OMF80, OMF86, OMF51 or OMF96.
Definition omf.cc:58
static index_t ReadIndex(Linker::Reader &rd)
Parses a 1 or 2 byte index value.
Definition omf.cc:23
static std::string ReadString(Linker::Reader &rd, size_t max_bytes=size_t(-1))
Reads a string prefixed with a length byte.
Definition omf.cc:11
static size_t IndexSize(index_t index)
Determines if the index value requires 1 or 2 bytes to store.
Definition omf.cc:46
static void WriteString(ChecksumWriter &wr, std::string text)
Writes a string prefixed with a length byte.
Definition omf.cc:17
uint16_t index_t
An index referring to an element or definition in the file, typically stored as 1 or 2 bytes,...
Definition omf.h:80
static void WriteIndex(ChecksumWriter &wr, index_t index)
Produces a 1 or 2 byte index value.
Definition omf.cc:33
Type representing the group and segment of some reference.
Definition omf.h:659
Type representing a relocatable segment.
Definition omf.h:983
Represents a null leaf.
Definition omf.h:1148
Represents a final repeat leaf, meaning that the data in this type should be repeated indefinitely.
Definition omf.h:1150
Represents a MethodAbsolute value.
Definition omf.h:464
Represents a MethodSource value.
Definition omf.h:458
Represents a MethodTarget value.
Definition omf.h:461
Represents a null leaf.
Definition omf.h:3274
Represents a final repeat leaf, meaning that the data in this type should be repeated indefinitely.
Definition omf.h:3276
uint16_t byte_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:338
uint16_t block_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:336