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/symbol_definition.h"
11#include "../linker/target.h"
12#include "../linker/writer.h"
13
14/* TODO: incomplete */
15
16/* Intel Object Module format (input only) */
17
18namespace OMF
19{
22 {
23 public:
24 Linker::Writer * wr;
25 uint8_t checksum = 0;
26
28 : wr(&wr)
29 {
30 }
31
32 void WriteWord(size_t bytes, uint64_t value)
33 {
34 wr->WriteWord(bytes, value);
35 for(size_t offset = 0; offset < bytes; offset++, value >>= 8)
36 {
37 checksum -= value;
38 }
39 }
40
41 size_t WriteData(const std::vector<uint8_t>& data)
42 {
43 size_t bytes = wr->WriteData(data);
44 for(size_t offset = 0; offset < bytes; offset++)
45 {
46 checksum -= data[offset];
47 }
48 return bytes;
49 }
50
51 size_t WriteData(std::string text)
52 {
53 wr->WriteData(text);
54 for(size_t offset = 0; offset < text.size(); offset++)
55 {
56 checksum -= text[offset];
57 }
58 return text.size();
59 }
60
61 void Skip(offset_t count)
62 {
63 wr->Skip(count);
64 }
65 };
66
70 class OMFFormat : public virtual Linker::Format
71 {
72 public:
73 virtual ~OMFFormat() = default;
74
76 static std::string ReadString(Linker::Reader& rd, size_t max_bytes = size_t(-1));
77
79 static void WriteString(ChecksumWriter& wr, std::string text);
80
82 typedef uint16_t index_t;
83
86
88 static void WriteIndex(ChecksumWriter& wr, index_t index);
89
91 static size_t IndexSize(index_t index);
92
99 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
100 class Record
101 {
102 public:
108 RecordTypeByte record_type;
109
110 Record(RecordTypeByte record_type = RecordTypeByte(0))
112 {
113 }
114
115 virtual ~Record() = default;
116
117 offset_t RecordEnd() const
118 {
119 return record_offset + record_length + 2;
120 }
121
123 virtual void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) = 0;
124
126 virtual uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const = 0;
127
129 virtual void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const = 0;
130
132 virtual void WriteRecord(FormatType * omf, ModuleType * mod, Linker::Writer& wr) const
133 {
134 ChecksumWriter ckswr(wr);
135 ckswr.WriteWord(1, record_type);
136 ckswr.WriteWord(2, GetRecordSize(omf, mod));
137 WriteRecordContents(omf, mod, ckswr);
138 wr.WriteWord(1, ckswr.checksum);
139 }
140
142 virtual void CalculateValues(FormatType * omf, ModuleType * mod)
143 {
144 record_offset = omf->file_size;
145 record_length = GetRecordSize(omf, mod);
147 }
148
150 virtual void ResolveReferences(FormatType * omf, ModuleType * mod)
151 {
152 }
153
154 virtual void DumpAddFields(Dumper::Dumper& dump, Dumper::Region& region, const FormatType * omf, const ModuleType * mod, size_t record_index, Dumper::display_option& options) const
155 {
156 }
157
158 virtual void Dump(Dumper::Dumper& dump, const FormatType * omf, const ModuleType * mod, size_t record_index) const
159 {
160 Dumper::Region record_region("Record", record_offset, RecordEnd() + 1 - record_offset, 8);
161 record_region.InsertField(0, "Index", Dumper::DecDisplay::Make(), offset_t(record_index + 1));
162 record_region.AddField("Record type", Dumper::HexDisplay::Make(2), offset_t(record_type));
163 Dumper::display_option options = Dumper::Control;
164 FormatType::DumpAddFields(this, dump, record_region, omf, mod, record_index, options);
165 DumpAddFields(dump, record_region, omf, mod, record_index, options);
166 record_region.Display(dump, options);
167 }
168
170 bool Is32Bit(FormatType * omf) const
171 {
172 return (record_type & 1) != 0;
173 }
174
176 size_t GetOffsetSize(FormatType * omf) const
177 {
178 return Is32Bit(omf) ? 4 : 2;
179 }
180 };
181
183 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
184 class UnknownRecord : public Record<RecordTypeByte, FormatType, ModuleType>
185 {
186 public:
188 std::vector<uint8_t> data;
189
190 UnknownRecord(RecordTypeByte record_type = RecordTypeByte(0))
191 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
192 {
193 }
194
195 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override
196 {
198 rd.ReadData(data);
199 }
200
201 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override
202 {
203 return data.size() + 1;
204 }
205
206 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override
207 {
208 wr.WriteData(data);
209 }
210 };
211
213 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
214 class EmptyRecord : public Record<RecordTypeByte, FormatType, ModuleType>
215 {
216 public:
217 EmptyRecord(RecordTypeByte record_type = RecordTypeByte(0))
219 {
220 }
221
222 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override
223 {
224 }
225
226 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override
227 {
228 return 1;
229 }
230
231 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override
232 {
233 }
234 };
235
240 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
241 class ContentRecord : public Record<RecordTypeByte, FormatType, ModuleType>
242 {
243 public:
244 uint8_t segment_id = 0;
245 uint16_t offset = 0;
246 std::vector<uint8_t> data;
247
248 ContentRecord(RecordTypeByte record_type = RecordTypeByte(0))
250 {
251 }
252
253 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
254 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
255 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
256 };
257
263 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
264 class LineNumbersRecord : public Record<RecordTypeByte, FormatType, ModuleType>
265 {
266 public:
268 {
269 public:
270 uint16_t line_number = 0;
271 uint16_t offset = 0;
272
273 static LineNumber Read(FormatType * omf, Linker::Reader& rd);
274 void Write(FormatType * omf, ChecksumWriter& wr) const;
275 };
276
277 uint8_t segment_id = 0;
278 std::vector<LineNumber> line_numbers;
279
280 LineNumbersRecord(RecordTypeByte record_type = RecordTypeByte(0))
281 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
282 {
283 }
284
285 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
286 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
287 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
288 };
289
291 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
292 class LibraryHeaderRecord : public Record<RecordTypeByte, FormatType, ModuleType>
293 {
294 public:
296 uint16_t module_count;
298 uint16_t block_number;
300 uint16_t byte_number;
301
302 LibraryHeaderRecord(RecordTypeByte record_type = RecordTypeByte(0))
303 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
304 {
305 }
306
307 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
308 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
309 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
310 };
311
313 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
314 class LibraryModuleNamesRecord : public Record<RecordTypeByte, FormatType, ModuleType>
315 {
316 public:
318 std::vector<std::string> names;
319
320 LibraryModuleNamesRecord(RecordTypeByte record_type = RecordTypeByte(0))
321 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
322 {
323 }
324
325 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
326 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
327 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
328 };
329
331 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
332 class LibraryModuleLocationsRecord : public Record<RecordTypeByte, FormatType, ModuleType>
333 {
334 public:
335 struct Location
336 {
337 public:
339 uint16_t block_number;
341 uint16_t byte_number;
342
343 static Location Read(Linker::Reader& rd);
344 void Write(ChecksumWriter& wr) const;
345 };
346
348 std::vector<Location> locations;
349
350 LibraryModuleLocationsRecord(RecordTypeByte record_type = RecordTypeByte(0))
351 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
352 {
353 }
354
355 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
356 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
357 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
358 };
359
361 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
362 class LibraryDictionaryRecord : public Record<RecordTypeByte, FormatType, ModuleType>
363 {
364 public:
365 class Group
366 {
367 public:
369 std::vector<std::string> names;
370
371 void Read(Linker::Reader& rd);
372 uint16_t Size() const;
373 void Write(ChecksumWriter& wr) const;
374 };
375
377 std::vector<Group> groups;
378
379 LibraryDictionaryRecord(RecordTypeByte record_type = RecordTypeByte(0))
380 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
381 {
382 }
383
384 void ReadRecordContents(FormatType * omf, ModuleType * mod, Linker::Reader& rd) override;
385 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
386 void WriteRecordContents(FormatType * omf, ModuleType * mod, ChecksumWriter& wr) const override;
387 };
388
390 static std::shared_ptr<OMFFormat> ReadOMFFile(Linker::Reader& rd);
391
393 offset_t file_size = 0;
394 };
395
399 class OMF86Format : public virtual OMFFormat, public virtual Linker::InputFormat
400 {
401 public:
402 class Module;
405
406 /* * * General members * * */
407
408 ::EndianType endian_type = ::LittleEndian;
409
424
427
430 {
431 }
432
434 static constexpr unsigned int FlagIntel = 0x10;
436 static constexpr unsigned int FlagPharLap = 0x20;
438 static constexpr unsigned int FlagTIS = 0x30;
439
441 enum
442 {
457 };
458
460 typedef uint16_t FrameNumber;
461
463 struct UsesSource { };
464
466 struct UsesTarget { };
467
469 struct UsesAbsolute { };
470
473 {
474 public:
475 index_t index;
476 std::string text;
477
478 NameIndex(index_t index = 0)
479 : index(index)
480 {
481 }
482
483 void CalculateValues(OMF86Format * omf, Module * mod);
484 void ResolveReferences(OMF86Format * omf, Module * mod);
485 };
486
489 {
490 public:
491 index_t index;
492 std::shared_ptr<SegmentDefinitionRecord> record;
493
494 SegmentIndex(index_t index = 0)
495 : index(index)
496 {
497 }
498
499 void CalculateValues(OMF86Format * omf, Module * mod);
500 void ResolveReferences(OMF86Format * omf, Module * mod);
501 };
502
505 {
506 public:
507 index_t index;
508 std::shared_ptr<GroupDefinitionRecord> record;
509
510 GroupIndex(index_t index = 0)
511 : index(index)
512 {
513 }
514
515 void CalculateValues(OMF86Format * omf, Module * mod);
516 void ResolveReferences(OMF86Format * omf, Module * mod);
517 };
518
522
525 {
526 public:
527 index_t index;
528 std::shared_ptr<TypeDefinitionRecord> record;
529
530 TypeIndex(index_t index = 0)
531 : index(index)
532 {
533 }
534
535 void CalculateValues(OMF86Format * omf, Module * mod);
536 void ResolveReferences(OMF86Format * omf, Module * mod);
537 };
538
541 {
542 public:
543 index_t index;
544 std::shared_ptr<BlockDefinitionRecord> record;
545
546 BlockIndex(index_t index = 0)
547 : index(index)
548 {
549 }
550
551 void CalculateValues(OMF86Format * omf, Module * mod);
552 void ResolveReferences(OMF86Format * omf, Module * mod);
553 };
554
557 {
558 public:
559 index_t index;
560 std::shared_ptr<OverlayDefinitionRecord> record;
561
562 OverlayIndex(index_t index = 0)
563 : index(index)
564 {
565 }
566
567 void CalculateValues(OMF86Format * omf, Module * mod);
568 void ResolveReferences(OMF86Format * omf, Module * mod);
569 };
570
573 {
574 public:
576 enum common_type_t : uint8_t
577 {
580
583
585 FarCommon = 0x61,
586
589 };
590
592 bool local = false;
594 bool name_is_index = false;
597 TypeIndex type;
598 common_type_t common_type = External;
599
600 union
601 {
602 uint8_t segment_index;
603 struct
604 {
605 uint32_t length;
606 } near;
607 struct
608 {
609 uint32_t number;
610 uint32_t element_size;
611 } far;
612 } value;
613
615 {
616 value.far.number = value.far.element_size = 0;
617 }
618
620 static uint32_t ReadValue(OMF86Format * omf, Linker::Reader& rd);
622 static uint32_t ValueSize(OMF86Format * omf, uint32_t length);
624 static void WriteValue(OMF86Format * omf, ChecksumWriter& wr, uint32_t length);
625
627 static ExternalName ReadExternalName(OMF86Format * omf, Linker::Reader& rd, bool local);
629 static ExternalName ReadCommonName(OMF86Format * omf, Linker::Reader& rd, bool local);
631 static ExternalName ReadComdatExternalName(OMF86Format * omf, Linker::Reader& rd);
632
634 uint16_t GetExternalNameSize(OMF86Format * omf) const;
636 void WriteExternalName(OMF86Format * omf, ChecksumWriter& wr) const;
637
638 void CalculateValues(OMF86Format * omf, Module * mod);
639 void ResolveReferences(OMF86Format * omf, Module * mod);
640 };
641
644 {
645 public:
646 index_t index;
647 ExternalName name;
648
649 ExternalIndex(index_t index = 0)
650 : index(index)
651 {
652 }
653
654 void CalculateValues(OMF86Format * omf, Module * mod);
655 void ResolveReferences(OMF86Format * omf, Module * mod);
656 };
657
660 {
661 public:
663 struct Location
664 {
665 GroupIndex group;
666 SegmentIndex segment;
667 };
668
670 std::variant<Location, FrameNumber> location;
671
672 void Read(OMF86Format * omf, Linker::Reader& rd);
673 uint16_t Size(OMF86Format * omf) const;
674 void Write(OMF86Format * omf, ChecksumWriter& wr) const;
675
676 void CalculateValues(OMF86Format * omf, Module * mod);
677 void ResolveReferences(OMF86Format * omf, Module * mod);
678 };
679
682 {
683 public:
685 bool local;
687 std::string name;
689 uint32_t offset;
692
693 static SymbolDefinition Read(OMF86Format * omf, Linker::Reader& rd, bool local, bool is32bit);
694 uint16_t Size(OMF86Format * omf, bool is32bit) const;
695 void Write(OMF86Format * omf, ChecksumWriter& wr, bool is32bit) const;
696
697 void CalculateValues(OMF86Format * omf, Module * mod);
698 void ResolveReferences(OMF86Format * omf, Module * mod);
699 };
700
703 {
704 public:
706 uint16_t number;
708 uint32_t offset;
709
710 static LineNumber Read(OMF86Format * omf, Linker::Reader& rd, bool is32bit);
711 void Write(OMF86Format * omf, ChecksumWriter& wr, bool is32bit) const;
712 };
713
722 {
723 public:
725 uint16_t repeat_count;
726
728 typedef std::vector<std::shared_ptr<DataBlock>> Blocks;
730 typedef std::vector<uint8_t> Data;
731
733 std::variant<Data, Blocks> content;
734
736 static std::shared_ptr<DataBlock> ReadEnumeratedDataBlock(OMF86Format * omf, Linker::Reader& rd, uint16_t data_length);
738 uint16_t GetEnumeratedDataBlockSize(OMF86Format * omf) const;
741
743 static std::shared_ptr<DataBlock> ReadIteratedDataBlock(OMF86Format * omf, Linker::Reader& rd, bool is32bit);
745 uint16_t GetIteratedDataBlockSize(OMF86Format * omf, bool is32bit) const;
747 void WriteIteratedDataBlock(OMF86Format * omf, ChecksumWriter& wr, bool is32bit) const;
748 };
749
752 {
753 public:
755 typedef unsigned ThreadNumber;
756
758 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber> target = ThreadNumber(0);
760 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute> frame = ThreadNumber(0);
762 uint32_t displacement;
763
764 void Read(OMF86Format * omf, Linker::Reader& rd, size_t displacement_size);
765 uint16_t Size(OMF86Format * omf, bool is32bit) const;
766 void Write(OMF86Format * omf, ChecksumWriter& wr, bool is32bit) const;
767
768 void CalculateValues(OMF86Format * omf, Module * mod);
769 void ResolveReferences(OMF86Format * omf, Module * mod);
770
771 static Linker::Target GetTarget(SegmentIndex segment_index);
772 static Linker::Target GetTarget(GroupIndex group_index);
773 static Linker::Target GetTarget(ExternalIndex external_index);
774 static Linker::Target GetTarget(FrameNumber frame_number);
775
776 static Linker::Target GetFrame(Linker::Location source, Linker::Target target, SegmentIndex segment_index);
777 static Linker::Target GetFrame(Linker::Location source, Linker::Target target, GroupIndex group_index);
778 static Linker::Target GetFrame(Linker::Location source, Linker::Target target, ExternalIndex external_index);
779 static Linker::Target GetFrame(Linker::Location source, Linker::Target target, FrameNumber frame_number);
783 };
784
786 enum record_type_t : uint8_t
787 {
788 RHEADR = 0x6E, // Intel 4.0
789 REGINT = 0x70, // Intel 4.0
790 REDATA = 0x72, // Intel 4.0
791 RIDATA = 0x74, // Intel 4.0
792 OVLDEF = 0x76, // Intel 4.0
793 ENDREC = 0x78, // Intel 4.0
794 BLKDEF = 0x7A, // Intel 4.0
795 BLKEND = 0x7C, // Intel 4.0
796 DEBSYM = 0x7E, // Intel 4.0
797 THEADR = 0x80,
798 LHEADR = 0x82,
799 PEDATA = 0x84, // Intel 4.0
800 PIDATA = 0x86, // Intel 4.0
801 COMENT = 0x88,
802 MODEND16 = 0x8A,
803 MODEND = 0x8A,
804 MODEND32 = 0x8B, // TIS 1.1
805 EXTDEF = 0x8C,
806 TYPDEF = 0x8E, // Intel 4.0
807 PUBDEF16 = 0x90,
808 PUBDEF = 0x90,
809 PUBDEF32 = 0x91, // TIS 1.1
810 LOCSYM = 0x92, // Intel 4.0
811 LINNUM = 0x94, // Intel 4.0
812 LNAMES = 0x96,
813 SEGDEF = 0x98, // Intel 4.0
814 GRPDEF = 0x9A, // Intel 4.0
815 FIXUPP16 = 0x9C,
816 FIXUPP = 0x9C,
817 FIXUPP32 = 0x9D, // TIS 1.1
818 LEDATA16 = 0xA0,
819 LEDATA = 0xA0,
820 LEDATA32 = 0xA1, // TIS 1.1
821 LIDATA16 = 0xA2,
822 LIDATA = 0xA2,
823 LIDATA32 = 0xA3, // TIS 1.1
824 LIBHED = 0xA4, // Intel 4.0
825 LIBNAM = 0xA6, // Intel 4.0
826 LIBLOC = 0xA8, // Intel 4.0
827 LIBDIC = 0xAA, // Intel 4.0
828 COMDEF = 0xB0, // TIS 1.1, since Microsoft LINK 3.5
829 BAKPAT16 = 0xB2, // TIS 1.1, since Microsoft QuickC 1.0
830 BAKPAT = 0xB2, // TIS 1.1
831 BAKPAT32 = 0xB3, // TIS 1.1
832 LEXTDEF16 = 0xB4, // TIS 1.1, since Microsoft C 5.0
833 LEXTDEF = 0xB4, // TIS 1.1
834 LEXTDEF32 = 0xB5, // TIS 1.1
835 LPUBDEF16 = 0xB6, // TIS 1.1, since Microsoft C 5.0
836 LPUBDEF = 0xB6, // TIS 1.1
837 LPUBDEF32 = 0xB7, // TIS 1.1
838 LCOMDEF = 0xB8, // TIS 1.1, since Microsoft C 5.0
839 CEXTDEF = 0xBC, // TIS 1.1, since Microsoft C 7.0
840 COMDAT16 = 0xC2, // TIS 1.1, since Microsoft C 7.0
841 COMDAT = 0xC2, // TIS 1.1
842 COMDAT32 = 0xC3, // TIS 1.1
843 LINSYM16 = 0xC4, // TIS 1.1, since Microsoft C 7.0
844 LINSYM = 0xC4, // TIS 1.1
845 LINSYM32 = 0xC5, // TIS 1.1
846 ALIAS = 0xC6, // TIS 1.1, since Microsoft LINK 5.13
847 NBKPAT16 = 0xC8, // TIS 1.1, since Microsoft C 7.0
848 NBKPAT = 0xC8, // TIS 1.1
849 NBKPAT32 = 0xC9, // TIS 1.1
850 LLNAMES = 0xCA, // TIS 1.1, since Microsoft C 7.0
851 VERNUM = 0xCC, // TIS 1.1
852 VENDEXT = 0xCE, // TIS 1.1
853 LibraryHeader = 0xF0, // TIS 1.1
854 LibraryEnd = 0xF1, // TIS 1.1
855 };
856
857 static const std::map<offset_t, std::string> RecordTypeNames;
858
866
868 std::shared_ptr<Record> ReadRecord(Linker::Reader& rd);
869
872 {
873 public:
875 std::string name;
876
879 {
880 }
881
882 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
883 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
884 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
885 };
886
889 {
890 public:
893
895 enum module_type_t : uint8_t
896 {
897 AbsoluteModule = 0,
898 RelocatableModule = 1,
899 PICModule = 2,
900 LTLModule = 3,
901 };
902
912 uint32_t overlay_record_offset; // TODO: resolve record index
913
915 uint32_t static_size;
922
925 {
926 }
927
930 {
931 }
932
933 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
934 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
935 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
936 };
937
940 {
941 public:
943 std::vector<std::string> names;
947 uint16_t lname_count = 0;
948
951 {
952 }
953
954 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
955 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
956 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
957
958 void CalculateValues(OMF86Format * omf, Module * mod) override;
959 void ResolveReferences(OMF86Format * omf, Module * mod) override;
960 };
961
963 class SegmentDefinitionRecord : public Record, public std::enable_shared_from_this<SegmentDefinitionRecord>
964 {
965 public:
993
996
998 typedef uint32_t Absolute;
999
1001 struct Relocatable { };
1002
1005 {
1006 public:
1007 bool group_member;
1008 uint16_t maximum_segment_length;
1009 uint16_t group_offset;
1010 };
1011
1013 std::variant<Relocatable, Absolute, LoadTimeLocatable> location = Relocatable{};
1014
1016 enum combination_t : uint8_t
1017 {
1024 Combination_Public = Combination_Append,
1027 Combination_Public4 = FlagTIS | 4,
1034 Combination_Common = FlagTIS | 6,
1037 Combination_Public7 = FlagTIS | 7,
1038 };
1039
1042
1044 bool page_resident = false; // Intel
1046 bool use32 = false;
1047
1054
1056 enum access_t : uint8_t
1057 {
1058 AccessReadOnly = 0,
1059 AccessExecuteOnly = 1,
1060 AccessExecuteRead = 2,
1061 AccessReadWrite = 3,
1062 };
1063
1065 std::optional<access_t> access;
1066
1068 std::shared_ptr<Linker::Section> linker_section = nullptr;
1069
1072 {
1073 }
1074
1075 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1076 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1077 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1078
1079 void CalculateValues(OMF86Format * omf, Module * mod) override;
1080 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1081
1082 std::shared_ptr<Linker::Section> GenerateLinkerSection();
1083 };
1084
1086 class GroupDefinitionRecord : public Record, public std::enable_shared_from_this<GroupDefinitionRecord>
1087 {
1088 public:
1091 {
1092 public:
1095 {
1096 public:
1097 NameIndex segment_name;
1098 NameIndex class_name;
1099 NameIndex overlay_name;
1100 };
1101
1104 {
1105 public:
1106 uint32_t maximum_group_length;
1107 uint32_t group_length;
1108 };
1109
1111 typedef uint32_t Absolute;
1112
1114 static constexpr uint8_t Absolute_type = 0xFA;
1116 static constexpr uint8_t LoadTimeLocatable_type = 0xFB;
1118 static constexpr uint8_t SegmentClassOverlayNames_type = 0xFD;
1120 static constexpr uint8_t ExternalIndex_type = 0xFE;
1122 static constexpr uint8_t SegmentIndex_type = 0xFF;
1123
1125 std::variant<ExternalIndex, SegmentIndex, SegmentClassOverlayNames, LoadTimeLocatable, Absolute> component = ExternalIndex();
1126
1127 static Component Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1128 uint16_t Size(OMF86Format * omf, Module * mod) const;
1129 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1130
1131 void CalculateValues(OMF86Format * omf, Module * mod);
1132 void ResolveReferences(OMF86Format * omf, Module * mod);
1133 };
1134
1138 std::vector<Component> components;
1139
1142 {
1143 }
1144
1145 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1146 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1147 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1148
1149 void CalculateValues(OMF86Format * omf, Module * mod) override;
1150 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1151 };
1152
1160 class TypeDefinitionRecord : public Record, public std::enable_shared_from_this<TypeDefinitionRecord>
1161 {
1162 public:
1165 {
1166 public:
1168 bool nice;
1169
1171 struct Null { };
1173 struct Repeat { };
1174
1176 std::variant<uint32_t, int32_t, std::string, TypeIndex, Null, Repeat> leaf = Null();
1177
1179 static constexpr uint8_t NullLeaf = 0x80;
1181 static constexpr uint8_t StringLeaf = 0x82;
1183 static constexpr uint8_t IndexLeaf = 0x83;
1185 static constexpr uint8_t RepeatLeaf = 0x85;
1187 static constexpr uint8_t NumericLeaf16 = 0x81;
1189 static constexpr uint8_t NumericLeaf24 = 0x84;
1191 static constexpr uint8_t SignedNumericLeaf8 = 0x86;
1193 static constexpr uint8_t SignedNumericLeaf16 = 0x87;
1195 static constexpr uint8_t SignedNumericLeaf32 = 0x88;
1196
1197 static LeafDescriptor Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1198 uint16_t Size(OMF86Format * omf, Module * mod) const;
1199 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1200
1201 void CalculateValues(OMF86Format * omf, Module * mod);
1202 void ResolveReferences(OMF86Format * omf, Module * mod);
1203 };
1204
1206 std::string name;
1208 std::vector<LeafDescriptor> leafs;
1209
1210 enum
1211 {
1212 Far = 0x61, // Far(Array(...)) - Microsoft
1213 Near = 0x62, // Near(Array | Structure | Scalar, length in bits) - Microsoft
1214 Interrupt = 0x63,
1215 File = 0x64,
1216 Packed = 0x65,
1217 Unpacked = 0x66,
1218 Set = 0x67,
1219 Chameleon = 0x69,
1220 Boolean = 0x6A,
1221 True = 0x6B,
1222 False = 0x6C,
1223 Char = 0x6D,
1224 Integer = 0x6E,
1225 Const = 0x6F,
1226 Label = 0x71, // Label(nil, Short | Long)
1227 Long = 0x72,
1228 Short = 0x73,
1229 Procedure = 0x74, // Procedure(nil, @type, Short | Long, parameter count, @List(...))
1230 Parameter = 0x75, // Parameter(@type)
1231 Dimension = 0x76,
1232 Array = 0x77, // Array(length, @type)
1233 Structure = 0x79, // Structure(length, component count, @List(...))
1234 Pointer = 0x7A,
1235 Scalar = 0x7B, // Scalar(length, UnsignedInteger | SignedInteger | Real | @Pointer)
1236 UnsignedInteger = 0x7C,
1237 SignedInteger = 0x7D,
1238 Real = 0x7E,
1239 List = 0x7F, // List(...)
1240 };
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:
1261
1263 std::vector<SymbolDefinition> symbols;
1264
1267 {
1268 }
1269
1270 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1271 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1272 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1273
1274 void CalculateValues(OMF86Format * omf, Module * mod) override;
1275 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1276 };
1277
1280 {
1281 public:
1285 uint16_t extdef_count = 0;
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
1302 {
1303 public:
1306
1308 std::vector<LineNumber> lines;
1309
1312 {
1313 }
1314
1315 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1316 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1317 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1318
1319 void CalculateValues(OMF86Format * omf, Module * mod) override;
1320 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1321 };
1322
1324 class BlockDefinitionRecord : public Record, public std::enable_shared_from_this<BlockDefinitionRecord>
1325 {
1326 public:
1330 std::string name;
1332 uint16_t offset;
1334 uint16_t length;
1336 enum block_type_t : uint8_t
1337 {
1344 };
1348 uint16_t return_address_offset; // only for procedures
1351
1354 {
1355 }
1356
1357 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1358 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1359 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1360
1361 void CalculateValues(OMF86Format * omf, Module * mod) override;
1362 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1363 };
1364
1367 {
1368 public:
1369 enum frame_type_t : uint8_t
1370 {
1371 Location = 0x00,
1372 Frame16 = 0x80,
1373 Frame32 = 0xC0,
1374 };
1375 frame_type_t frame_type;
1376
1377 static constexpr uint8_t SymbolBaseMethod = 0x00;
1378 static constexpr uint8_t ExternalMethod = 0x01;
1379 static constexpr uint8_t BlockMethod = 0x02;
1380
1381 std::variant<BaseSpecification, ExternalIndex, BlockIndex> base = ExternalIndex();
1382
1383 std::vector<SymbolDefinition> names;
1384
1387 {
1388 }
1389
1390 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1391 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1392 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1393
1394 void CalculateValues(OMF86Format * omf, Module * mod) override;
1395 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1396 };
1397
1400 {
1401 public:
1405 uint16_t offset;
1407 std::shared_ptr<DataBlock> data;
1408
1411 {
1412 }
1413
1414 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1415 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1416 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1417
1418 void CalculateValues(OMF86Format * omf, Module * mod) override;
1419 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1420 };
1421
1424 {
1425 public:
1427 uint32_t address;
1429 std::shared_ptr<DataBlock> data;
1430
1433 {
1434 }
1435
1436 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1437 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1438 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1439 };
1440
1443 {
1444 public:
1448 uint32_t offset;
1450 std::shared_ptr<DataBlock> data;
1451
1454 {
1455 }
1456
1457 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1458 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1459 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1460
1461 void CalculateValues(OMF86Format * omf, Module * mod) override;
1462 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1463 };
1464
1466 class FixupRecord : public Record
1467 {
1468 public:
1469 typedef std::variant<SegmentIndex, GroupIndex, ExternalIndex, FrameNumber> target_reference_type;
1470 typedef std::variant<SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute> frame_reference_type;
1471
1474 {
1475 public:
1479 bool frame;
1481 frame_reference_type reference = FrameNumber(0);
1482
1483 static Thread Read(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint8_t leading_data_byte);
1484 uint16_t Size(OMF86Format * omf, Module * mod) const;
1485 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1486
1487 void CalculateValues(OMF86Format * omf, Module * mod);
1488 void ResolveReferences(OMF86Format * omf, Module * mod);
1489 };
1490
1491 class Fixup
1492 {
1493 public:
1496
1523
1527 uint16_t offset;
1530
1531 static Fixup Read(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint8_t leading_data_byte, bool is32bit);
1532 uint16_t Size(OMF86Format * omf, Module * mod, bool is32bit) const;
1533 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr, bool is32bit) const;
1534
1535 void CalculateValues(OMF86Format * omf, Module * mod);
1536 void ResolveReferences(OMF86Format * omf, Module * mod);
1537 };
1538
1540 std::vector<std::variant<Thread, Fixup>> fixup_data;
1541
1544 {
1545 }
1546
1547 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1548 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1549 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1550
1551 void CalculateValues(OMF86Format * omf, Module * mod) override;
1552 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1553 };
1554
1556 class OverlayDefinitionRecord : public Record, public std::enable_shared_from_this<OverlayDefinitionRecord>
1557 {
1558 public:
1560 std::string name;
1562 uint32_t location;
1566 std::optional<OverlayIndex> shared_overlay;
1568 std::optional<OverlayIndex> adjacent_overlay;
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 void CalculateValues(OMF86Format * omf, Module * mod) override;
1580 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1581 };
1582
1584 class EndRecord : public Record
1585 {
1586 public:
1588 enum block_type_t : uint8_t
1589 {
1590 Overlay = 0,
1591 Block = 1,
1592 };
1595
1598 {
1599 }
1600
1601 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1602 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1603 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1604 };
1605
1608 {
1609 public:
1612 {
1613 public:
1615 enum register_t : uint8_t
1616 {
1625 };
1626
1629 {
1630 public:
1634 uint16_t offset;
1635 };
1639 std::variant<Reference, InitialValue> value = Reference();
1640
1641 static Register Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1642 uint16_t Size(OMF86Format * omf, Module * mod) const;
1643 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1644
1645 void CalculateValues(OMF86Format * omf, Module * mod);
1646 void ResolveReferences(OMF86Format * omf, Module * mod);
1647 };
1648
1650 std::vector<Register> registers;
1651
1654 {
1655 }
1656
1657 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1658 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1659 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1660
1661 void CalculateValues(OMF86Format * omf, Module * mod) override;
1662 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1663 };
1664
1667 {
1668 public:
1672 std::optional<std::variant<Reference, std::tuple<uint16_t, uint16_t>>> start_address;
1673
1676 {
1677 }
1678
1679 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1680 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1681 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1682 };
1683
1686 {
1687 public:
1690 {
1691 public:
1693 uint32_t offset;
1695 uint32_t value;
1696 };
1697
1701 enum location_type_t : uint8_t
1702 {
1703 Location8bit = 0,
1704 Location16bit = 1,
1705 Location32bit = 2,
1706 Location32bit_IBM = 9,
1707 };
1709 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:
1732
1734 uint8_t type;
1737 std::vector<OffsetValuePair> offset_value_pairs;
1738
1741 {
1742 }
1743
1744 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1745 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1746 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1747
1748 void CalculateValues(OMF86Format * omf, Module * mod) override;
1749 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1750 };
1751
1754 {
1755 public:
1761 bool local;
1764
1765 // TODO: document further
1766
1767 enum selection_criterion_t : uint8_t
1768 {
1769 SelectNoMatch = 0x00,
1770 SelectPickAny = 0x10,
1771 SelectSameSize = 0x20,
1772 SelectExactMatch = 0x30,
1773 };
1774 static constexpr uint8_t SelectionCriterionMask = 0xF0;
1775 selection_criterion_t selection_criterion;
1776
1777 enum allocation_type_t : uint8_t
1778 {
1779 AllocateExplicit = 0x00,
1780 AllocateFarCode = 0x01,
1781 AllocateFarData = 0x02,
1782 AllocateCode32 = 0x03,
1783 AllocateData32 = 0x04,
1784 };
1785 static constexpr uint8_t AllocationTypeMask = 0x0F;
1786 allocation_type_t allocation_type;
1787
1790
1791 uint32_t offset;
1792 TypeIndex type;
1793 BaseSpecification base;
1794 NameIndex name;
1795 std::shared_ptr<DataBlock> data;
1796
1797 InitializedCommunalDataRecord(record_type_t record_type = record_type_t(0))
1798 : Record(record_type)
1799 {
1800 }
1801
1802 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1803 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1804 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1805
1806 void CalculateValues(OMF86Format * omf, Module * mod) override;
1807 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1808 };
1809
1812 {
1813 public:
1819 std::vector<LineNumber> line_numbers;
1820
1823 {
1824 }
1825
1826 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1827 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1828 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1829
1830 void CalculateValues(OMF86Format * omf, Module * mod) override;
1831 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1832 };
1833
1836 {
1837 public:
1840 {
1841 public:
1843 std::string alias_name;
1845 std::string substitute_name;
1846
1847 static AliasDefinition Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1848 uint16_t Size(OMF86Format * omf, Module * mod) const;
1849 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1850 };
1852 std::vector<AliasDefinition> alias_definitions;
1853
1856 {
1857 }
1858
1859 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1860 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1861 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1862 };
1863
1866 {
1867 public:
1869 std::string version;
1870
1873 {
1874 }
1875
1876 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1877 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1878 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1879 };
1880
1883 {
1884 public:
1888 std::vector<uint8_t> extension;
1889
1892 {
1893 }
1894
1895 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1896 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1897 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1898 };
1899
1900 // TODO: document
1901
1902 class CommentRecord : public Record
1903 {
1904 public:
1905 bool no_purge;
1906 bool no_list;
1907 enum comment_class_t : uint8_t
1908 {
1909 Translator = 0x00,
1910 IntelCopyright = 0x01,
1911 LibrarySpecifier = 0x81,
1912 MSDOSVersion = 0x9C,
1913 MemoryModel = 0x9D,
1914 DOSSEG = 0x9E,
1915 DefaultLibrarySearchName = 0x9F,
1916 OMFExtension = 0xA0,
1917 NewOMFExtension = 0xA1,
1918 LinkPassSeparator = 0xA2,
1919 LIBMOD = 0xA3,
1920 EXESTR = 0xA4,
1921 INCERR = 0xA6,
1922 NOPAD = 0xA7,
1923 WKEXT = 0xA8,
1924 LZEXT = 0xA9,
1925 Comment = 0xDA,
1926 Compiler = 0xDB,
1927 Date = 0xDC,
1928 TimeStamp = 0xDD,
1929 User = 0xDF,
1930 DependencyFile = 0xE9,
1931 CommandLine = 0xFF,
1932 };
1933 comment_class_t comment_class;
1934
1936 : Record(COMENT)
1937 {
1938 }
1939
1940 CommentRecord(comment_class_t comment_class = comment_class_t(0))
1941 : Record(COMENT), comment_class(comment_class)
1942 {
1943 }
1944
1945 virtual void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) = 0;
1946 virtual uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const = 0;
1947 virtual void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const = 0;
1948
1949 static std::shared_ptr<CommentRecord> ReadCommentRecord(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t record_length);
1950 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
1951 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1952 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1953
1955 class EmptyCommentRecord;
1956 class TextCommentRecord;
1957 };
1958
1960 {
1961 public:
1962 std::vector<SegmentIndex> segments;
1963
1965 : CommentRecord(NOPAD)
1966 {
1967 }
1968
1969 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
1970 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
1971 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
1972
1973 void CalculateValues(OMF86Format * omf, Module * mod) override;
1974 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1975 };
1976
1978 {
1979 public:
1981 {
1982 public:
1983 ExternalIndex definition;
1984 ExternalIndex default_resolution;
1985
1986 static ExternalAssociation Read(OMF86Format * omf, Module * mod, Linker::Reader& rd);
1987 uint16_t Size(OMF86Format * omf, Module * mod) const;
1988 void Write(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const;
1989
1990 void CalculateValues(OMF86Format * omf, Module * mod);
1991 void ResolveReferences(OMF86Format * omf, Module * mod);
1992 };
1993
1994 std::vector<ExternalAssociation> associations;
1995
1996 ExternalAssociationRecord(comment_class_t comment_class = comment_class_t(0))
1997 : CommentRecord(comment_class)
1998 {
1999 }
2000
2001 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2002 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2003 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2004
2005 void CalculateValues(OMF86Format * omf, Module * mod) override;
2006 void ResolveReferences(OMF86Format * omf, Module * mod) override;
2007 };
2008
2010 {
2011 public:
2012 enum extension_type_t : uint8_t
2013 {
2014 IMPDEF = 0x01,
2015 EXPDEF = 0x02,
2016 INCDEF = 0x03,
2017 ProtectedModeLibrary = 0x04,
2018 LNKDIR = 0x05,
2019 BigEndian = 0x06,
2020 PRECOMP = 0x07,
2021 };
2022 extension_type_t subtype;
2023
2024 OMFExtensionRecord(extension_type_t subtype = extension_type_t(0))
2025 : CommentRecord(OMFExtension), subtype(subtype)
2026 {
2027 }
2028
2031 };
2032
2034 {
2035 public:
2036 std::string internal_name;
2037 std::string module_name;
2038 std::variant<std::string, uint16_t> entry_ident;
2039
2041 : OMFExtensionRecord(IMPDEF)
2042 {
2043 }
2044
2045 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2046 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2047 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2048 };
2049
2051 {
2052 public:
2053 bool resident_name;
2054 bool no_data;
2055 uint8_t parameter_count;
2056 std::string exported_name;
2057 std::string internal_name;
2058 std::optional<uint16_t> ordinal;
2059
2061 : OMFExtensionRecord(EXPDEF)
2062 {
2063 }
2064
2065 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2066 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2067 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2068 };
2069
2071 {
2072 public:
2073 uint16_t extdef_delta;
2074 uint16_t linnum_delta;
2075 uint16_t padding_byte_count;
2076
2078 : OMFExtensionRecord(INCDEF)
2079 {
2080 }
2081
2082 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2083 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2084 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2085 };
2086
2088 {
2089 public:
2090 bool new_executable;
2091 bool omit_codeview_publics;
2092 bool run_mpc;
2093 uint8_t pseudocode_version;
2094 uint8_t codeview_version;
2095
2096 static constexpr uint8_t FlagNewExecutable = 0x01;
2097 static constexpr uint8_t FlagOmitCodeViewPublics = 0x02;
2098 static constexpr uint8_t FlagRunMPC = 0x04;
2099
2101 : OMFExtensionRecord(LNKDIR)
2102 {
2103 }
2104
2105 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2106 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2107 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2108 };
2109
2111 {
2112 public:
2113 uint32_t dictionary_offset;
2114 uint16_t dictionary_size;
2115 bool case_sensitive;
2116
2119 {
2120 }
2121
2122 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
2123 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
2124 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2125
2126 void WriteRecord(OMF86Format * omf, Module * mod, Linker::Writer& wr) const override;
2127 };
2128
2130 {
2131 public:
2134 {
2135 }
2136
2137 void ReadRecordContents(OMF86Format * omf, Module * mod, Linker::Reader& rd) override;
2138 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
2139 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2140
2141 void WriteRecord(OMF86Format * omf, Module * mod, Linker::Writer& wr) const override;
2142 };
2143
2146 {
2147 public:
2149 size_t first_record = 0;
2151 size_t record_count = 0;
2152
2154 std::vector<std::string> lnames;
2156 std::vector<std::shared_ptr<SegmentDefinitionRecord>> segdefs;
2158 std::vector<std::shared_ptr<GroupDefinitionRecord>> grpdefs;
2160 std::vector<std::shared_ptr<TypeDefinitionRecord>> typdefs;
2162 std::vector<std::shared_ptr<BlockDefinitionRecord>> blkdefs;
2164 std::vector<std::shared_ptr<OverlayDefinitionRecord>> ovldefs;
2166 std::vector<ExternalName> extdefs; // also includes comdefs and cextdefs
2167 // TODO: CalculateValue/etc. for ExternalName
2168 };
2169
2171 std::vector<std::shared_ptr<Record>> records;
2172
2174 std::vector<Module> modules;
2175
2176 // TIS library fields
2177 uint16_t page_size;
2178
2180 static std::shared_ptr<OMF86Format> ReadOMFFile(Linker::Reader& rd);
2181
2182 static void DumpAddFields(const Record * record, Dumper::Dumper& dump, Dumper::Region& region, const OMF86Format * omf, const Module * mod, size_t record_index, Dumper::display_option& options);
2183
2184 void ReadFile(Linker::Reader& rd) override;
2186 offset_t WriteFile(Linker::Writer& wr) const override;
2187 void Dump(Dumper::Dumper& dump) const override;
2188
2189 static uint32_t FillSectionData(std::shared_ptr<Linker::Section> section, uint32_t offset, std::shared_ptr<OMF86Format::DataBlock> data);
2190
2192 void GenerateModule(Linker::Module& module) const override;
2193 /* TODO */
2194 };
2195
2197 {
2198 public:
2199 std::vector<uint8_t> data;
2200
2201 GenericCommentRecord(comment_class_t comment_class = comment_class_t(0))
2202 : CommentRecord(comment_class)
2203 {
2204 }
2205
2206 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2207 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2208 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2209 };
2210
2212 {
2213 public:
2214 EmptyCommentRecord(comment_class_t comment_class = comment_class_t(0))
2215 : CommentRecord(comment_class)
2216 {
2217 }
2218
2219 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2220 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2221 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2222 };
2223
2225 {
2226 public:
2227 std::string name;
2228
2229 TextCommentRecord(comment_class_t comment_class = comment_class_t(0))
2230 : CommentRecord(comment_class)
2231 {
2232 }
2233
2234 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2235 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2236 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2237 };
2238
2240 {
2241 public:
2242 std::vector<uint8_t> data;
2243
2244 GenericOMFExtensionRecord(extension_type_t extension_type = extension_type_t(0))
2245 : OMFExtensionRecord(extension_type)
2246 {
2247 }
2248
2249 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2250 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2251 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2252 };
2253
2255 {
2256 public:
2257 EmptyOMFExtensionRecord(extension_type_t extension_type = extension_type_t(0))
2258 : OMFExtensionRecord(extension_type)
2259 {
2260 }
2261
2262 void ReadComment(OMF86Format * omf, Module * mod, Linker::Reader& rd, uint16_t comment_length) override;
2263 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2264 void WriteComment(OMF86Format * omf, Module * mod, ChecksumWriter& wr) const override;
2265 };
2266
2270 class OMF80Format : public virtual OMFFormat, public virtual Linker::InputFormat
2271 {
2272 public:
2273 class Module;
2274
2275 enum record_type_t : uint8_t
2276 {
2277 ModuleHeader = 0x02,
2278 ModuleEnd = 0x04,
2279 Content = 0x06,
2280 LineNumbers = 0x08,
2281 EndOfFile = 0x0E,
2282 ModuleAncestor = 0x10,
2283 LocalSymbols = 0x12,
2284 PublicDefinitions = 0x16,
2285 ExternalDefinitions = 0x18,
2286 ExternalReferences = 0x20,
2287 Relocations = 0x22,
2288 InterSegmentReferences = 0x24,
2289 LibraryModuleLocations = 0x26,
2290 LibraryModuleNames = 0x28,
2291 LibraryDictionary = 0x2A,
2292 LibraryHeader = 0x2C,
2293 NamedCommonDefinitions = 0x2E,
2294 };
2295
2296 static const std::map<offset_t, std::string> RecordTypeNames;
2297
2307
2309 std::shared_ptr<Record> ReadRecord(Linker::Reader& rd);
2310
2316 typedef uint8_t segment_id_t;
2317
2319 static constexpr segment_id_t AbsoluteSegment = 0;
2321 static constexpr segment_id_t CodeSegment = 1;
2323 static constexpr segment_id_t DataSegment = 2;
2325 static constexpr segment_id_t StackSegment = 3;
2327 static constexpr segment_id_t MemorySegment = 4;
2331 static constexpr segment_id_t LastNamedCommonSegment = 254;
2333 static constexpr segment_id_t UnnamedCommonSegment = 255;
2334
2335 // TODO: document
2336
2337 enum alignment_t : uint8_t
2338 {
2339 // page is 256 bytes
2340 AlignFitsPage = 1,
2341 AlignPage = 2,
2342 AlignByte = 3,
2343 };
2344
2346 {
2347 public:
2348 uint16_t index;
2349 std::string external_name;
2350
2351 void CalculateValues(OMF80Format * omf, Module * mod);
2352 void ResolveReferences(OMF80Format * omf, Module * mod);
2353 };
2354
2356 {
2357 public:
2359 {
2360 public:
2361 segment_id_t segment_id = 0;
2362 uint16_t length = 0;
2363 alignment_t alignment = AlignByte;
2364
2365 static SegmentDefinition Read(OMF80Format * omf, Linker::Reader& rd);
2366 void Write(OMF80Format * omf, ChecksumWriter& wr) const;
2367 };
2368
2369 std::string name;
2370 std::vector<SegmentDefinition> segment_definitions;
2371
2372 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
2374 {
2375 }
2376
2377 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2378 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2379 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2380
2381 void CalculateValues(OMF80Format * omf, Module * mod) override;
2382 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2383 };
2384
2386 {
2387 public:
2388 bool main;
2389 segment_id_t start_segment_id;
2390 uint16_t start_offset;
2391 std::vector<uint8_t> info;
2392
2393 ModuleEndRecord(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:
2410 {
2411 public:
2412 segment_id_t segment_id;
2413 std::string common_name;
2414
2415 static NamedCommonDefinition ReadNamedCommonDefinition(OMF80Format * omf, Linker::Reader& rd);
2416 uint16_t GetNamedCommonDefinitionSize(OMF80Format * omf) const;
2417 void WriteNamedCommonDefinition(OMF80Format * omf, ChecksumWriter& wr) const;
2418 };
2419
2420 std::vector<NamedCommonDefinition> named_common_definitions;
2421
2422 NamedCommonDefinitionsRecord(record_type_t record_type = record_type_t(0))
2424 {
2425 }
2426
2427 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2428 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2429 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2430
2431 void CalculateValues(OMF80Format * omf, Module * mod) override;
2432 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2433 };
2434
2436 {
2437 public:
2438 Module * mod;
2439
2440 std::vector<std::string> external_names; // only used for generation
2441 uint16_t first_external_name;
2442 uint16_t external_name_count;
2443
2444 ExternalDefinitionsRecord(record_type_t record_type = record_type_t(0))
2446 {
2447 }
2448
2449 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2450 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2451 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2452
2453 void CalculateValues(OMF80Format * omf, Module * mod) override;
2454 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2455 };
2456
2458 {
2459 public:
2461 {
2462 public:
2463 uint16_t offset;
2464 std::string name;
2465
2466 static SymbolDefinition Read(OMF80Format * omf, Module * mod, Linker::Reader& rd);
2467 uint16_t Size(OMF80Format * omf, Module * mod) const;
2468 void Write(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const;
2469 };
2470
2471 uint8_t segment_id;
2472 std::vector<SymbolDefinition> public_definitions;
2473
2474 SymbolDefinitionsRecord(record_type_t record_type = record_type_t(0))
2476 {
2477 }
2478
2479 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2480 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2481 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2482
2483 void CalculateValues(OMF80Format * omf, Module * mod) override;
2484 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2485 };
2486
2487 enum relocation_type_t : uint8_t
2488 {
2489 RelocationLowByte = 1,
2490 RelocationHighByte = 2,
2491 RelocationWord = 3,
2492 };
2493
2495 {
2496 public:
2497 relocation_type_t relocation_type;
2498 std::vector<uint16_t> offsets;
2499
2500 RelocationsRecord(record_type_t record_type = record_type_t(0))
2502 {
2503 }
2504
2505 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2506 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2507 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2508
2509 void CalculateValues(OMF80Format * omf, Module * mod) override;
2510 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2511 };
2512
2514 {
2515 public:
2516 segment_id_t segment_id;
2517
2518 InterSegmentReferencesRecord(record_type_t record_type = record_type_t(0))
2520 {
2521 }
2522
2523 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2524 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2525 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2526
2527 void CalculateValues(OMF80Format * omf, Module * mod) override;
2528 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2529 };
2530
2532 {
2533 public:
2535 {
2536 public:
2537 ExternalNameIndex name_index;
2538 uint16_t offset;
2539 };
2540
2541 relocation_type_t relocation_type;
2542 std::vector<ExternalReference> external_references;
2543
2544 ExternalReferencesRecord(record_type_t record_type = record_type_t(0))
2546 {
2547 }
2548
2549 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2550 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2551 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2552
2553 void CalculateValues(OMF80Format * omf, Module * mod) override;
2554 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2555 };
2556
2558 {
2559 public:
2560 std::string name;
2561
2562 ModuleAncestorRecord(record_type_t record_type = record_type_t(0))
2564 {
2565 }
2566
2567 void ReadRecordContents(OMF80Format * omf, Module * mod, Linker::Reader& rd) override;
2568 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2569 void WriteRecordContents(OMF80Format * omf, Module * mod, ChecksumWriter& wr) const override;
2570
2571 void CalculateValues(OMF80Format * omf, Module * mod) override;
2572 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2573 };
2574
2576 {
2577 public:
2578 segment_id_t segment_id = 0;
2579 uint16_t length = 0;
2580 alignment_t alignment = AlignByte;
2581 std::string common_name;
2582
2584 {
2585 }
2586
2588 : segment_id(segment_definition.segment_id), length(segment_definition.length), alignment(segment_definition.alignment)
2589 {
2590 }
2591 };
2592
2594 {
2595 public:
2597 size_t first_record = 0;
2599 size_t record_count = 0;
2600
2601 std::map<segment_id_t, SegmentDefinition> segment_definitions;
2602 std::vector<std::string> external_names;
2603 };
2604
2606 std::vector<std::shared_ptr<Record>> records;
2607
2609 std::vector<Module> modules;
2610
2612 static std::shared_ptr<OMF80Format> ReadOMFFile(Linker::Reader& rd);
2613
2614 static void DumpAddFields(const Record * record, Dumper::Dumper& dump, Dumper::Region& region, const OMF80Format * omf, const Module * mod, size_t record_index, Dumper::display_option& options);
2615
2616 void ReadFile(Linker::Reader& rd) override;
2618 offset_t WriteFile(Linker::Writer& wr) const override;
2619 void Dump(Dumper::Dumper& dump) const override;
2621 void GenerateModule(Linker::Module& module) const override;
2622 /* TODO */
2623 };
2624
2628 class OMF51Format : public virtual OMFFormat, public virtual Linker::InputFormat
2629 {
2630 public:
2631 class Module;
2632
2633 enum record_type_t : uint8_t
2634 {
2635 ModuleHeader = OMF80Format::ModuleHeader,
2636 ModuleEnd = OMF80Format::ModuleEnd,
2637 Content = OMF80Format::Content,
2638 Fixups = 0x08,
2639 SegmentDefinitions = 0x0E,
2640 ScopeDefinition = 0x10,
2641 DebugItems = 0x12,
2642 PublicDefinitions = OMF80Format::PublicDefinitions,
2643 ExternalDefinitions = OMF80Format::ExternalDefinitions,
2644 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
2645 LibraryModuleNames = OMF80Format::LibraryModuleNames,
2646 LibraryDictionary = OMF80Format::LibraryDictionary,
2647 LibraryHeader = OMF80Format::LibraryHeader,
2648 };
2649
2650 static const std::map<offset_t, std::string> RecordTypeNames;
2651
2660
2662 std::shared_ptr<Record> ReadRecord(Linker::Reader& rd);
2663
2664 // TODO: document record types
2665
2666 static constexpr uint8_t SegmentAbsolute = 0;
2667
2683
2699
2701 {
2702 public:
2703 bool overlayable;
2704 uint8_t register_bank;
2705 segment_type_t segment_type;
2706
2707 static constexpr uint8_t MaskSegmentType = 0x07;
2708 static constexpr uint8_t MaskRegisterBank = 0x18;
2709 static constexpr uint8_t ShiftRegisterBank = 3;
2710 static constexpr uint8_t FlagOverlayable = 0x20;
2711 static constexpr uint8_t FlagSegmentEmpty = 0x80;
2712
2713 void ReadSegmentInfo(OMF51Format * omf, Module * mod, uint8_t segment_info);
2714 uint8_t WriteSegmentInfo(OMF51Format * omf, Module * mod) const;
2715 };
2716
2718 {
2719 public:
2720 uint8_t segment_id;
2721 SegmentInfo info;
2722 alignment_t alignment;
2723 uint16_t base;
2724 uint32_t size;
2725 std::string name;
2726
2727 static SegmentDefinition Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2728 uint16_t Size(OMF51Format * omf, Module * mod) const;
2729 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2730 };
2731
2733 {
2734 public:
2735 bool indirectly_callable;
2736 bool variable;
2737 std::optional<unsigned> register_bank;
2738 segment_type_t usage;
2739
2740 static constexpr uint8_t MaskSegmentType = 0x07;
2741 static constexpr uint8_t MaskRegisterBank = 0x18;
2742 static constexpr uint8_t ShiftRegisterBank = 3;
2743 static constexpr uint8_t FlagRegisterBank = 0x20;
2744 static constexpr uint8_t FlagVariable = 0x40;
2745 static constexpr uint8_t FlagIndirectlyCallable = 0x80;
2746
2747 void Read(OMF51Format * omf, Module * mod, uint8_t segment_info);
2748 uint8_t Write(OMF51Format * omf, Module * mod) const;
2749 };
2750
2752 {
2753 public:
2754 uint8_t segment_id;
2755 SymbolInfo info;
2756 uint16_t offset;
2757 std::string name;
2758
2759 static SymbolDefinition Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2760 uint16_t Size(OMF51Format * omf, Module * mod) const;
2761 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2762 };
2763
2765 {
2766 public:
2767 uint8_t block_id = 2;
2768 uint8_t external_id;
2769 SymbolInfo info;
2770 std::string name;
2771
2772 static ExternalDefinition Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2773 uint16_t Size(OMF51Format * omf, Module * mod) const;
2774 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2775 };
2776
2778 {
2779 public:
2780 std::string name;
2781 enum translator_id_t : uint8_t
2782 {
2783 Assembler = 0xFD,
2784 PLMCompiler = 0xFE,
2785 Linker = 0xFF,
2786 };
2787 translator_id_t translator_id;
2788
2789 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
2791 {
2792 }
2793
2794 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2795 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2796 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2797 };
2798
2800 {
2801 public:
2802 std::string name;
2803 std::array<bool, 4> banks;
2804
2805 ModuleEndRecord(record_type_t record_type = record_type_t(0))
2807 {
2808 }
2809
2810 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2811 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2812 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2813 };
2814
2816 {
2817 public:
2818 std::vector<SegmentDefinition> segment_definitions;
2819
2820 SegmentDefinitionsRecord(record_type_t record_type = record_type_t(0))
2822 {
2823 }
2824
2825 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2826 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2827 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2828
2829 void CalculateValues(OMF51Format * omf, Module * mod) override;
2830 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2831 };
2832
2834 {
2835 public:
2836 std::vector<SymbolDefinition> symbol_definitions;
2837
2838 PublicSymbolsRecord(record_type_t record_type = record_type_t(0))
2840 {
2841 }
2842
2843 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2844 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2845 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2846
2847 void CalculateValues(OMF51Format * omf, Module * mod) override;
2848 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2849 };
2850
2852 {
2853 public:
2854 std::vector<ExternalDefinition> external_definitions;
2855
2856 ExternalDefinitionsRecord(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:
2872 enum block_type_t : uint8_t
2873 {
2874 ModuleBlock = 0,
2875 DoBlock = 1,
2876 ProcedureBlock = 2,
2877 EndModuleBlock = 3,
2878 EndDoBlock = 4,
2879 EndProcedureBlock = 5,
2880 };
2881
2882 block_type_t block_type;
2883 std::string name;
2884
2885 ScopeDefinitionRecord(record_type_t record_type = record_type_t(0))
2887 {
2888 }
2889
2890 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2891 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2892 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2893
2894 void CalculateValues(OMF51Format * omf, Module * mod) override;
2895 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2896 };
2897
2899 {
2900 public:
2902 {
2903 public:
2904 uint8_t segment_id;
2905 SymbolInfo info;
2906 uint16_t offset;
2907 std::string name;
2908
2909 static Symbol Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2910 uint16_t Size(OMF51Format * omf, Module * mod) const;
2911 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2912 };
2913
2915 {
2916 public:
2917 std::vector<Symbol> symbols;
2918 };
2919
2921 {
2922 public:
2923 std::vector<Symbol> symbols;
2924 };
2925
2927 {
2928 public:
2929 uint8_t segment_id;
2930 SegmentInfo info;
2931 uint16_t offset;
2932 std::string name;
2933
2934 static SegmentSymbol Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2935 uint16_t Size(OMF51Format * omf, Module * mod) const;
2936 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2937 };
2938
2940 {
2941 public:
2942 std::vector<SegmentSymbol> symbols;
2943 };
2944
2946 {
2947 public:
2948 uint8_t segment_id;
2949 uint16_t offset;
2950 uint16_t line_number;
2951
2952 static LineNumber Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
2953 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
2954 };
2955
2957 {
2958 public:
2959 std::vector<LineNumber> symbols;
2960 };
2961
2962 static constexpr uint8_t Type_LocalSymbols = 0;
2963 static constexpr uint8_t Type_PublicSymbols = 1;
2964 static constexpr uint8_t Type_SegmentSymbols = 2;
2965 static constexpr uint8_t Type_LineNumbers = 3;
2966
2967 std::variant<LocalSymbols, PublicSymbols, SegmentSymbols, LineNumbers> contents;
2968
2969 DebugItemsRecord(record_type_t record_type = record_type_t(0))
2971 {
2972 }
2973
2974 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
2975 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2976 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
2977
2978 void CalculateValues(OMF51Format * omf, Module * mod) override;
2979 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2980 };
2981
2982 class FixupRecord : public Record
2983 {
2984 public:
2985 enum relocation_type_t : uint8_t
2986 {
2987 RelocationLow8 = 0,
2988 RelocationByte8 = 1,
2989 RelocationRelative8 = 2,
2990 RelocationHigh8 = 3,
2991 RelocationWord16 = 4,
2992 RelocationAbsolute11 = 5,
2993 RelocationBit7 = 6,
2994 RelocationConv7 = 7,
2995 };
2996
3006
3007 class Fixup
3008 {
3009 public:
3010 uint16_t location;
3011 relocation_type_t relocation;
3012 reference_type_t reference;
3013 uint8_t id;
3014 uint16_t offset;
3015
3016 static Fixup Read(OMF51Format * omf, Module * mod, Linker::Reader& rd);
3017 void Write(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const;
3018 };
3019
3020 std::vector<Fixup> fixups;
3021
3022 FixupRecord(record_type_t record_type = record_type_t(0))
3024 {
3025 }
3026
3027 void ReadRecordContents(OMF51Format * omf, Module * mod, Linker::Reader& rd) override;
3028 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
3029 void WriteRecordContents(OMF51Format * omf, Module * mod, ChecksumWriter& wr) const override;
3030
3031 void CalculateValues(OMF51Format * omf, Module * mod) override;
3032 void ResolveReferences(OMF51Format * omf, Module * mod) override;
3033 };
3034
3036 {
3037 public:
3039 size_t first_record = 0;
3041 size_t record_count = 0;
3042
3043 std::map<uint8_t, SegmentDefinition> segment_definitions;
3044 std::map<uint8_t, ExternalDefinition> external_definitions;
3045 };
3046
3048 std::vector<std::shared_ptr<Record>> records;
3049
3051 std::vector<Module> modules;
3052
3054 static std::shared_ptr<OMF51Format> ReadOMFFile(Linker::Reader& rd);
3055
3056 static void DumpAddFields(const Record * record, Dumper::Dumper& dump, Dumper::Region& region, const OMF51Format * omf, const Module * mod, size_t record_index, Dumper::display_option& options);
3057
3058 void ReadFile(Linker::Reader& rd) override;
3060 offset_t WriteFile(Linker::Writer& wr) const override;
3061 void Dump(Dumper::Dumper& dump) const override;
3063 void GenerateModule(Linker::Module& module) const override;
3064 /* TODO */
3065 };
3066
3070 class OMF96Format : public virtual OMFFormat, public virtual Linker::InputFormat
3071 {
3072 public:
3073 class Module;
3074
3075 typedef uint16_t index_t;
3076
3077 enum record_type_t : uint8_t
3078 {
3079 ModuleHeader = OMF80Format::ModuleHeader,
3080 ModuleEnd = OMF80Format::ModuleEnd,
3081 Content = OMF80Format::Content,
3082 LineNumbers = OMF80Format::LineNumbers,
3083 BlockDefinition = 0x0A,
3084 BlockEnd = 0x0C,
3085 EndOfFile = OMF80Format::EndOfFile,
3086 ModuleAncestor = OMF80Format::ModuleAncestor,
3087 LocalSymbols = OMF80Format::LocalSymbols,
3088 TypeDefinition = 0x14,
3089 PublicDefinitions = OMF80Format::PublicDefinitions,
3090 ExternalDefinitions = OMF80Format::ExternalDefinitions,
3091 SegmentDefinitions = 0x20, // different from OMF51 number
3092 Relocations = OMF80Format::Relocations,
3093 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
3094 LibraryModuleNames = OMF80Format::LibraryModuleNames,
3095 LibraryDictionary = OMF80Format::LibraryDictionary,
3096 LibraryHeader = 0x2E, // different from OMF80 number
3097 };
3098
3099 static const std::map<offset_t, std::string> RecordTypeNames;
3100
3110
3112 std::shared_ptr<Record> ReadRecord(Linker::Reader& rd);
3113
3114 typedef uint8_t segment_id_t;
3115
3116 static constexpr segment_id_t CodeSegment = 0;
3117 static constexpr segment_id_t DataSegment = 1;
3118 static constexpr segment_id_t RegisterSegment = 2;
3119 static constexpr segment_id_t OverlaySegment = 3;
3120 static constexpr segment_id_t StackSegment = 4;
3121 static constexpr segment_id_t DynamicSymbol = 5;
3122 static constexpr segment_id_t NullSegment = 6;
3123 static constexpr segment_id_t SegmentTypeMask = 7;
3124
3125 static constexpr segment_id_t FlagBasedVariable = 0x40;
3126
3127 static constexpr segment_id_t FlagRelocatableSegment = 0x80;
3128
3129 enum alignment_t
3130 {
3131 AlignByte = 0,
3132 AlignWord = 1,
3133 AlignLong = 2,
3134 };
3135
3137 {
3138 public:
3139 segment_id_t segment_id;
3140 private:
3141 union
3142 {
3143 alignment_t alignment; // for RelocatableSegment
3144 uint16_t base_address;
3145 };
3146 public:
3147 uint16_t size;
3148
3149 bool IsRelocatable() const
3150 {
3151 return segment_id & FlagRelocatableSegment;
3152 }
3153
3154 bool IsAbsolute() const
3155 {
3156 return !IsRelocatable();
3157 }
3158
3159 alignment_t GetAlignment() const
3160 {
3161 return IsRelocatable() ? alignment : alignment_t(-1);
3162 }
3163
3164 uint16_t GetBaseAddress() const
3165 {
3166 return IsAbsolute() ? base_address : 0;
3167 }
3168
3169 void MakeRelocatable(alignment_t rel_alignment)
3170 {
3171 segment_id |= FlagRelocatableSegment;
3172 alignment = rel_alignment;
3173 }
3174
3175 void MakeAbsolute(uint16_t address)
3176 {
3177 segment_id &= ~FlagRelocatableSegment;
3178 base_address = address;
3179 }
3180
3181 static SegmentDefinition Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3182 uint16_t Size(OMF96Format * omf, Module * mod) const;
3183 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3184 };
3185
3187
3189 {
3190 public:
3191 index_t index;
3192 std::shared_ptr<TypeDefinitionRecord> record;
3193
3194 TypeIndex(index_t index = 0)
3195 : index(index)
3196 {
3197 }
3198
3199 void CalculateValues(OMF86Format * omf, Module * mod);
3200 void ResolveReferences(OMF86Format * omf, Module * mod);
3201 };
3202
3204 {
3205 public:
3206 std::string name;
3207 TypeIndex type;
3208
3209 static ExternalDefinition Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3210 uint16_t Size(OMF96Format * omf, Module * mod) const;
3211 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3212
3213 void CalculateValues(OMF96Format * omf, Module * mod);
3214 void ResolveReferences(OMF96Format * omf, Module * mod);
3215 };
3216
3218 {
3219 public:
3220 uint16_t offset;
3221 std::string name;
3222 TypeIndex type;
3223
3224 static SymbolDefinition Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3225 uint16_t Size(OMF96Format * omf, Module * mod) const;
3226 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3227
3228 void CalculateValues(OMF96Format * omf, Module * mod);
3229 void ResolveReferences(OMF96Format * omf, Module * mod);
3230 };
3231
3233 {
3234 public:
3235 std::string name;
3236 uint8_t translator_id;
3237 std::string date_time;
3238
3239 static constexpr uint8_t Version14 = 0xE0;
3240 static constexpr uint8_t Version20 = 0xE4;
3241 static constexpr uint8_t Translator = 0x00;
3242 static constexpr uint8_t Linker = 0x01;
3243
3244 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
3246 {
3247 }
3248
3249 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3250 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3251 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3252 };
3253
3255 {
3256 public:
3257 bool main;
3258 bool valid;
3259
3260 static constexpr uint8_t MainModule = 0x01;
3261 static constexpr uint8_t OtherModule = 0x00;
3262
3263 static constexpr uint8_t ValidModule = 0x00;
3264 static constexpr uint8_t ErroneousModule = 0x01;
3265
3266 ModuleEndRecord(record_type_t record_type = record_type_t(0))
3268 {
3269 }
3270
3271 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3272 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3273 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3274 };
3275
3277 {
3278 public:
3279 std::vector<SegmentDefinition> segment_definitions;
3280
3281 SegmentDefinitionsRecord(record_type_t record_type = record_type_t(0))
3283 {
3284 }
3285
3286 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3287 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3288 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3289
3290 void CalculateValues(OMF96Format * omf, Module * mod) override;
3291 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3292 };
3293
3294 class TypeDefinitionRecord : public Record, public std::enable_shared_from_this<TypeDefinitionRecord>
3295 {
3296 public:
3298 {
3299 public:
3300 bool nice; // easy if false
3301
3303 struct Null { };
3305 struct Repeat { };
3306 // TODO: document
3307 struct EndOfBranch { };
3308
3309 std::variant<Null, int32_t, std::string, TypeIndex, Repeat, EndOfBranch> leaf = Null();
3310
3312 static constexpr uint8_t NullLeaf = 0x64;
3314 static constexpr uint8_t SignedNumericLeaf16 = 0x65;
3316 static constexpr uint8_t SignedNumericLeaf32 = 0x66;
3318 static constexpr uint8_t StringLeaf = 0x67;
3320 static constexpr uint8_t IndexLeaf = 0x68;
3322 static constexpr uint8_t RepeatLeaf = 0x69;
3324 static constexpr uint8_t EndOfBranchLeaf = 0x6A;
3325
3326 static LeafDescriptor Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3327 uint16_t Size(OMF96Format * omf, Module * mod) const;
3328 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3329
3330 void CalculateValues(OMF96Format * omf, Module * mod);
3331 void ResolveReferences(OMF96Format * omf, Module * mod);
3332 };
3333
3335 std::vector<LeafDescriptor> leafs;
3336
3337 TypeDefinitionRecord(record_type_t record_type = record_type_t(0))
3339 {
3340 }
3341
3342 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3343 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3344 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3345
3346 void CalculateValues(OMF96Format * omf, Module * mod) override;
3347 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3348 };
3349
3351 {
3352 public:
3353 segment_id_t segment_id;
3354 std::vector<SymbolDefinition> symbol_definitions;
3355
3356 SymbolDefinitionsRecord(record_type_t record_type = record_type_t(0))
3358 {
3359 }
3360
3361 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3362 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3363 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3364
3365 void CalculateValues(OMF96Format * omf, Module * mod) override;
3366 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3367 };
3368
3370 {
3371 public:
3372 segment_id_t segment_id;
3373 std::vector<ExternalDefinition> external_definitions;
3374
3375 ExternalDefinitionsRecord(record_type_t record_type = record_type_t(0))
3377 {
3378 }
3379
3380 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3381 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3382 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3383
3384 void CalculateValues(OMF96Format * omf, Module * mod) override;
3385 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3386 };
3387
3389 {
3390 public:
3392 {
3393 public:
3394 typedef segment_id_t LocalReference;
3395 typedef uint16_t ExternalReference;
3396
3397 enum reference_type_t
3398 {
3399 RegisterSimple = 0,
3400 RegisterAutoIncrement = 1,
3401 ShiftCountImmediate = 2,
3402 ShiftCountRegister = 3,
3403 ByteConstant = 4,
3404 ShortJump = 6,
3405 MediumJump = 7,
3406 MediumCall = 8,
3407 LongJumpCall = 9,
3408 LongDirect = 10,
3409 };
3410
3411 static constexpr uint8_t FlagAddendInCode = 0x40;
3412 static constexpr uint8_t FlagExternal = 0x80;
3413
3414 uint16_t offset;
3415 std::variant<LocalReference, ExternalReference> reference = LocalReference(0);
3416 std::optional<uint16_t> addend;
3417 reference_type_t reference_type;
3418 alignment_t alignment;
3419
3420 static Relocation Read(OMF96Format * omf, Module * mod, Linker::Reader& rd);
3421 uint16_t Size(OMF96Format * omf, Module * mod) const;
3422 void Write(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const;
3423 };
3424
3425 std::vector<Relocation> relocations;
3426
3427 RelocationRecord(record_type_t record_type = record_type_t(0))
3429 {
3430 }
3431
3432 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3433 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3434 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3435
3436 void CalculateValues(OMF96Format * omf, Module * mod) override;
3437 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3438 };
3439
3441 {
3442 public:
3443 std::string name;
3444 std::optional<SegmentDefinition> segment_definition;
3445
3446 ModuleAncestorRecord(record_type_t record_type = record_type_t(0))
3448 {
3449 }
3450
3451 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3452 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3453 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3454
3455 void CalculateValues(OMF96Format * omf, Module * mod) override;
3456 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3457 };
3458
3460 {
3461 public:
3463 {
3464 public:
3465 std::string name;
3466 TypeIndex type;
3467 };
3468
3469 typedef segment_id_t LocalReference;
3470 typedef uint16_t ExternalReference;
3471
3473 {
3474 public:
3475 std::variant<LocalReference, ExternalReference> frame_pointer = LocalReference(0);
3476 uint16_t return_offset;
3477 uint8_t prologue_size;
3478 };
3479
3480 segment_id_t segment_id;
3481 uint16_t offset;
3482 uint16_t size;
3483 std::optional<BlockNameAndType> name_and_type;
3484 std::optional<ProcedureInformation> procedure_info;
3485
3486 BlockDefinitionRecord(record_type_t record_type = record_type_t(0))
3488 {
3489 }
3490
3491 static constexpr uint8_t FlagProcedure = 0x40;
3492 static constexpr uint8_t FlagExternal = 0x80;
3493
3494 void ReadRecordContents(OMF96Format * omf, Module * mod, Linker::Reader& rd) override;
3495 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3496 void WriteRecordContents(OMF96Format * omf, Module * mod, ChecksumWriter& wr) const override;
3497
3498 void CalculateValues(OMF96Format * omf, Module * mod) override;
3499 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3500 };
3501
3503 {
3504 public:
3506 size_t first_record = 0;
3508 size_t record_count = 0;
3509
3510 std::map<segment_id_t, SegmentDefinition> segment_definitions;
3511 std::vector<std::shared_ptr<TypeDefinitionRecord>> type_definitions;
3512 };
3513
3515 std::vector<std::shared_ptr<Record>> records;
3516
3518 std::vector<Module> modules;
3519
3521 static std::shared_ptr<OMF96Format> ReadOMFFile(Linker::Reader& rd);
3522
3523 static void DumpAddFields(const Record * record, Dumper::Dumper& dump, Dumper::Region& region, const OMF96Format * omf, const Module * mod, size_t record_index, Dumper::display_option& options);
3524
3525 void ReadFile(Linker::Reader& rd) override;
3527 offset_t WriteFile(Linker::Writer& wr) const override;
3528 void Dump(Dumper::Dumper& dump) const override;
3530 void GenerateModule(Linker::Module& module) const override;
3531 /* TODO */
3532 };
3533
3535 {
3536 public:
3537 std::shared_ptr<OMFFormat> contents;
3538
3539 void ReadFile(Linker::Reader& rd) override;
3540
3542 void GenerateModule(Linker::Module& module) const override;
3543
3545 offset_t WriteFile(Linker::Writer& wr) const override;
3546
3547 offset_t ImageSize() const override;
3548
3549 void Dump(Dumper::Dumper& dump) const override;
3550 };
3551}
3552
3553#endif /* OMF_H */
static std::shared_ptr< DecDisplay > Make(bool enable_signed)
Creates a decimal display.
Definition dumper.h:328
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:828
static std::shared_ptr< HexDisplay > Make(unsigned width=8)
Creates a hexadecimal display.
Definition dumper.h:301
A record that represents a region within the file.
Definition dumper.h:721
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:198
virtual void GenerateModule(ModuleCollector &linker, std::string file_name, bool is_library=false) const
Loads the information into a module object.
Definition format.cc:221
Represents a single offset within a section, or an absolute location in memory if the section is null...
Definition location.h:17
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:20
void ReadData(size_t count, void *data)
Read in a sequence of bytes.
Definition reader.cc:30
Represents a possible target or reference frame of a relocation.
Definition target.h:24
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:22
Definition omf.h:2983
reference_type_t
Definition omf.h:2998
@ ReferenceSegmentStart
The starting address of the portion of the segment in the file.
Definition omf.h:3002
@ ReferenceExternal
An external reference.
Definition omf.h:3004
@ ReferenceSegmentBase
The starting address of the segment.
Definition omf.h:3000
Definition omf.h:3036
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:3039
size_t record_count
The number of records belonging to this module.
Definition omf.h:3041
Definition omf.h:2701
Definition omf.h:2733
Intel Relocatable Object Module for the Intel MCS-51.
Definition omf.h:2629
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:6086
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:3048
std::shared_ptr< Record > ReadRecord(Linker::Reader &rd)
Parses and returns an instance of the next record.
Definition omf.cc:5968
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:6060
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:6040
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:6053
static std::shared_ptr< OMF51Format > ReadOMFFile(Linker::Reader &rd)
Parses an OMF51 file.
Definition omf.cc:6028
alignment_t
Definition omf.h:2685
@ AlignFitsBlock
Must fit a 256 byte block.
Definition omf.h:2695
@ AlignFitsPage
Must fit a 256 byte page.
Definition omf.h:2693
@ AlignUnit
Byte or bit alignment for SegmentBit segments.
Definition omf.h:2689
@ AlignPage
Align to a 256 byte page boundary.
Definition omf.h:2697
@ AlignBitAddressable
Must be allocated within the bit addressable part of SegmentData.
Definition omf.h:2691
@ AlignAbsolute
Non-relocatable.
Definition omf.h:2687
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:3051
segment_type_t
Definition omf.h:2669
@ SegmentNone
Not a segment, but a symbol with this segment type is treated as a value.
Definition omf.h:2681
@ SegmentIData
256 B internal RAM that is accessible via indirect addressing, first 128 B shared with SegmentData
Definition omf.h:2677
@ SegmentBit
256 bit address space, part of SegmentData
Definition omf.h:2679
@ SegmentData
256 B internal RAM that is accessible via direct addressing, first 128 B shared with SegmentIData
Definition omf.h:2675
@ SegmentCode
64 KiB read-only memory
Definition omf.h:2671
@ SegmentXData
64 KiB read-write memory
Definition omf.h:2673
Definition omf.h:2594
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:2597
size_t record_count
The number of records belonging to this module.
Definition omf.h:2599
Intel Relocatable Object Module for the Intel 8080.
Definition omf.h:2271
static constexpr segment_id_t CodeSegment
Used for instructions and generally anything loaded into the ROM.
Definition omf.h:2321
static constexpr segment_id_t StackSegment
Used to specify size of segment.
Definition omf.h:2325
uint8_t segment_id_t
Represents one of the 256 segments.
Definition omf.h:2316
static constexpr segment_id_t UnnamedCommonSegment
The unnamed common segment.
Definition omf.h:2333
static constexpr segment_id_t DataSegment
Used for data and generally anything loaded into the RAM.
Definition omf.h:2323
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:2609
static constexpr segment_id_t LastNamedCommonSegment
The last segment number corresponding to a named common segment.
Definition omf.h:2331
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:5317
static constexpr segment_id_t AbsoluteSegment
The absolute segment, all offsets are absolute memory locations.
Definition omf.h:2319
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:5350
static constexpr segment_id_t MemorySegment
Used to specify the highest memory address available.
Definition omf.h:2327
static std::shared_ptr< OMF80Format > ReadOMFFile(Linker::Reader &rd)
Parses an OMF80 file.
Definition omf.cc:5292
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:2606
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:5324
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:5304
std::shared_ptr< Record > ReadRecord(Linker::Reader &rd)
Parses and returns an instance of the next record.
Definition omf.cc:5222
static constexpr segment_id_t FirstNamedCommonSegment
The first segment number corresponding to a named common segment.
Definition omf.h:2329
Represents a single substitution.
Definition omf.h:1840
std::string alias_name
Name used in references.
Definition omf.h:1843
std::string substitute_name
Name it should be substituted with.
Definition omf.h:1845
Record defining a replacement name for symbols, used for ALIAS (included in TIS)
Definition omf.h:1836
std::vector< AliasDefinition > alias_definitions
List of replacements.
Definition omf.h:1852
Represents a single fixup.
Definition omf.h:1690
uint32_t offset
The offset at which the fixup should happen.
Definition omf.h:1693
uint32_t value
The value to be added to the fixup location.
Definition omf.h:1695
A specialized relocation, used for BAKPAT (included in TIS)
Definition omf.h:1686
std::vector< OffsetValuePair > offset_value_pairs
The data for the relocations.
Definition omf.h:1711
location_type_t
Relocation type.
Definition omf.h:1702
SegmentIndex segment
Segment to which the relocations belong.
Definition omf.h:1699
uint8_t type
The type of the relocations.
Definition omf.h:1709
Specification for the group and segment of some reference, and the frame if both are 0.
Definition omf.h:660
std::variant< Location, FrameNumber > location
The actual location of the reference.
Definition omf.h:670
A record that defines a block, used for BLKDEF records (Intel only)
Definition omf.h:1325
block_type_t
Type of the block, if it is a procedure.
Definition omf.h:1337
@ NotProcedure
Block is not a procedure.
Definition omf.h:1339
@ NearProcedure
Block is a near procedure.
Definition omf.h:1341
@ FarProcedure
Block is a far procedure.
Definition omf.h:1343
block_type_t procedure
Whether this block is a procedure, and whether it is a near or far procedure.
Definition omf.h:1346
uint16_t length
Length of the block.
Definition omf.h:1334
TypeIndex type
Type of block or procedure, only used if name != "".
Definition omf.h:1350
std::string name
The name of the block or empty.
Definition omf.h:1330
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:1348
uint16_t offset
Offset to the first byte of the block.
Definition omf.h:1332
BaseSpecification base
The first byte of the segment containing the block.
Definition omf.h:1328
A rich container for indexes referring to a BLKDEF record.
Definition omf.h:541
Definition omf.h:1903
Represents a sequence of data, with optional repeated parts, used by RelocatableDataRecord,...
Definition omf.h:722
std::vector< std::shared_ptr< DataBlock > > Blocks
If the contents are a sequence of blocks (iterated only)
Definition omf.h:728
uint16_t repeat_count
Number of times the data should be appear. Should be 1 for enumerated data.
Definition omf.h:725
uint16_t GetIteratedDataBlockSize(OMF86Format *omf, bool is32bit) const
Gets the size of an encoded iterated record in bytes.
Definition omf.cc:820
void WriteIteratedDataBlock(OMF86Format *omf, ChecksumWriter &wr, bool is32bit) const
Writes the contents of an iterated record into a file.
Definition omf.cc:842
static std::shared_ptr< DataBlock > ReadIteratedDataBlock(OMF86Format *omf, Linker::Reader &rd, bool is32bit)
Parses the contents of an iterated record.
Definition omf.cc:790
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:779
void WriteEnumeratedDataBlock(OMF86Format *omf, ChecksumWriter &wr) const
Writes the contents of an enumerated record into a file.
Definition omf.cc:837
std::variant< Data, Blocks > content
The actual contents of the block, whether iterated or enumerated.
Definition omf.h:733
std::vector< uint8_t > Data
If the contents are a sequence of bytes (either iterated or enumerated)
Definition omf.h:730
uint16_t GetEnumeratedDataBlockSize(OMF86Format *omf) const
Gets the size of an encoded enumerated record in bytes.
Definition omf.cc:815
Record to store debug symbols, used for DEBSYM (Intel only)
Definition omf.h:1367
Record to signal termination of an overloay or block, used for ENDBLK (Intel only)
Definition omf.h:1585
block_type_t
Type of block that is terminated by an EndRecord.
Definition omf.h:1589
block_type_t block_type
Type of block this record terminates.
Definition omf.h:1594
A rich container for indexes referring to symbols in an EXTDEF, LEXTDEF, COMDEF, LCOMDEF,...
Definition omf.h:644
An external name declaration, appearing in an EXTDEF, LEXTDEF, COMDEF, LCOMDEF or CEXTDEF record.
Definition omf.h:573
static uint32_t ReadValue(OMF86Format *omf, Linker::Reader &rd)
Read a length value, for near or far elements.
Definition omf.cc:471
void WriteExternalName(OMF86Format *omf, ChecksumWriter &wr) const
Writes this entry to file.
Definition omf.cc:606
NameIndex name
Name of the symbol.
Definition omf.h:596
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:490
static ExternalName ReadCommonName(OMF86Format *omf, Linker::Reader &rd, bool local)
Parse a COMDEF or LCOMDEF entry.
Definition omf.cc:535
static void WriteValue(OMF86Format *omf, ChecksumWriter &wr, uint32_t length)
Writes a length value, for near or far elements.
Definition omf.cc:502
bool local
Signals if a symbol is local.
Definition omf.h:592
bool name_is_index
Set if name.index contains a valid value, for CEXTDEF entries.
Definition omf.h:594
common_type_t
Type of a common symbol.
Definition omf.h:577
@ NearCommon
Near variable.
Definition omf.h:588
@ FarCommon
Far variable.
Definition omf.h:585
@ SegmentIndexCommon
Borland segment index.
Definition omf.h:582
@ External
Not a common symbol, appears in an EXTDEF, LEXTDEF or CEXTDEF record.
Definition omf.h:579
uint16_t GetExternalNameSize(OMF86Format *omf) const
Returns the number of bytes required to write this entry.
Definition omf.cc:578
static ExternalName ReadExternalName(OMF86Format *omf, Linker::Reader &rd, bool local)
Parse an EXTDEF or LEXTDEF entry.
Definition omf.cc:525
static ExternalName ReadComdatExternalName(OMF86Format *omf, Linker::Reader &rd)
Parse a CEXTDEF entry.
Definition omf.cc:568
A record defining several external or common symbols, used for EXTDEF, LEXTDEF, CEXTDEF,...
Definition omf.h:1280
ExternalIndex first_extdef
Index of first external or common symbol in module.
Definition omf.h:1283
uint16_t extdef_count
Number of external or common symbols defined in this record.
Definition omf.h:1285
uint16_t offset
Offset to value to be relocated, relative to the latest data block.
Definition omf.h:1527
relocation_type_t type
The type of the relocation value.
Definition omf.h:1525
relocation_type_t
Types for the value that needs to be relocated.
Definition omf.h:1499
@ RelocationOffset32_LoaderResolved
A 32-bit loader-resolved value (TIS assignment)
Definition omf.h:1521
@ RelocationHighByte
Most significant 8 bits of a 16-bit value.
Definition omf.h:1509
@ RelocationOffset16
A 16-bit value or the 16-bit offset portion of a far address.
Definition omf.h:1503
@ RelocationSegment
The segment portion of a far address.
Definition omf.h:1505
@ RelocationPointer32
A 32-bit far address, consisting of a 16-bit segment portion and a 16-bit offset portion.
Definition omf.h:1507
@ RelocationOffset32_PharLap
A 32-bit value or the 32-bit offset portion of a far address (Phar Lap assignment)
Definition omf.h:1513
@ RelocationLowByte
Least significant 8 bits of value.
Definition omf.h:1501
@ RelocationOffset16_LoaderResolved
A 16-bit loader-resolved value (TIS assignment)
Definition omf.h:1511
@ RelocationOffset32
A 32-bit value or the 32-bit offset portion of a far address (TIS assignment)
Definition omf.h:1517
@ RelocationPointer48
A 48-bit far address, consisting of a 16-bit segment portion and a 32-bit offset portion (TIS assignm...
Definition omf.h:1519
@ 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:1515
Reference ref
Reference of this relocation.
Definition omf.h:1529
bool segment_relative
Set if segment relative, self relative otherwise.
Definition omf.h:1495
Threads are intermediary storage for relocation targets and frames, this class represents a thread as...
Definition omf.h:1474
unsigned thread_number
The thread number which gets assigned to, a value from 0 to 3.
Definition omf.h:1477
frame_reference_type reference
The frame or target reference.
Definition omf.h:1481
bool frame
Set if this is a frame thread, it is a target thread otherwise.
Definition omf.h:1479
A record containing relocation data, used for FIXUPP.
Definition omf.h:1467
std::vector< std::variant< Thread, Fixup > > fixup_data
Sequence of thread assignments and relocations.
Definition omf.h:1540
Represents the data required for a load-time locatable group (Intel only)
Definition omf.h:1104
Represents the data required for identifying a the segment by the name, class name and overlay name (...
Definition omf.h:1095
Represents a component of the group.
Definition omf.h:1091
static constexpr uint8_t SegmentIndex_type
The type prefix for a segment (the only type defined by TIS)
Definition omf.h:1122
static constexpr uint8_t Absolute_type
The type prefix for the address of the group (Intel only)
Definition omf.h:1114
static constexpr uint8_t SegmentClassOverlayNames_type
The type prefix for segment, class, overlay name triplets (Intel only)
Definition omf.h:1118
static constexpr uint8_t LoadTimeLocatable_type
The type prefix for a load time locatable group (Intel only)
Definition omf.h:1116
uint32_t Absolute
Represents the data required for an absolute group (Intel only)
Definition omf.h:1111
static constexpr uint8_t ExternalIndex_type
The type prefix for the segment of an external symbol (Intel only)
Definition omf.h:1120
std::variant< ExternalIndex, SegmentIndex, SegmentClassOverlayNames, LoadTimeLocatable, Absolute > component
The contents of the component.
Definition omf.h:1125
A record that defines a segment group, used for GRPDEF records.
Definition omf.h:1087
std::vector< Component > components
The components of the group, such as member segments or load address.
Definition omf.h:1138
NameIndex name
Name of the group.
Definition omf.h:1136
A rich container for indexes referring to a GRPDEF record.
Definition omf.h:505
Initialization data for common segments, used for COMDAT (included in TIS)
Definition omf.h:1754
bool iterated
Set if the format of the data is iterated, cleared for enumerated.
Definition omf.h:1759
bool local
Local common segment.
Definition omf.h:1761
bool continued
Set if this record is the continuation of a previous record, cleared if it is a new record.
Definition omf.h:1757
bool code_segment
Set if the data is to be placed in a code segment.
Definition omf.h:1763
Represents a line number, used by LineNumbersRecord and SymbolLineNumbersRecord.
Definition omf.h:703
uint32_t offset
The offset in memory where the line starts.
Definition omf.h:708
uint16_t number
The line number value.
Definition omf.h:706
Stores as debugging data the line number information, used for LINNUM.
Definition omf.h:1302
BaseSpecification base
The first byte of the segment containing the line.
Definition omf.h:1305
std::vector< LineNumber > lines
List of lines.
Definition omf.h:1308
A list of names to be referenced, used for LNAMES and LLNAMES records.
Definition omf.h:940
index_t first_lname
Index of the first name in the module.
Definition omf.h:945
std::vector< std::string > names
List of names (only needed for genering OMF files.
Definition omf.h:943
uint16_t lname_count
Number of names appearing in this record.
Definition omf.h:947
Logical enumerated or iterated data, used for LEDATA and LIDATA.
Definition omf.h:1443
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1450
SegmentIndex segment
Segment that contains this data.
Definition omf.h:1446
uint32_t offset
Offset within segment where the data starts.
Definition omf.h:1448
Terminates a module, used for MODEND.
Definition omf.h:1667
bool main_module
Set if this is a main module.
Definition omf.h:1670
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:1672
A header record, used for THEADR and LHEADR.
Definition omf.h:872
std::string name
The name of the record.
Definition omf.h:875
Represents a single module inside the OMF file.
Definition omf.h:2146
std::vector< std::shared_ptr< BlockDefinitionRecord > > blkdefs
List of blocks declared in the module.
Definition omf.h:2162
std::vector< std::shared_ptr< GroupDefinitionRecord > > grpdefs
List of groups declared in the module.
Definition omf.h:2158
std::vector< ExternalName > extdefs
List of external symbols declared in the module.
Definition omf.h:2166
std::vector< std::string > lnames
List of names declared in the module.
Definition omf.h:2154
std::vector< std::shared_ptr< TypeDefinitionRecord > > typdefs
List of types declared in the module.
Definition omf.h:2160
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:2149
std::vector< std::shared_ptr< OverlayDefinitionRecord > > ovldefs
List of overlays declared in the module.
Definition omf.h:2164
std::vector< std::shared_ptr< SegmentDefinitionRecord > > segdefs
List of segments declared in the module.
Definition omf.h:2156
size_t record_count
The number of records belonging to this module.
Definition omf.h:2151
A rich container for indexes referring to a LNAME/LLNAME declaration.
Definition omf.h:473
A specialized relocation for named common segments, used for NBKPAT (included in TIS)
Definition omf.h:1728
uint8_t type
The type of the relocations.
Definition omf.h:1734
NameIndex name
The name of the common segment to which the relocations belong to.
Definition omf.h:1736
The version of the OMF format, used for VERNUM (included in TIS)
Definition omf.h:1866
std::string version
Textual representation of the version number.
Definition omf.h:1869
A record that defines an overlay, used for OVLDEF records.
Definition omf.h:1557
size_t first_data_record_index
Index of the first overlay data record within the file.
Definition omf.h:1564
std::optional< OverlayIndex > shared_overlay
Must be loaded at the same location as the shared overlay.
Definition omf.h:1566
std::string name
Name of the overlay.
Definition omf.h:1560
uint32_t location
Offset to the first overlay data record within the file.
Definition omf.h:1562
std::optional< OverlayIndex > adjacent_overlay
Must be loaded adjacent to the adjacent overlay.
Definition omf.h:1568
A rich container for indexes referring to a OVLDEF record.
Definition omf.h:557
Physical enumerated or iterated data, used for PEDATA and PIDATA (Intel only)
Definition omf.h:1424
uint32_t address
Physical address where data starts.
Definition omf.h:1427
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1429
A header record for an R-Module, used for RHEADR (not part of TIS OMF)
Definition omf.h:889
uint32_t maximum_dynamic_storage
Maximum memory size to allocate on load.
Definition omf.h:921
uint32_t dynamic_storage
Memory size to allocate on load.
Definition omf.h:919
module_type_t module_type
The type of the module.
Definition omf.h:904
uint16_t group_record_count
Number of group definition records in module.
Definition omf.h:908
module_type_t
Represents the type of the module.
Definition omf.h:896
uint32_t static_size
Total size of LTL segments.
Definition omf.h:915
uint16_t segment_record_count
Number of segment definition records in module.
Definition omf.h:906
uint32_t maximum_static_size
Maximum size needed for all LTL segments.
Definition omf.h:917
uint32_t overlay_record_offset
Offset to the first overlay definition record from the start of the file or 0.
Definition omf.h:912
uint16_t overlay_record_count
Number of overlay definition records in module.
Definition omf.h:910
Module * mod
The module object this record appears in.
Definition omf.h:892
Represents a reference for a relocation.
Definition omf.h:752
std::variant< ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute > frame
The frame for a reference, or a thread number.
Definition omf.h:760
unsigned ThreadNumber
A number between 0 and 3.
Definition omf.h:755
std::variant< ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber > target
The target for a reference, or a thread number.
Definition omf.h:758
uint32_t displacement
Displacement to be added to the value.
Definition omf.h:762
Used to initialize the register.
Definition omf.h:1629
uint16_t offset
An offset, needed for CS:IP and SS:SP.
Definition omf.h:1634
BaseSpecification base
The segment base.
Definition omf.h:1632
A single initialization entry.
Definition omf.h:1612
register_t
Register type that can be initialized.
Definition omf.h:1616
@ DS
The DS segment register, the default data segment.
Definition omf.h:1622
@ ES
The ES segment register.
Definition omf.h:1624
@ CS_IP
The CS and IP register pair, it signifies the starting address as a far pointer.
Definition omf.h:1618
@ SS_SP
The SS and SP register pair, it signifies the initial stack as a far pointer.
Definition omf.h:1620
std::variant< Reference, InitialValue > value
The initial value of the register.
Definition omf.h:1639
register_t reg_id
The register to initialize.
Definition omf.h:1637
Initialization values for registers, used for REGINT (Intel only)
Definition omf.h:1608
std::vector< Register > registers
List of registers to be initialized.
Definition omf.h:1650
Relocatable enumerated or iterated data, used for REDATA and RIDATA (Intel only)
Definition omf.h:1400
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1407
uint16_t offset
Offset within paragraph where data starts.
Definition omf.h:1405
BaseSpecification base
Reference to paragraph that contains this data.
Definition omf.h:1403
Additional data for LTL segment, not part of TIS.
Definition omf.h:1005
A record that defines a segment, used for SEGDEF records.
Definition omf.h:964
combination_t
Describes how two segments of the same name and class name should be combined.
Definition omf.h:1017
@ Combination_Join_High
Merges the two segments at their highest address, adds their sizes (Intel interpretation)
Definition omf.h:1029
@ Combination_Private
Do not combine segments, also known as Private.
Definition omf.h:1019
@ Combination_Stack
Same as Public, but for stack segments.
Definition omf.h:1031
@ Combination_Join_Low
Merges the two segments at their lowest address, adds their sizes (Intel interpretation)
Definition omf.h:1026
@ Combination_Merge_High
Merges the two segments at their highest address, their size is the maximum (Intel interpretation)
Definition omf.h:1036
@ Combination_Merge_Low
Merges the two segments at their lowest address, their size is the maximum (Intel interpretation)
Definition omf.h:1033
@ Combination_Append
Appends the segments, also known as Public.
Definition omf.h:1023
@ Combination_Merge_Highest
Like Combination_Merge_High, but also places the segment above all other segments (not used by TIS)
Definition omf.h:1021
NameIndex class_name
The name of the segment's class (not used for AlignUnnamed)
Definition omf.h:1051
NameIndex segment_name
The name of the segment (not used for AlignUnnamed)
Definition omf.h:1049
combination_t combination
How segments of the same type should be combined.
Definition omf.h:1041
alignment_t alignment
Alignment of segment.
Definition omf.h:995
bool use32
Set if the USE32 directive is used for the segment. The field appears in different places for Phar La...
Definition omf.h:1046
std::variant< Relocatable, Absolute, LoadTimeLocatable > location
Information on where the segment should be placed at runtime.
Definition omf.h:1013
uint64_t segment_length
The length of the segment (maximum 0x100000000)
Definition omf.h:967
std::shared_ptr< Linker::Section > linker_section
The section that gets generated during parsing the OMF file.
Definition omf.h:1068
bool page_resident
Set if the segment should not cross a 256 byte page boundary (only Intel)
Definition omf.h:1044
access_t
Represents an additional field used by Phar Lap.
Definition omf.h:1057
NameIndex overlay_name
The name of the overlay the segment appears in (not used for AlignUnnamed)
Definition omf.h:1053
std::optional< access_t > access
Represents the value of a Phar Lap specific extension word.
Definition omf.h:1065
alignment_t
Alignment type for a segment.
Definition omf.h:970
@ Align16
Relocatable segment, paragraph (16-byte) aligned.
Definition omf.h:978
@ Align256
Relocatable segment, page (256-byte) aligned, as defined by Intel.
Definition omf.h:985
@ AlignLTL16
Load-time locatable or, if not part of a group, paragraph (16-byte) aligned (Intel only)
Definition omf.h:982
@ Align2
Relocatable segment, word (2-byte) aligned.
Definition omf.h:976
@ Align4
Relocatable segment, double word (4-byte) aligned, type 5 as defined by TIS.
Definition omf.h:991
@ Align4096
Relocatable segment, page (4096-byte) aligned, as used by IBM.
Definition omf.h:987
@ AlignUnnamed
Unnamed absolute portion of the memory address space, type 5 as defined by Intel.
Definition omf.h:989
@ AlignAbsolute
Absolute segment, its position in memory is fixed.
Definition omf.h:972
@ AlignPage
Relocatable segment, page aligned, exact size depends on OMF version.
Definition omf.h:980
@ Align1
Relocatable segment, byte aligned.
Definition omf.h:974
uint32_t Absolute
Additional data used for absolute segments, type 0 or 5 if Intel version is used.
Definition omf.h:998
A rich container for indexes referring to a SEGDEF record.
Definition omf.h:489
Represents a symbol definition, used by SymbolDefinitionsRecord and DebugSymbolsRecord.
Definition omf.h:682
std::string name
The name of the symbol.
Definition omf.h:687
bool local
Set to true if the symbol is local.
Definition omf.h:685
uint32_t offset
The offset (value) of the symbol.
Definition omf.h:689
TypeIndex type
The type of the symbol, or 0.
Definition omf.h:691
Line numbers for common segments, used by LINSYM (included in TIS)
Definition omf.h:1812
std::vector< LineNumber > line_numbers
The line numbers.
Definition omf.h:1819
bool continued
Set if this record is the continuation of a previous record, cleared if it is a new record.
Definition omf.h:1815
NameIndex name
The name of the common segment to which the line numbers belong to.
Definition omf.h:1817
A record that defines a symbol, used by PUBDEF, LPUBDEF, LOCSYM.
Definition omf.h:1257
std::vector< SymbolDefinition > symbols
A list of symbols.
Definition omf.h:1263
BaseSpecification base
The first byte of the segment containing the symbol.
Definition omf.h:1260
A single item in a type definition.
Definition omf.h:1165
static constexpr uint8_t RepeatLeaf
Type byte for a repeat leaf leaf.
Definition omf.h:1185
static constexpr uint8_t NumericLeaf24
Type byte for an unsigned 24-bit leaf.
Definition omf.h:1189
bool nice
Set to false if "easy", true if "nice".
Definition omf.h:1168
std::variant< uint32_t, int32_t, std::string, TypeIndex, Null, Repeat > leaf
The actual contents of the leaf.
Definition omf.h:1176
static constexpr uint8_t StringLeaf
Type byte for a string leaf.
Definition omf.h:1181
static constexpr uint8_t NullLeaf
Type byte for a null leaf.
Definition omf.h:1179
static constexpr uint8_t SignedNumericLeaf16
Type byte for an signed 16-bit leaf.
Definition omf.h:1193
static constexpr uint8_t NumericLeaf16
Type byte for an unsigned 16-bit leaf.
Definition omf.h:1187
static constexpr uint8_t SignedNumericLeaf32
Type byte for an signed 32-bit leaf.
Definition omf.h:1195
static constexpr uint8_t IndexLeaf
Type byte for an index leaf, usually a type index.
Definition omf.h:1183
static constexpr uint8_t SignedNumericLeaf8
Type byte for an signed 8-bit leaf.
Definition omf.h:1191
A record that defines a data type, used for TYPDEF records.
Definition omf.h:1161
std::vector< LeafDescriptor > leafs
The parameters of this type.
Definition omf.h:1208
std::string name
The name of this type.
Definition omf.h:1206
A rich container for indexes referring to a TYPDEF record.
Definition omf.h:525
Vendor specific extension to the OMF format, used for VENDEXT (included in TIS)
Definition omf.h:1883
uint16_t vendor_number
Assigned vendor identifier.
Definition omf.h:1886
std::vector< uint8_t > extension
Extension data.
Definition omf.h:1888
Intel Relocatable Object Module format, used by various 16/32-bit DOS based compilers and linkers,...
Definition omf.h:400
static constexpr unsigned int FlagIntel
Flag binary or'ed to certain values to mark Intel interpretation.
Definition omf.h:434
@ MethodGroup
References a group defined in a module, for either targets or frames.
Definition omf.h:446
@ MethodFrame
References a physical paragraph address in a module, for either targets or frames.
Definition omf.h:450
@ MethodAbsolute
No frame is provided, intended for Intel 8089, only the Intel version supports it,...
Definition omf.h:456
@ MethodExternal
References a external symbol declared in a module, for either targets or frames.
Definition omf.h:448
@ MethodSegment
References a segment defined in a module, for either targets or frames.
Definition omf.h:444
@ MethodSource
References the frame of the relocation source, only for frames.
Definition omf.h:452
@ MethodTarget
References the frame of the relocation target, only for frames.
Definition omf.h:454
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:4458
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:2174
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:4451
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:2171
std::shared_ptr< Record > ReadRecord(Linker::Reader &rd)
Parses and returns an instance of the next record.
Definition omf.cc:4257
static constexpr unsigned int FlagPharLap
Flag binary or'ed to certain values to mark Phar Lap interpretation.
Definition omf.h:436
static std::shared_ptr< OMF86Format > ReadOMFFile(Linker::Reader &rd)
Parses an OMF86 file.
Definition omf.cc:4418
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:4430
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:4513
static constexpr unsigned int FlagTIS
Flag binary or'ed to certain values to mark TIS interpretation.
Definition omf.h:438
omf_version_t
Represents the various variants of the OMF file format, some of them are incompatible.
Definition omf.h:412
@ OMF_VERSION_INTEL_40
The original Intel definition, version 4.0 (including any extensions that are compatible)
Definition omf.h:414
@ OMF_VERSION_TIS_11
Version 1.1 produced and consolidated by the Tool Interface Standard.
Definition omf.h:422
@ OMF_VERSION_PHARLAP
Phar Lap's extensions, mostly concerning 32-bit (partly incompatible with later versions)
Definition omf.h:416
@ OMF_VERSION_IBM
Format generated by IBM's tools (partly incompatible with other versions)
Definition omf.h:420
@ OMF_VERSION_MICROSOFT
Format generated by Microsoft's tools (partly incompatible with other versions)
Definition omf.h:418
record_type_t
The recognized record types in an OMF86 file.
Definition omf.h:787
uint16_t FrameNumber
Represents a MethodFrame value.
Definition omf.h:460
omf_version_t omf_version
The variant of the OMF format, needed to handle certain fields.
Definition omf.h:426
Definition omf.h:3503
size_t record_count
The number of records belonging to this module.
Definition omf.h:3508
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:3506
static constexpr uint8_t StringLeaf
Type byte for a string leaf.
Definition omf.h:3318
static constexpr uint8_t SignedNumericLeaf32
Type byte for an signed 32-bit leaf.
Definition omf.h:3316
static constexpr uint8_t NullLeaf
Type byte for a null leaf.
Definition omf.h:3312
static constexpr uint8_t EndOfBranchLeaf
Type byte for an end of branch leaf.
Definition omf.h:3324
static constexpr uint8_t SignedNumericLeaf16
Type byte for an signed 16-bit leaf.
Definition omf.h:3314
static constexpr uint8_t IndexLeaf
Type byte for an index leaf, usually a type index.
Definition omf.h:3320
static constexpr uint8_t RepeatLeaf
Type byte for a repeat leaf leaf.
Definition omf.h:3322
std::vector< LeafDescriptor > leafs
The parameters of this type.
Definition omf.h:3335
Definition omf.h:3189
Intel Relocatable Object Module for the Intel MCS-96.
Definition omf.h:3071
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:6924
std::shared_ptr< Record > ReadRecord(Linker::Reader &rd)
Parses and returns an instance of the next record.
Definition omf.cc:6817
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:6904
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:6950
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:3515
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:6917
static std::shared_ptr< OMF96Format > ReadOMFFile(Linker::Reader &rd)
Parses an OMF96 file.
Definition omf.cc:6892
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:3518
Definition omf.h:3535
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:6981
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition omf.cc:6971
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition omf.cc:6957
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:6962
offset_t ImageSize() const override
Retrieves size of stored data.
Definition omf.cc:6976
A record representing data to be loaded into a segment.
Definition omf.h:242
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:146
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:152
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:137
A record type that has no contents, aside from the type, length and checksum, used for BLKEND.
Definition omf.h:215
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.h:231
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:226
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.h:222
std::vector< std::string > names
List of public symbols for one library module.
Definition omf.h:369
All public symbols of all modules, used for LIBDIC.
Definition omf.h:363
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:340
std::vector< Group > groups
List of public symbols, grouped by library modules.
Definition omf.h:377
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:361
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:350
Library header record, used for LIBHED.
Definition omf.h:293
uint16_t block_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:298
uint16_t module_count
Number of modules contained.
Definition omf.h:296
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:216
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:208
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:222
uint16_t byte_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:300
Library module offsets, used for LIBLOC.
Definition omf.h:333
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:281
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:290
std::vector< Location > locations
List of starting locations, one for each library module.
Definition omf.h:348
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:296
Library module names, used for LIBNAM.
Definition omf.h:315
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:232
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:252
std::vector< std::string > names
List of module names.
Definition omf.h:318
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:241
A record representing line number information.
Definition omf.h:265
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:196
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:190
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:180
Base class representing OMF record types.
Definition omf.h:101
offset_t record_offset
Offset of record within the file.
Definition omf.h:104
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:176
virtual void WriteRecord(FormatType *omf, ModuleType *mod, Linker::Writer &wr) const
Writes the full record.
Definition omf.h:132
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:170
virtual void ResolveReferences(FormatType *omf, ModuleType *mod)
Resolves any fields read from an OMF module, should be called after inpnut.
Definition omf.h:150
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:108
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:142
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:106
An unparsed record type, if the format is not recognized.
Definition omf.h:185
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.h:206
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.h:195
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:201
std::vector< uint8_t > data
Contents of the record, without the type, length and checksum.
Definition omf.h:188
Base class for a family of Intel Relocatable Object formats.
Definition omf.h:71
offset_t file_size
Used to calculate record offsets when generating OMF file.
Definition omf.h:393
static std::shared_ptr< OMFFormat > ReadOMFFile(Linker::Reader &rd)
Attempts to parse an OMF file, whether OMF80, OMF86, OMF51 or OMF96.
Definition omf.cc:60
static index_t ReadIndex(Linker::Reader &rd)
Parses a 1 or 2 byte index value.
Definition omf.cc:25
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:13
static size_t IndexSize(index_t index)
Determines if the index value requires 1 or 2 bytes to store.
Definition omf.cc:48
static void WriteString(ChecksumWriter &wr, std::string text)
Writes a string prefixed with a length byte.
Definition omf.cc:19
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:82
static void WriteIndex(ChecksumWriter &wr, index_t index)
Produces a 1 or 2 byte index value.
Definition omf.cc:35
Type representing the group and segment of some reference.
Definition omf.h:664
Type representing a relocatable segment.
Definition omf.h:1001
Represents a null leaf.
Definition omf.h:1171
Represents a final repeat leaf, meaning that the data in this type should be repeated indefinitely.
Definition omf.h:1173
Represents a MethodAbsolute value.
Definition omf.h:469
Represents a MethodSource value.
Definition omf.h:463
Represents a MethodTarget value.
Definition omf.h:466
Represents a null leaf.
Definition omf.h:3303
Represents a final repeat leaf, meaning that the data in this type should be repeated indefinitely.
Definition omf.h:3305
uint16_t byte_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:341
uint16_t block_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:339