RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
as86obj.h
1#ifndef AS86OBJ_H
2#define AS86OBJ_H
3
4#include <array>
5#include "../common.h"
6#include "../dumper/dumper.h"
7#include "../linker/buffer.h"
8#include "../linker/format.h"
9#include "../linker/reader.h"
10#include "../linker/writer.h"
11
12/* TODO: not fully implemented */
13
14namespace AS86Obj
15{
19 class AS86ObjFormat : public virtual Linker::InputFormat
20 {
21 public:
22 static inline constexpr int GetSize(int size) { return size < 3 ? size : 4; }
23
24 class Symbol
25 {
26 public:
27 static constexpr uint16_t Absolute = 0x0010;
28 static constexpr uint16_t Relative = 0x0020;
29 static constexpr uint16_t Imported = 0x0040;
30 static constexpr uint16_t Exported = 0x0080;
31 static constexpr uint16_t Entry = 0x0100;
32 static constexpr uint16_t Common = 0x2000;
33
34 uint16_t name_offset = 0;
35 std::string name;
36 uint16_t symbol_type = 0;
37 uint8_t segment = 0;
38 int offset_size = 0;
39 uint32_t offset = 0;
40 offset_t symbol_definition_offset = 0; // convenience entry
41 };
42
44 {
45 public:
46 virtual ~ByteCode();
47 virtual offset_t GetLength() const;
48 virtual offset_t GetMemorySize() const = 0;
49 virtual void Dump(Dumper::Dumper& dump, unsigned index, offset_t& file_offset, offset_t& memory_offset) const = 0;
50 virtual void Generate(Linker::Module& module, int& current_segment, std::array<std::shared_ptr<Linker::Section>, 16>& segments) const;
51 static std::unique_ptr<ByteCode> ReadFile(Linker::Reader& rd, int& relocation_size);
52 };
53
54 class RelocatorSize : public ByteCode
55 {
56 public:
57 uint8_t size;
58 RelocatorSize(uint8_t size)
59 : size(GetSize(size > 3 ? 3 : size))
60 {
61 }
62
63 offset_t GetMemorySize() const override;
64 void Dump(Dumper::Dumper& dump, unsigned index, offset_t& file_offset, offset_t& memory_offset) const override;
65 };
66
67 class SkipBytes : public ByteCode
68 {
69 public:
70 uint8_t count;
71 SkipBytes(uint8_t count)
72 : count(count)
73 {
74 }
75
76 offset_t GetMemorySize() const override;
77 void Dump(Dumper::Dumper& dump, unsigned index, offset_t& file_offset, offset_t& memory_offset) const override;
78 void Generate(Linker::Module& module, int& current_segment, std::array<std::shared_ptr<Linker::Section>, 16>& segments) const override;
79 };
80
81 class ChangeSegment : public ByteCode
82 {
83 public:
84 uint8_t segment;
85 ChangeSegment(uint8_t segment)
86 : segment(segment)
87 {
88 }
89
90 offset_t GetMemorySize() const override;
91 void Dump(Dumper::Dumper& dump, unsigned index, offset_t& file_offset, offset_t& memory_offset) const override;
92 void Generate(Linker::Module& module, int& current_segment, std::array<std::shared_ptr<Linker::Section>, 16>& segments) const override;
93 };
94
95 class RawBytes : public ByteCode
96 {
97 public:
98 std::shared_ptr<Linker::Buffer> buffer;
99
100 offset_t GetLength() const override;
101 offset_t GetMemorySize() const override;
102 void Dump(Dumper::Dumper& dump, unsigned index, offset_t& file_offset, offset_t& memory_offset) const override;
103 void Generate(Linker::Module& module, int& current_segment, std::array<std::shared_ptr<Linker::Section>, 16>& segments) const override;
104 };
105
107 {
108 public:
109 uint32_t offset;
110 uint8_t segment;
111 bool ip_relative;
112 int relocation_size;
113 SimpleRelocator(uint8_t type, uint32_t offset, int relocation_size)
114 : offset(offset), segment(type & 0xF), ip_relative((type & 0x20) != 0), relocation_size(GetSize(relocation_size))
115 {
116 }
117
118 offset_t GetLength() const override;
119 offset_t GetMemorySize() const override;
120 void Dump(Dumper::Dumper& dump, unsigned index, offset_t& file_offset, offset_t& memory_offset) const override;
121 void Generate(Linker::Module& module, int& current_segment, std::array<std::shared_ptr<Linker::Section>, 16>& segments) const override;
122 };
123
125 {
126 public:
127 uint32_t offset;
128 uint16_t symbol_index;
129 std::string symbol_name;
130 bool ip_relative;
131 int relocation_size;
132 int offset_size;
133 int index_size;
134 SymbolRelocator(uint8_t type, uint32_t offset, uint16_t symbol_index, int relocation_size, int offset_size, int index_size)
135 : offset(offset), symbol_index(symbol_index), ip_relative((type & 0x20) != 0), relocation_size(GetSize(relocation_size)), offset_size(GetSize(offset_size)), index_size(GetSize(index_size))
136 {
137 }
138
139 offset_t GetLength() const override;
140 offset_t GetMemorySize() const override;
141 void Dump(Dumper::Dumper& dump, unsigned index, offset_t& file_offset, offset_t& memory_offset) const override;
142 void Generate(Linker::Module& module, int& current_segment, std::array<std::shared_ptr<Linker::Section>, 16>& segments) const override;
143 };
144
146 {
147 uint32_t word = 0;
148 struct offset
149 {
150 uint32_t& word;
151 int index;
152
153 operator int() const;
154 offset& operator =(int value);
155 };
156 int operator[](int index) const;
157 offset operator[](int index);
158 segment_size_list& operator =(uint32_t value);
159 };
160
161 class Module
162 {
163 public:
164 offset_t file_offset = 0;
165 offset_t module_size = 0;
166 uint32_t code_offset = 0;
167 uint32_t image_size = 0;
168 uint16_t string_table_size = 0;
169 struct version
170 {
171 uint8_t major, minor;
172 };
173 version module_version = { };
174 uint32_t maximum_segment_size = 0;
175 segment_size_list segment_sizes_word;
176 std::array<uint32_t, 16> segment_sizes = { };
177 std::vector<Symbol> symbols;
178 offset_t string_table_offset = 0;
179 std::string module_name;
180 std::vector<std::unique_ptr<ByteCode>> data;
181
182 void Dump(Dumper::Dumper& dump, unsigned index) const;
183 };
184
185 offset_t file_size = offset_t(-1);
186
187 enum cpu_type
188 {
189 /* represented here in big-endian format */
190 CPU_I8086 = 0xA086,
191 CPU_I80386 = 0xA386,
192 CPU_MC6809 = 0x5331, /* S1 */
193 };
194 cpu_type cpu = cpu_type(0);
195
196 std::vector<Module> modules;
197
198 void ReadFile(Linker::Reader& rd) override;
199
200 offset_t ImageSize() const override;
201
203 offset_t WriteFile(Linker::Writer& wr) const override;
204
205 void Dump(Dumper::Dumper& dump) const override;
206
207 protected:
208 static std::string GetDefaultSectionName(unsigned index);
209 static std::shared_ptr<Linker::Section> GetDefaultSection(unsigned index);
210
211 public:
213 void GenerateModule(Linker::Module& module) const override;
214 };
215}
216
217#endif /* AS86OBJ_H */
Definition as86obj.h:44
Definition as86obj.h:162
Definition as86obj.h:96
Definition as86obj.h:68
Definition as86obj.h:25
Object format of Introl-C, output format for as86, used as an output by Bruce's C compiler from the d...
Definition as86obj.h:20
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition as86obj.cc:428
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition as86obj.cc:434
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 as86obj.cc:486
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition as86obj.cc:343
offset_t ImageSize() const override
Retrieves size of stored data.
Definition as86obj.cc:423
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:586
offset_t WriteFile(Writer &wr) const override=0
Stores data in memory to file.
A class that provides a general interface to loading a module.
Definition format.h:166
virtual void GenerateModule(ModuleCollector &linker, std::string file_name, bool is_library=false) const
Loads the information into a module object.
Definition format.cc:180
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
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15