|Type of format||Binary, executable, object, shared libraries|
a.out is a file format used in older versions of Unix-like computer operating systems for executables, object code, and, in later systems, shared libraries. The name stands for "assembler output", and was coined by Ken Thompson as the fixed name for output of his PDP-7 assembler in 1968. The term was subsequently applied to the format of the resulting file, to contrast with other formats for object code.
"a.out" remains the default output file name for executables created by certain compilers and linkers when no output name is specified, even though the created files actually are not in the a.out format.
An a.out format for the PDP-7, similar to the a.out format used on the PDP-11, appeared in the first edition of UNIX. It was superseded by the COFF format in AT&T Unix System V, which was in turn superseded by the ELF format in System V Release 4.
Though Berkeley Unix continued using the a.out format for some time, modern BSD-systems have since switched to ELF. NetBSD/i386 switched formally from a.out to ELF in its 1.5 release. FreeBSD/i386 switched to ELF during the 2.2 to 3.0 transition.
Linux also used a.out until kernel 1.2 (ELF support was added in the experimental 1.1.52), when it was superseded by ELF for that platform as well. Linux's transition to ELF was more or less forced due to the complex nature of building a.out shared libraries on that platform, which included the need to register the virtual address space at which the library was located with a central authority, as the a.out ld.so in Linux was unable to relocate shared libraries. The various BSD flavours were able to continue using a.out binaries long after Linux was forced to switch to ELF, due to the somewhat more flexible nature of the BSD a.out format compared to that of Linux. MINIX 3 switched to ELF in the 3.2.0 release.
a.out executables typically came in one of several variants: OMAGIC, NMAGIC, QMAGIC, or ZMAGIC:
- OMAGIC – contiguous segments after the header, with no separation of text and data; this format was also used as object file format.
- NMAGIC – similar to OMAGIC, however the data segment was loaded on the immediate next page after the end of the text segment, and the text segment was marked read-only.
- ZMAGIC – added support for demand paging; the length of the code and data segments in the file had to be multiples of the page size.
- QMAGIC – these binaries were typically loaded one page above the bottom of the virtual address space, in order to permit trapping of null pointer dereferences via a segmentation fault; the a.out header was merged with the first page of the text segment, typically saving a page worth of memory
- CMAGIC – old versions of Linux use this format for core dumps.
Early versions of UNIX loaded a.out files into memory and began execution at location zero. For this reason the original OMAGIC value corresponded to a branch instruction that jumped around the remainder of the a.out header information.
An a.out file consists of up to seven sections, in the following order:
- exec header – contains parameters used by the kernel to load a binary file into memory and execute it, and by the link editor ld to combine a binary file with other binary files; this section is the only mandatory one.
- text segment – contains machine code and related data that are loaded into memory when a program executes; may be loaded read-only.
- data segment – contains initialized data; always loaded into writable memory.
- text relocations – contains records used by the link editor to update pointers in the text segment when combining binary files.
- data relocations – like the text relocation section, but for data segment pointers.
- symbol table – contains records used by the link editor to cross-reference the addresses of named variables and functions (symbols) between binary files.
- string table – contains the character strings corresponding to the symbol names.
- Ritchie (1993): "Thompson's PDP-7 assembler outdid even DEC's in simplicity; it evaluated expressions and emitted the corresponding bits. There were no libraries, no loader or link editor: the entire source of a program was presented to the assembler, and the output file—with a fixed name—that emerged was directly executable. (This name, a.out, explains a bit of Unix etymology; it is the output of the assembler. Even after the system gained a linker and a means of specifying another name explicitly, it was retained as the default executable result of a compilation.)"
- Rupert Wood (8 April 2002). "What to do with a.out". gcc-help (Mailing list). Retrieved 2007-04-28.
- Dennis Ritchie (3 November 1971). a.out — assembler and link editor output (PDF). Bell Labs. Retrieved 2006-11-24.
- Daniel Barlow (14 July 1996). "The Linux ELF HOWTO (v1.29)". Retrieved 2008-03-28.
- Ulrich Drepper (20 August 2006). "How To Write Shared Libraries" (PDF). 4.0. Section 1.1 (A Little Bit of History). Archived (PDF) from the original on 16 June 2007. Retrieved 2007-06-20.
When introducing shared libraries certain design decisions had to be made to work in the limitations of a.out. (...) For all these reasons and more, Linux converted early on to using ELF (Executable Linkage Format) as the binary format.
- Eric Youngdale (1 April 1995). "The ELF Object File Format: Introduction". Archived from the original on 10 March 2009. Retrieved 6 May 2012.
(...) it is not impossible to design shared library implementations that work with a.out. The current Linux shared libraries are certainly one example; another example is SunOS-style shared libraries which are currently used by BSD-du-jour. SunOS-style shared libraries contain a lot of the same concepts as ELF shared libraries (...)
- "BSD Myths". Archived from the original on 17 April 2007. Retrieved 2007-04-10.
There were no pressing reasons to switch earlier. In particular, FreeBSD did not (and does not) have the problems building shared libraries that spurred the Linux conversion from a.out to ELF.