7#include "../dumper/dumper.h"
8#include "../linker/format.h"
9#include "../linker/reader.h"
10#include "../linker/writer.h"
30 void WriteWord(
size_t bytes, uint64_t value)
33 for(
size_t offset = 0; offset < bytes; offset++, value >>= 8)
39 size_t WriteData(
const std::vector<uint8_t>& data)
42 for(
size_t offset = 0; offset < bytes; offset++)
44 checksum -= data[offset];
49 size_t WriteData(std::string text)
52 for(
size_t offset = 0; offset < text.size(); offset++)
54 checksum -= text[offset];
59 void Skip(offset_t count)
97 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
115 offset_t RecordEnd()
const
124 virtual uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const = 0;
152 virtual void DumpAddFields(
Dumper::Dumper& dump,
Dumper::Region& region,
const FormatType * omf,
const ModuleType * mod,
size_t record_index)
const
156 virtual void Dump(
Dumper::Dumper& dump,
const FormatType * omf,
const ModuleType * mod,
size_t record_index)
const
159 record_region.InsertField(0,
"Index", Dumper::DecDisplay::Make(), offset_t(record_index + 1));
160 record_region.AddField(
"Record type", Dumper::HexDisplay::Make(2), offset_t(
record_type));
161 FormatType::DumpAddFields(
this, dump, record_region, omf, mod, record_index);
162 DumpAddFields(dump, record_region, omf, mod, record_index);
163 record_region.Display(dump);
180 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
200 return data.size() + 1;
210 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
237 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
241 uint8_t segment_id = 0;
243 std::vector<uint8_t> data;
251 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
260 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
267 uint16_t line_number = 0;
274 uint8_t segment_id = 0;
275 std::vector<LineNumber> line_numbers;
283 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
288 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
305 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
310 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
323 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
328 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
353 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
358 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
369 uint16_t Size()
const;
382 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
487 std::shared_ptr<SegmentDefinitionRecord> record;
503 std::shared_ptr<GroupDefinitionRecord> record;
523 std::shared_ptr<TypeDefinitionRecord> record;
539 std::shared_ptr<BlockDefinitionRecord> record;
555 std::shared_ptr<OverlayDefinitionRecord> record;
597 uint8_t segment_index;
605 uint32_t element_size;
611 value.far.number = value.far.element_size = 0;
633 void CalculateValues(
OMF86Format * omf, Module * mod);
634 void ResolveReferences(
OMF86Format * omf, Module * mod);
689 uint16_t Size(
OMF86Format * omf,
bool is32bit)
const;
723 typedef std::vector<std::shared_ptr<DataBlock>>
Blocks;
725 typedef std::vector<uint8_t>
Data;
753 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber>
target =
ThreadNumber(0);
755 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute>
frame =
ThreadNumber(0);
760 uint16_t Size(
OMF86Format * omf,
bool is32bit)
const;
835 LibraryHeader = 0xF0,
839 static const std::map<offset_t, std::string> RecordTypeNames;
880 RelocatableModule = 1,
916 uint16_t GetRecordSize(
OMF86Format * omf, Module *
mod)
const override;
990 uint16_t maximum_segment_length;
991 uint16_t group_offset;
1009 Combination_Public4 =
FlagTIS | 4,
1016 Combination_Common =
FlagTIS | 6,
1019 Combination_Public7 =
FlagTIS | 4,
1041 AccessExecuteOnly = 1,
1042 AccessExecuteRead = 2,
1043 AccessReadWrite = 3,
1083 uint32_t maximum_group_length;
1084 uint32_t group_length;
1102 std::variant<ExternalIndex, SegmentIndex, SegmentClassOverlayNames, LoadTimeLocatable, Absolute>
component =
ExternalIndex();
1153 std::variant<uint32_t, int32_t, std::string, TypeIndex, Null, Repeat>
leaf =
Null();
1213 UnsignedInteger = 0x7C,
1214 SignedInteger = 0x7D,
1225 uint16_t GetRecordSize(
OMF86Format * omf, Module * mod)
const override;
1228 void CalculateValues(
OMF86Format * omf, Module * mod)
override;
1229 void ResolveReferences(
OMF86Format * omf, Module * mod)
override;
1346 enum frame_type_t : uint8_t
1352 frame_type_t frame_type;
1354 static constexpr uint8_t SymbolBaseMethod = 0x00;
1355 static constexpr uint8_t ExternalMethod = 0x01;
1356 static constexpr uint8_t BlockMethod = 0x02;
1358 std::variant<BaseSpecification, ExternalIndex, BlockIndex> base =
ExternalIndex();
1360 std::vector<SymbolDefinition> names;
1455 std::variant<SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute>
reference =
FrameNumber(0);
1646 std::optional<std::variant<Reference, std::tuple<uint16_t, uint16_t>>>
start_address;
1680 Location32bit_IBM = 9,
1711 std::vector<OffsetValuePair> offset_value_pairs;
1741 enum selection_criterion_t : uint8_t
1743 SelectNoMatch = 0x00,
1744 SelectPickAny = 0x10,
1745 SelectSameSize = 0x20,
1746 SelectExactMatch = 0x30,
1748 static constexpr uint8_t SelectionCriterionMask = 0xF0;
1749 selection_criterion_t selection_criterion;
1751 enum allocation_type_t : uint8_t
1753 AllocateExplicit = 0x00,
1754 AllocateFarCode = 0x01,
1755 AllocateFarData = 0x02,
1756 AllocateCode32 = 0x03,
1757 AllocateData32 = 0x04,
1759 static constexpr uint8_t AllocationTypeMask = 0x0F;
1760 allocation_type_t allocation_type;
1767 BaseSpecification base;
1769 std::shared_ptr<DataBlock> data;
1776 void ReadRecordContents(OMF86Format * omf, Module * mod,
Linker::Reader& rd)
override;
1777 uint16_t GetRecordSize(OMF86Format * omf, Module * mod)
const override;
1778 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr)
const override;
1780 void CalculateValues(OMF86Format * omf, Module * mod)
override;
1781 void ResolveReferences(OMF86Format * omf, Module * mod)
override;
1881 enum comment_class_t : uint8_t
1884 IntelCopyright = 0x01,
1885 LibrarySpecifier = 0x81,
1886 MSDOSVersion = 0x9C,
1889 DefaultLibrarySearchName = 0x9F,
1890 OMFExtension = 0xA0,
1891 NewOMFExtension = 0xA1,
1892 LinkPassSeparator = 0xA2,
1904 DependencyFile = 0xE9,
1907 comment_class_t comment_class;
1914 CommentRecord(comment_class_t comment_class = comment_class_t(0))
1915 :
Record(COMENT), comment_class(comment_class)
1936 std::vector<SegmentIndex> segments;
1968 std::vector<ExternalAssociation> associations;
1986 enum extension_type_t : uint8_t
1991 ProtectedModeLibrary = 0x04,
1996 extension_type_t subtype;
2010 std::string internal_name;
2011 std::string module_name;
2012 std::variant<std::string, uint16_t> entry_ident;
2029 uint8_t parameter_count;
2030 std::string exported_name;
2031 std::string internal_name;
2032 std::optional<uint16_t> ordinal;
2047 uint16_t extdef_delta;
2048 uint16_t linnum_delta;
2049 uint16_t padding_byte_count;
2064 bool new_executable;
2065 bool omit_codeview_publics;
2067 uint8_t pseudocode_version;
2068 uint8_t codeview_version;
2070 static constexpr uint8_t FlagNewExecutable = 0x01;
2071 static constexpr uint8_t FlagOmitCodeViewPublics = 0x02;
2072 static constexpr uint8_t FlagRunMPC = 0x04;
2087 uint32_t dictionary_offset;
2088 uint16_t dictionary_size;
2089 bool case_sensitive;
2130 std::vector<std::shared_ptr<SegmentDefinitionRecord>>
segdefs;
2132 std::vector<std::shared_ptr<GroupDefinitionRecord>>
grpdefs;
2134 std::vector<std::shared_ptr<TypeDefinitionRecord>>
typdefs;
2136 std::vector<std::shared_ptr<BlockDefinitionRecord>>
blkdefs;
2138 std::vector<std::shared_ptr<OverlayDefinitionRecord>>
ovldefs;
2170 std::vector<uint8_t> data;
2213 std::vector<uint8_t> data;
2246 enum record_type_t : uint8_t
2248 ModuleHeader = 0x02,
2253 ModuleAncestor = 0x10,
2254 LocalSymbols = 0x12,
2255 PublicDefinitions = 0x16,
2256 ExternalDefinitions = 0x18,
2257 ExternalReferences = 0x20,
2259 InterSegmentReferences = 0x24,
2260 LibraryModuleLocations = 0x26,
2261 LibraryModuleNames = 0x28,
2262 LibraryDictionary = 0x2A,
2263 LibraryHeader = 0x2C,
2264 NamedCommonDefinitions = 0x2E,
2267 static const std::map<offset_t, std::string> RecordTypeNames;
2308 enum alignment_t : uint8_t
2320 std::string external_name;
2333 uint16_t length = 0;
2334 alignment_t alignment = AlignByte;
2341 std::vector<SegmentDefinition> segment_definitions;
2361 uint16_t start_offset;
2362 std::vector<uint8_t> info;
2384 std::string common_name;
2387 uint16_t GetNamedCommonDefinitionSize(
OMF80Format * omf)
const;
2391 std::vector<NamedCommonDefinition> named_common_definitions;
2411 std::vector<std::string> external_names;
2412 uint16_t first_external_name;
2413 uint16_t external_name_count;
2443 std::vector<SymbolDefinition> public_definitions;
2458 enum relocation_type_t : uint8_t
2460 RelocationLowByte = 1,
2461 RelocationHighByte = 2,
2468 relocation_type_t relocation_type;
2469 std::vector<uint16_t> offsets;
2512 relocation_type_t relocation_type;
2513 std::vector<ExternalReference> external_references;
2550 uint16_t length = 0;
2551 alignment_t alignment = AlignByte;
2552 std::string common_name;
2559 : segment_id(segment_definition.segment_id), length(segment_definition.length), alignment(segment_definition.alignment)
2572 std::map<segment_id_t, SegmentDefinition> segment_definitions;
2573 std::vector<std::string> external_names;
2604 enum record_type_t : uint8_t
2606 ModuleHeader = OMF80Format::ModuleHeader,
2607 ModuleEnd = OMF80Format::ModuleEnd,
2608 Content = OMF80Format::Content,
2610 SegmentDefinitions = 0x0E,
2611 ScopeDefinition = 0x10,
2613 PublicDefinitions = OMF80Format::PublicDefinitions,
2614 ExternalDefinitions = OMF80Format::ExternalDefinitions,
2615 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
2616 LibraryModuleNames = OMF80Format::LibraryModuleNames,
2617 LibraryDictionary = OMF80Format::LibraryDictionary,
2618 LibraryHeader = OMF80Format::LibraryHeader,
2621 static const std::map<offset_t, std::string> RecordTypeNames;
2637 static constexpr uint8_t SegmentAbsolute = 0;
2675 uint8_t register_bank;
2678 static constexpr uint8_t MaskSegmentType = 0x07;
2679 static constexpr uint8_t MaskRegisterBank = 0x18;
2680 static constexpr uint8_t ShiftRegisterBank = 3;
2681 static constexpr uint8_t FlagOverlayable = 0x20;
2682 static constexpr uint8_t FlagSegmentEmpty = 0x80;
2706 bool indirectly_callable;
2708 std::optional<unsigned> register_bank;
2711 static constexpr uint8_t MaskSegmentType = 0x07;
2712 static constexpr uint8_t MaskRegisterBank = 0x18;
2713 static constexpr uint8_t ShiftRegisterBank = 3;
2714 static constexpr uint8_t FlagRegisterBank = 0x20;
2715 static constexpr uint8_t FlagVariable = 0x40;
2716 static constexpr uint8_t FlagIndirectlyCallable = 0x80;
2738 uint8_t block_id = 2;
2739 uint8_t external_id;
2752 enum translator_id_t : uint8_t
2758 translator_id_t translator_id;
2774 std::array<bool, 4> banks;
2789 std::vector<SegmentDefinition> segment_definitions;
2807 std::vector<SymbolDefinition> symbol_definitions;
2825 std::vector<ExternalDefinition> external_definitions;
2843 enum block_type_t : uint8_t
2850 EndProcedureBlock = 5,
2853 block_type_t block_type;
2888 std::vector<Symbol> symbols;
2894 std::vector<Symbol> symbols;
2913 std::vector<SegmentSymbol> symbols;
2921 uint16_t line_number;
2930 std::vector<LineNumber> symbols;
2933 static constexpr uint8_t Type_LocalSymbols = 0;
2934 static constexpr uint8_t Type_PublicSymbols = 1;
2935 static constexpr uint8_t Type_SegmentSymbols = 2;
2936 static constexpr uint8_t Type_LineNumbers = 3;
2938 std::variant<LocalSymbols, PublicSymbols, SegmentSymbols, LineNumbers> contents;
2956 enum relocation_type_t : uint8_t
2959 RelocationByte8 = 1,
2960 RelocationRelative8 = 2,
2961 RelocationHigh8 = 3,
2962 RelocationWord16 = 4,
2963 RelocationAbsolute11 = 5,
2965 RelocationConv7 = 7,
2982 relocation_type_t relocation;
2991 std::vector<Fixup> fixups;
3014 std::map<uint8_t, SegmentDefinition> segment_definitions;
3015 std::map<uint8_t, ExternalDefinition> external_definitions;
3046 typedef uint16_t index_t;
3048 enum record_type_t : uint8_t
3050 ModuleHeader = OMF80Format::ModuleHeader,
3051 ModuleEnd = OMF80Format::ModuleEnd,
3052 Content = OMF80Format::Content,
3053 LineNumbers = OMF80Format::LineNumbers,
3054 BlockDefinition = 0x0A,
3056 EndOfFile = OMF80Format::EndOfFile,
3057 ModuleAncestor = OMF80Format::ModuleAncestor,
3058 LocalSymbols = OMF80Format::LocalSymbols,
3059 TypeDefinition = 0x14,
3060 PublicDefinitions = OMF80Format::PublicDefinitions,
3061 ExternalDefinitions = OMF80Format::ExternalDefinitions,
3062 SegmentDefinitions = 0x20,
3063 Relocations = OMF80Format::Relocations,
3064 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
3065 LibraryModuleNames = OMF80Format::LibraryModuleNames,
3066 LibraryDictionary = OMF80Format::LibraryDictionary,
3067 LibraryHeader = 0x2E,
3070 static const std::map<offset_t, std::string> RecordTypeNames;
3085 typedef uint8_t segment_id_t;
3087 static constexpr segment_id_t CodeSegment = 0;
3088 static constexpr segment_id_t DataSegment = 1;
3089 static constexpr segment_id_t RegisterSegment = 2;
3090 static constexpr segment_id_t OverlaySegment = 3;
3091 static constexpr segment_id_t StackSegment = 4;
3092 static constexpr segment_id_t DynamicSymbol = 5;
3093 static constexpr segment_id_t NullSegment = 6;
3094 static constexpr segment_id_t SegmentTypeMask = 7;
3096 static constexpr segment_id_t FlagBasedVariable = 0x40;
3098 static constexpr segment_id_t FlagRelocatableSegment = 0x80;
3110 segment_id_t segment_id;
3114 alignment_t alignment;
3115 uint16_t base_address;
3120 bool IsRelocatable()
const
3122 return segment_id & FlagRelocatableSegment;
3125 bool IsAbsolute()
const
3127 return !IsRelocatable();
3130 alignment_t GetAlignment()
const
3132 return IsRelocatable() ? alignment : alignment_t(-1);
3135 uint16_t GetBaseAddress()
const
3137 return IsAbsolute() ? base_address : 0;
3140 void MakeRelocatable(alignment_t rel_alignment)
3142 segment_id |= FlagRelocatableSegment;
3143 alignment = rel_alignment;
3146 void MakeAbsolute(uint16_t address)
3148 segment_id &= ~FlagRelocatableSegment;
3149 base_address = address;
3163 std::shared_ptr<TypeDefinitionRecord> record;
3207 uint8_t translator_id;
3208 std::string date_time;
3210 static constexpr uint8_t Version14 = 0xE0;
3211 static constexpr uint8_t Version20 = 0xE4;
3212 static constexpr uint8_t Translator = 0x00;
3213 static constexpr uint8_t Linker = 0x01;
3231 static constexpr uint8_t MainModule = 0x01;
3232 static constexpr uint8_t OtherModule = 0x00;
3234 static constexpr uint8_t ValidModule = 0x00;
3235 static constexpr uint8_t ErroneousModule = 0x01;
3250 std::vector<SegmentDefinition> segment_definitions;
3280 std::variant<Null, int32_t, std::string, TypeIndex, Repeat, EndOfBranch> leaf =
Null();
3324 segment_id_t segment_id;
3325 std::vector<SymbolDefinition> symbol_definitions;
3343 segment_id_t segment_id;
3344 std::vector<ExternalDefinition> external_definitions;
3365 typedef segment_id_t LocalReference;
3366 typedef uint16_t ExternalReference;
3368 enum reference_type_t
3371 RegisterAutoIncrement = 1,
3372 ShiftCountImmediate = 2,
3373 ShiftCountRegister = 3,
3382 static constexpr uint8_t FlagAddendInCode = 0x40;
3383 static constexpr uint8_t FlagExternal = 0x80;
3386 std::variant<LocalReference, ExternalReference> reference = LocalReference(0);
3387 std::optional<uint16_t> addend;
3388 reference_type_t reference_type;
3389 alignment_t alignment;
3396 std::vector<Relocation> relocations;
3415 std::optional<SegmentDefinition> segment_definition;
3440 typedef segment_id_t LocalReference;
3441 typedef uint16_t ExternalReference;
3446 std::variant<LocalReference, ExternalReference> frame_pointer = LocalReference(0);
3447 uint16_t return_offset;
3448 uint8_t prologue_size;
3451 segment_id_t segment_id;
3454 std::optional<BlockNameAndType> name_and_type;
3455 std::optional<ProcedureInformation> procedure_info;
3462 static constexpr uint8_t FlagProcedure = 0x40;
3463 static constexpr uint8_t FlagExternal = 0x80;
3481 std::map<segment_id_t, SegmentDefinition> segment_definitions;
3482 std::vector<std::shared_ptr<TypeDefinitionRecord>> type_definitions;
3508 std::shared_ptr<OMFFormat> contents;
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:586
A record that represents a region within the file.
Definition dumper.h:485
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
void ReadData(size_t count, void *data)
Read in a sequence of bytes.
Definition reader.cc:30
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
void WriteData(size_t count, const void *data)
Write out a sequence of bytes.
Definition writer.cc:7
void Skip(offset_t offset)
Jump to a distance in the output stream.
Definition writer.cc:104
void WriteWord(size_t bytes, uint64_t value, EndianType endiantype)
Read a word.
Definition writer.cc:67
Convenience class to calculate the checksum of a record while writing it.
Definition omf.h:20
A record representing data to be loaded into a segment.
Definition omf.h:239
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.cc:144
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:150
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:135