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"
32 void WriteWord(
size_t bytes, uint64_t value)
35 for(
size_t offset = 0; offset < bytes; offset++, value >>= 8)
41 size_t WriteData(
const std::vector<uint8_t>& data)
44 for(
size_t offset = 0; offset < bytes; offset++)
46 checksum -= data[offset];
51 size_t WriteData(std::string text)
54 for(
size_t offset = 0; offset < text.size(); offset++)
56 checksum -= text[offset];
61 void Skip(offset_t count)
99 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
117 offset_t RecordEnd()
const
126 virtual uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const = 0;
154 virtual void DumpAddFields(
Dumper::Dumper& dump,
Dumper::Region& region,
const FormatType * omf,
const ModuleType * mod,
size_t record_index, Dumper::display_option& options)
const
158 virtual void Dump(
Dumper::Dumper& dump,
const FormatType * omf,
const ModuleType * mod,
size_t record_index)
const
163 Dumper::display_option options = Dumper::Control;
164 FormatType::DumpAddFields(
this, dump, record_region, omf, mod, record_index, options);
165 DumpAddFields(dump, record_region, omf, mod, record_index, options);
166 record_region.Display(dump, options);
183 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
203 return data.size() + 1;
213 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
240 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
244 uint8_t segment_id = 0;
246 std::vector<uint8_t> data;
254 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
263 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
270 uint16_t line_number = 0;
277 uint8_t segment_id = 0;
278 std::vector<LineNumber> line_numbers;
286 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
291 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
308 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
313 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
326 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
331 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
356 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
361 template <
typename RecordTypeByte,
typename FormatType,
typename ModuleType>
372 uint16_t Size()
const;
385 uint16_t
GetRecordSize(FormatType * omf, ModuleType * mod)
const override;
408 ::EndianType endian_type = ::LittleEndian;
492 std::shared_ptr<SegmentDefinitionRecord> record;
508 std::shared_ptr<GroupDefinitionRecord> record;
528 std::shared_ptr<TypeDefinitionRecord> record;
544 std::shared_ptr<BlockDefinitionRecord> record;
560 std::shared_ptr<OverlayDefinitionRecord> record;
602 uint8_t segment_index;
610 uint32_t element_size;
616 value.far.number = value.far.element_size = 0;
638 void CalculateValues(
OMF86Format * omf, Module * mod);
639 void ResolveReferences(
OMF86Format * omf, Module * mod);
694 uint16_t Size(
OMF86Format * omf,
bool is32bit)
const;
728 typedef std::vector<std::shared_ptr<DataBlock>>
Blocks;
730 typedef std::vector<uint8_t>
Data;
758 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber>
target =
ThreadNumber(0);
760 std::variant<ThreadNumber, SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute>
frame =
ThreadNumber(0);
765 uint16_t Size(
OMF86Format * omf,
bool is32bit)
const;
853 LibraryHeader = 0xF0,
857 static const std::map<offset_t, std::string> RecordTypeNames;
898 RelocatableModule = 1,
934 uint16_t GetRecordSize(
OMF86Format * omf, Module *
mod)
const override;
1008 uint16_t maximum_segment_length;
1009 uint16_t group_offset;
1027 Combination_Public4 =
FlagTIS | 4,
1034 Combination_Common =
FlagTIS | 6,
1037 Combination_Public7 =
FlagTIS | 7,
1059 AccessExecuteOnly = 1,
1060 AccessExecuteRead = 2,
1061 AccessReadWrite = 3,
1082 std::shared_ptr<Linker::Section> GenerateLinkerSection();
1106 uint32_t maximum_group_length;
1107 uint32_t group_length;
1125 std::variant<ExternalIndex, SegmentIndex, SegmentClassOverlayNames, LoadTimeLocatable, Absolute>
component =
ExternalIndex();
1176 std::variant<uint32_t, int32_t, std::string, TypeIndex, Null, Repeat>
leaf =
Null();
1236 UnsignedInteger = 0x7C,
1237 SignedInteger = 0x7D,
1248 uint16_t GetRecordSize(
OMF86Format * omf, Module * mod)
const override;
1251 void CalculateValues(
OMF86Format * omf, Module * mod)
override;
1252 void ResolveReferences(
OMF86Format * omf, Module * mod)
override;
1369 enum frame_type_t : uint8_t
1375 frame_type_t frame_type;
1377 static constexpr uint8_t SymbolBaseMethod = 0x00;
1378 static constexpr uint8_t ExternalMethod = 0x01;
1379 static constexpr uint8_t BlockMethod = 0x02;
1381 std::variant<BaseSpecification, ExternalIndex, BlockIndex> base =
ExternalIndex();
1383 std::vector<SymbolDefinition> names;
1469 typedef std::variant<SegmentIndex, GroupIndex, ExternalIndex, FrameNumber> target_reference_type;
1470 typedef std::variant<SegmentIndex, GroupIndex, ExternalIndex, FrameNumber, UsesSource, UsesTarget, UsesAbsolute> frame_reference_type;
1672 std::optional<std::variant<Reference, std::tuple<uint16_t, uint16_t>>>
start_address;
1706 Location32bit_IBM = 9,
1737 std::vector<OffsetValuePair> offset_value_pairs;
1767 enum selection_criterion_t : uint8_t
1769 SelectNoMatch = 0x00,
1770 SelectPickAny = 0x10,
1771 SelectSameSize = 0x20,
1772 SelectExactMatch = 0x30,
1774 static constexpr uint8_t SelectionCriterionMask = 0xF0;
1775 selection_criterion_t selection_criterion;
1777 enum allocation_type_t : uint8_t
1779 AllocateExplicit = 0x00,
1780 AllocateFarCode = 0x01,
1781 AllocateFarData = 0x02,
1782 AllocateCode32 = 0x03,
1783 AllocateData32 = 0x04,
1785 static constexpr uint8_t AllocationTypeMask = 0x0F;
1786 allocation_type_t allocation_type;
1793 BaseSpecification base;
1795 std::shared_ptr<DataBlock> data;
1802 void ReadRecordContents(OMF86Format * omf, Module * mod,
Linker::Reader& rd)
override;
1803 uint16_t GetRecordSize(OMF86Format * omf, Module * mod)
const override;
1804 void WriteRecordContents(OMF86Format * omf, Module * mod, ChecksumWriter& wr)
const override;
1806 void CalculateValues(OMF86Format * omf, Module * mod)
override;
1807 void ResolveReferences(OMF86Format * omf, Module * mod)
override;
1907 enum comment_class_t : uint8_t
1910 IntelCopyright = 0x01,
1911 LibrarySpecifier = 0x81,
1912 MSDOSVersion = 0x9C,
1915 DefaultLibrarySearchName = 0x9F,
1916 OMFExtension = 0xA0,
1917 NewOMFExtension = 0xA1,
1918 LinkPassSeparator = 0xA2,
1930 DependencyFile = 0xE9,
1933 comment_class_t comment_class;
1940 CommentRecord(comment_class_t comment_class = comment_class_t(0))
1941 :
Record(COMENT), comment_class(comment_class)
1962 std::vector<SegmentIndex> segments;
1994 std::vector<ExternalAssociation> associations;
2012 enum extension_type_t : uint8_t
2017 ProtectedModeLibrary = 0x04,
2022 extension_type_t subtype;
2036 std::string internal_name;
2037 std::string module_name;
2038 std::variant<std::string, uint16_t> entry_ident;
2055 uint8_t parameter_count;
2056 std::string exported_name;
2057 std::string internal_name;
2058 std::optional<uint16_t> ordinal;
2073 uint16_t extdef_delta;
2074 uint16_t linnum_delta;
2075 uint16_t padding_byte_count;
2090 bool new_executable;
2091 bool omit_codeview_publics;
2093 uint8_t pseudocode_version;
2094 uint8_t codeview_version;
2096 static constexpr uint8_t FlagNewExecutable = 0x01;
2097 static constexpr uint8_t FlagOmitCodeViewPublics = 0x02;
2098 static constexpr uint8_t FlagRunMPC = 0x04;
2113 uint32_t dictionary_offset;
2114 uint16_t dictionary_size;
2115 bool case_sensitive;
2156 std::vector<std::shared_ptr<SegmentDefinitionRecord>>
segdefs;
2158 std::vector<std::shared_ptr<GroupDefinitionRecord>>
grpdefs;
2160 std::vector<std::shared_ptr<TypeDefinitionRecord>>
typdefs;
2162 std::vector<std::shared_ptr<BlockDefinitionRecord>>
blkdefs;
2164 std::vector<std::shared_ptr<OverlayDefinitionRecord>>
ovldefs;
2189 static uint32_t FillSectionData(std::shared_ptr<Linker::Section> section, uint32_t offset, std::shared_ptr<OMF86Format::DataBlock> data);
2199 std::vector<uint8_t> data;
2242 std::vector<uint8_t> data;
2275 enum record_type_t : uint8_t
2277 ModuleHeader = 0x02,
2282 ModuleAncestor = 0x10,
2283 LocalSymbols = 0x12,
2284 PublicDefinitions = 0x16,
2285 ExternalDefinitions = 0x18,
2286 ExternalReferences = 0x20,
2288 InterSegmentReferences = 0x24,
2289 LibraryModuleLocations = 0x26,
2290 LibraryModuleNames = 0x28,
2291 LibraryDictionary = 0x2A,
2292 LibraryHeader = 0x2C,
2293 NamedCommonDefinitions = 0x2E,
2296 static const std::map<offset_t, std::string> RecordTypeNames;
2337 enum alignment_t : uint8_t
2349 std::string external_name;
2362 uint16_t length = 0;
2363 alignment_t alignment = AlignByte;
2370 std::vector<SegmentDefinition> segment_definitions;
2390 uint16_t start_offset;
2391 std::vector<uint8_t> info;
2413 std::string common_name;
2416 uint16_t GetNamedCommonDefinitionSize(
OMF80Format * omf)
const;
2420 std::vector<NamedCommonDefinition> named_common_definitions;
2440 std::vector<std::string> external_names;
2441 uint16_t first_external_name;
2442 uint16_t external_name_count;
2472 std::vector<SymbolDefinition> public_definitions;
2487 enum relocation_type_t : uint8_t
2489 RelocationLowByte = 1,
2490 RelocationHighByte = 2,
2497 relocation_type_t relocation_type;
2498 std::vector<uint16_t> offsets;
2541 relocation_type_t relocation_type;
2542 std::vector<ExternalReference> external_references;
2579 uint16_t length = 0;
2580 alignment_t alignment = AlignByte;
2581 std::string common_name;
2588 : segment_id(segment_definition.segment_id), length(segment_definition.length), alignment(segment_definition.alignment)
2601 std::map<segment_id_t, SegmentDefinition> segment_definitions;
2602 std::vector<std::string> external_names;
2633 enum record_type_t : uint8_t
2635 ModuleHeader = OMF80Format::ModuleHeader,
2636 ModuleEnd = OMF80Format::ModuleEnd,
2637 Content = OMF80Format::Content,
2639 SegmentDefinitions = 0x0E,
2640 ScopeDefinition = 0x10,
2642 PublicDefinitions = OMF80Format::PublicDefinitions,
2643 ExternalDefinitions = OMF80Format::ExternalDefinitions,
2644 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
2645 LibraryModuleNames = OMF80Format::LibraryModuleNames,
2646 LibraryDictionary = OMF80Format::LibraryDictionary,
2647 LibraryHeader = OMF80Format::LibraryHeader,
2650 static const std::map<offset_t, std::string> RecordTypeNames;
2666 static constexpr uint8_t SegmentAbsolute = 0;
2704 uint8_t register_bank;
2707 static constexpr uint8_t MaskSegmentType = 0x07;
2708 static constexpr uint8_t MaskRegisterBank = 0x18;
2709 static constexpr uint8_t ShiftRegisterBank = 3;
2710 static constexpr uint8_t FlagOverlayable = 0x20;
2711 static constexpr uint8_t FlagSegmentEmpty = 0x80;
2735 bool indirectly_callable;
2737 std::optional<unsigned> register_bank;
2740 static constexpr uint8_t MaskSegmentType = 0x07;
2741 static constexpr uint8_t MaskRegisterBank = 0x18;
2742 static constexpr uint8_t ShiftRegisterBank = 3;
2743 static constexpr uint8_t FlagRegisterBank = 0x20;
2744 static constexpr uint8_t FlagVariable = 0x40;
2745 static constexpr uint8_t FlagIndirectlyCallable = 0x80;
2767 uint8_t block_id = 2;
2768 uint8_t external_id;
2781 enum translator_id_t : uint8_t
2787 translator_id_t translator_id;
2803 std::array<bool, 4> banks;
2818 std::vector<SegmentDefinition> segment_definitions;
2836 std::vector<SymbolDefinition> symbol_definitions;
2854 std::vector<ExternalDefinition> external_definitions;
2872 enum block_type_t : uint8_t
2879 EndProcedureBlock = 5,
2882 block_type_t block_type;
2917 std::vector<Symbol> symbols;
2923 std::vector<Symbol> symbols;
2942 std::vector<SegmentSymbol> symbols;
2950 uint16_t line_number;
2959 std::vector<LineNumber> symbols;
2962 static constexpr uint8_t Type_LocalSymbols = 0;
2963 static constexpr uint8_t Type_PublicSymbols = 1;
2964 static constexpr uint8_t Type_SegmentSymbols = 2;
2965 static constexpr uint8_t Type_LineNumbers = 3;
2967 std::variant<LocalSymbols, PublicSymbols, SegmentSymbols, LineNumbers> contents;
2985 enum relocation_type_t : uint8_t
2988 RelocationByte8 = 1,
2989 RelocationRelative8 = 2,
2990 RelocationHigh8 = 3,
2991 RelocationWord16 = 4,
2992 RelocationAbsolute11 = 5,
2994 RelocationConv7 = 7,
3011 relocation_type_t relocation;
3020 std::vector<Fixup> fixups;
3043 std::map<uint8_t, SegmentDefinition> segment_definitions;
3044 std::map<uint8_t, ExternalDefinition> external_definitions;
3075 typedef uint16_t index_t;
3077 enum record_type_t : uint8_t
3079 ModuleHeader = OMF80Format::ModuleHeader,
3080 ModuleEnd = OMF80Format::ModuleEnd,
3081 Content = OMF80Format::Content,
3082 LineNumbers = OMF80Format::LineNumbers,
3083 BlockDefinition = 0x0A,
3085 EndOfFile = OMF80Format::EndOfFile,
3086 ModuleAncestor = OMF80Format::ModuleAncestor,
3087 LocalSymbols = OMF80Format::LocalSymbols,
3088 TypeDefinition = 0x14,
3089 PublicDefinitions = OMF80Format::PublicDefinitions,
3090 ExternalDefinitions = OMF80Format::ExternalDefinitions,
3091 SegmentDefinitions = 0x20,
3092 Relocations = OMF80Format::Relocations,
3093 LibraryModuleLocations = OMF80Format::LibraryModuleLocations,
3094 LibraryModuleNames = OMF80Format::LibraryModuleNames,
3095 LibraryDictionary = OMF80Format::LibraryDictionary,
3096 LibraryHeader = 0x2E,
3099 static const std::map<offset_t, std::string> RecordTypeNames;
3114 typedef uint8_t segment_id_t;
3116 static constexpr segment_id_t CodeSegment = 0;
3117 static constexpr segment_id_t DataSegment = 1;
3118 static constexpr segment_id_t RegisterSegment = 2;
3119 static constexpr segment_id_t OverlaySegment = 3;
3120 static constexpr segment_id_t StackSegment = 4;
3121 static constexpr segment_id_t DynamicSymbol = 5;
3122 static constexpr segment_id_t NullSegment = 6;
3123 static constexpr segment_id_t SegmentTypeMask = 7;
3125 static constexpr segment_id_t FlagBasedVariable = 0x40;
3127 static constexpr segment_id_t FlagRelocatableSegment = 0x80;
3139 segment_id_t segment_id;
3143 alignment_t alignment;
3144 uint16_t base_address;
3149 bool IsRelocatable()
const
3151 return segment_id & FlagRelocatableSegment;
3154 bool IsAbsolute()
const
3156 return !IsRelocatable();
3159 alignment_t GetAlignment()
const
3161 return IsRelocatable() ? alignment : alignment_t(-1);
3164 uint16_t GetBaseAddress()
const
3166 return IsAbsolute() ? base_address : 0;
3169 void MakeRelocatable(alignment_t rel_alignment)
3171 segment_id |= FlagRelocatableSegment;
3172 alignment = rel_alignment;
3175 void MakeAbsolute(uint16_t address)
3177 segment_id &= ~FlagRelocatableSegment;
3178 base_address = address;
3192 std::shared_ptr<TypeDefinitionRecord> record;
3236 uint8_t translator_id;
3237 std::string date_time;
3239 static constexpr uint8_t Version14 = 0xE0;
3240 static constexpr uint8_t Version20 = 0xE4;
3241 static constexpr uint8_t Translator = 0x00;
3242 static constexpr uint8_t Linker = 0x01;
3260 static constexpr uint8_t MainModule = 0x01;
3261 static constexpr uint8_t OtherModule = 0x00;
3263 static constexpr uint8_t ValidModule = 0x00;
3264 static constexpr uint8_t ErroneousModule = 0x01;
3279 std::vector<SegmentDefinition> segment_definitions;
3309 std::variant<Null, int32_t, std::string, TypeIndex, Repeat, EndOfBranch> leaf =
Null();
3353 segment_id_t segment_id;
3354 std::vector<SymbolDefinition> symbol_definitions;
3372 segment_id_t segment_id;
3373 std::vector<ExternalDefinition> external_definitions;
3394 typedef segment_id_t LocalReference;
3395 typedef uint16_t ExternalReference;
3397 enum reference_type_t
3400 RegisterAutoIncrement = 1,
3401 ShiftCountImmediate = 2,
3402 ShiftCountRegister = 3,
3411 static constexpr uint8_t FlagAddendInCode = 0x40;
3412 static constexpr uint8_t FlagExternal = 0x80;
3415 std::variant<LocalReference, ExternalReference> reference = LocalReference(0);
3416 std::optional<uint16_t> addend;
3417 reference_type_t reference_type;
3418 alignment_t alignment;
3425 std::vector<Relocation> relocations;
3444 std::optional<SegmentDefinition> segment_definition;
3469 typedef segment_id_t LocalReference;
3470 typedef uint16_t ExternalReference;
3475 std::variant<LocalReference, ExternalReference> frame_pointer = LocalReference(0);
3476 uint16_t return_offset;
3477 uint8_t prologue_size;
3480 segment_id_t segment_id;
3483 std::optional<BlockNameAndType> name_and_type;
3484 std::optional<ProcedureInformation> procedure_info;
3491 static constexpr uint8_t FlagProcedure = 0x40;
3492 static constexpr uint8_t FlagExternal = 0x80;
3510 std::map<segment_id_t, SegmentDefinition> segment_definitions;
3511 std::vector<std::shared_ptr<TypeDefinitionRecord>> type_definitions;
3537 std::shared_ptr<OMFFormat> contents;
static std::shared_ptr< DecDisplay > Make(bool enable_signed)
Creates a decimal display.
Definition dumper.h:328
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:828
static std::shared_ptr< HexDisplay > Make(unsigned width=8)
Creates a hexadecimal display.
Definition dumper.h:301
A record that represents a region within the file.
Definition dumper.h:721
Represents a single offset within a section, or an absolute location in memory if the section is null...
Definition location.h:17
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:20
void ReadData(size_t count, void *data)
Read in a sequence of bytes.
Definition reader.cc:30
Represents a possible target or reference frame of a relocation.
Definition target.h:24
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
void WriteData(size_t count, const void *data)
Write out a sequence of bytes.
Definition writer.cc:7
void Skip(offset_t offset)
Jump to a distance in the output stream.
Definition writer.cc:104
void WriteWord(size_t bytes, uint64_t value, EndianType endiantype)
Read a word.
Definition writer.cc:67
Convenience class to calculate the checksum of a record while writing it.
Definition omf.h:22
A record representing data to be loaded into a segment.
Definition omf.h:242
uint16_t GetRecordSize(FormatType *omf, ModuleType *mod) const override
Calculates the required bytes to write the record, might be less than record_length.
Definition omf.cc:146
void WriteRecordContents(FormatType *omf, ModuleType *mod, ChecksumWriter &wr) const override
Writes the record contents, except for the type, length and checksum.
Definition omf.cc:152
void ReadRecordContents(FormatType *omf, ModuleType *mod, Linker::Reader &rd) override
Reads the record contents, except for the type, length and checksum.
Definition omf.cc:137