Skip to content

Personalities

A personality is the OS ABI a process expects. Every context carries one, and it drives syscall dispatch, argument translation, error encoding, signals, and process startup.

Supported personalities

PersonalityValueBinary formatStatus
Kernel (native)0ELF (native)Native ABI, default
Linux1ELF (OS/ABI 0 or 3)~80/450 syscalls mapped
Windows (NT)2PE (machine 0x8664 / 0xAA64)Not started
Darwin (macOS)3Mach-O (x86_64 / arm64)Not started
FreeBSD4ELF (OS/ABI 9)Not started
NetBSD5ELF (OS/ABI 2)Not started
OpenBSD6ELF (OS/ABI 12)Not started

The numeric values are the on-wire representation stored in each Context and shared with the Zig layer; they match the C enum in include/personality.h.

Detection

Personality is detected from the binary during exec(), before the first return to userspace. The Zig layer provides the detection helpers:

ELF — fromElfOsAbi(osabi, machine)

Reads e_ident[EI_OSABI]:

OS/ABI byteMeaningPersonality
0ELFOSABI_NONE (System V)Linux (most common default)
3ELFOSABI_LINUX / GNULinux
9ELFOSABI_FREEBSDFreeBSD
2ELFOSABI_NETBSDNetBSD
12ELFOSABI_OPENBSDOpenBSD
othernative kernel

Modern Linux toolchains emit ELFOSABI_NONE, so 0 is treated as Linux by default; the loader may override based on other signals.

PE — fromPe(machine, subsystem)

Maps the PE machine type (0x8664 AMD64, 0xAA64 ARM64, 0x14C i386, …) to the Windows personality.

Mach-O — fromMachO(cputype, filetype)

Maps the Mach-O cputype (0x01000000 arm64, 0x00000007 x86_64, …) to the Darwin personality.

Wiring status

These helpers are implemented and unit-tested in Zig, but the Rust exec() path does not yet call them — contexts currently default to the native personality. Wiring this is part of the M1 milestone. See ELF & ABI spec.

Per-OS conventions

Different personalities encode results differently. The Zig dispatcher re-encodes the kernel's -errno/value convention into:

  • Linux — negative errno in the return register (no carry flag on x86_64).
  • Windows — NTSTATUS return convention.
  • *Darwin / BSD — error signalled via the carry flag on x86_64 (value in the return register otherwise).

Adding a new personality

  1. Add a variant to the Personality enum (personality/src/personality.zig).
  2. Add a detection clause in fromElfOsAbi() / fromPe() / fromMachO().
  3. Create personality/src/<name>/tables.zig with the syscall-number table.
  4. Create personality/src/<name>/shim.zig with argument/structure translators.
  5. Wire dispatch in personality/src/main.zig.
  6. Add binary-format loading on the Rust side (src/elf.rs, future src/pe.rs / src/macho.rs).

See the generated Personality Components for the current Zig surface.

Released under the AWFixer Source Available License v0.4. #linuswasright