AOUT(4)

πŸ’Ύ AOUT(4) πŸ’Ύ

okay bestie, gather round, because we're talking about aout β€” kernel support for executing binary files in the legacy a.out format ✨ this is the manual page for it, from the Kernel Interfaces Manual, and yes it's giving vintage but we love her πŸŽ€


✨ SYNOPSIS ✨

kldload a.out

πŸ¦‹ DESCRIPTION πŸ¦‹

so the a.out(5) executable format is old old. like, it was the whole thing before the release of FreeBSD 3.0 πŸ’€ and since i386 was literally the only supported architecture back then, a.out(5) executables can only be activated on platforms that support execution of i386 code β€” think i386 and amd64 🫢

to add kernel support for old syscalls and old syscall invocation methods, you gotta put these options in the kernel configuration file:

options COMPAT_43
options COMPAT_FREEBSD32
heads up: the COMPAT_FREEBSD32 option is only required on 64-bit CPU architectures πŸ’…

and the aout.ko module needs to be loaded with the kldload(8) utility in order to support the a.out(5) image activator:

kldload aout

alternatively, if you want the module to load at boot time instead (main character energy, honestly), drop this line into loader.conf(5):

aout_load="YES"

okay so here's the tea β˜• the a.out(5) format was mainstream quite a long time ago. and the reasonable default settings + security requirements of modern operating systems today contradict the default environment of that time 😭 so you'll need to make adjustments to your system to mimic the natural environment for those old binaries. it's giving time capsule.

the following sysctl(8) tunables are useful for exactly this:

  • security.bsd.map_at_zero β€” set to 1 to allow mapping of process pages at address 0. some very old ZMAGIC executable images require text mapping at address 0. no cap πŸ”₯
  • kern.pid_max β€” old versions of FreeBSD used a signed 16-bit type for pid_t. current kernels use a 32-bit type for pid_t, and allow process id's up to 99999. those values cannot be represented by the old pid_t, which mostly causes issues for processes using wait(2) syscalls β€” for example, shells πŸ™ˆ set the sysctl to 30000 to work around the problem.
  • kern.elf32.read_exec β€” set to 1 to force any accessible memory mapping performed by a 32-bit process to allow execution, see mmap(2). old i386 CPUs did not have a bit in PTE which disallowed execution from the page, so a lot of old programs didn't specify PROT_EXEC even for mapping of executable code 😳 the sysctl forces PROT_EXEC if the mapping has any access allowed at all. this setting is only needed if the host architecture allows non-executable mappings.

🌈 SEE ALSO 🌈

execve(2), a.out(5), elf(5), sysctl(8)


πŸ‘‘ HISTORY πŸ‘‘

the a.out(5) executable format was used on ancient AT&T UNIX and served as the main executable format for FreeBSD from the very beginning up to FreeBSD 2.2.9 ⭐ and then in FreeBSD 3.0 it was superseded by elf(5). era ended, we move πŸ’…


🫢 AUTHORS 🫢

the aout manual page was written by Konstantin Belousov <kib@FreeBSD.org> πŸ’–


πŸ’€ BUGS πŸ’€

on 64bit architectures, not all wrappers for older syscalls are implemented. so like, not everything's gonna work, bestie, fair warning πŸ™ˆ


and that's the whole page, mwah πŸ’‹ this one came to us by way of Debian, dated August 14, 2012, and it lives under AOUT(4) β€” okay love you, bye πŸŽ€βœ¨

πŸ“¦ where this page comes from