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 std::shared_ptr<Linker::Writer> wr;
25 uint8_t checksum = 0;
26
27 ChecksumWriter(const std::shared_ptr<Linker::Writer>& wr)
28 : Linker::Writer(::LittleEndian), wr(wr)
29 {
30 }
31
33 void WriteData(size_t count, const void * data) override;
34 void Seek(offset_t offset) override;
35 void Skip(relative_offset_t offset) override;
36 void SeekEnd(relative_offset_t offset = 0) override;
37 offset_t Tell() override;
38 };
39
43 class OMFFormat : public virtual Linker::Format
44 {
45 public:
46 virtual ~OMFFormat() = default;
47
49 static std::string ReadString(const std::shared_ptr<Linker::Reader>& rd, size_t max_bytes = size_t(-1));
50
52 static void WriteString(const std::shared_ptr<ChecksumWriter>& wr, std::string text);
53
55 typedef uint16_t index_t;
56
58 static index_t ReadIndex(const std::shared_ptr<Linker::Reader>& rd);
59
61 static void WriteIndex(const std::shared_ptr<ChecksumWriter>& wr, index_t index);
62
64 static size_t IndexSize(index_t index);
65
72 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
73 class Record
74 {
75 public:
77 offset_t record_offset;
79 uint16_t record_length;
81 RecordTypeByte record_type;
82
83 Record(RecordTypeByte record_type = RecordTypeByte(0))
85 {
86 }
87
88 virtual ~Record() = default;
89
90 offset_t RecordEnd() const
91 {
92 return record_offset + record_length + 2;
93 }
94
96 virtual void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) = 0;
97
99 virtual uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const = 0;
100
102 virtual void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const = 0;
103
105 virtual void WriteRecord(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Writer>& wr) const
106 {
107 auto ckswr = std::make_shared<ChecksumWriter>(wr);
108 ckswr->WriteWord(1, record_type);
109 ckswr->WriteWord(2, GetRecordSize(omf, mod));
110 WriteRecordContents(omf, mod, ckswr);
111 wr->WriteWord(1, ckswr->checksum);
112 }
113
115 virtual void CalculateValues(FormatType * omf, ModuleType * mod)
116 {
117 record_offset = omf->file_size;
118 record_length = GetRecordSize(omf, mod);
120 }
121
123 virtual void ResolveReferences(FormatType * omf, ModuleType * mod)
124 {
125 }
126
127 virtual void DumpAddFields(Dumper::Dumper& dump, Dumper::Region& region, const FormatType * omf, const ModuleType * mod, size_t record_index, Dumper::display_option& options) const
128 {
129 }
130
131 virtual void Dump(Dumper::Dumper& dump, const FormatType * omf, const ModuleType * mod, size_t record_index) const
132 {
133 Dumper::Region record_region("Record", record_offset, RecordEnd() + 1 - record_offset, 8);
134 record_region.InsertField(0, "Index", Dumper::DecDisplay::Make(), offset_t(record_index + 1));
135 record_region.AddField("Record type", Dumper::HexDisplay::Make(2), offset_t(record_type));
136 Dumper::display_option options = Dumper::Control;
137 FormatType::DumpAddFields(this, dump, record_region, omf, mod, record_index, options);
138 DumpAddFields(dump, record_region, omf, mod, record_index, options);
139 record_region.Display(dump, options);
140 }
141
143 bool Is32Bit(FormatType * omf) const
144 {
145 return (record_type & 1) != 0;
146 }
147
149 size_t GetOffsetSize(FormatType * omf) const
150 {
151 return Is32Bit(omf) ? 4 : 2;
152 }
153 };
154
156 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
157 class UnknownRecord : public Record<RecordTypeByte, FormatType, ModuleType>
158 {
159 public:
161 std::vector<uint8_t> data;
162
163 UnknownRecord(RecordTypeByte record_type = RecordTypeByte(0))
164 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
165 {
166 }
167
168 void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) override
169 {
171 rd->ReadData(data);
172 }
173
174 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override
175 {
176 return data.size() + 1;
177 }
178
179 void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const override
180 {
181 wr->WriteData(data);
182 }
183 };
184
186 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
187 class EmptyRecord : public Record<RecordTypeByte, FormatType, ModuleType>
188 {
189 public:
190 EmptyRecord(RecordTypeByte record_type = RecordTypeByte(0))
192 {
193 }
194
195 void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) override
196 {
197 }
198
199 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override
200 {
201 return 1;
202 }
203
204 void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const override
205 {
206 }
207 };
208
213 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
214 class ContentRecord : public Record<RecordTypeByte, FormatType, ModuleType>
215 {
216 public:
217 uint8_t segment_id = 0;
218 uint16_t offset = 0;
219 std::vector<uint8_t> data;
220
221 ContentRecord(RecordTypeByte record_type = RecordTypeByte(0))
223 {
224 }
225
226 void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) override;
227 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
228 void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
229 };
230
236 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
237 class LineNumbersRecord : public Record<RecordTypeByte, FormatType, ModuleType>
238 {
239 public:
241 {
242 public:
243 uint16_t line_number = 0;
244 uint16_t offset = 0;
245
246 static LineNumber Read(FormatType * omf, const std::shared_ptr<Linker::Reader>& rd);
247 void Write(FormatType * omf, const std::shared_ptr<ChecksumWriter>& wr) const;
248 };
249
250 uint8_t segment_id = 0;
251 std::vector<LineNumber> line_numbers;
252
253 LineNumbersRecord(RecordTypeByte record_type = RecordTypeByte(0))
254 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
255 {
256 }
257
258 void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) override;
259 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
260 void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
261 };
262
264 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
265 class LibraryHeaderRecord : public Record<RecordTypeByte, FormatType, ModuleType>
266 {
267 public:
269 uint16_t module_count;
271 uint16_t block_number;
273 uint16_t byte_number;
274
275 LibraryHeaderRecord(RecordTypeByte record_type = RecordTypeByte(0))
276 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
277 {
278 }
279
280 void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) override;
281 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
282 void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
283 };
284
286 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
287 class LibraryModuleNamesRecord : public Record<RecordTypeByte, FormatType, ModuleType>
288 {
289 public:
291 std::vector<std::string> names;
292
293 LibraryModuleNamesRecord(RecordTypeByte record_type = RecordTypeByte(0))
294 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
295 {
296 }
297
298 void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) override;
299 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
300 void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
301 };
302
304 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
305 class LibraryModuleLocationsRecord : public Record<RecordTypeByte, FormatType, ModuleType>
306 {
307 public:
308 struct Location
309 {
310 public:
312 uint16_t block_number;
314 uint16_t byte_number;
315
316 static Location Read(const std::shared_ptr<Linker::Reader>& rd);
317 void Write(const std::shared_ptr<ChecksumWriter>& wr) const;
318 };
319
321 std::vector<Location> locations;
322
323 LibraryModuleLocationsRecord(RecordTypeByte record_type = RecordTypeByte(0))
324 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
325 {
326 }
327
328 void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) override;
329 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
330 void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
331 };
332
334 template <typename RecordTypeByte, typename FormatType, typename ModuleType>
335 class LibraryDictionaryRecord : public Record<RecordTypeByte, FormatType, ModuleType>
336 {
337 public:
338 class Group
339 {
340 public:
342 std::vector<std::string> names;
343
344 void Read(const std::shared_ptr<Linker::Reader>& rd);
345 uint16_t Size() const;
346 void Write(const std::shared_ptr<ChecksumWriter>& wr) const;
347 };
348
350 std::vector<Group> groups;
351
352 LibraryDictionaryRecord(RecordTypeByte record_type = RecordTypeByte(0))
353 : Record<RecordTypeByte, FormatType, ModuleType>(record_type)
354 {
355 }
356
357 void ReadRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<Linker::Reader>& rd) override;
358 uint16_t GetRecordSize(FormatType * omf, ModuleType * mod) const override;
359 void WriteRecordContents(FormatType * omf, ModuleType * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
360 };
361
363 static std::shared_ptr<OMFFormat> ReadOMFFile(const std::shared_ptr<Linker::Reader>& rd);
364
366 offset_t file_size = 0;
367 };
368
372 class OMF86Format : public virtual OMFFormat, public virtual Linker::InputFormat
373 {
374 public:
375 class Module;
378
379 /* * * General members * * */
380
381 ::EndianType endian_type = ::LittleEndian;
382
397
400
403 {
404 }
405
407 static constexpr unsigned int FlagIntel = 0x10;
409 static constexpr unsigned int FlagPharLap = 0x20;
411 static constexpr unsigned int FlagTIS = 0x30;
412
414 enum
415 {
430 };
431
433 typedef uint16_t FrameNumber;
434
436 struct UsesSource { };
437
439 struct UsesTarget { };
440
442 struct UsesAbsolute { };
443
446 {
447 public:
448 index_t index;
449 std::string text;
450
451 NameIndex(index_t index = 0)
452 : index(index)
453 {
454 }
455
456 void CalculateValues(OMF86Format * omf, Module * mod);
457 void ResolveReferences(OMF86Format * omf, Module * mod);
458 };
459
462 {
463 public:
464 index_t index;
465 std::shared_ptr<SegmentDefinitionRecord> record;
466
467 SegmentIndex(index_t index = 0)
468 : index(index)
469 {
470 }
471
472 void CalculateValues(OMF86Format * omf, Module * mod);
473 void ResolveReferences(OMF86Format * omf, Module * mod);
474 };
475
478 {
479 public:
480 index_t index;
481 std::shared_ptr<GroupDefinitionRecord> record;
482
483 GroupIndex(index_t index = 0)
484 : index(index)
485 {
486 }
487
488 void CalculateValues(OMF86Format * omf, Module * mod);
489 void ResolveReferences(OMF86Format * omf, Module * mod);
490 };
491
495
498 {
499 public:
500 index_t index;
501 std::shared_ptr<TypeDefinitionRecord> record;
502
503 TypeIndex(index_t index = 0)
504 : index(index)
505 {
506 }
507
508 void CalculateValues(OMF86Format * omf, Module * mod);
509 void ResolveReferences(OMF86Format * omf, Module * mod);
510 };
511
514 {
515 public:
516 index_t index;
517 std::shared_ptr<BlockDefinitionRecord> record;
518
519 BlockIndex(index_t index = 0)
520 : index(index)
521 {
522 }
523
524 void CalculateValues(OMF86Format * omf, Module * mod);
525 void ResolveReferences(OMF86Format * omf, Module * mod);
526 };
527
530 {
531 public:
532 index_t index;
533 std::shared_ptr<OverlayDefinitionRecord> record;
534
535 OverlayIndex(index_t index = 0)
536 : index(index)
537 {
538 }
539
540 void CalculateValues(OMF86Format * omf, Module * mod);
541 void ResolveReferences(OMF86Format * omf, Module * mod);
542 };
543
546 {
547 public:
549 enum common_type_t : uint8_t
550 {
553
556
558 FarCommon = 0x61,
559
562 };
563
565 bool local = false;
567 bool name_is_index = false;
570 TypeIndex type;
571 common_type_t common_type = External;
572
573 union
574 {
575 uint8_t segment_index;
576 struct
577 {
578 uint32_t length;
579 } near;
580 struct
581 {
582 uint32_t number;
583 uint32_t element_size;
584 } far;
585 } value;
586
588 {
589 value.far.number = value.far.element_size = 0;
590 }
591
593 static uint32_t ReadValue(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd);
595 static uint32_t ValueSize(OMF86Format * omf, uint32_t length);
597 static void WriteValue(OMF86Format * omf, const std::shared_ptr<ChecksumWriter>& wr, uint32_t length);
598
600 static ExternalName ReadExternalName(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd, bool local);
602 static ExternalName ReadCommonName(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd, bool local);
604 static ExternalName ReadComdatExternalName(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd);
605
607 uint16_t GetExternalNameSize(OMF86Format * omf) const;
609 void WriteExternalName(OMF86Format * omf, const std::shared_ptr<ChecksumWriter>& wr) const;
610
611 void CalculateValues(OMF86Format * omf, Module * mod);
612 void ResolveReferences(OMF86Format * omf, Module * mod);
613 };
614
617 {
618 public:
619 index_t index;
620 ExternalName name;
621
622 ExternalIndex(index_t index = 0)
623 : index(index)
624 {
625 }
626
627 void CalculateValues(OMF86Format * omf, Module * mod);
628 void ResolveReferences(OMF86Format * omf, Module * mod);
629 };
630
633 {
634 public:
636 struct Location
637 {
638 GroupIndex group;
639 SegmentIndex segment;
640 };
641
643 std::variant<Location, FrameNumber> location;
644
645 void Read(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd);
646 uint16_t Size(OMF86Format * omf) const;
647 void Write(OMF86Format * omf, const std::shared_ptr<ChecksumWriter>& wr) const;
648
649 void CalculateValues(OMF86Format * omf, Module * mod);
650 void ResolveReferences(OMF86Format * omf, Module * mod);
651 };
652
655 {
656 public:
658 bool local;
660 std::string name;
662 uint32_t offset;
665
666 static SymbolDefinition Read(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd, bool local, bool is32bit);
667 uint16_t Size(OMF86Format * omf, bool is32bit) const;
668 void Write(OMF86Format * omf, const std::shared_ptr<ChecksumWriter>& wr, bool is32bit) const;
669
670 void CalculateValues(OMF86Format * omf, Module * mod);
671 void ResolveReferences(OMF86Format * omf, Module * mod);
672 };
673
676 {
677 public:
679 uint16_t number;
681 uint32_t offset;
682
683 static LineNumber Read(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd, bool is32bit);
684 void Write(OMF86Format * omf, const std::shared_ptr<ChecksumWriter>& wr, bool is32bit) const;
685 };
686
695 {
696 public:
698 uint16_t repeat_count;
699
701 typedef std::vector<std::shared_ptr<DataBlock>> Blocks;
703 typedef std::vector<uint8_t> Data;
704
706 std::variant<Data, Blocks> content;
707
709 static std::shared_ptr<DataBlock> ReadEnumeratedDataBlock(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd, uint16_t data_length);
711 uint16_t GetEnumeratedDataBlockSize(OMF86Format * omf) const;
713 void WriteEnumeratedDataBlock(OMF86Format * omf, const std::shared_ptr<ChecksumWriter>& wr) const;
714
716 static std::shared_ptr<DataBlock> ReadIteratedDataBlock(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd, bool is32bit);
718 uint16_t GetIteratedDataBlockSize(OMF86Format * omf, bool is32bit) const;
720 void WriteIteratedDataBlock(OMF86Format * omf, const std::shared_ptr<ChecksumWriter>& wr, bool is32bit) const;
721 };
722
725 {
726 public:
728 typedef unsigned ThreadNumber;
729
731 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber> target = ThreadNumber(0);
733 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute> frame = ThreadNumber(0);
735 uint32_t displacement;
736
737 void Read(OMF86Format * omf, const std::shared_ptr<Linker::Reader>& rd, size_t displacement_size);
738 uint16_t Size(OMF86Format * omf, bool is32bit) const;
739 void Write(OMF86Format * omf, const std::shared_ptr<ChecksumWriter>& wr, bool is32bit) const;
740
741 void CalculateValues(OMF86Format * omf, Module * mod);
742 void ResolveReferences(OMF86Format * omf, Module * mod);
743
744 static Linker::Target GetTarget(SegmentIndex segment_index);
745 static Linker::Target GetTarget(GroupIndex group_index);
746 static Linker::Target GetTarget(ExternalIndex external_index);
747 static Linker::Target GetTarget(FrameNumber frame_number);
748
749 static Linker::Target GetFrame(Linker::Location source, Linker::Target target, SegmentIndex segment_index);
750 static Linker::Target GetFrame(Linker::Location source, Linker::Target target, GroupIndex group_index);
751 static Linker::Target GetFrame(Linker::Location source, Linker::Target target, ExternalIndex external_index);
752 static Linker::Target GetFrame(Linker::Location source, Linker::Target target, FrameNumber frame_number);
756 };
757
759 enum record_type_t : uint8_t
760 {
761 RHEADR = 0x6E, // Intel 4.0
762 REGINT = 0x70, // Intel 4.0
763 REDATA = 0x72, // Intel 4.0
764 RIDATA = 0x74, // Intel 4.0
765 OVLDEF = 0x76, // Intel 4.0
766 ENDREC = 0x78, // Intel 4.0
767 BLKDEF = 0x7A, // Intel 4.0
768 BLKEND = 0x7C, // Intel 4.0
769 DEBSYM = 0x7E, // Intel 4.0
770 THEADR = 0x80,
771 LHEADR = 0x82,
772 PEDATA = 0x84, // Intel 4.0
773 PIDATA = 0x86, // Intel 4.0
774 COMENT = 0x88,
775 MODEND16 = 0x8A,
776 MODEND = 0x8A,
777 MODEND32 = 0x8B, // TIS 1.1
778 EXTDEF = 0x8C,
779 TYPDEF = 0x8E, // Intel 4.0
780 PUBDEF16 = 0x90,
781 PUBDEF = 0x90,
782 PUBDEF32 = 0x91, // TIS 1.1
783 LOCSYM = 0x92, // Intel 4.0
784 LINNUM = 0x94, // Intel 4.0
785 LNAMES = 0x96,
786 SEGDEF = 0x98, // Intel 4.0
787 GRPDEF = 0x9A, // Intel 4.0
788 FIXUPP16 = 0x9C,
789 FIXUPP = 0x9C,
790 FIXUPP32 = 0x9D, // TIS 1.1
791 LEDATA16 = 0xA0,
792 LEDATA = 0xA0,
793 LEDATA32 = 0xA1, // TIS 1.1
794 LIDATA16 = 0xA2,
795 LIDATA = 0xA2,
796 LIDATA32 = 0xA3, // TIS 1.1
797 LIBHED = 0xA4, // Intel 4.0
798 LIBNAM = 0xA6, // Intel 4.0
799 LIBLOC = 0xA8, // Intel 4.0
800 LIBDIC = 0xAA, // Intel 4.0
801 COMDEF = 0xB0, // TIS 1.1, since Microsoft LINK 3.5
802 BAKPAT16 = 0xB2, // TIS 1.1, since Microsoft QuickC 1.0
803 BAKPAT = 0xB2, // TIS 1.1
804 BAKPAT32 = 0xB3, // TIS 1.1
805 LEXTDEF16 = 0xB4, // TIS 1.1, since Microsoft C 5.0
806 LEXTDEF = 0xB4, // TIS 1.1
807 LEXTDEF32 = 0xB5, // TIS 1.1
808 LPUBDEF16 = 0xB6, // TIS 1.1, since Microsoft C 5.0
809 LPUBDEF = 0xB6, // TIS 1.1
810 LPUBDEF32 = 0xB7, // TIS 1.1
811 LCOMDEF = 0xB8, // TIS 1.1, since Microsoft C 5.0
812 CEXTDEF = 0xBC, // TIS 1.1, since Microsoft C 7.0
813 COMDAT16 = 0xC2, // TIS 1.1, since Microsoft C 7.0
814 COMDAT = 0xC2, // TIS 1.1
815 COMDAT32 = 0xC3, // TIS 1.1
816 LINSYM16 = 0xC4, // TIS 1.1, since Microsoft C 7.0
817 LINSYM = 0xC4, // TIS 1.1
818 LINSYM32 = 0xC5, // TIS 1.1
819 ALIAS = 0xC6, // TIS 1.1, since Microsoft LINK 5.13
820 NBKPAT16 = 0xC8, // TIS 1.1, since Microsoft C 7.0
821 NBKPAT = 0xC8, // TIS 1.1
822 NBKPAT32 = 0xC9, // TIS 1.1
823 LLNAMES = 0xCA, // TIS 1.1, since Microsoft C 7.0
824 VERNUM = 0xCC, // TIS 1.1
825 VENDEXT = 0xCE, // TIS 1.1
826 LibraryHeader = 0xF0, // TIS 1.1
827 LibraryEnd = 0xF1, // TIS 1.1
828 };
829
830 static const std::map<offset_t, std::string> RecordTypeNames;
831
839
841 std::shared_ptr<Record> ReadRecord(const std::shared_ptr<Linker::Reader>& rd);
842
845 {
846 public:
848 std::string name;
849
852 {
853 }
854
855 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
856 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
857 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
858 };
859
862 {
863 public:
866
868 enum module_type_t : uint8_t
869 {
870 AbsoluteModule = 0,
871 RelocatableModule = 1,
872 PICModule = 2,
873 LTLModule = 3,
874 };
875
885 uint32_t overlay_record_offset; // TODO: resolve record index
886
888 uint32_t static_size;
895
898 {
899 }
900
903 {
904 }
905
906 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
907 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
908 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
909 };
910
913 {
914 public:
916 std::vector<std::string> names;
920 uint16_t lname_count = 0;
921
924 {
925 }
926
927 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
928 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
929 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
930
931 void CalculateValues(OMF86Format * omf, Module * mod) override;
932 void ResolveReferences(OMF86Format * omf, Module * mod) override;
933 };
934
936 class SegmentDefinitionRecord : public Record, public std::enable_shared_from_this<SegmentDefinitionRecord>
937 {
938 public:
966
969
971 typedef uint32_t Absolute;
972
974 struct Relocatable { };
975
978 {
979 public:
980 bool group_member;
981 uint16_t maximum_segment_length;
982 uint16_t group_offset;
983 };
984
986 std::variant<Relocatable, Absolute, LoadTimeLocatable> location = Relocatable{};
987
989 enum combination_t : uint8_t
990 {
997 Combination_Public = Combination_Append,
1000 Combination_Public4 = FlagTIS | 4,
1007 Combination_Common = FlagTIS | 6,
1010 Combination_Public7 = FlagTIS | 7,
1011 };
1012
1015
1017 bool page_resident = false; // Intel
1019 bool use32 = false;
1020
1027
1029 enum access_t : uint8_t
1030 {
1031 AccessReadOnly = 0,
1032 AccessExecuteOnly = 1,
1033 AccessExecuteRead = 2,
1034 AccessReadWrite = 3,
1035 };
1036
1038 std::optional<access_t> access;
1039
1041 std::shared_ptr<Linker::Section> linker_section = nullptr;
1042
1045 {
1046 }
1047
1048 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1049 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1050 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1051
1052 void CalculateValues(OMF86Format * omf, Module * mod) override;
1053 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1054
1055 std::shared_ptr<Linker::Section> GenerateLinkerSection();
1056 };
1057
1059 class GroupDefinitionRecord : public Record, public std::enable_shared_from_this<GroupDefinitionRecord>
1060 {
1061 public:
1064 {
1065 public:
1068 {
1069 public:
1070 NameIndex segment_name;
1071 NameIndex class_name;
1072 NameIndex overlay_name;
1073 };
1074
1077 {
1078 public:
1079 uint32_t maximum_group_length;
1080 uint32_t group_length;
1081 };
1082
1084 typedef uint32_t Absolute;
1085
1087 static constexpr uint8_t Absolute_type = 0xFA;
1089 static constexpr uint8_t LoadTimeLocatable_type = 0xFB;
1091 static constexpr uint8_t SegmentClassOverlayNames_type = 0xFD;
1093 static constexpr uint8_t ExternalIndex_type = 0xFE;
1095 static constexpr uint8_t SegmentIndex_type = 0xFF;
1096
1098 std::variant<ExternalIndex, SegmentIndex, SegmentClassOverlayNames, LoadTimeLocatable, Absolute> component = ExternalIndex();
1099
1100 static Component Read(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
1101 uint16_t Size(OMF86Format * omf, Module * mod) const;
1102 void Write(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
1103
1104 void CalculateValues(OMF86Format * omf, Module * mod);
1105 void ResolveReferences(OMF86Format * omf, Module * mod);
1106 };
1107
1111 std::vector<Component> components;
1112
1115 {
1116 }
1117
1118 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1119 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1120 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1121
1122 void CalculateValues(OMF86Format * omf, Module * mod) override;
1123 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1124 };
1125
1133 class TypeDefinitionRecord : public Record, public std::enable_shared_from_this<TypeDefinitionRecord>
1134 {
1135 public:
1138 {
1139 public:
1141 bool nice;
1142
1144 struct Null { };
1146 struct Repeat { };
1147
1149 std::variant<uint32_t, int32_t, std::string, TypeIndex, Null, Repeat> leaf = Null();
1150
1152 static constexpr uint8_t NullLeaf = 0x80;
1154 static constexpr uint8_t StringLeaf = 0x82;
1156 static constexpr uint8_t IndexLeaf = 0x83;
1158 static constexpr uint8_t RepeatLeaf = 0x85;
1160 static constexpr uint8_t NumericLeaf16 = 0x81;
1162 static constexpr uint8_t NumericLeaf24 = 0x84;
1164 static constexpr uint8_t SignedNumericLeaf8 = 0x86;
1166 static constexpr uint8_t SignedNumericLeaf16 = 0x87;
1168 static constexpr uint8_t SignedNumericLeaf32 = 0x88;
1169
1170 static LeafDescriptor Read(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
1171 uint16_t Size(OMF86Format * omf, Module * mod) const;
1172 void Write(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
1173
1174 void CalculateValues(OMF86Format * omf, Module * mod);
1175 void ResolveReferences(OMF86Format * omf, Module * mod);
1176 };
1177
1179 std::string name;
1181 std::vector<LeafDescriptor> leafs;
1182
1183 enum
1184 {
1185 Far = 0x61, // Far(Array(...)) - Microsoft
1186 Near = 0x62, // Near(Array | Structure | Scalar, length in bits) - Microsoft
1187 Interrupt = 0x63,
1188 File = 0x64,
1189 Packed = 0x65,
1190 Unpacked = 0x66,
1191 Set = 0x67,
1192 Chameleon = 0x69,
1193 Boolean = 0x6A,
1194 True = 0x6B,
1195 False = 0x6C,
1196 Char = 0x6D,
1197 Integer = 0x6E,
1198 Const = 0x6F,
1199 Label = 0x71, // Label(nil, Short | Long)
1200 Long = 0x72,
1201 Short = 0x73,
1202 Procedure = 0x74, // Procedure(nil, @type, Short | Long, parameter count, @List(...))
1203 Parameter = 0x75, // Parameter(@type)
1204 Dimension = 0x76,
1205 Array = 0x77, // Array(length, @type)
1206 Structure = 0x79, // Structure(length, component count, @List(...))
1207 Pointer = 0x7A,
1208 Scalar = 0x7B, // Scalar(length, UnsignedInteger | SignedInteger | Real | @Pointer)
1209 UnsignedInteger = 0x7C,
1210 SignedInteger = 0x7D,
1211 Real = 0x7E,
1212 List = 0x7F, // List(...)
1213 };
1214
1217 {
1218 }
1219
1220 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1221 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1222 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1223
1224 void CalculateValues(OMF86Format * omf, Module * mod) override;
1225 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1226 };
1227
1230 {
1231 public:
1234
1236 std::vector<SymbolDefinition> symbols;
1237
1240 {
1241 }
1242
1243 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1244 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1245 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1246
1247 void CalculateValues(OMF86Format * omf, Module * mod) override;
1248 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1249 };
1250
1253 {
1254 public:
1258 uint16_t extdef_count = 0;
1259
1262 {
1263 }
1264
1265 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1266 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1267 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1268
1269 void CalculateValues(OMF86Format * omf, Module * mod) override;
1270 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1271 };
1272
1275 {
1276 public:
1279
1281 std::vector<LineNumber> lines;
1282
1285 {
1286 }
1287
1288 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1289 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1290 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1291
1292 void CalculateValues(OMF86Format * omf, Module * mod) override;
1293 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1294 };
1295
1297 class BlockDefinitionRecord : public Record, public std::enable_shared_from_this<BlockDefinitionRecord>
1298 {
1299 public:
1303 std::string name;
1305 uint16_t offset;
1307 uint16_t length;
1309 enum block_type_t : uint8_t
1310 {
1317 };
1321 uint16_t return_address_offset; // only for procedures
1324
1327 {
1328 }
1329
1330 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1331 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1332 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1333
1334 void CalculateValues(OMF86Format * omf, Module * mod) override;
1335 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1336 };
1337
1340 {
1341 public:
1342 enum frame_type_t : uint8_t
1343 {
1344 Location = 0x00,
1345 Frame16 = 0x80,
1346 Frame32 = 0xC0,
1347 };
1348 frame_type_t frame_type;
1349
1350 static constexpr uint8_t SymbolBaseMethod = 0x00;
1351 static constexpr uint8_t ExternalMethod = 0x01;
1352 static constexpr uint8_t BlockMethod = 0x02;
1353
1354 std::variant<BaseSpecification, ExternalIndex, BlockIndex> base = ExternalIndex();
1355
1356 std::vector<SymbolDefinition> names;
1357
1360 {
1361 }
1362
1363 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1364 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1365 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1366
1367 void CalculateValues(OMF86Format * omf, Module * mod) override;
1368 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1369 };
1370
1373 {
1374 public:
1378 uint16_t offset;
1380 std::shared_ptr<DataBlock> data;
1381
1384 {
1385 }
1386
1387 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1388 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1389 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1390
1391 void CalculateValues(OMF86Format * omf, Module * mod) override;
1392 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1393 };
1394
1397 {
1398 public:
1400 uint32_t address;
1402 std::shared_ptr<DataBlock> data;
1403
1406 {
1407 }
1408
1409 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1410 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1411 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1412 };
1413
1416 {
1417 public:
1421 uint32_t offset;
1423 std::shared_ptr<DataBlock> data;
1424
1427 {
1428 }
1429
1430 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1431 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1432 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1433
1434 void CalculateValues(OMF86Format * omf, Module * mod) override;
1435 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1436 };
1437
1439 class FixupRecord : public Record
1440 {
1441 public:
1442 typedef std::variant<SegmentIndex, GroupIndex, ExternalIndex, FrameNumber> target_reference_type;
1443 typedef std::variant<SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute> frame_reference_type;
1444
1447 {
1448 public:
1452 bool frame;
1454 frame_reference_type reference = FrameNumber(0);
1455
1456 static Thread Read(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint8_t leading_data_byte);
1457 uint16_t Size(OMF86Format * omf, Module * mod) const;
1458 void Write(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
1459
1460 void CalculateValues(OMF86Format * omf, Module * mod);
1461 void ResolveReferences(OMF86Format * omf, Module * mod);
1462 };
1463
1464 class Fixup
1465 {
1466 public:
1469
1496
1500 uint16_t offset;
1503
1504 static Fixup Read(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint8_t leading_data_byte, bool is32bit);
1505 uint16_t Size(OMF86Format * omf, Module * mod, bool is32bit) const;
1506 void Write(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr, bool is32bit) const;
1507
1508 void CalculateValues(OMF86Format * omf, Module * mod);
1509 void ResolveReferences(OMF86Format * omf, Module * mod);
1510 };
1511
1513 std::vector<std::variant<Thread, Fixup>> fixup_data;
1514
1517 {
1518 }
1519
1520 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1521 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1522 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1523
1524 void CalculateValues(OMF86Format * omf, Module * mod) override;
1525 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1526 };
1527
1529 class OverlayDefinitionRecord : public Record, public std::enable_shared_from_this<OverlayDefinitionRecord>
1530 {
1531 public:
1533 std::string name;
1535 uint32_t location;
1539 std::optional<OverlayIndex> shared_overlay;
1541 std::optional<OverlayIndex> adjacent_overlay;
1542
1545 {
1546 }
1547
1548 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1549 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1550 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1551
1552 void CalculateValues(OMF86Format * omf, Module * mod) override;
1553 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1554 };
1555
1557 class EndRecord : public Record
1558 {
1559 public:
1561 enum block_type_t : uint8_t
1562 {
1563 Overlay = 0,
1564 Block = 1,
1565 };
1568
1571 {
1572 }
1573
1574 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1575 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1576 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1577 };
1578
1581 {
1582 public:
1585 {
1586 public:
1588 enum register_t : uint8_t
1589 {
1598 };
1599
1602 {
1603 public:
1607 uint16_t offset;
1608 };
1612 std::variant<Reference, InitialValue> value = Reference();
1613
1614 static Register Read(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
1615 uint16_t Size(OMF86Format * omf, Module * mod) const;
1616 void Write(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
1617
1618 void CalculateValues(OMF86Format * omf, Module * mod);
1619 void ResolveReferences(OMF86Format * omf, Module * mod);
1620 };
1621
1623 std::vector<Register> registers;
1624
1627 {
1628 }
1629
1630 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1631 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1632 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1633
1634 void CalculateValues(OMF86Format * omf, Module * mod) override;
1635 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1636 };
1637
1640 {
1641 public:
1645 std::optional<std::variant<Reference, std::tuple<uint16_t, uint16_t>>> start_address;
1646
1649 {
1650 }
1651
1652 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1653 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1654 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1655 };
1656
1659 {
1660 public:
1663 {
1664 public:
1666 uint32_t offset;
1668 uint32_t value;
1669 };
1670
1674 enum location_type_t : uint8_t
1675 {
1676 Location8bit = 0,
1677 Location16bit = 1,
1678 Location32bit = 2,
1679 Location32bit_IBM = 9,
1680 };
1682 uint8_t type;
1684 std::vector<OffsetValuePair> offset_value_pairs;
1685
1688 {
1689 }
1690
1691 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1692 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1693 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1694
1695 void CalculateValues(OMF86Format * omf, Module * mod) override;
1696 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1697 };
1698
1701 {
1702 public:
1705
1707 uint8_t type;
1710 std::vector<OffsetValuePair> offset_value_pairs;
1711
1714 {
1715 }
1716
1717 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1718 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1719 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1720
1721 void CalculateValues(OMF86Format * omf, Module * mod) override;
1722 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1723 };
1724
1727 {
1728 public:
1734 bool local;
1737
1738 // TODO: document further
1739
1740 enum selection_criterion_t : uint8_t
1741 {
1742 SelectNoMatch = 0x00,
1743 SelectPickAny = 0x10,
1744 SelectSameSize = 0x20,
1745 SelectExactMatch = 0x30,
1746 };
1747 static constexpr uint8_t SelectionCriterionMask = 0xF0;
1748 selection_criterion_t selection_criterion;
1749
1750 enum allocation_type_t : uint8_t
1751 {
1752 AllocateExplicit = 0x00,
1753 AllocateFarCode = 0x01,
1754 AllocateFarData = 0x02,
1755 AllocateCode32 = 0x03,
1756 AllocateData32 = 0x04,
1757 };
1758 static constexpr uint8_t AllocationTypeMask = 0x0F;
1759 allocation_type_t allocation_type;
1760
1763
1764 uint32_t offset;
1765 TypeIndex type;
1766 BaseSpecification base;
1767 NameIndex name;
1768 std::shared_ptr<DataBlock> data;
1769
1770 InitializedCommunalDataRecord(record_type_t record_type = record_type_t(0))
1771 : Record(record_type)
1772 {
1773 }
1774
1775 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1776 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1777 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1778
1779 void CalculateValues(OMF86Format * omf, Module * mod) override;
1780 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1781 };
1782
1785 {
1786 public:
1792 std::vector<LineNumber> line_numbers;
1793
1796 {
1797 }
1798
1799 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1800 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1801 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1802
1803 void CalculateValues(OMF86Format * omf, Module * mod) override;
1804 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1805 };
1806
1809 {
1810 public:
1813 {
1814 public:
1816 std::string alias_name;
1818 std::string substitute_name;
1819
1820 static AliasDefinition Read(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
1821 uint16_t Size(OMF86Format * omf, Module * mod) const;
1822 void Write(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
1823 };
1825 std::vector<AliasDefinition> alias_definitions;
1826
1829 {
1830 }
1831
1832 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1833 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1834 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1835 };
1836
1839 {
1840 public:
1842 std::string version;
1843
1846 {
1847 }
1848
1849 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1850 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1851 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1852 };
1853
1856 {
1857 public:
1861 std::vector<uint8_t> extension;
1862
1865 {
1866 }
1867
1868 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1869 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1870 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1871 };
1872
1873 // TODO: document
1874
1875 class CommentRecord : public Record
1876 {
1877 public:
1878 bool no_purge;
1879 bool no_list;
1880 enum comment_class_t : uint8_t
1881 {
1882 Translator = 0x00,
1883 IntelCopyright = 0x01,
1884 LibrarySpecifier = 0x81,
1885 MSDOSVersion = 0x9C,
1886 MemoryModel = 0x9D,
1887 DOSSEG = 0x9E,
1888 DefaultLibrarySearchName = 0x9F,
1889 OMFExtension = 0xA0,
1890 NewOMFExtension = 0xA1,
1891 LinkPassSeparator = 0xA2,
1892 LIBMOD = 0xA3,
1893 EXESTR = 0xA4,
1894 INCERR = 0xA6,
1895 NOPAD = 0xA7,
1896 WKEXT = 0xA8,
1897 LZEXT = 0xA9,
1898 Comment = 0xDA,
1899 Compiler = 0xDB,
1900 Date = 0xDC,
1901 TimeStamp = 0xDD,
1902 User = 0xDF,
1903 DependencyFile = 0xE9,
1904 CommandLine = 0xFF,
1905 };
1906 comment_class_t comment_class;
1907
1909 : Record(COMENT)
1910 {
1911 }
1912
1913 CommentRecord(comment_class_t comment_class = comment_class_t(0))
1914 : Record(COMENT), comment_class(comment_class)
1915 {
1916 }
1917
1918 virtual void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) = 0;
1919 virtual uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const = 0;
1920 virtual void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const = 0;
1921
1922 static std::shared_ptr<CommentRecord> ReadCommentRecord(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t record_length);
1923 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
1924 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
1925 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1926
1928 class EmptyCommentRecord;
1929 class TextCommentRecord;
1930 };
1931
1933 {
1934 public:
1935 std::vector<SegmentIndex> segments;
1936
1938 : CommentRecord(NOPAD)
1939 {
1940 }
1941
1942 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
1943 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
1944 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1945
1946 void CalculateValues(OMF86Format * omf, Module * mod) override;
1947 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1948 };
1949
1951 {
1952 public:
1954 {
1955 public:
1956 ExternalIndex definition;
1957 ExternalIndex default_resolution;
1958
1959 static ExternalAssociation Read(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
1960 uint16_t Size(OMF86Format * omf, Module * mod) const;
1961 void Write(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
1962
1963 void CalculateValues(OMF86Format * omf, Module * mod);
1964 void ResolveReferences(OMF86Format * omf, Module * mod);
1965 };
1966
1967 std::vector<ExternalAssociation> associations;
1968
1969 ExternalAssociationRecord(comment_class_t comment_class = comment_class_t(0))
1970 : CommentRecord(comment_class)
1971 {
1972 }
1973
1974 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
1975 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
1976 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
1977
1978 void CalculateValues(OMF86Format * omf, Module * mod) override;
1979 void ResolveReferences(OMF86Format * omf, Module * mod) override;
1980 };
1981
1983 {
1984 public:
1985 enum extension_type_t : uint8_t
1986 {
1987 IMPDEF = 0x01,
1988 EXPDEF = 0x02,
1989 INCDEF = 0x03,
1990 ProtectedModeLibrary = 0x04,
1991 LNKDIR = 0x05,
1992 BigEndian = 0x06,
1993 PRECOMP = 0x07,
1994 };
1995 extension_type_t subtype;
1996
1997 OMFExtensionRecord(extension_type_t subtype = extension_type_t(0))
1998 : CommentRecord(OMFExtension), subtype(subtype)
1999 {
2000 }
2001
2004 };
2005
2007 {
2008 public:
2009 std::string internal_name;
2010 std::string module_name;
2011 std::variant<std::string, uint16_t> entry_ident;
2012
2014 : OMFExtensionRecord(IMPDEF)
2015 {
2016 }
2017
2018 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2019 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2020 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2021 };
2022
2024 {
2025 public:
2026 bool resident_name;
2027 bool no_data;
2028 uint8_t parameter_count;
2029 std::string exported_name;
2030 std::string internal_name;
2031 std::optional<uint16_t> ordinal;
2032
2034 : OMFExtensionRecord(EXPDEF)
2035 {
2036 }
2037
2038 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2039 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2040 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2041 };
2042
2044 {
2045 public:
2046 uint16_t extdef_delta;
2047 uint16_t linnum_delta;
2048 uint16_t padding_byte_count;
2049
2051 : OMFExtensionRecord(INCDEF)
2052 {
2053 }
2054
2055 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2056 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2057 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2058 };
2059
2061 {
2062 public:
2063 bool new_executable;
2064 bool omit_codeview_publics;
2065 bool run_mpc;
2066 uint8_t pseudocode_version;
2067 uint8_t codeview_version;
2068
2069 static constexpr uint8_t FlagNewExecutable = 0x01;
2070 static constexpr uint8_t FlagOmitCodeViewPublics = 0x02;
2071 static constexpr uint8_t FlagRunMPC = 0x04;
2072
2074 : OMFExtensionRecord(LNKDIR)
2075 {
2076 }
2077
2078 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2079 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2080 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2081 };
2082
2084 {
2085 public:
2086 uint32_t dictionary_offset;
2087 uint16_t dictionary_size;
2088 bool case_sensitive;
2089
2092 {
2093 }
2094
2095 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2096 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
2097 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2098
2099 void WriteRecord(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Writer>& wr) const override;
2100 };
2101
2103 {
2104 public:
2107 {
2108 }
2109
2110 void ReadRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2111 uint16_t GetRecordSize(OMF86Format * omf, Module * mod) const override;
2112 void WriteRecordContents(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2113
2114 void WriteRecord(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Writer>& wr) const override;
2115 };
2116
2119 {
2120 public:
2122 size_t first_record = 0;
2124 size_t record_count = 0;
2125
2127 std::vector<std::string> lnames;
2129 std::vector<std::shared_ptr<SegmentDefinitionRecord>> segdefs;
2131 std::vector<std::shared_ptr<GroupDefinitionRecord>> grpdefs;
2133 std::vector<std::shared_ptr<TypeDefinitionRecord>> typdefs;
2135 std::vector<std::shared_ptr<BlockDefinitionRecord>> blkdefs;
2137 std::vector<std::shared_ptr<OverlayDefinitionRecord>> ovldefs;
2139 std::vector<ExternalName> extdefs; // also includes comdefs and cextdefs
2140 // TODO: CalculateValue/etc. for ExternalName
2141 };
2142
2144 std::vector<std::shared_ptr<Record>> records;
2145
2147 std::vector<Module> modules;
2148
2149 // TIS library fields
2150 uint16_t page_size;
2151
2153 static std::shared_ptr<OMF86Format> ReadOMFFile(const std::shared_ptr<Linker::Reader>& rd);
2154
2155 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);
2156
2157 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
2159 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
2160 void Dump(Dumper::Dumper& dump) const override;
2161
2162 static uint32_t FillSectionData(std::shared_ptr<Linker::Section> section, uint32_t offset, std::shared_ptr<OMF86Format::DataBlock> data);
2163
2165 void GenerateModule(Linker::Module& module) const override;
2166 /* TODO */
2167 };
2168
2170 {
2171 public:
2172 std::vector<uint8_t> data;
2173
2174 GenericCommentRecord(comment_class_t comment_class = comment_class_t(0))
2175 : CommentRecord(comment_class)
2176 {
2177 }
2178
2179 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2180 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2181 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2182 };
2183
2185 {
2186 public:
2187 EmptyCommentRecord(comment_class_t comment_class = comment_class_t(0))
2188 : CommentRecord(comment_class)
2189 {
2190 }
2191
2192 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2193 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2194 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2195 };
2196
2198 {
2199 public:
2200 std::string name;
2201
2202 TextCommentRecord(comment_class_t comment_class = comment_class_t(0))
2203 : CommentRecord(comment_class)
2204 {
2205 }
2206
2207 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2208 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2209 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2210 };
2211
2213 {
2214 public:
2215 std::vector<uint8_t> data;
2216
2217 GenericOMFExtensionRecord(extension_type_t extension_type = extension_type_t(0))
2218 : OMFExtensionRecord(extension_type)
2219 {
2220 }
2221
2222 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2223 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2224 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2225 };
2226
2228 {
2229 public:
2230 EmptyOMFExtensionRecord(extension_type_t extension_type = extension_type_t(0))
2231 : OMFExtensionRecord(extension_type)
2232 {
2233 }
2234
2235 void ReadComment(OMF86Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd, uint16_t comment_length) override;
2236 uint16_t GetCommentSize(OMF86Format * omf, Module * mod) const override;
2237 void WriteComment(OMF86Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2238 };
2239
2243 class OMF80Format : public virtual OMFFormat, public virtual Linker::InputFormat
2244 {
2245 public:
2246 class Module;
2247
2248 enum record_type_t : uint8_t
2249 {
2250 ModuleHeader = 0x02,
2251 ModuleEnd = 0x04,
2252 Content = 0x06,
2253 LineNumbers = 0x08,
2254 EndOfFile = 0x0E,
2255 ModuleAncestor = 0x10,
2256 LocalSymbols = 0x12,
2257 PublicDefinitions = 0x16,
2258 ExternalDefinitions = 0x18,
2259 ExternalReferences = 0x20,
2260 Relocations = 0x22,
2261 InterSegmentReferences = 0x24,
2262 LibraryModuleLocations = 0x26,
2263 LibraryModuleNames = 0x28,
2264 LibraryDictionary = 0x2A,
2265 LibraryHeader = 0x2C,
2266 NamedCommonDefinitions = 0x2E,
2267 };
2268
2269 static const std::map<offset_t, std::string> RecordTypeNames;
2270
2280
2282 std::shared_ptr<Record> ReadRecord(const std::shared_ptr<Linker::Reader>& rd);
2283
2289 typedef uint8_t segment_id_t;
2290
2292 static constexpr segment_id_t AbsoluteSegment = 0;
2294 static constexpr segment_id_t CodeSegment = 1;
2296 static constexpr segment_id_t DataSegment = 2;
2298 static constexpr segment_id_t StackSegment = 3;
2300 static constexpr segment_id_t MemorySegment = 4;
2304 static constexpr segment_id_t LastNamedCommonSegment = 254;
2306 static constexpr segment_id_t UnnamedCommonSegment = 255;
2307
2308 // TODO: document
2309
2310 enum alignment_t : uint8_t
2311 {
2312 // page is 256 bytes
2313 AlignFitsPage = 1,
2314 AlignPage = 2,
2315 AlignByte = 3,
2316 };
2317
2319 {
2320 public:
2321 uint16_t index;
2322 std::string external_name;
2323
2324 void CalculateValues(OMF80Format * omf, Module * mod);
2325 void ResolveReferences(OMF80Format * omf, Module * mod);
2326 };
2327
2329 {
2330 public:
2332 {
2333 public:
2334 segment_id_t segment_id = 0;
2335 uint16_t length = 0;
2336 alignment_t alignment = AlignByte;
2337
2338 static SegmentDefinition Read(OMF80Format * omf, const std::shared_ptr<Linker::Reader>& rd);
2339 void Write(OMF80Format * omf, const std::shared_ptr<ChecksumWriter>& wr) const;
2340 };
2341
2342 std::string name;
2343 std::vector<SegmentDefinition> segment_definitions;
2344
2345 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
2347 {
2348 }
2349
2350 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2351 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2352 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2353
2354 void CalculateValues(OMF80Format * omf, Module * mod) override;
2355 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2356 };
2357
2359 {
2360 public:
2361 bool main;
2362 segment_id_t start_segment_id;
2363 uint16_t start_offset;
2364 std::vector<uint8_t> info;
2365
2366 ModuleEndRecord(record_type_t record_type = record_type_t(0))
2368 {
2369 }
2370
2371 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2372 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2373 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2374
2375 void CalculateValues(OMF80Format * omf, Module * mod) override;
2376 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2377 };
2378
2380 {
2381 public:
2383 {
2384 public:
2385 segment_id_t segment_id;
2386 std::string common_name;
2387
2388 static NamedCommonDefinition ReadNamedCommonDefinition(OMF80Format * omf, const std::shared_ptr<Linker::Reader>& rd);
2389 uint16_t GetNamedCommonDefinitionSize(OMF80Format * omf) const;
2390 void WriteNamedCommonDefinition(OMF80Format * omf, const std::shared_ptr<ChecksumWriter>& wr) const;
2391 };
2392
2393 std::vector<NamedCommonDefinition> named_common_definitions;
2394
2395 NamedCommonDefinitionsRecord(record_type_t record_type = record_type_t(0))
2397 {
2398 }
2399
2400 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2401 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2402 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2403
2404 void CalculateValues(OMF80Format * omf, Module * mod) override;
2405 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2406 };
2407
2409 {
2410 public:
2411 Module * mod;
2412
2413 std::vector<std::string> external_names; // only used for generation
2414 uint16_t first_external_name;
2415 uint16_t external_name_count;
2416
2417 ExternalDefinitionsRecord(record_type_t record_type = record_type_t(0))
2419 {
2420 }
2421
2422 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2423 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2424 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2425
2426 void CalculateValues(OMF80Format * omf, Module * mod) override;
2427 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2428 };
2429
2431 {
2432 public:
2434 {
2435 public:
2436 uint16_t offset;
2437 std::string name;
2438
2439 static SymbolDefinition Read(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
2440 uint16_t Size(OMF80Format * omf, Module * mod) const;
2441 void Write(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
2442 };
2443
2444 uint8_t segment_id;
2445 std::vector<SymbolDefinition> public_definitions;
2446
2447 SymbolDefinitionsRecord(record_type_t record_type = record_type_t(0))
2449 {
2450 }
2451
2452 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2453 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2454 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2455
2456 void CalculateValues(OMF80Format * omf, Module * mod) override;
2457 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2458 };
2459
2460 enum relocation_type_t : uint8_t
2461 {
2462 RelocationLowByte = 1,
2463 RelocationHighByte = 2,
2464 RelocationWord = 3,
2465 };
2466
2468 {
2469 public:
2470 relocation_type_t relocation_type;
2471 std::vector<uint16_t> offsets;
2472
2473 RelocationsRecord(record_type_t record_type = record_type_t(0))
2475 {
2476 }
2477
2478 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2479 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2480 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2481
2482 void CalculateValues(OMF80Format * omf, Module * mod) override;
2483 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2484 };
2485
2487 {
2488 public:
2489 segment_id_t segment_id;
2490
2491 InterSegmentReferencesRecord(record_type_t record_type = record_type_t(0))
2493 {
2494 }
2495
2496 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2497 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2498 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2499
2500 void CalculateValues(OMF80Format * omf, Module * mod) override;
2501 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2502 };
2503
2505 {
2506 public:
2508 {
2509 public:
2510 ExternalNameIndex name_index;
2511 uint16_t offset;
2512 };
2513
2514 relocation_type_t relocation_type;
2515 std::vector<ExternalReference> external_references;
2516
2517 ExternalReferencesRecord(record_type_t record_type = record_type_t(0))
2519 {
2520 }
2521
2522 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2523 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2524 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2525
2526 void CalculateValues(OMF80Format * omf, Module * mod) override;
2527 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2528 };
2529
2531 {
2532 public:
2533 std::string name;
2534
2535 ModuleAncestorRecord(record_type_t record_type = record_type_t(0))
2537 {
2538 }
2539
2540 void ReadRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2541 uint16_t GetRecordSize(OMF80Format * omf, Module * mod) const override;
2542 void WriteRecordContents(OMF80Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2543
2544 void CalculateValues(OMF80Format * omf, Module * mod) override;
2545 void ResolveReferences(OMF80Format * omf, Module * mod) override;
2546 };
2547
2549 {
2550 public:
2551 segment_id_t segment_id = 0;
2552 uint16_t length = 0;
2553 alignment_t alignment = AlignByte;
2554 std::string common_name;
2555
2557 {
2558 }
2559
2561 : segment_id(segment_definition.segment_id), length(segment_definition.length), alignment(segment_definition.alignment)
2562 {
2563 }
2564 };
2565
2567 {
2568 public:
2570 size_t first_record = 0;
2572 size_t record_count = 0;
2573
2574 std::map<segment_id_t, SegmentDefinition> segment_definitions;
2575 std::vector<std::string> external_names;
2576 };
2577
2579 std::vector<std::shared_ptr<Record>> records;
2580
2582 std::vector<Module> modules;
2583
2585 static std::shared_ptr<OMF80Format> ReadOMFFile(const std::shared_ptr<Linker::Reader>& rd);
2586
2587 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);
2588
2589 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
2591 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
2592 void Dump(Dumper::Dumper& dump) const override;
2594 void GenerateModule(Linker::Module& module) const override;
2595 /* TODO */
2596 };
2597
2601 class OMF51Format : public virtual OMFFormat, public virtual Linker::InputFormat
2602 {
2603 public:
2604 class Module;
2605
2606 enum record_type_t : uint8_t
2607 {
2608 ModuleHeader = OMF80Format::ModuleHeader,
2609 ModuleEnd = OMF80Format::ModuleEnd,
2610 Content = OMF80Format::Content,
2611 Fixups = 0x08,
2612 SegmentDefinitions = 0x0E,
2613 ScopeDefinition = 0x10,
2614 DebugItems = 0x12,
2615 PublicDefinitions = OMF80Format::PublicDefinitions,
2616 ExternalDefinitions = OMF80Format::ExternalDefinitions,
2617 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
2618 LibraryModuleNames = OMF80Format::LibraryModuleNames,
2619 LibraryDictionary = OMF80Format::LibraryDictionary,
2620 LibraryHeader = OMF80Format::LibraryHeader,
2621 };
2622
2623 static const std::map<offset_t, std::string> RecordTypeNames;
2624
2633
2635 std::shared_ptr<Record> ReadRecord(const std::shared_ptr<Linker::Reader>& rd);
2636
2637 // TODO: document record types
2638
2639 static constexpr uint8_t SegmentAbsolute = 0;
2640
2656
2672
2674 {
2675 public:
2676 bool overlayable;
2677 uint8_t register_bank;
2678 segment_type_t segment_type;
2679
2680 static constexpr uint8_t MaskSegmentType = 0x07;
2681 static constexpr uint8_t MaskRegisterBank = 0x18;
2682 static constexpr uint8_t ShiftRegisterBank = 3;
2683 static constexpr uint8_t FlagOverlayable = 0x20;
2684 static constexpr uint8_t FlagSegmentEmpty = 0x80;
2685
2686 void ReadSegmentInfo(OMF51Format * omf, Module * mod, uint8_t segment_info);
2687 uint8_t WriteSegmentInfo(OMF51Format * omf, Module * mod) const;
2688 };
2689
2691 {
2692 public:
2693 uint8_t segment_id;
2694 SegmentInfo info;
2695 alignment_t alignment;
2696 uint16_t base;
2697 uint32_t size;
2698 std::string name;
2699
2700 static SegmentDefinition Read(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
2701 uint16_t Size(OMF51Format * omf, Module * mod) const;
2702 void Write(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
2703 };
2704
2706 {
2707 public:
2708 bool indirectly_callable;
2709 bool variable;
2710 std::optional<unsigned> register_bank;
2711 segment_type_t usage;
2712
2713 static constexpr uint8_t MaskSegmentType = 0x07;
2714 static constexpr uint8_t MaskRegisterBank = 0x18;
2715 static constexpr uint8_t ShiftRegisterBank = 3;
2716 static constexpr uint8_t FlagRegisterBank = 0x20;
2717 static constexpr uint8_t FlagVariable = 0x40;
2718 static constexpr uint8_t FlagIndirectlyCallable = 0x80;
2719
2720 void Read(OMF51Format * omf, Module * mod, uint8_t segment_info);
2721 uint8_t Write(OMF51Format * omf, Module * mod) const;
2722 };
2723
2725 {
2726 public:
2727 uint8_t segment_id;
2728 SymbolInfo info;
2729 uint16_t offset;
2730 std::string name;
2731
2732 static SymbolDefinition Read(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
2733 uint16_t Size(OMF51Format * omf, Module * mod) const;
2734 void Write(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
2735 };
2736
2738 {
2739 public:
2740 uint8_t block_id = 2;
2741 uint8_t external_id;
2742 SymbolInfo info;
2743 std::string name;
2744
2745 static ExternalDefinition Read(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
2746 uint16_t Size(OMF51Format * omf, Module * mod) const;
2747 void Write(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
2748 };
2749
2751 {
2752 public:
2753 std::string name;
2754 enum translator_id_t : uint8_t
2755 {
2756 Assembler = 0xFD,
2757 PLMCompiler = 0xFE,
2758 Linker = 0xFF,
2759 };
2760 translator_id_t translator_id;
2761
2762 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
2764 {
2765 }
2766
2767 void ReadRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2768 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2769 void WriteRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2770 };
2771
2773 {
2774 public:
2775 std::string name;
2776 std::array<bool, 4> banks;
2777
2778 ModuleEndRecord(record_type_t record_type = record_type_t(0))
2780 {
2781 }
2782
2783 void ReadRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2784 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2785 void WriteRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2786 };
2787
2789 {
2790 public:
2791 std::vector<SegmentDefinition> segment_definitions;
2792
2793 SegmentDefinitionsRecord(record_type_t record_type = record_type_t(0))
2795 {
2796 }
2797
2798 void ReadRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2799 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2800 void WriteRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2801
2802 void CalculateValues(OMF51Format * omf, Module * mod) override;
2803 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2804 };
2805
2807 {
2808 public:
2809 std::vector<SymbolDefinition> symbol_definitions;
2810
2811 PublicSymbolsRecord(record_type_t record_type = record_type_t(0))
2813 {
2814 }
2815
2816 void ReadRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2817 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2818 void WriteRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2819
2820 void CalculateValues(OMF51Format * omf, Module * mod) override;
2821 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2822 };
2823
2825 {
2826 public:
2827 std::vector<ExternalDefinition> external_definitions;
2828
2829 ExternalDefinitionsRecord(record_type_t record_type = record_type_t(0))
2831 {
2832 }
2833
2834 void ReadRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2835 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2836 void WriteRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2837
2838 void CalculateValues(OMF51Format * omf, Module * mod) override;
2839 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2840 };
2841
2843 {
2844 public:
2845 enum block_type_t : uint8_t
2846 {
2847 ModuleBlock = 0,
2848 DoBlock = 1,
2849 ProcedureBlock = 2,
2850 EndModuleBlock = 3,
2851 EndDoBlock = 4,
2852 EndProcedureBlock = 5,
2853 };
2854
2855 block_type_t block_type;
2856 std::string name;
2857
2858 ScopeDefinitionRecord(record_type_t record_type = record_type_t(0))
2860 {
2861 }
2862
2863 void ReadRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2864 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2865 void WriteRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2866
2867 void CalculateValues(OMF51Format * omf, Module * mod) override;
2868 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2869 };
2870
2872 {
2873 public:
2875 {
2876 public:
2877 uint8_t segment_id;
2878 SymbolInfo info;
2879 uint16_t offset;
2880 std::string name;
2881
2882 static Symbol Read(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
2883 uint16_t Size(OMF51Format * omf, Module * mod) const;
2884 void Write(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
2885 };
2886
2888 {
2889 public:
2890 std::vector<Symbol> symbols;
2891 };
2892
2894 {
2895 public:
2896 std::vector<Symbol> symbols;
2897 };
2898
2900 {
2901 public:
2902 uint8_t segment_id;
2903 SegmentInfo info;
2904 uint16_t offset;
2905 std::string name;
2906
2907 static SegmentSymbol Read(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
2908 uint16_t Size(OMF51Format * omf, Module * mod) const;
2909 void Write(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
2910 };
2911
2913 {
2914 public:
2915 std::vector<SegmentSymbol> symbols;
2916 };
2917
2919 {
2920 public:
2921 uint8_t segment_id;
2922 uint16_t offset;
2923 uint16_t line_number;
2924
2925 static LineNumber Read(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
2926 void Write(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
2927 };
2928
2930 {
2931 public:
2932 std::vector<LineNumber> symbols;
2933 };
2934
2935 static constexpr uint8_t Type_LocalSymbols = 0;
2936 static constexpr uint8_t Type_PublicSymbols = 1;
2937 static constexpr uint8_t Type_SegmentSymbols = 2;
2938 static constexpr uint8_t Type_LineNumbers = 3;
2939
2940 std::variant<LocalSymbols, PublicSymbols, SegmentSymbols, LineNumbers> contents;
2941
2942 DebugItemsRecord(record_type_t record_type = record_type_t(0))
2944 {
2945 }
2946
2947 void ReadRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
2948 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
2949 void WriteRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
2950
2951 void CalculateValues(OMF51Format * omf, Module * mod) override;
2952 void ResolveReferences(OMF51Format * omf, Module * mod) override;
2953 };
2954
2955 class FixupRecord : public Record
2956 {
2957 public:
2958 enum relocation_type_t : uint8_t
2959 {
2960 RelocationLow8 = 0,
2961 RelocationByte8 = 1,
2962 RelocationRelative8 = 2,
2963 RelocationHigh8 = 3,
2964 RelocationWord16 = 4,
2965 RelocationAbsolute11 = 5,
2966 RelocationBit7 = 6,
2967 RelocationConv7 = 7,
2968 };
2969
2979
2980 class Fixup
2981 {
2982 public:
2983 uint16_t location;
2984 relocation_type_t relocation;
2985 reference_type_t reference;
2986 uint8_t id;
2987 uint16_t offset;
2988
2989 static Fixup Read(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
2990 void Write(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
2991 };
2992
2993 std::vector<Fixup> fixups;
2994
2995 FixupRecord(record_type_t record_type = record_type_t(0))
2997 {
2998 }
2999
3000 void ReadRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3001 uint16_t GetRecordSize(OMF51Format * omf, Module * mod) const override;
3002 void WriteRecordContents(OMF51Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3003
3004 void CalculateValues(OMF51Format * omf, Module * mod) override;
3005 void ResolveReferences(OMF51Format * omf, Module * mod) override;
3006 };
3007
3009 {
3010 public:
3012 size_t first_record = 0;
3014 size_t record_count = 0;
3015
3016 std::map<uint8_t, SegmentDefinition> segment_definitions;
3017 std::map<uint8_t, ExternalDefinition> external_definitions;
3018 };
3019
3021 std::vector<std::shared_ptr<Record>> records;
3022
3024 std::vector<Module> modules;
3025
3027 static std::shared_ptr<OMF51Format> ReadOMFFile(const std::shared_ptr<Linker::Reader>& rd);
3028
3029 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);
3030
3031 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
3033 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
3034 void Dump(Dumper::Dumper& dump) const override;
3036 void GenerateModule(Linker::Module& module) const override;
3037 /* TODO */
3038 };
3039
3043 class OMF96Format : public virtual OMFFormat, public virtual Linker::InputFormat
3044 {
3045 public:
3046 class Module;
3047
3048 typedef uint16_t index_t;
3049
3050 enum record_type_t : uint8_t
3051 {
3052 ModuleHeader = OMF80Format::ModuleHeader,
3053 ModuleEnd = OMF80Format::ModuleEnd,
3054 Content = OMF80Format::Content,
3055 LineNumbers = OMF80Format::LineNumbers,
3056 BlockDefinition = 0x0A,
3057 BlockEnd = 0x0C,
3058 EndOfFile = OMF80Format::EndOfFile,
3059 ModuleAncestor = OMF80Format::ModuleAncestor,
3060 LocalSymbols = OMF80Format::LocalSymbols,
3061 TypeDefinition = 0x14,
3062 PublicDefinitions = OMF80Format::PublicDefinitions,
3063 ExternalDefinitions = OMF80Format::ExternalDefinitions,
3064 SegmentDefinitions = 0x20, // different from OMF51 number
3065 Relocations = OMF80Format::Relocations,
3066 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
3067 LibraryModuleNames = OMF80Format::LibraryModuleNames,
3068 LibraryDictionary = OMF80Format::LibraryDictionary,
3069 LibraryHeader = 0x2E, // different from OMF80 number
3070 };
3071
3072 static const std::map<offset_t, std::string> RecordTypeNames;
3073
3083
3085 std::shared_ptr<Record> ReadRecord(const std::shared_ptr<Linker::Reader>& rd);
3086
3087 typedef uint8_t segment_id_t;
3088
3089 static constexpr segment_id_t CodeSegment = 0;
3090 static constexpr segment_id_t DataSegment = 1;
3091 static constexpr segment_id_t RegisterSegment = 2;
3092 static constexpr segment_id_t OverlaySegment = 3;
3093 static constexpr segment_id_t StackSegment = 4;
3094 static constexpr segment_id_t DynamicSymbol = 5;
3095 static constexpr segment_id_t NullSegment = 6;
3096 static constexpr segment_id_t SegmentTypeMask = 7;
3097
3098 static constexpr segment_id_t FlagBasedVariable = 0x40;
3099
3100 static constexpr segment_id_t FlagRelocatableSegment = 0x80;
3101
3102 enum alignment_t
3103 {
3104 AlignByte = 0,
3105 AlignWord = 1,
3106 AlignLong = 2,
3107 };
3108
3110 {
3111 public:
3112 segment_id_t segment_id;
3113 private:
3114 union
3115 {
3116 alignment_t alignment; // for RelocatableSegment
3117 uint16_t base_address;
3118 };
3119 public:
3120 uint16_t size;
3121
3122 bool IsRelocatable() const
3123 {
3124 return segment_id & FlagRelocatableSegment;
3125 }
3126
3127 bool IsAbsolute() const
3128 {
3129 return !IsRelocatable();
3130 }
3131
3132 alignment_t GetAlignment() const
3133 {
3134 return IsRelocatable() ? alignment : alignment_t(-1);
3135 }
3136
3137 uint16_t GetBaseAddress() const
3138 {
3139 return IsAbsolute() ? base_address : 0;
3140 }
3141
3142 void MakeRelocatable(alignment_t rel_alignment)
3143 {
3144 segment_id |= FlagRelocatableSegment;
3145 alignment = rel_alignment;
3146 }
3147
3148 void MakeAbsolute(uint16_t address)
3149 {
3150 segment_id &= ~FlagRelocatableSegment;
3151 base_address = address;
3152 }
3153
3154 static SegmentDefinition Read(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
3155 uint16_t Size(OMF96Format * omf, Module * mod) const;
3156 void Write(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
3157 };
3158
3160
3162 {
3163 public:
3164 index_t index;
3165 std::shared_ptr<TypeDefinitionRecord> record;
3166
3167 TypeIndex(index_t index = 0)
3168 : index(index)
3169 {
3170 }
3171
3172 void CalculateValues(OMF86Format * omf, Module * mod);
3173 void ResolveReferences(OMF86Format * omf, Module * mod);
3174 };
3175
3177 {
3178 public:
3179 std::string name;
3180 TypeIndex type;
3181
3182 static ExternalDefinition Read(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
3183 uint16_t Size(OMF96Format * omf, Module * mod) const;
3184 void Write(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
3185
3186 void CalculateValues(OMF96Format * omf, Module * mod);
3187 void ResolveReferences(OMF96Format * omf, Module * mod);
3188 };
3189
3191 {
3192 public:
3193 uint16_t offset;
3194 std::string name;
3195 TypeIndex type;
3196
3197 static SymbolDefinition Read(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
3198 uint16_t Size(OMF96Format * omf, Module * mod) const;
3199 void Write(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
3200
3201 void CalculateValues(OMF96Format * omf, Module * mod);
3202 void ResolveReferences(OMF96Format * omf, Module * mod);
3203 };
3204
3206 {
3207 public:
3208 std::string name;
3209 uint8_t translator_id;
3210 std::string date_time;
3211
3212 static constexpr uint8_t Version14 = 0xE0;
3213 static constexpr uint8_t Version20 = 0xE4;
3214 static constexpr uint8_t Translator = 0x00;
3215 static constexpr uint8_t Linker = 0x01;
3216
3217 ModuleHeaderRecord(record_type_t record_type = record_type_t(0))
3219 {
3220 }
3221
3222 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3223 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3224 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3225 };
3226
3228 {
3229 public:
3230 bool main;
3231 bool valid;
3232
3233 static constexpr uint8_t MainModule = 0x01;
3234 static constexpr uint8_t OtherModule = 0x00;
3235
3236 static constexpr uint8_t ValidModule = 0x00;
3237 static constexpr uint8_t ErroneousModule = 0x01;
3238
3239 ModuleEndRecord(record_type_t record_type = record_type_t(0))
3241 {
3242 }
3243
3244 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3245 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3246 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3247 };
3248
3250 {
3251 public:
3252 std::vector<SegmentDefinition> segment_definitions;
3253
3254 SegmentDefinitionsRecord(record_type_t record_type = record_type_t(0))
3256 {
3257 }
3258
3259 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3260 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3261 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3262
3263 void CalculateValues(OMF96Format * omf, Module * mod) override;
3264 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3265 };
3266
3267 class TypeDefinitionRecord : public Record, public std::enable_shared_from_this<TypeDefinitionRecord>
3268 {
3269 public:
3271 {
3272 public:
3273 bool nice; // easy if false
3274
3276 struct Null { };
3278 struct Repeat { };
3279 // TODO: document
3280 struct EndOfBranch { };
3281
3282 std::variant<Null, int32_t, std::string, TypeIndex, Repeat, EndOfBranch> leaf = Null();
3283
3285 static constexpr uint8_t NullLeaf = 0x64;
3287 static constexpr uint8_t SignedNumericLeaf16 = 0x65;
3289 static constexpr uint8_t SignedNumericLeaf32 = 0x66;
3291 static constexpr uint8_t StringLeaf = 0x67;
3293 static constexpr uint8_t IndexLeaf = 0x68;
3295 static constexpr uint8_t RepeatLeaf = 0x69;
3297 static constexpr uint8_t EndOfBranchLeaf = 0x6A;
3298
3299 static LeafDescriptor Read(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
3300 uint16_t Size(OMF96Format * omf, Module * mod) const;
3301 void Write(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
3302
3303 void CalculateValues(OMF96Format * omf, Module * mod);
3304 void ResolveReferences(OMF96Format * omf, Module * mod);
3305 };
3306
3308 std::vector<LeafDescriptor> leafs;
3309
3310 TypeDefinitionRecord(record_type_t record_type = record_type_t(0))
3312 {
3313 }
3314
3315 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3316 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3317 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3318
3319 void CalculateValues(OMF96Format * omf, Module * mod) override;
3320 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3321 };
3322
3324 {
3325 public:
3326 segment_id_t segment_id;
3327 std::vector<SymbolDefinition> symbol_definitions;
3328
3329 SymbolDefinitionsRecord(record_type_t record_type = record_type_t(0))
3331 {
3332 }
3333
3334 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3335 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3336 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3337
3338 void CalculateValues(OMF96Format * omf, Module * mod) override;
3339 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3340 };
3341
3343 {
3344 public:
3345 segment_id_t segment_id;
3346 std::vector<ExternalDefinition> external_definitions;
3347
3348 ExternalDefinitionsRecord(record_type_t record_type = record_type_t(0))
3350 {
3351 }
3352
3353 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3354 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3355 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3356
3357 void CalculateValues(OMF96Format * omf, Module * mod) override;
3358 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3359 };
3360
3362 {
3363 public:
3365 {
3366 public:
3367 typedef segment_id_t LocalReference;
3368 typedef uint16_t ExternalReference;
3369
3370 enum reference_type_t
3371 {
3372 RegisterSimple = 0,
3373 RegisterAutoIncrement = 1,
3374 ShiftCountImmediate = 2,
3375 ShiftCountRegister = 3,
3376 ByteConstant = 4,
3377 ShortJump = 6,
3378 MediumJump = 7,
3379 MediumCall = 8,
3380 LongJumpCall = 9,
3381 LongDirect = 10,
3382 };
3383
3384 static constexpr uint8_t FlagAddendInCode = 0x40;
3385 static constexpr uint8_t FlagExternal = 0x80;
3386
3387 uint16_t offset;
3388 std::variant<LocalReference, ExternalReference> reference = LocalReference(0);
3389 std::optional<uint16_t> addend;
3390 reference_type_t reference_type;
3391 alignment_t alignment;
3392
3393 static Relocation Read(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd);
3394 uint16_t Size(OMF96Format * omf, Module * mod) const;
3395 void Write(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const;
3396 };
3397
3398 std::vector<Relocation> relocations;
3399
3400 RelocationRecord(record_type_t record_type = record_type_t(0))
3402 {
3403 }
3404
3405 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3406 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3407 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3408
3409 void CalculateValues(OMF96Format * omf, Module * mod) override;
3410 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3411 };
3412
3414 {
3415 public:
3416 std::string name;
3417 std::optional<SegmentDefinition> segment_definition;
3418
3419 ModuleAncestorRecord(record_type_t record_type = record_type_t(0))
3421 {
3422 }
3423
3424 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3425 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3426 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3427
3428 void CalculateValues(OMF96Format * omf, Module * mod) override;
3429 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3430 };
3431
3433 {
3434 public:
3436 {
3437 public:
3438 std::string name;
3439 TypeIndex type;
3440 };
3441
3442 typedef segment_id_t LocalReference;
3443 typedef uint16_t ExternalReference;
3444
3446 {
3447 public:
3448 std::variant<LocalReference, ExternalReference> frame_pointer = LocalReference(0);
3449 uint16_t return_offset;
3450 uint8_t prologue_size;
3451 };
3452
3453 segment_id_t segment_id;
3454 uint16_t offset;
3455 uint16_t size;
3456 std::optional<BlockNameAndType> name_and_type;
3457 std::optional<ProcedureInformation> procedure_info;
3458
3459 BlockDefinitionRecord(record_type_t record_type = record_type_t(0))
3461 {
3462 }
3463
3464 static constexpr uint8_t FlagProcedure = 0x40;
3465 static constexpr uint8_t FlagExternal = 0x80;
3466
3467 void ReadRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<Linker::Reader>& rd) override;
3468 uint16_t GetRecordSize(OMF96Format * omf, Module * mod) const override;
3469 void WriteRecordContents(OMF96Format * omf, Module * mod, const std::shared_ptr<ChecksumWriter>& wr) const override;
3470
3471 void CalculateValues(OMF96Format * omf, Module * mod) override;
3472 void ResolveReferences(OMF96Format * omf, Module * mod) override;
3473 };
3474
3476 {
3477 public:
3479 size_t first_record = 0;
3481 size_t record_count = 0;
3482
3483 std::map<segment_id_t, SegmentDefinition> segment_definitions;
3484 std::vector<std::shared_ptr<TypeDefinitionRecord>> type_definitions;
3485 };
3486
3488 std::vector<std::shared_ptr<Record>> records;
3489
3491 std::vector<Module> modules;
3492
3494 static std::shared_ptr<OMF96Format> ReadOMFFile(const std::shared_ptr<Linker::Reader>& rd);
3495
3496 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);
3497
3498 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
3500 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
3501 void Dump(Dumper::Dumper& dump) const override;
3503 void GenerateModule(Linker::Module& module) const override;
3504 /* TODO */
3505 };
3506
3508 {
3509 public:
3510 std::shared_ptr<OMFFormat> contents;
3511
3512 void ReadFile(const std::shared_ptr<Linker::Reader>& rd) override;
3513
3515 void GenerateModule(Linker::Module& module) const override;
3516
3518 offset_t WriteFile(const std::shared_ptr<Linker::Writer>& wr) const override;
3519
3520 offset_t ImageSize() const override;
3521
3522 void Dump(Dumper::Dumper& dump) const override;
3523 };
3524}
3525
3526#endif /* OMF_H */
static std::shared_ptr< DecDisplay > Make(bool enable_signed)
Creates a decimal display.
Definition dumper.h:384
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:1009
static std::shared_ptr< HexDisplay > Make(unsigned width=8)
Creates a hexadecimal display.
Definition dumper.h:357
A record that represents a region within the file.
Definition dumper.h:902
A class to encode a general file format.
Definition format.h:29
offset_t WriteFile(const std::shared_ptr< 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:218
virtual void GenerateModule(ModuleCollector &linker, std::string file_name, bool is_library=false) const
Loads the information into a module object.
Definition format.cc:226
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
Represents a possible target or reference frame of a relocation.
Definition target.h:24
Abstract base class that encapsulates functionality needed to export binary data.
Definition writer.h:15
virtual void WriteData(size_t count, const void *data)=0
Write out a sequence of bytes.
Convenience class to calculate the checksum of a record while writing it.
Definition omf.h:22
void Skip(relative_offset_t offset) override
Jump to a distance in the output stream.
Definition omf.cc:27
offset_t Tell() override
Retrieve the current location.
Definition omf.cc:41
void WriteData(size_t count, const void *data) override
Write out a sequence of bytes.
Definition omf.cc:13
void Seek(offset_t offset) override
Jump to a specific location in the ouput stream.
Definition omf.cc:22
void SeekEnd(relative_offset_t offset=0) override
Jump to a specific offset from the end.
Definition omf.cc:32
Definition omf.h:2956
reference_type_t
Definition omf.h:2971
@ ReferenceSegmentStart
The starting address of the portion of the segment in the file.
Definition omf.h:2975
@ ReferenceExternal
An external reference.
Definition omf.h:2977
@ ReferenceSegmentBase
The starting address of the segment.
Definition omf.h:2973
Definition omf.h:3009
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:3012
size_t record_count
The number of records belonging to this module.
Definition omf.h:3014
Definition omf.h:2674
Definition omf.h:2706
Intel Relocatable Object Module for the Intel MCS-51.
Definition omf.h:2602
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:6121
void ReadFile(const std::shared_ptr< Linker::Reader > &rd) override
Loads file into memory.
Definition omf.cc:6075
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:3021
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:6095
static std::shared_ptr< OMF51Format > ReadOMFFile(const std::shared_ptr< Linker::Reader > &rd)
Parses an OMF51 file.
Definition omf.cc:6063
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr) const override
Stores data in memory to file.
Definition omf.cc:6088
alignment_t
Definition omf.h:2658
@ AlignFitsBlock
Must fit a 256 byte block.
Definition omf.h:2668
@ AlignFitsPage
Must fit a 256 byte page.
Definition omf.h:2666
@ AlignUnit
Byte or bit alignment for SegmentBit segments.
Definition omf.h:2662
@ AlignPage
Align to a 256 byte page boundary.
Definition omf.h:2670
@ AlignBitAddressable
Must be allocated within the bit addressable part of SegmentData.
Definition omf.h:2664
@ AlignAbsolute
Non-relocatable.
Definition omf.h:2660
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:3024
segment_type_t
Definition omf.h:2642
@ SegmentNone
Not a segment, but a symbol with this segment type is treated as a value.
Definition omf.h:2654
@ SegmentIData
256 B internal RAM that is accessible via indirect addressing, first 128 B shared with SegmentData
Definition omf.h:2650
@ SegmentBit
256 bit address space, part of SegmentData
Definition omf.h:2652
@ SegmentData
256 B internal RAM that is accessible via direct addressing, first 128 B shared with SegmentIData
Definition omf.h:2648
@ SegmentCode
64 KiB read-only memory
Definition omf.h:2644
@ SegmentXData
64 KiB read-write memory
Definition omf.h:2646
std::shared_ptr< Record > ReadRecord(const std::shared_ptr< Linker::Reader > &rd)
Parses and returns an instance of the next record.
Definition omf.cc:6003
Definition omf.h:2567
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:2570
size_t record_count
The number of records belonging to this module.
Definition omf.h:2572
Intel Relocatable Object Module for the Intel 8080.
Definition omf.h:2244
static constexpr segment_id_t CodeSegment
Used for instructions and generally anything loaded into the ROM.
Definition omf.h:2294
static constexpr segment_id_t StackSegment
Used to specify size of segment.
Definition omf.h:2298
uint8_t segment_id_t
Represents one of the 256 segments.
Definition omf.h:2289
static constexpr segment_id_t UnnamedCommonSegment
The unnamed common segment.
Definition omf.h:2306
static constexpr segment_id_t DataSegment
Used for data and generally anything loaded into the RAM.
Definition omf.h:2296
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:2582
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr) const override
Stores data in memory to file.
Definition omf.cc:5352
static constexpr segment_id_t LastNamedCommonSegment
The last segment number corresponding to a named common segment.
Definition omf.h:2304
static constexpr segment_id_t AbsoluteSegment
The absolute segment, all offsets are absolute memory locations.
Definition omf.h:2292
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:5385
static constexpr segment_id_t MemorySegment
Used to specify the highest memory address available.
Definition omf.h:2300
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:2579
std::shared_ptr< Record > ReadRecord(const std::shared_ptr< Linker::Reader > &rd)
Parses and returns an instance of the next record.
Definition omf.cc:5257
static std::shared_ptr< OMF80Format > ReadOMFFile(const std::shared_ptr< Linker::Reader > &rd)
Parses an OMF80 file.
Definition omf.cc:5327
void ReadFile(const std::shared_ptr< Linker::Reader > &rd) override
Loads file into memory.
Definition omf.cc:5339
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:5359
static constexpr segment_id_t FirstNamedCommonSegment
The first segment number corresponding to a named common segment.
Definition omf.h:2302
Represents a single substitution.
Definition omf.h:1813
std::string alias_name
Name used in references.
Definition omf.h:1816
std::string substitute_name
Name it should be substituted with.
Definition omf.h:1818
Record defining a replacement name for symbols, used for ALIAS (included in TIS)
Definition omf.h:1809
std::vector< AliasDefinition > alias_definitions
List of replacements.
Definition omf.h:1825
Represents a single fixup.
Definition omf.h:1663
uint32_t offset
The offset at which the fixup should happen.
Definition omf.h:1666
uint32_t value
The value to be added to the fixup location.
Definition omf.h:1668
A specialized relocation, used for BAKPAT (included in TIS)
Definition omf.h:1659
std::vector< OffsetValuePair > offset_value_pairs
The data for the relocations.
Definition omf.h:1684
location_type_t
Relocation type.
Definition omf.h:1675
SegmentIndex segment
Segment to which the relocations belong.
Definition omf.h:1672
uint8_t type
The type of the relocations.
Definition omf.h:1682
Specification for the group and segment of some reference, and the frame if both are 0.
Definition omf.h:633
std::variant< Location, FrameNumber > location
The actual location of the reference.
Definition omf.h:643
A record that defines a block, used for BLKDEF records (Intel only)
Definition omf.h:1298
block_type_t
Type of the block, if it is a procedure.
Definition omf.h:1310
@ NotProcedure
Block is not a procedure.
Definition omf.h:1312
@ NearProcedure
Block is a near procedure.
Definition omf.h:1314
@ FarProcedure
Block is a far procedure.
Definition omf.h:1316
block_type_t procedure
Whether this block is a procedure, and whether it is a near or far procedure.
Definition omf.h:1319
uint16_t length
Length of the block.
Definition omf.h:1307
TypeIndex type
Type of block or procedure, only used if name != "".
Definition omf.h:1323
std::string name
The name of the block or empty.
Definition omf.h:1303
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:1321
uint16_t offset
Offset to the first byte of the block.
Definition omf.h:1305
BaseSpecification base
The first byte of the segment containing the block.
Definition omf.h:1301
A rich container for indexes referring to a BLKDEF record.
Definition omf.h:514
Definition omf.h:1876
Represents a sequence of data, with optional repeated parts, used by RelocatableDataRecord,...
Definition omf.h:695
std::vector< std::shared_ptr< DataBlock > > Blocks
If the contents are a sequence of blocks (iterated only)
Definition omf.h:701
uint16_t repeat_count
Number of times the data should be appear. Should be 1 for enumerated data.
Definition omf.h:698
void WriteEnumeratedDataBlock(OMF86Format *omf, const std::shared_ptr< ChecksumWriter > &wr) const
Writes the contents of an enumerated record into a file.
Definition omf.cc:872
uint16_t GetIteratedDataBlockSize(OMF86Format *omf, bool is32bit) const
Gets the size of an encoded iterated record in bytes.
Definition omf.cc:855
static std::shared_ptr< DataBlock > ReadEnumeratedDataBlock(OMF86Format *omf, const std::shared_ptr< Linker::Reader > &rd, uint16_t data_length)
Parses the contents of an enumerated record.
Definition omf.cc:814
void WriteIteratedDataBlock(OMF86Format *omf, const std::shared_ptr< ChecksumWriter > &wr, bool is32bit) const
Writes the contents of an iterated record into a file.
Definition omf.cc:877
static std::shared_ptr< DataBlock > ReadIteratedDataBlock(OMF86Format *omf, const std::shared_ptr< Linker::Reader > &rd, bool is32bit)
Parses the contents of an iterated record.
Definition omf.cc:825
std::variant< Data, Blocks > content
The actual contents of the block, whether iterated or enumerated.
Definition omf.h:706
std::vector< uint8_t > Data
If the contents are a sequence of bytes (either iterated or enumerated)
Definition omf.h:703
uint16_t GetEnumeratedDataBlockSize(OMF86Format *omf) const
Gets the size of an encoded enumerated record in bytes.
Definition omf.cc:850
Record to store debug symbols, used for DEBSYM (Intel only)
Definition omf.h:1340
Record to signal termination of an overloay or block, used for ENDBLK (Intel only)
Definition omf.h:1558
block_type_t
Type of block that is terminated by an EndRecord.
Definition omf.h:1562
block_type_t block_type
Type of block this record terminates.
Definition omf.h:1567
A rich container for indexes referring to symbols in an EXTDEF, LEXTDEF, COMDEF, LCOMDEF,...
Definition omf.h:617
An external name declaration, appearing in an EXTDEF, LEXTDEF, COMDEF, LCOMDEF or CEXTDEF record.
Definition omf.h:546
void WriteExternalName(OMF86Format *omf, const std::shared_ptr< ChecksumWriter > &wr) const
Writes this entry to file.
Definition omf.cc:641
static ExternalName ReadCommonName(OMF86Format *omf, const std::shared_ptr< Linker::Reader > &rd, bool local)
Parse a COMDEF or LCOMDEF entry.
Definition omf.cc:570
NameIndex name
Name of the symbol.
Definition omf.h:569
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:525
static ExternalName ReadComdatExternalName(OMF86Format *omf, const std::shared_ptr< Linker::Reader > &rd)
Parse a CEXTDEF entry.
Definition omf.cc:603
static uint32_t ReadValue(OMF86Format *omf, const std::shared_ptr< Linker::Reader > &rd)
Read a length value, for near or far elements.
Definition omf.cc:506
static ExternalName ReadExternalName(OMF86Format *omf, const std::shared_ptr< Linker::Reader > &rd, bool local)
Parse an EXTDEF or LEXTDEF entry.
Definition omf.cc:560
static void WriteValue(OMF86Format *omf, const std::shared_ptr< ChecksumWriter > &wr, uint32_t length)
Writes a length value, for near or far elements.
Definition omf.cc:537
bool local
Signals if a symbol is local.
Definition omf.h:565
bool name_is_index
Set if name.index contains a valid value, for CEXTDEF entries.
Definition omf.h:567
common_type_t
Type of a common symbol.
Definition omf.h:550
@ NearCommon
Near variable.
Definition omf.h:561
@ FarCommon
Far variable.
Definition omf.h:558
@ SegmentIndexCommon
Borland segment index.
Definition omf.h:555
@ External
Not a common symbol, appears in an EXTDEF, LEXTDEF or CEXTDEF record.
Definition omf.h:552
uint16_t GetExternalNameSize(OMF86Format *omf) const
Returns the number of bytes required to write this entry.
Definition omf.cc:613
A record defining several external or common symbols, used for EXTDEF, LEXTDEF, CEXTDEF,...
Definition omf.h:1253
ExternalIndex first_extdef
Index of first external or common symbol in module.
Definition omf.h:1256
uint16_t extdef_count
Number of external or common symbols defined in this record.
Definition omf.h:1258
uint16_t offset
Offset to value to be relocated, relative to the latest data block.
Definition omf.h:1500
relocation_type_t type
The type of the relocation value.
Definition omf.h:1498
relocation_type_t
Types for the value that needs to be relocated.
Definition omf.h:1472
@ RelocationOffset32_LoaderResolved
A 32-bit loader-resolved value (TIS assignment)
Definition omf.h:1494
@ RelocationHighByte
Most significant 8 bits of a 16-bit value.
Definition omf.h:1482
@ RelocationOffset16
A 16-bit value or the 16-bit offset portion of a far address.
Definition omf.h:1476
@ RelocationSegment
The segment portion of a far address.
Definition omf.h:1478
@ RelocationPointer32
A 32-bit far address, consisting of a 16-bit segment portion and a 16-bit offset portion.
Definition omf.h:1480
@ RelocationOffset32_PharLap
A 32-bit value or the 32-bit offset portion of a far address (Phar Lap assignment)
Definition omf.h:1486
@ RelocationLowByte
Least significant 8 bits of value.
Definition omf.h:1474
@ RelocationOffset16_LoaderResolved
A 16-bit loader-resolved value (TIS assignment)
Definition omf.h:1484
@ RelocationOffset32
A 32-bit value or the 32-bit offset portion of a far address (TIS assignment)
Definition omf.h:1490
@ RelocationPointer48
A 48-bit far address, consisting of a 16-bit segment portion and a 32-bit offset portion (TIS assignm...
Definition omf.h:1492
@ 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:1488
Reference ref
Reference of this relocation.
Definition omf.h:1502
bool segment_relative
Set if segment relative, self relative otherwise.
Definition omf.h:1468
Threads are intermediary storage for relocation targets and frames, this class represents a thread as...
Definition omf.h:1447
unsigned thread_number
The thread number which gets assigned to, a value from 0 to 3.
Definition omf.h:1450
frame_reference_type reference
The frame or target reference.
Definition omf.h:1454
bool frame
Set if this is a frame thread, it is a target thread otherwise.
Definition omf.h:1452
A record containing relocation data, used for FIXUPP.
Definition omf.h:1440
std::vector< std::variant< Thread, Fixup > > fixup_data
Sequence of thread assignments and relocations.
Definition omf.h:1513
Represents the data required for a load-time locatable group (Intel only)
Definition omf.h:1077
Represents the data required for identifying a the segment by the name, class name and overlay name (...
Definition omf.h:1068
Represents a component of the group.
Definition omf.h:1064
static constexpr uint8_t SegmentIndex_type
The type prefix for a segment (the only type defined by TIS)
Definition omf.h:1095
static constexpr uint8_t Absolute_type
The type prefix for the address of the group (Intel only)
Definition omf.h:1087
static constexpr uint8_t SegmentClassOverlayNames_type
The type prefix for segment, class, overlay name triplets (Intel only)
Definition omf.h:1091
static constexpr uint8_t LoadTimeLocatable_type
The type prefix for a load time locatable group (Intel only)
Definition omf.h:1089
uint32_t Absolute
Represents the data required for an absolute group (Intel only)
Definition omf.h:1084
static constexpr uint8_t ExternalIndex_type
The type prefix for the segment of an external symbol (Intel only)
Definition omf.h:1093
std::variant< ExternalIndex, SegmentIndex, SegmentClassOverlayNames, LoadTimeLocatable, Absolute > component
The contents of the component.
Definition omf.h:1098
A record that defines a segment group, used for GRPDEF records.
Definition omf.h:1060
std::vector< Component > components
The components of the group, such as member segments or load address.
Definition omf.h:1111
NameIndex name
Name of the group.
Definition omf.h:1109
A rich container for indexes referring to a GRPDEF record.
Definition omf.h:478
Initialization data for common segments, used for COMDAT (included in TIS)
Definition omf.h:1727
bool iterated
Set if the format of the data is iterated, cleared for enumerated.
Definition omf.h:1732
bool local
Local common segment.
Definition omf.h:1734
bool continued
Set if this record is the continuation of a previous record, cleared if it is a new record.
Definition omf.h:1730
bool code_segment
Set if the data is to be placed in a code segment.
Definition omf.h:1736
Represents a line number, used by LineNumbersRecord and SymbolLineNumbersRecord.
Definition omf.h:676
uint32_t offset
The offset in memory where the line starts.
Definition omf.h:681
uint16_t number
The line number value.
Definition omf.h:679
Stores as debugging data the line number information, used for LINNUM.
Definition omf.h:1275
BaseSpecification base
The first byte of the segment containing the line.
Definition omf.h:1278
std::vector< LineNumber > lines
List of lines.
Definition omf.h:1281
A list of names to be referenced, used for LNAMES and LLNAMES records.
Definition omf.h:913
index_t first_lname
Index of the first name in the module.
Definition omf.h:918
std::vector< std::string > names
List of names (only needed for genering OMF files.
Definition omf.h:916
uint16_t lname_count
Number of names appearing in this record.
Definition omf.h:920
Logical enumerated or iterated data, used for LEDATA and LIDATA.
Definition omf.h:1416
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1423
SegmentIndex segment
Segment that contains this data.
Definition omf.h:1419
uint32_t offset
Offset within segment where the data starts.
Definition omf.h:1421
Terminates a module, used for MODEND.
Definition omf.h:1640
bool main_module
Set if this is a main module.
Definition omf.h:1643
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:1645
A header record, used for THEADR and LHEADR.
Definition omf.h:845
std::string name
The name of the record.
Definition omf.h:848
Represents a single module inside the OMF file.
Definition omf.h:2119
std::vector< std::shared_ptr< BlockDefinitionRecord > > blkdefs
List of blocks declared in the module.
Definition omf.h:2135
std::vector< std::shared_ptr< GroupDefinitionRecord > > grpdefs
List of groups declared in the module.
Definition omf.h:2131
std::vector< ExternalName > extdefs
List of external symbols declared in the module.
Definition omf.h:2139
std::vector< std::string > lnames
List of names declared in the module.
Definition omf.h:2127
std::vector< std::shared_ptr< TypeDefinitionRecord > > typdefs
List of types declared in the module.
Definition omf.h:2133
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:2122
std::vector< std::shared_ptr< OverlayDefinitionRecord > > ovldefs
List of overlays declared in the module.
Definition omf.h:2137
std::vector< std::shared_ptr< SegmentDefinitionRecord > > segdefs
List of segments declared in the module.
Definition omf.h:2129
size_t record_count
The number of records belonging to this module.
Definition omf.h:2124
A rich container for indexes referring to a LNAME/LLNAME declaration.
Definition omf.h:446
A specialized relocation for named common segments, used for NBKPAT (included in TIS)
Definition omf.h:1701
uint8_t type
The type of the relocations.
Definition omf.h:1707
NameIndex name
The name of the common segment to which the relocations belong to.
Definition omf.h:1709
The version of the OMF format, used for VERNUM (included in TIS)
Definition omf.h:1839
std::string version
Textual representation of the version number.
Definition omf.h:1842
A record that defines an overlay, used for OVLDEF records.
Definition omf.h:1530
size_t first_data_record_index
Index of the first overlay data record within the file.
Definition omf.h:1537
std::optional< OverlayIndex > shared_overlay
Must be loaded at the same location as the shared overlay.
Definition omf.h:1539
std::string name
Name of the overlay.
Definition omf.h:1533
uint32_t location
Offset to the first overlay data record within the file.
Definition omf.h:1535
std::optional< OverlayIndex > adjacent_overlay
Must be loaded adjacent to the adjacent overlay.
Definition omf.h:1541
A rich container for indexes referring to a OVLDEF record.
Definition omf.h:530
Physical enumerated or iterated data, used for PEDATA and PIDATA (Intel only)
Definition omf.h:1397
uint32_t address
Physical address where data starts.
Definition omf.h:1400
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1402
A header record for an R-Module, used for RHEADR (not part of TIS OMF)
Definition omf.h:862
uint32_t maximum_dynamic_storage
Maximum memory size to allocate on load.
Definition omf.h:894
uint32_t dynamic_storage
Memory size to allocate on load.
Definition omf.h:892
module_type_t module_type
The type of the module.
Definition omf.h:877
uint16_t group_record_count
Number of group definition records in module.
Definition omf.h:881
module_type_t
Represents the type of the module.
Definition omf.h:869
uint32_t static_size
Total size of LTL segments.
Definition omf.h:888
uint16_t segment_record_count
Number of segment definition records in module.
Definition omf.h:879
uint32_t maximum_static_size
Maximum size needed for all LTL segments.
Definition omf.h:890
uint32_t overlay_record_offset
Offset to the first overlay definition record from the start of the file or 0.
Definition omf.h:885
uint16_t overlay_record_count
Number of overlay definition records in module.
Definition omf.h:883
Module * mod
The module object this record appears in.
Definition omf.h:865
Represents a reference for a relocation.
Definition omf.h:725
std::variant< ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute > frame
The frame for a reference, or a thread number.
Definition omf.h:733
unsigned ThreadNumber
A number between 0 and 3.
Definition omf.h:728
std::variant< ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber > target
The target for a reference, or a thread number.
Definition omf.h:731
uint32_t displacement
Displacement to be added to the value.
Definition omf.h:735
Used to initialize the register.
Definition omf.h:1602
uint16_t offset
An offset, needed for CS:IP and SS:SP.
Definition omf.h:1607
BaseSpecification base
The segment base.
Definition omf.h:1605
A single initialization entry.
Definition omf.h:1585
register_t
Register type that can be initialized.
Definition omf.h:1589
@ DS
The DS segment register, the default data segment.
Definition omf.h:1595
@ ES
The ES segment register.
Definition omf.h:1597
@ CS_IP
The CS and IP register pair, it signifies the starting address as a far pointer.
Definition omf.h:1591
@ SS_SP
The SS and SP register pair, it signifies the initial stack as a far pointer.
Definition omf.h:1593
std::variant< Reference, InitialValue > value
The initial value of the register.
Definition omf.h:1612
register_t reg_id
The register to initialize.
Definition omf.h:1610
Initialization values for registers, used for REGINT (Intel only)
Definition omf.h:1581
std::vector< Register > registers
List of registers to be initialized.
Definition omf.h:1623
Relocatable enumerated or iterated data, used for REDATA and RIDATA (Intel only)
Definition omf.h:1373
std::shared_ptr< DataBlock > data
The data contents.
Definition omf.h:1380
uint16_t offset
Offset within paragraph where data starts.
Definition omf.h:1378
BaseSpecification base
Reference to paragraph that contains this data.
Definition omf.h:1376
Additional data for LTL segment, not part of TIS.
Definition omf.h:978
A record that defines a segment, used for SEGDEF records.
Definition omf.h:937
combination_t
Describes how two segments of the same name and class name should be combined.
Definition omf.h:990
@ Combination_Join_High
Merges the two segments at their highest address, adds their sizes (Intel interpretation)
Definition omf.h:1002
@ Combination_Private
Do not combine segments, also known as Private.
Definition omf.h:992
@ Combination_Stack
Same as Public, but for stack segments.
Definition omf.h:1004
@ Combination_Join_Low
Merges the two segments at their lowest address, adds their sizes (Intel interpretation)
Definition omf.h:999
@ Combination_Merge_High
Merges the two segments at their highest address, their size is the maximum (Intel interpretation)
Definition omf.h:1009
@ Combination_Merge_Low
Merges the two segments at their lowest address, their size is the maximum (Intel interpretation)
Definition omf.h:1006
@ Combination_Append
Appends the segments, also known as Public.
Definition omf.h:996
@ Combination_Merge_Highest
Like Combination_Merge_High, but also places the segment above all other segments (not used by TIS)
Definition omf.h:994
NameIndex class_name
The name of the segment's class (not used for AlignUnnamed)
Definition omf.h:1024
NameIndex segment_name
The name of the segment (not used for AlignUnnamed)
Definition omf.h:1022
combination_t combination
How segments of the same type should be combined.
Definition omf.h:1014
alignment_t alignment
Alignment of segment.
Definition omf.h:968
bool use32
Set if the USE32 directive is used for the segment. The field appears in different places for Phar La...
Definition omf.h:1019
std::variant< Relocatable, Absolute, LoadTimeLocatable > location
Information on where the segment should be placed at runtime.
Definition omf.h:986
uint64_t segment_length
The length of the segment (maximum 0x100000000)
Definition omf.h:940
std::shared_ptr< Linker::Section > linker_section
The section that gets generated during parsing the OMF file.
Definition omf.h:1041
bool page_resident
Set if the segment should not cross a 256 byte page boundary (only Intel)
Definition omf.h:1017
access_t
Represents an additional field used by Phar Lap.
Definition omf.h:1030
NameIndex overlay_name
The name of the overlay the segment appears in (not used for AlignUnnamed)
Definition omf.h:1026
std::optional< access_t > access
Represents the value of a Phar Lap specific extension word.
Definition omf.h:1038
alignment_t
Alignment type for a segment.
Definition omf.h:943
@ Align16
Relocatable segment, paragraph (16-byte) aligned.
Definition omf.h:951
@ Align256
Relocatable segment, page (256-byte) aligned, as defined by Intel.
Definition omf.h:958
@ AlignLTL16
Load-time locatable or, if not part of a group, paragraph (16-byte) aligned (Intel only)
Definition omf.h:955
@ Align2
Relocatable segment, word (2-byte) aligned.
Definition omf.h:949
@ Align4
Relocatable segment, double word (4-byte) aligned, type 5 as defined by TIS.
Definition omf.h:964
@ Align4096
Relocatable segment, page (4096-byte) aligned, as used by IBM.
Definition omf.h:960
@ AlignUnnamed
Unnamed absolute portion of the memory address space, type 5 as defined by Intel.
Definition omf.h:962
@ AlignAbsolute
Absolute segment, its position in memory is fixed.
Definition omf.h:945
@ AlignPage
Relocatable segment, page aligned, exact size depends on OMF version.
Definition omf.h:953
@ Align1
Relocatable segment, byte aligned.
Definition omf.h:947
uint32_t Absolute
Additional data used for absolute segments, type 0 or 5 if Intel version is used.
Definition omf.h:971
A rich container for indexes referring to a SEGDEF record.
Definition omf.h:462
Represents a symbol definition, used by SymbolDefinitionsRecord and DebugSymbolsRecord.
Definition omf.h:655
std::string name
The name of the symbol.
Definition omf.h:660
bool local
Set to true if the symbol is local.
Definition omf.h:658
uint32_t offset
The offset (value) of the symbol.
Definition omf.h:662
TypeIndex type
The type of the symbol, or 0.
Definition omf.h:664
Line numbers for common segments, used by LINSYM (included in TIS)
Definition omf.h:1785
std::vector< LineNumber > line_numbers
The line numbers.
Definition omf.h:1792
bool continued
Set if this record is the continuation of a previous record, cleared if it is a new record.
Definition omf.h:1788
NameIndex name
The name of the common segment to which the line numbers belong to.
Definition omf.h:1790
A record that defines a symbol, used by PUBDEF, LPUBDEF, LOCSYM.
Definition omf.h:1230
std::vector< SymbolDefinition > symbols
A list of symbols.
Definition omf.h:1236
BaseSpecification base
The first byte of the segment containing the symbol.
Definition omf.h:1233
A single item in a type definition.
Definition omf.h:1138
static constexpr uint8_t RepeatLeaf
Type byte for a repeat leaf leaf.
Definition omf.h:1158
static constexpr uint8_t NumericLeaf24
Type byte for an unsigned 24-bit leaf.
Definition omf.h:1162
bool nice
Set to false if "easy", true if "nice".
Definition omf.h:1141
std::variant< uint32_t, int32_t, std::string, TypeIndex, Null, Repeat > leaf
The actual contents of the leaf.
Definition omf.h:1149
static constexpr uint8_t StringLeaf
Type byte for a string leaf.
Definition omf.h:1154
static constexpr uint8_t NullLeaf
Type byte for a null leaf.
Definition omf.h:1152
static constexpr uint8_t SignedNumericLeaf16
Type byte for an signed 16-bit leaf.
Definition omf.h:1166
static constexpr uint8_t NumericLeaf16
Type byte for an unsigned 16-bit leaf.
Definition omf.h:1160
static constexpr uint8_t SignedNumericLeaf32
Type byte for an signed 32-bit leaf.
Definition omf.h:1168
static constexpr uint8_t IndexLeaf
Type byte for an index leaf, usually a type index.
Definition omf.h:1156
static constexpr uint8_t SignedNumericLeaf8
Type byte for an signed 8-bit leaf.
Definition omf.h:1164
A record that defines a data type, used for TYPDEF records.
Definition omf.h:1134
std::vector< LeafDescriptor > leafs
The parameters of this type.
Definition omf.h:1181
std::string name
The name of this type.
Definition omf.h:1179
A rich container for indexes referring to a TYPDEF record.
Definition omf.h:498
Vendor specific extension to the OMF format, used for VENDEXT (included in TIS)
Definition omf.h:1856
uint16_t vendor_number
Assigned vendor identifier.
Definition omf.h:1859
std::vector< uint8_t > extension
Extension data.
Definition omf.h:1861
Intel Relocatable Object Module format, used by various 16/32-bit DOS based compilers and linkers,...
Definition omf.h:373
static constexpr unsigned int FlagIntel
Flag binary or'ed to certain values to mark Intel interpretation.
Definition omf.h:407
@ MethodGroup
References a group defined in a module, for either targets or frames.
Definition omf.h:419
@ MethodFrame
References a physical paragraph address in a module, for either targets or frames.
Definition omf.h:423
@ MethodAbsolute
No frame is provided, intended for Intel 8089, only the Intel version supports it,...
Definition omf.h:429
@ MethodExternal
References a external symbol declared in a module, for either targets or frames.
Definition omf.h:421
@ MethodSegment
References a segment defined in a module, for either targets or frames.
Definition omf.h:417
@ MethodSource
References the frame of the relocation source, only for frames.
Definition omf.h:425
@ MethodTarget
References the frame of the relocation target, only for frames.
Definition omf.h:427
void ReadFile(const std::shared_ptr< Linker::Reader > &rd) override
Loads file into memory.
Definition omf.cc:4465
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:4493
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:2147
std::shared_ptr< Record > ReadRecord(const std::shared_ptr< Linker::Reader > &rd)
Parses and returns an instance of the next record.
Definition omf.cc:4292
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:2144
static constexpr unsigned int FlagPharLap
Flag binary or'ed to certain values to mark Phar Lap interpretation.
Definition omf.h:409
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:4548
static constexpr unsigned int FlagTIS
Flag binary or'ed to certain values to mark TIS interpretation.
Definition omf.h:411
static std::shared_ptr< OMF86Format > ReadOMFFile(const std::shared_ptr< Linker::Reader > &rd)
Parses an OMF86 file.
Definition omf.cc:4453
omf_version_t
Represents the various variants of the OMF file format, some of them are incompatible.
Definition omf.h:385
@ OMF_VERSION_INTEL_40
The original Intel definition, version 4.0 (including any extensions that are compatible)
Definition omf.h:387
@ OMF_VERSION_TIS_11
Version 1.1 produced and consolidated by the Tool Interface Standard.
Definition omf.h:395
@ OMF_VERSION_PHARLAP
Phar Lap's extensions, mostly concerning 32-bit (partly incompatible with later versions)
Definition omf.h:389
@ OMF_VERSION_IBM
Format generated by IBM's tools (partly incompatible with other versions)
Definition omf.h:393
@ OMF_VERSION_MICROSOFT
Format generated by Microsoft's tools (partly incompatible with other versions)
Definition omf.h:391
record_type_t
The recognized record types in an OMF86 file.
Definition omf.h:760
uint16_t FrameNumber
Represents a MethodFrame value.
Definition omf.h:433
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr) const override
Stores data in memory to file.
Definition omf.cc:4486
omf_version_t omf_version
The variant of the OMF format, needed to handle certain fields.
Definition omf.h:399
Definition omf.h:3476
size_t record_count
The number of records belonging to this module.
Definition omf.h:3481
size_t first_record
The index of the first record inside the file, stored in the OMF86Format objects.
Definition omf.h:3479
static constexpr uint8_t StringLeaf
Type byte for a string leaf.
Definition omf.h:3291
static constexpr uint8_t SignedNumericLeaf32
Type byte for an signed 32-bit leaf.
Definition omf.h:3289
static constexpr uint8_t NullLeaf
Type byte for a null leaf.
Definition omf.h:3285
static constexpr uint8_t EndOfBranchLeaf
Type byte for an end of branch leaf.
Definition omf.h:3297
static constexpr uint8_t SignedNumericLeaf16
Type byte for an signed 16-bit leaf.
Definition omf.h:3287
static constexpr uint8_t IndexLeaf
Type byte for an index leaf, usually a type index.
Definition omf.h:3293
static constexpr uint8_t RepeatLeaf
Type byte for a repeat leaf leaf.
Definition omf.h:3295
std::vector< LeafDescriptor > leafs
The parameters of this type.
Definition omf.h:3308
Definition omf.h:3162
Intel Relocatable Object Module for the Intel MCS-96.
Definition omf.h:3044
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:6959
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr) const override
Stores data in memory to file.
Definition omf.cc:6952
static std::shared_ptr< OMF96Format > ReadOMFFile(const std::shared_ptr< Linker::Reader > &rd)
Parses an OMF96 file.
Definition omf.cc:6927
void ReadFile(const std::shared_ptr< Linker::Reader > &rd) override
Loads file into memory.
Definition omf.cc:6939
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:6985
std::shared_ptr< Record > ReadRecord(const std::shared_ptr< Linker::Reader > &rd)
Parses and returns an instance of the next record.
Definition omf.cc:6852
std::vector< std::shared_ptr< Record > > records
The ordered collection of records contained in the file.
Definition omf.h:3488
std::vector< Module > modules
List of modules appearing in an OMF file, typically only one for an object file.
Definition omf.h:3491
Definition omf.h:3508
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition omf.cc:7016
void ReadFile(const std::shared_ptr< Linker::Reader > &rd) override
Loads file into memory.
Definition omf.cc:6992
offset_t WriteFile(const std::shared_ptr< Linker::Writer > &wr) const override
Stores data in memory to file.
Definition omf.cc:7006
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:6997
offset_t ImageSize() const override
Retrieves the offset of the byte after the last one belonging to this format from the first one.
Definition omf.cc:7011
A record representing data to be loaded into a segment.
Definition omf.h:215
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:181
void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:187
void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:172
A record type that has no contents, aside from the type, length and checksum, used for BLKEND.
Definition omf.h:188
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:199
void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.h:195
void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.h:204
std::vector< std::string > names
List of public symbols for one library module.
Definition omf.h:342
All public symbols of all modules, used for LIBDIC.
Definition omf.h:336
void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:396
void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:375
std::vector< Group > groups
List of public symbols, grouped by library modules.
Definition omf.h:350
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:385
Library header record, used for LIBHED.
Definition omf.h:266
uint16_t block_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:271
uint16_t module_count
Number of modules contained.
Definition omf.h:269
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:251
void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:243
void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:257
uint16_t byte_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:273
Library module offsets, used for LIBLOC.
Definition omf.h:306
void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:331
void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:316
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:325
std::vector< Location > locations
List of starting locations, one for each library module.
Definition omf.h:321
Library module names, used for LIBNAM.
Definition omf.h:288
std::vector< std::string > names
List of module names.
Definition omf.h:291
void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:267
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:276
void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:287
A record representing line number information.
Definition omf.h:238
void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc: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.cc:225
void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:215
Base class representing OMF record types.
Definition omf.h:74
offset_t record_offset
Offset of record within the file.
Definition omf.h:77
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:149
virtual void WriteRecord(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Writer > &wr) const
Writes the full record.
Definition omf.h:105
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:143
virtual void ResolveReferences(FormatType *omf, ModuleType *mod)
Resolves any fields read from an OMF module, should be called after inpnut.
Definition omf.h:123
RecordTypeByte record_type
A byte value identifying the type of record.
Definition omf.h:81
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:115
virtual void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const =0
Writes 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:79
virtual void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd)=0
Reads the record contents, except for the type, length and checksum.
An unparsed record type, if the format is not recognized.
Definition omf.h:158
void WriteRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< ChecksumWriter > &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.h:179
void ReadRecordContents(FormatType *omf, ModuleType *mod, const std::shared_ptr< Linker::Reader > &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.h:168
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:174
std::vector< uint8_t > data
Contents of the record, without the type, length and checksum.
Definition omf.h:161
Base class for a family of Intel Relocatable Object formats.
Definition omf.h:44
static void WriteIndex(const std::shared_ptr< ChecksumWriter > &wr, index_t index)
Produces a 1 or 2 byte index value.
Definition omf.cc:70
offset_t file_size
Used to calculate record offsets when generating OMF file.
Definition omf.h:366
static index_t ReadIndex(const std::shared_ptr< Linker::Reader > &rd)
Parses a 1 or 2 byte index value.
Definition omf.cc:60
static std::string ReadString(const std::shared_ptr< Linker::Reader > &rd, size_t max_bytes=size_t(-1))
Reads a string prefixed with a length byte.
Definition omf.cc:48
static void WriteString(const std::shared_ptr< ChecksumWriter > &wr, std::string text)
Writes a string prefixed with a length byte.
Definition omf.cc:54
static std::shared_ptr< OMFFormat > ReadOMFFile(const std::shared_ptr< Linker::Reader > &rd)
Attempts to parse an OMF file, whether OMF80, OMF86, OMF51 or OMF96.
Definition omf.cc:95
static size_t IndexSize(index_t index)
Determines if the index value requires 1 or 2 bytes to store.
Definition omf.cc:83
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:55
Type representing the group and segment of some reference.
Definition omf.h:637
Type representing a relocatable segment.
Definition omf.h:974
Represents a null leaf.
Definition omf.h:1144
Represents a final repeat leaf, meaning that the data in this type should be repeated indefinitely.
Definition omf.h:1146
Represents a MethodAbsolute value.
Definition omf.h:442
Represents a MethodSource value.
Definition omf.h:436
Represents a MethodTarget value.
Definition omf.h:439
Represents a null leaf.
Definition omf.h:3276
Represents a final repeat leaf, meaning that the data in this type should be repeated indefinitely.
Definition omf.h:3278
uint16_t byte_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:314
uint16_t block_number
Offset to the first byte of the library module, as a block:byte pair.
Definition omf.h:312