8#include "../dumper/dumper.h"
9#include "../linker/module.h"
10#include "../linker/segment.h"
11#include "../linker/segment_manager.h"
12#include "../linker/writer.h"
67 OMF_VERSION_0 = 0x0000,
68 OMF_VERSION_1 = 0x0100,
69 OMF_VERSION_2 = 0x0200,
70 OMF_VERSION_2_1 = 0x0201,
116 ::EndianType GetEndianType()
const;
119 offset_t
ReadUnsigned(
const std::shared_ptr<Linker::Reader>& rd)
const;
121 void WriteWord(
const std::shared_ptr<Linker::Writer>& wr, offset_t value)
const;
124 std::string
ReadLabel(
const std::shared_ptr<Linker::Reader>& rd)
const;
126 void WriteLabel(
const std::shared_ptr<Linker::Writer>& wr, std::string text)
const;
135 void ReadFile(
const std::shared_ptr<Linker::Reader>& rd);
136 void WriteFile(
const std::shared_ptr<Linker::Writer>& wr)
const;
139 size_t ReadData(
size_t bytes, offset_t offset,
void * buffer)
const;
140 offset_t
ReadUnsigned(
size_t bytes, offset_t offset)
const;
156 Multiplication = 0x03,
158 IntegerRemainder = 0x05,
165 LessOrEqualTo = 0x0C,
166 GreaterOrEqualTo = 0x0D,
175 LocationCounterOperand = 0x80,
176 ConstantOperand = 0x81,
177 WeakLabelReferenceOperand = 0x82,
178 LabelReferenceOperand = 0x83,
179 LengthOfLabelReferenceOperand = 0x84,
180 TypeOfLabelReferenceOperand = 0x85,
181 CountOfLabelReferenceOperand = 0x86,
182 RelativeOffsetOperand = 0x87,
193 std::optional<std::variant<offset_t, std::string>>
value;
203 operands.emplace_back(std::move(operand));
206 Expression(
int operation, std::unique_ptr<Expression>& operand1, std::unique_ptr<Expression>& operand2)
209 operands.emplace_back(std::move(operand1));
210 operands.emplace_back(std::move(operand2));
223 offset_t GetLength(
const Segment& segment)
const;
224 void ReadFile(Segment& segment,
const std::shared_ptr<Linker::Reader>& rd);
225 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const;
230 void PopElementsInto(
size_t count, std::vector<std::unique_ptr<Expression>>& target);
252 typedef precedence::precedence_type precedence_type;
264 OPC_CONST_BASE = 0x00,
265 OPC_CONST_FIRST = 0x01,
266 OPC_CONST_LAST = 0xDF,
287 OPC_C_INTERSEG = 0xF6,
308 virtual void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd);
309 virtual void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const;
326 virtual void ReadData(
size_t bytes, offset_t offset,
void * buffer)
const;
333 std::shared_ptr<Linker::Contents> image;
335 DataRecord(record_type type, std::shared_ptr<Linker::Contents> image)
336 :
Record(type), image(image)
347 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
348 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
350 void ReadData(
size_t bytes, offset_t offset,
void * buffer)
const override;
360 :
Record(type), value(value)
366 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
367 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
369 void ReadData(
size_t bytes, offset_t offset,
void * buffer)
const override;
386 RelocationRecord(record_type type, uint8_t size, int8_t shift, offset_t source, offset_t target)
387 :
Record(type), size(size), shift(shift), source(source), target(target)
392 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
393 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
402 uint16_t file_number = 0;
403 uint16_t segment_number = 0;
415 IntersegmentRelocationRecord(record_type type, uint8_t size, uint8_t shift, offset_t source, uint16_t file_number, uint16_t segment_number, offset_t target)
416 :
RelocationRecord(type, size, shift, source, target), file_number(file_number), segment_number(segment_number)
421 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
422 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
433 :
Record(type), name(name)
438 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
439 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
448 uint16_t line_length = 0;
459 OP_REF_ADDRESS_DC =
'K',
460 OP_SOFT_REF_DC =
'L',
461 OP_INSTRUCTION =
'M',
462 OP_ASM_DIRECTIVE =
'N',
466 OP_ARITHMETIC_SYMBOL =
'X',
467 OP_BOOL_SYMBOL =
'Y',
470 operation_type operation = operation_type(0);
471 uint16_t private_flag = 0;
478 LabelRecord(record_type type, std::string name, uint16_t line_length,
int operation, uint16_t private_flag)
479 :
Record(type), name(name), line_length(line_length), operation(operation_type(operation)), private_flag(private_flag)
484 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
485 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
493 std::unique_ptr<Expression> expression;
500 LabelExpressionRecord(record_type type, std::string name, uint16_t line_length,
int operation, uint16_t private_flag, std::unique_ptr<Expression> expression)
501 :
LabelRecord(type, name, line_length, operation, private_flag), expression(std::move(expression))
506 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
507 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
523 RangeRecord(record_type type, offset_t start, offset_t end)
524 :
Record(type), start(start), end(end)
529 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
530 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
539 std::unique_ptr<Expression> expression;
546 ExpressionRecord(record_type type, uint8_t size, std::unique_ptr<Expression> expression)
547 :
Record(type), size(size), expression(std::move(expression))
553 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
554 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
556 void ReadData(
size_t bytes, offset_t offset,
void * buffer)
const override;
576 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
577 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
585 uint16_t segment_number;
594 EntryRecord(record_type type, uint16_t segment_number, offset_t location, std::string name)
595 :
Record(type), segment_number(segment_number), location(location), name(name)
600 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
601 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
609 enum super_record_type
614 SUPER_INTERSEG13 = SUPER_INTERSEG1 - 1 + 13,
615 SUPER_INTERSEG25 = SUPER_INTERSEG1 - 1 + 25,
616 SUPER_INTERSEG36 = SUPER_INTERSEG1 - 1 + 36,
619 super_record_type super_type = super_record_type(0);
621 std::vector<uint16_t> offsets;
623 SuperCompactRecord(record_type type, super_record_type super_type = super_record_type(0))
624 :
Record(type), super_type(super_type)
629 void ReadFile(
Segment& segment,
const std::shared_ptr<Linker::Reader>& rd)
override;
630 void WriteFile(
const Segment& segment,
const std::shared_ptr<Linker::Writer>& wr)
const override;
632 void WritePatchList(
const std::shared_ptr<Linker::Writer>& wr,
const std::vector<uint8_t>& patches)
const;
645 std::vector<std::unique_ptr<Record>> records;
647 std::unique_ptr<Expression> ReadExpression(
const std::shared_ptr<Linker::Reader>& rd);
649 std::unique_ptr<Record> ReadRecord(
const std::shared_ptr<Linker::Reader>& rd);
651 std::unique_ptr<Record> makeEND();
652 std::unique_ptr<Record> makeCONST(std::shared_ptr<Linker::Contents> image);
653 std::unique_ptr<Record> makeCONST(
size_t length);
654 std::unique_ptr<Record> makeALIGN(offset_t
align = 0);
655 std::unique_ptr<Record> makeORG(offset_t value = 0);
656 std::unique_ptr<Record> makeRELOC(uint8_t size, uint8_t shift, offset_t source, offset_t target);
657 std::unique_ptr<Record> makeRELOC();
658 std::unique_ptr<Record> makeINTERSEG(uint8_t size, uint8_t shift, offset_t source, uint16_t file_number, uint16_t
segment_number, offset_t target);
659 std::unique_ptr<Record> makeINTERSEG();
660 std::unique_ptr<Record> makeUSING(std::string name =
"");
661 std::unique_ptr<Record> makeSTRONG(std::string name =
"");
662 std::unique_ptr<Record> makeGLOBAL();
663 std::unique_ptr<Record> makeGLOBAL(std::string name, uint16_t line_length,
int operation, uint16_t private_flag);
664 std::unique_ptr<Record> makeGEQU();
665 std::unique_ptr<Record> makeGEQU(std::string name, uint16_t line_length,
int operation, uint16_t private_flag, std::unique_ptr<Expression> expression);
666 std::unique_ptr<Record> makeMEM();
667 std::unique_ptr<Record> makeMEM(offset_t start, offset_t end);
668 std::unique_ptr<Record> makeEXPR();
669 std::unique_ptr<Record> makeEXPR(uint8_t size, std::unique_ptr<Expression> expression);
670 std::unique_ptr<Record> makeZEXPR();
671 std::unique_ptr<Record> makeZEXPR(uint8_t size, std::unique_ptr<Expression> expression);
672 std::unique_ptr<Record> makeBEXPR();
673 std::unique_ptr<Record> makeBEXPR(uint8_t size, std::unique_ptr<Expression> expression);
674 std::unique_ptr<Record> makeRELEXPR();
675 std::unique_ptr<Record> makeRELEXPR(uint8_t size, offset_t origin, std::unique_ptr<Expression> expression);
676 std::unique_ptr<Record> makeLOCAL();
677 std::unique_ptr<Record> makeLOCAL(std::string name, uint16_t line_length,
int operation, uint16_t private_flag);
678 std::unique_ptr<Record> makeEQU();
679 std::unique_ptr<Record> makeEQU(std::string name, uint16_t line_length,
int operation, uint16_t private_flag, std::unique_ptr<Expression> expression);
680 std::unique_ptr<Record> makeDS(offset_t count = 0);
681 std::unique_ptr<Record> makeLCONST();
682 std::unique_ptr<Record> makeLCONST(std::shared_ptr<Linker::Contents> image);
683 std::unique_ptr<Record> makeLEXPR();
684 std::unique_ptr<Record> makeLEXPR(uint8_t size, std::unique_ptr<Expression> expression);
685 std::unique_ptr<Record> makeENTRY();
686 std::unique_ptr<Record> makeENTRY(uint16_t
segment_number, offset_t location, std::string name);
687 std::unique_ptr<Record> makecRELOC(uint8_t size, uint8_t shift, uint16_t source, uint16_t target);
688 std::unique_ptr<Record> makecRELOC();
689 std::unique_ptr<Record> makecINTERSEG(uint8_t size, uint8_t shift, uint16_t source, uint16_t
segment_number, uint16_t target);
690 std::unique_ptr<Record> makecINTERSEG();
691 std::unique_ptr<Record> makeSUPER(SuperCompactRecord::super_record_type super_type = SuperCompactRecord::super_record_type(0));
694 std::vector<std::unique_ptr<Segment>> segments;
697 void ReadFile(
const std::shared_ptr<Linker::Reader>& rd)
override;
699 offset_t
WriteFile(
const std::shared_ptr<Linker::Writer>& wr)
const override;
711 static constexpr uint32_t FreeBlockSize = 8;
712 static constexpr uint32_t ReferenceRecordSize = 20;
714 uint32_t file_version = 0;
715 uint32_t file_to_map = 0;
716 uint32_t file_map_size = 0;
717 std::shared_ptr<Linker::Contents> file_memo;
719 uint32_t map_next = 0;
720 uint16_t map_flag = 0;
721 uint32_t map_offset = 0;
722 uint32_t map_size = 0;
723 uint16_t map_to_index = 0;
724 uint16_t map_file_num = 0;
726 uint32_t map_index_size = 0;
727 uint32_t map_index_used = 0;
728 uint16_t map_free_list_size = 0;
729 uint16_t map_free_list_used = 0;
737 static FreeBlock ReadFile(
const std::shared_ptr<Linker::Reader>& rd);
738 void WriteFile(
const std::shared_ptr<Linker::Writer>& wr)
const;
748 uint16_t attributes = 0;
752 std::shared_ptr<Linker::Contents> image;
754 static std::shared_ptr<ReferenceRecord> ReadFile(
const std::shared_ptr<Linker::Reader>& rd);
755 void WriteFile(
const std::shared_ptr<Linker::Writer>& wr)
const;
758 void WriteContents(
const GSOSResourceFileFormat& format,
const std::shared_ptr<Linker::Writer>& wr)
const;
762 std::vector<FreeBlock> free_list;
763 std::vector<std::shared_ptr<ReferenceRecord>> map_index;
766 void ReadFile(
const std::shared_ptr<Linker::Reader>& rd)
override;
768 offset_t
WriteFile(
const std::shared_ptr<Linker::Writer>& wr)
const override;
813 enum file_type_t : uint8_t
815 FILE_TYPE_BIN = 0x06,
816 FILE_TYPE_SOS = 0x0C,
817 FILE_TYPE_S16 = 0xB3,
818 FILE_TYPE_EXE = 0xB5,
819 FILE_TYPE_SYS = 0xFF,
This is not actually a file format, but an interface to permit generating multiple binary outputs for...
Definition gsos.h:783
std::shared_ptr< GSOSResourceFileFormat > resource_fork
Definition gsos.h:838
produce_format_t
Represents what additional files should be generated.
Definition gsos.h:803
@ PRODUCE_RESOURCE_FORK
Places a GS/OS format resource file under the directory .rsrc.
Definition gsos.h:805
@ PRODUCE_APPLE_DOUBLE
Creates an AppleDouble binary with the '' prefix.
Definition gsos.h:807
@ PRODUCE_NAPS_SUFFIX
NuLib2 attribute preservation string suffix, such as #06xxxx.
Definition gsos.h:809
target_format_t
Represents the file type of the main file.
Definition gsos.h:787
@ TARGET_RESOURCE_FORK
Main file is a resource fork.
Definition gsos.h:793
@ TARGET_APPLE_SINGLE
Main file is an AppleSingle.
Definition gsos.h:795
@ TARGET_DATA_FORK
Main file is a data fork, typically empty.
Definition gsos.h:791
@ TARGET_APPLE_DOUBLE
Main file is an AppleDouble.
Definition gsos.h:797
@ TARGET_NONE
Do not generate main file.
Definition gsos.h:789
Represents an ENTRY record.
Definition gsos.h:583
void AddFields(Dumper::Dumper &dump, Dumper::Region ®ion, const OMFFormat &omf, const Segment &segment, unsigned index, offset_t file_offset, offset_t address) const override
Adds any further fields to the file region that encompasses this record.
Definition gsos.cc:1286
offset_t GetLength(const Segment &segment) const override
Returns the size of the record, as stored in the file.
Definition gsos.cc:1266
This is not actually a file format, but an interface to permit generating multiple binary outputs for...
Definition apple.h:709
produce_format_t
Represents what additional files should be generated.
Definition apple.h:731
@ PRODUCE_NAPS_SUFFIX
NuLib2 attribute preservation string suffix, such as #06xxxx (Apple II, III, IIgs only)
Definition apple.h:741
@ PRODUCE_RESOURCE_FORK
Places a GS/OS format resource file under the directory .rsrc.
Definition apple.h:733
@ PRODUCE_APPLE_DOUBLE
Creates an AppleDouble binary with the '' prefix.
Definition apple.h:737
target_format_t target
Format of "filename".
Definition apple.h:746
@ TARGET_DATA_FORK
Main file is a data fork, typically empty.
Definition apple.h:717
@ TARGET_RESOURCE_FORK
Main file is a resource fork.
Definition apple.h:719
@ TARGET_APPLE_SINGLE
Main file is an AppleSingle.
Definition apple.h:721
@ TARGET_NONE
Do not generate main file.
Definition apple.h:715
@ TARGET_APPLE_DOUBLE
Main file is an AppleDouble.
Definition apple.h:723
produce_format_t produce
Bitset of other files to produce.
Definition apple.h:749
A region within a file that can be dumped, decompiled, and it may contain fixups.
Definition dumper.h:941
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:1009
A record that represents a region within the file.
Definition dumper.h:902
A helper class to collect sections into segments.
Definition segment_manager.h:32
offset_t current_address
Holds the current address value when there is no current_segment.
Definition segment_manager.h:37