Fat binary


A fat binary is a computer executable program or library which has been expanded with code native to multiple instruction sets which can consequently be run on multiple processor types. This results in a file larger than a normal one-architecture binary file, thus the name.
The usual method of implementation is to include a version of the machine code for each instruction set, preceded by a single entry point with code compatible with all operating systems, which executes a jump to the appropriate section. Alternative implementations store different executables in different forks, each with its own entry point that is directly used by the operating system.
The use of fat binaries is not common in operating system software; there are several alternatives to solve the same problem, such as the use of an installer program to choose an architecture-specific binary at install time, selecting an architecture-specific binary at runtime, distributing software in source code form and compiling it in-place, or the use of a virtual machine and just-in-time compilation.

Apollo

Apollo's compound executables

In 1988, Apollo Computer's Domain/OS SR10.1 introduced a new file type, "cmpexe", that bundled binaries for Motorola 680x0 and Apollo PRISM executables.

Apple

Apple's fat binary

A fat-binary scheme smoothed the Apple Macintosh's transition, beginning in 1994, from 68k microprocessors to PowerPC microprocessors. Many applications for the old platform ran transparently on the new platform under an evolving emulation scheme, but emulated code generally runs slower than native code. Applications released as "fat binaries" took up more storage space, but they ran at full speed on either platform. This was achieved by packaging both a 68000-compiled version and a PowerPC-compiled version of the same program into their executable files. The older 68K code continued to be stored in the resource fork, while the newer PowerPC code was contained in the data fork, in PEF format.
Fat binaries were larger than programs supporting only the PowerPC or 68k, which led to the creation of a number of utilities that would strip out the unneeded version. In the era of small hard drives, when 80 MB hard drives were a common size, these utilities were sometimes useful, as program code was generally a large percentage of overall drive usage, and stripping the unneeded members of a fat binary would free up a significant amount of space on a hard drive.

NeXT's/Apple's multi-architecture binaries

NeXTSTEP Multi-Architecture Binaries

Fat binaries were a feature of NeXT's NeXTSTEP/OPENSTEP operating system, starting with NeXTSTEP 3.1. In NeXTSTEP, they were called "Multi-Architecture Binaries". Multi-Architecture Binaries were originally intended to allow software to be compiled to run both on NeXT's Motorola 68k-based hardware and on Intel IA-32-based PCs running NeXTSTEP, with a single binary file for both platforms. It was later used to allow OPENSTEP applications to run on PCs and the various RISC platforms OPENSTEP supported. Multi-Architecture Binary files are in a special archive format, in which a single file stores one or more Mach-O subfiles for each architecture supported by the Multi-Architecture Binary. Every Multi-Architecture Binary starts with a structure containing two unsigned integers. The first integer is used as a magic number to identify this file as a Fat Binary. The second integer defines how many Mach-O Files the archive contains. After this header, there are number of fat_arch structures. This structure defines the offset at which to find the file, the alignment, the size and the CPU type and subtype which the Mach-O binary is targeted at.
The version of the GNU Compiler Collection shipped with the Developer Tools was able to cross-compile source code for the different architectures on which NeXTStep was able to run. For example, it was possible to choose the target architectures with multiple '-arch' options. This was a convenient way to distribute a program for NeXTStep running on different architectures.
It was also possible to create libraries with different targeted object files.

Mach-O and Mac OS X

Apple Computer acquired NeXT in 1996 and continued to work with the OPENSTEP code. Mach-O became the native object file format in Apple's free Darwin operating system and Apple's Mac OS X, and NeXT's Multi-Architecture Binaries continued to be supported by the operating system. Under Mac OS X, Multi-Architecture Binaries can be used to support multiple variants of an architecture, for instance to have different versions of 32-bit code optimized for the PowerPC G3, PowerPC G4, and PowerPC 970 generations of processors. It can also be used to support multiple architectures, such as 32-bit and 64-bit PowerPC, or PowerPC and x86, or x86-64 and ARM64.

Apple's Universal binary

In 2005, Apple announced another transition, from PowerPC processors to Intel x86 processors. Apple promoted the distribution of new applications that support both PowerPC and x86 natively by using executable files in Multi-Architecture Binary format. Apple calls such programs "Universal applications" and calls the file format "Universal binary" as perhaps a way to distinguish this new transition from the previous transition, or other uses of Multi-Architecture Binary format.
Universal binary format was not necessary for forward migration of pre-existing native PowerPC applications; from 2006 to 2011, Apple supplied Rosetta, a PowerPC -to-x86 dynamic binary translator, to play this role. However, Rosetta had a fairly steep performance overhead, so developers were encouraged to offer both PPC and Intel binaries, using Universal binaries. The obvious cost of Universal binary is that every installed executable file is larger, but in the years since the release of the PPC, hard-drive space has greatly outstripped executable size; while a Universal binary might be double the size of a single-platform version of the same application, free-space resources generally dwarf the code size, which becomes a minor issue. In fact, often a Universal-binary application will be smaller than two single-architecture applications because program resources can be shared rather than duplicated. If not all of the architectures are required, the and command-line applications can be used to remove versions from the Multi-Architecture Binary image, thereby creating what is sometimes called a thin binary.
In addition, Multi-Architecture Binary executables can contain code for both 32-bit and 64-bit versions of PowerPC and x86, allowing applications to be shipped in a form that supports 32-bit processors but that makes use of the larger address space and wider data paths when run on 64-bit processors.
In versions of the Xcode development environment from 2.1 through 3.2, Apple included utilities which allowed applications to be targeted for both Intel and PowerPC architecture; universal binaries could eventually contain up to four versions of the executable code. However, PowerPC support was removed from Xcode 4.0 and is therefore not available to developers running Mac OS X 10.7 or greater.
In 2020, Apple announced another transition, this time from Intel x86 processors to Apple silicon. To smooth the transition Apple added support for the Universal 2 binary format; Universal 2 binary files are Multi-Architecture Binary files containing both x86-64 and ARM64 executable code, allowing the binary to run natively on both 64-bit Intel and 64-bit Apple silicon. Additionally, Apple introduced Rosetta 2 dynamic binary translation for x86 to Arm64 instruction set to allow users to run applications that do not have Universal binary variants.

Apple Fat EFI binary

In 2006, Apple switched from PowerPC to Intel CPUs, and replaced Open Firmware with EFI. However, by 2008, some of their Macs used 32-bit EFI and some used 64-bit EFI. For this reason, Apple extended the EFI specification with "fat" binaries that contained both 32-bit and 64-bit EFI binaries.

CP/M and DOS

Combined COM-style binaries for CP/M-80 and DOS

, MP/M-80, Concurrent CP/M, CP/M Plus, Personal CP/M-80, SCP and MSX-DOS executables for the Intel 8080 processor families use the same.COM file extension as DOS-compatible operating systems for Intel 8086 binaries. In both cases programs are loaded at offset +100h and executed by jumping to the first byte in the file. As the opcodes of the two processor families are not compatible, attempting to start a program under the wrong operating system leads to incorrect and unpredictable behaviour.
In order to avoid this, some methods have been devised to build fat binaries which contain both a CP/M-80 and a DOS program, preceded by initial code which is interpreted correctly on both platforms. The methods either combine two fully functional programs each built for their corresponding environment, or add stubs which cause the program to exit gracefully if started on the wrong processor. For this to work, the first few instructions in the.COM file have to be valid code for both 8086 and 8080 processors, which would cause the processors to branch into different locations within the code.
For example, the utilities in Simeon Cran's emulator MyZ80 start with the opcode sequence. An 8086 sees this as a jump and reads its next instruction from offset +154h whereas an 8080 or compatible processor goes straight through and reads its next instruction from +103h.
A similar sequence used for this purpose is.
John C. Elliott's FATBIN is a utility to combine a CP/M-80 and a DOS.COM file into one executable. His derivative of the original PMsfx modifies archives created by Yoshihiko Mino's PMarc to be self-extractable under both, CP/M-80 and DOS, starting with to also include the "-pms-" signature for self-extracting PMA archives, thereby also representing a form of executable ASCII code.
Another method to keep a DOS-compatible operating system from erroneously executing.COM programs for CP/M-80 and MSX-DOS machines is to start the 8080 code with, which is decoded as a "RET" instruction by x86 processors, thereby gracefully exiting the program, while it will be decoded as "JP 103h" instruction by 8080 processors and simply jump to the next instruction in the program. Similar, the CP/M assembler Z80ASM+ by SLR Systems would display an error message when erroneously run on DOS.
Some CP/M-80 3.0.COM files may have one or more RSX overlays attached to them by GENCOM. If so, they start with an extra 256-byte header. In order to indicate this, the first byte in the header is set to magic byte, which works both as a signature identifying this type of COM file to the CP/M 3.0 executable loader, as well as a "RET" instruction for 8080-compatible processors which leads to a graceful exit if the file is executed under older versions of CP/M-80.
is never appropriate as the first byte of a program for any x86 processor ; the executable loader in some versions of DOS rejects COM files that start with, avoiding incorrect operation.
Similar overlapping code sequences have also been devised for combined Z80/6502, 8086/68000 or x86/MIPS/ARM binaries.