RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
aout.h
1#ifndef AOUT_H
2#define AOUT_H
3
4#include "mzexe.h"
5#include "../common.h"
6#include "../dumper/dumper.h"
7#include "../linker/module.h"
8#include "../linker/options.h"
9#include "../linker/segment.h"
10#include "../linker/segment_manager.h"
11#include "../linker/writer.h"
12
13/* TODO: UNIX v1 a.out
14 magic
15 header_size + text_size + data_size
16 symtab_size
17 relocations_size
18 bss_size
19 0
20
21TODO: PDP-11 a.out
22*/
23
24namespace AOut
25{
49 class AOutFormat : public virtual Linker::InputFormat, public virtual Linker::SegmentManager
50 {
51 public:
52 /* * * General members * * */
53 ::EndianType endiantype = ::UndefinedEndian;
54
59 {
67 LINUX, /* TODO: not fully supported */
73 FREEBSD, /* TODO */
79 NETBSD, /* TODO */
96 };
97
102
107 {
109 OMAGIC = 0x0107,
111 NMAGIC = 0x0108,
113 ZMAGIC = 0x010B,
115 QMAGIC = 0x00CC,
116 };
121
129 {
130 switch(system)
131 {
132 default:
133 case DJGPP1:
134 return ZMAGIC;
135 case PDOS386:
136 return OMAGIC;
137 }
138 }
139
144 ::EndianType midmag_endiantype;
145
146 protected:
149 {
150 }
151
152 public:
153 AOutFormat()
155 {
156 }
157
159 uint16_t mid_value = 0;
160
162 uint8_t flags = 0;
163
164 static constexpr uint16_t MID_UNKNOWN = 0x000;
165 static constexpr uint16_t MID_68010 = 0x001;
166 static constexpr uint16_t MID_68020 = 0x002;
167 static constexpr uint16_t MID_PC386 = 0x064; // mentioned for Linux and NetBSD
168 static constexpr uint16_t MID_I386 = 0x086; // mentioned for FreeBSD and NetBSD
169 static constexpr uint16_t MID_ARM6 = 0x08F; // mentioned for FreeBSD and NetBSD
170 static constexpr uint16_t MID_MIPS1 = 0x097; // mentioned for Linux and NetBSD
171 static constexpr uint16_t MID_MIPS2 = 0x098; // mentioned for Linux and NetBSD
172 static constexpr uint16_t MID_HP200 = 0x0C8; // mentioned for FreeBSD and NetBSD
173 static constexpr uint16_t MID_HP300 = 0x12C; // mentioned for FreeBSD and NetBSD
174 static constexpr uint16_t MID_HPUX800 = 0x20B; // mentioned for FreeBSD and NetBSD
175 static constexpr uint16_t MID_HPUX = 0x20C; // mentioned for FreeBSD and NetBSD
176
177 // according to a.out.h
178 static constexpr uint16_t MID_LINUX_OLDSUN2 = 0x000;
179 static constexpr uint16_t MID_LINUX_SPARC = 0x003;
180
181 // according to imgact_aout.h
182 static constexpr uint16_t MID_FREEBSD_SPARC = 0x08C;
183
184 // according to aout_mids.h
185 static constexpr uint16_t MID_NETBSD_M68K = 0x087;
186 static constexpr uint16_t MID_NETBSD_M68K4K = 0x088;
187 static constexpr uint16_t MID_NETBSD_NS32532K = 0x089;
188 static constexpr uint16_t MID_NETBSD_SPARC = 0x08A;
189 static constexpr uint16_t MID_NETBSD_PMAX = 0x08B;
190 static constexpr uint16_t MID_NETBSD_VAX1K = 0x08C;
191 static constexpr uint16_t MID_NETBSD_ALPHA = 0x08D;
192 static constexpr uint16_t MID_NETBSD_MIPS = 0x08E;
193 static constexpr uint16_t MID_NETBSD_M680002K = 0x090;
194 static constexpr uint16_t MID_NETBSD_SH3 = 0x091;
195 static constexpr uint16_t MID_NETBSD_POWERPC64 = 0x094;
196 static constexpr uint16_t MID_NETBSD_POWERPC = 0x095;
197 static constexpr uint16_t MID_NETBSD_VAX = 0x096;
198 static constexpr uint16_t MID_NETBSD_M88K = 0x099;
199 static constexpr uint16_t MID_NETBSD_HPPA = 0x09A;
200 static constexpr uint16_t MID_NETBSD_SH5_64 = 0x09B;
201 static constexpr uint16_t MID_NETBSD_SPARC64 = 0x09C;
202 static constexpr uint16_t MID_NETBSD_X86_64 = 0x09D;
203 static constexpr uint16_t MID_NETBSD_SH5_32 = 0x09E;
204 static constexpr uint16_t MID_NETBSD_IA64 = 0x09F;
205 static constexpr uint16_t MID_NETBSD_AARCH64 = 0x0B7;
206 static constexpr uint16_t MID_NETBSD_OR1K = 0x0B8;
207 static constexpr uint16_t MID_NETBSD_RISCV = 0x0B9;
208
209 static constexpr uint16_t MID_BFD_ARM = 0x067;
210
211 enum word_size_t
212 {
213 WordSize16 = 2,
214 WordSize32 = 4,
215 };
216
218 word_size_t word_size = word_size_t(0);
219
221 constexpr uint32_t GetHeaderSize() const
222 {
223 return word_size * 8;
224 }
225
226 enum cpu_type
227 {
228 UNKNOWN,
229 M68K,
230 SPARC,
231 SPARC64,
232 I386,
233 AMD64,
234 ARM,
235 AARCH64,
236 MIPS,
237 PARISC,
238 PDP11,
239 NS32K,
240 VAX,
241 ALPHA,
242 SUPERH,
243 SUPERH64,
244 PPC,
245 PPC64,
246 M88K,
247 IA64,
248 OR1K,
249 RISCV,
250 };
251 cpu_type cpu = UNKNOWN;
252
254 ::EndianType GetEndianType() const;
255
257 word_size_t GetWordSize() const;
258
259 uint32_t code_size = 0;
260 uint32_t data_size = 0;
261 uint32_t bss_size = 0;
262 uint32_t symbol_table_size = 0;
263 uint32_t entry_address = 0;
264 uint32_t code_relocation_size = 0;
265 uint32_t data_relocation_size = 0;
266 std::map<uint32_t, uint32_t> code_relocations, data_relocations; /* only used by PDOS386 OMAGIC */
267
268 std::shared_ptr<Linker::Image> code, data, bss;
269
270 private:
271 bool AttemptFetchMagic(uint8_t signature[4]);
272
273 bool CheckFileSizes(Linker::Reader& rd, offset_t image_size);
274
275 bool AttemptReadFile(Linker::Reader& rd, uint8_t signature[4], offset_t image_size);
276
277 public:
278 class Symbol
279 {
280 public:
281 std::string name;
282 uint16_t unknown = 0;
283 uint16_t name_offset = 0;
284 uint16_t type = 0;
285 uint16_t value = 0;
286 };
287
288 std::vector<Symbol> symbols;
289
290 mutable uint32_t page_size = 0; // GetPageSize will set this if it is 0, and so it needs to be declared mutable
291
292 uint32_t GetPageSize() const;
293 uint32_t GetTextOffset() const;
294 uint32_t GetTextAddress() const;
295 uint32_t GetDataOffsetAlign() const;
296 uint32_t GetDataAddressAlign() const;
297
298 void ReadHeader(Linker::Reader& rd);
299
300 void ReadFile(Linker::Reader& rd) override;
301
302 offset_t ImageSize() const override;
303
304 void WriteHeader(Linker::Writer& wr) const;
306 offset_t WriteFile(Linker::Writer& wr) const override;
307
308 void Dump(Dumper::Dumper& dump) const override;
309
310 /* * * Reader members * * */
311
312 static std::shared_ptr<AOutFormat> CreateReader(word_size_t word_size, ::EndianType endiantype, system_type system = UNSPECIFIED);
313
315 void GenerateModule(Linker::Module& module) const override;
316
317 /* * * Writer members * * */
318
319 static std::shared_ptr<AOutFormat> CreateWriter(system_type system, magic_type magic);
320 static std::shared_ptr<AOutFormat> CreateWriter(system_type system);
321
323 {
324 public:
325 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
326
328 {
329 InitializeFields(stub);
330 }
331 };
332
333 // for old DJGPP executables
335
336 static std::vector<Linker::OptionDescription<void> *> ParameterNames;
337 std::vector<Linker::OptionDescription<void> *> GetLinkerScriptParameterNames() override;
338
339 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
340
341 void SetOptions(std::map<std::string, std::string>& options) override;
342
343 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
344
345 void CreateDefaultSegments();
346
347 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
348
349 void Link(Linker::Module& module);
350
351 std::shared_ptr<Linker::Segment> GetCodeSegment();
352
353 std::shared_ptr<Linker::Segment> GetDataSegment();
354
355 std::shared_ptr<Linker::Segment> GetBssSegment();
356
357 void ProcessModule(Linker::Module& module) override;
358
359 void CalculateValues() override;
360
361 void GenerateFile(std::string filename, Linker::Module& module) override;
362
364 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
365 std::string GetDefaultExtension(Linker::Module& module) const override;
366 };
367
368}
369
370#endif /* AOUT_H */
Definition aout.h:279
UNIX/Linux a.out binary file format.
Definition aout.h:50
static constexpr magic_type GetDefaultMagic(system_type system)
Default magic number associated with the system.
Definition aout.h:128
magic_type
The low 16 bits of the midmag field, it determines how sections should be loaded into memory,...
Definition aout.h:107
@ ZMAGIC
Demand paged executable: Like NMAGIC, the data section starts on a page boundary, but the text sectio...
Definition aout.h:113
@ OMAGIC
Object file or impure executable: The text, data and bss sections are loaded contiguously.
Definition aout.h:109
@ QMAGIC
The header is included in the text segment, but the first page is unmapped.
Definition aout.h:115
@ NMAGIC
Pure executable: The data section starts on a page boundary, making it possible to have a write prote...
Definition aout.h:111
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition aout.cc:916
magic_type magic
The low 16 bits of the midmag field.
Definition aout.h:120
word_size_t word_size
Number of bytes in a machine word (2 or 4), typically also determines the size of the header (16 or 3...
Definition aout.h:218
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 aout.cc:1142
system_type system
The target operating system, it influences section offset and address choices.
Definition aout.h:101
uint8_t flags
Definition aout.h:162
constexpr uint32_t GetHeaderSize() const
Retrieves the size of the header for the current settings.
Definition aout.h:221
std::vector< Linker::OptionDescription< void > * > GetLinkerScriptParameterNames() override
Returns a list of the parameters used in the linker scripts, used for documentation.
Definition aout.cc:1348
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition aout.cc:954
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition aout.cc:1461
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition aout.cc:1353
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition aout.cc:1358
::EndianType midmag_endiantype
All fields in the header must appear in native byte order, except for FreeBSD and NetBSD where:
Definition aout.h:144
system_type
The target operating system type for parsing or generating binaries.
Definition aout.h:59
@ LINUX
Treat it as a Linux a.out binary, used before kernel 5.19 (Linux switched to ELF in 1....
Definition aout.h:67
@ NETBSD
Treat it as a NetBSD a.out binary, used before 1.5.
Definition aout.h:79
@ FREEBSD
Treat it as a FreeBSD a.out binary, used before 3.0.
Definition aout.h:73
@ UNSPECIFIED
Treat it as undetermined, intended for object files and early UNIX binaries.
Definition aout.h:61
@ DJGPP1
Treat it as a DJGPP a.out binary, used before DJGPP 1.11.
Definition aout.h:85
@ EMX
Treat it as an EMX a.out binary, should only be used with EMXAOutFormat.
Definition aout.h:95
@ PDOS386
Treat it as a Public Domain OS a.out, a 32-bit DOS-like operating system (http://pdos....
Definition aout.h:91
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition aout.cc:1577
word_size_t GetWordSize() const
Returns the expected word size for the currently set CPU.
Definition aout.cc:38
uint16_t mid_value
Definition aout.h:159
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition aout.cc:1648
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition aout.cc:394
void OnNewSegment(std::shared_ptr< Linker::Segment > segment) override
Callback function when allocating a new segment When the linker script runs, it creates segments cons...
Definition aout.cc:1367
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition aout.cc:1611
offset_t ImageSize() const override
Retrieves size of stored data.
Definition aout.cc:899
::EndianType GetEndianType() const
Returns the default endian type for the currently set CPU.
Definition aout.cc:8
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:193
virtual void GenerateModule(ModuleCollector &linker, std::string file_name, bool is_library=false) const
Loads the information into a module object.
Definition format.cc:215
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
Helper class that contains the options interpreted by the format.
Definition options.h:467
Documents and handles command line options.
Definition options.h:303
virtual std::string GetDefaultExtension(Module &module, std::string filename) const
Appends a default extension to the filename.
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
A helper class to collect sections into segments.
Definition segment_manager.h:32
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
Definition mzexe.h:269