From bytes
to liftoff. ๐
Build the runtime, reproduce the guests and follow their execution. Every compatibility claim refers to tested examples, with the remaining boundaries made explicit.
01 / Quick start
Requires Zig 0.16.0 and Python 3. The verified execution host is Apple M2 / macOS 26.6 ARM64. Linux x86-64 and ARM64 builds have been cross-compiled, with runtime execution there still unverified.
git clone https://github.com/OthmaneBlial/universe.git
cd universe
zig build -Doptimize=ReleaseSafe
python3 scripts/fixtures.py
./zig-out/bin/universe artifacts/guests/x86_64/hello-asm
Expected output: Hello from x86-64 Linux!
The
macOS ARM64 release bundle
includes bin/universe, sources and local check
scripts. Verify its archive against the included
SHA256SUMS.
๐ / Download an app. Run it on your Mac.
Current main runs unchanged official Linux x86-64 binaries of jq 1.8.2, ripgrep 15.2.0, 7-Zip 26.03, fd 10.5.0 and BusyBox 1.35.0. The explicit download script verifies archive and executable SHA-256 hashes. It does not rebuild the apps. Use the v0.2.1 bundle or build current source.
zig build -Doptimize=ReleaseSafe
python3 scripts/public-apps.py
python3 tests/public-apps.py
printf '{"answer":42}\n' |
./zig-out/bin/universe artifacts/public-apps/jq '.answer'
printf 'alpha\nbeta\ngamma\n' |
./zig-out/bin/universe --allow-files artifacts/public-apps/rg \
--threads 1 --color never -n '^(alpha|gamma)'
./zig-out/bin/universe --allow-files artifacts/public-apps/7zzs \
a -tzip -mmt=off -mx=1 artifacts/universe-docs.zip README.md
./zig-out/bin/universe --allow-files artifacts/public-apps/7zzs \
t -mmt=off artifacts/universe-docs.zip
./zig-out/bin/universe --allow-files --max-instructions 30000000 --timeout-ms 30000 \
artifacts/public-apps/fd --threads 2 --color never --type f --extension c . examples
./zig-out/bin/universe artifacts/public-apps/busybox printf '%s:%04d\n' hello 42
Expected outputs: 42, then 1:alpha and
3:gamma, then Everything is Ok from 7-Zip.
BusyBox prints hello:0042.
The optional suite checks 334 output/status/data workflows
across interpreter and JIT on ARM64 macOS: decimal JSON filters, Unicode/sorting,
predicates, parse errors, regex search/counts, two-thread directory searches/file listings, ZIP/7z creation/extraction,
hashing, threaded 7z round trips, recursive ZIP folders, preserved timestamps and denied access.
Python independently checks ZIP CRCs/member bytes and provides a second archive input.
fd adds 19 cases per engine for exact NUL-delimited file/directory/symlink inventories,
Unicode names, hidden/ignore rules, extension/glob/depth/exclusion filters,
physical absolute paths, two-thread traversal and error exits.
BusyBox adds 113 cases per engine: 30 utility/file cases for dispatch/help, formatting, sequences, hashes,
Base64 binary round trips, text filters, exit statuses, Unicode file reads,
exact copies/renames/removals, directories and denied access;
11 virtual-identity cases, 57 noninteractive shell cases and fourteen device/mount/system-info cases, including external guest commands,
mount, three df modes, guest-memory free and guest-backed ps without file grants, signal traps, background output,
wait statuses and child reaping.
The BusyBox binary comes from its official 1.35.0 download directory;
its SHA-256 pin records the downloaded bytes, rather than a separately published upstream checksum.
This older binary is unchanged and has not been rebuilt.
It falls back from unavailable sendfile to its own read/write code.
Isolated fork/wait/exec supports selected subshells, command substitution and external pipelines,
including unchanged jq and ripgrep guests. Standard signals also run selected background jobs and traps.
Terminal job control, networking and all-app compatibility remain future work.
./zig-out/bin/universe artifacts/public-apps/busybox sh -c \
'n=0; for x in 2 3 5; do n=$((n+x)); done; printf "%d\n" "$n"'
# 10
Selected unchanged sh -c scripts now pass loops, functions,
conditions, arithmetic, Unicode/spaced arguments, stdin reads, exit statuses
and allowed/denied file redirection. Guest UID/GID remain 1000 with an empty
supplementary-group list; PID/parent expansion is 1:0.
Identity names are checked in a controlled sysroot, without host credentials.
Native file access and redirection require --allow-files; internal null/zero devices and synthetic read-only /proc/mounts and guest-memory /proc/meminfo need no grant.
fd's file searches need --allow-files; its scoped checks use
one/two threads and a 30-million-instruction, 30-second execution limit.
The source-file command above is checked against Python's real file inventory.
Subprocess execution (--exec) and arbitrary fd workflows remain unverified.
ripgrep needs --allow-files for its cwd query, even with stdin.
The stdin example selects --threads 1; directory searches and file listings
also pass with --threads 2. Its build's PCRE2/JIT availability message is
not validation of PCRE2 JIT. Linux 7-Zip checks cover -mmt=off
and threaded -mmt=2 round trips with file access.
This milestone covers useful CLI workflows;
GUI apps, networking, Windows guest threads and broad Windows app compatibility remain future work.
Exact app evidence and boundaries โ
Windows 7-Zip lands too ๐ช
The unchanged Windows x64 7za.exe completes 34 workflows across both engines:
ZIP/7z round trips, Unicode filenames, hashing, recursive folders, timestamps, corrupt/missing input and denied access.
Python independently checks ZIP member bytes and CRCs.
python3 scripts/public-apps.py --windows
./zig-out/bin/universe --allow-files artifacts/public-apps/7za.exe \
a -tzip -mmt=off -mx=1 artifacts/windows-docs.zip README.md
./zig-out/bin/universe --allow-files artifacts/public-apps/7za.exe \
t -mmt=off artifacts/windows-docs.zip
python3 tests/public-apps.py --windows
The Windows probe exits 0 with all 34 checks passing. Denied file access now runs the app's own C++ cleanup and catch machine code, returning its expected application exit 2. The download script extracts the pinned Windows release using Linux 7-Zip inside UNIVERSE. All 1,335,296 executable bytes match the original. Build current main first; fresh extraction can take several minutes within its separate 300-second limit. Execution uses UNIVERSE's own CPU and APIs.
Guest threads take their own seats ๐งต
Actual musl pthread code now runs on x86-64, AArch64 and RISC-V64 in both engines: mutexes, condition waits, joins, separate TLS, CPU-bound preemption, timed waits and sleeps. Guest pipes also move 32,769 exact bytes between threads, with blocking, backpressure and EOF checks. ๐จ
./zig-out/bin/universe artifacts/guests/x86_64/pthread
./zig-out/bin/universe artifacts/guests/aarch64/pthread
./zig-out/bin/universe artifacts/guests/riscv64/pthread
# pthread: pipe blocking, backpressure, exact 32769 bytes and EOF ok
Build the core fixtures first. Guest thread contexts share memory and execute serially, with global instruction/time limits. Relative/absolute sleeps suspend the calling guest while other contexts continue; a sleeping guest still respects the runtime deadline. Empty pipe reads and full queues suspend the calling guest too. Pipe waits and x86-64 poll still respect the execution deadline. Pipes work without a file-access grant. Isolated fork/wait/exec also runs selected BusyBox pipelines, command substitution and external same-architecture ELF programs. Robust recovery, cancellation and dynamic-library pthread TLS remain unsupported or unverified. Thread evidence and limits โ
Fork, exec, and pass the bytes along ๐
Children have separate CPU/TLS contexts, memory and descriptor tables, while file offsets and pipe queues stay shared. The default 256 MiB mapped-memory budget and execution limits cover the whole process tree. A source fixture checks identity, independent variables/masks, 4,097 exact pipe bytes, EOF, WNOHANG and child exit status on all three CPUs in both engines.
./zig-out/bin/universe --allow-files artifacts/public-apps/busybox sh -c \
'printf '\''{"answer":42}\n'\'' | ./artifacts/public-apps/jq .answer'
# 42
Run from the repository after downloading the pinned apps. BusyBox creates a guest child, jq replaces its image, and JSON bytes travel through the guest pipe. Twelve new cases per engine compare exact results for external commands, PATH lookup, Unicode argv/environment, file redirection and three-stage pipelines. An execโd cat returns all 4,620 producer bytes through the 4 KiB queue. ๐จ Failed loading preserves the old image; successful exec keeps process identity and closes CLOEXEC descriptors. All three CPUs also pass dynamic musl handoffs. Standard SIGCHLD delivery and selected background waits now work; general shell compatibility remains unverified. Process evidence and limits โ
A signal reaches the guest ๐ก
Guest handlers now receive checked Linux signal frames on x86-64, AArch64 and RISC-V64. Masks, siginfo, alternate stacks and handler edits to saved registers are verified in both engines. Child exits deliver SIGCHLD; broken guest pipes deliver SIGPIPE. These signals stay inside UNIVERSE.
./zig-out/bin/universe artifacts/public-apps/busybox sh -c \
'trap '\''echo caught'\'' USR1; kill -USR1 $$; echo hi & wait'
# caught
# hi
Run from this repository after downloading the pinned apps. Twelve cases per engine check
background bytes, child statuses, USR1/USR2/TERM and SIGCHLD traps, ignored signals, SIGKILL,
background jq output and repeated wait/reaping. BusyBox opens UNIVERSEโs internal /dev/null;
no sysroot device node is needed. Ten of these cases also pass without file grants.
SA_RESTART covers guest pipe I/O, wait4 and untimed futex waits. Caught signals interrupt sleeps,
poll and timed futex waits with EINTR. Real-time queues, stop/continue, host Ctrl-C forwarding,
native fault signals and terminal job control remain future work.
Exact signal profile โ
Two tiny devices, no host files ๐ณ๏ธ
Guest /dev/null discards output and returns EOF. Guest /dev/zero
supplies zero bytes and private zero-filled mappings. Both work inside an empty sysroot
without --allow-files, and keep shared descriptor flags across dup and fork.
./zig-out/bin/universe artifacts/public-apps/busybox sh -c \
'printf hidden > /dev/null; echo visible; echo hi & wait'
# visible
# hi
Nine device workflows check exact zero bytes, EOF, redirection, character-device stat records, trailing-slash errors and ordinary-file denial in both engines. Their sysroot stays empty. Real files and external exec still need grants. Directory enumeration, shared device mappings, terminal devices and a general device filesystem remain future work. Exact device profile โ
02 / Explore the guests
All core guests are rebuilt from C and assembly in the repository. Try another architecture or OS ABI using the same runtime:
./zig-out/bin/universe artifacts/guests/riscv64/compute
./zig-out/bin/universe artifacts/guests/aarch64/system
./zig-out/bin/universe artifacts/musl-hello
./zig-out/bin/universe artifacts/hello.exe
BusyBox on a Mac ๐ช
The optional script downloads checksum-pinned official BusyBox
1.37.0 source and compiles a minimal static x86-64 musl build.
Selected applets include echo, printf,
grep, sed, tr,
uniq, mkdir, cp,
mv and touch. Regression tests exercise
representative text and file operations. Requires Python 3.12+,
make, native cc and network access.
python3 scripts/busybox.py
python3 tests/busybox.py
./zig-out/bin/universe artifacts/busybox-1.37.0/busybox echo hello
./zig-out/bin/universe --allow-files artifacts/busybox-1.37.0/busybox ls examples
BusyBox is a separate GPL-2.0 guest and is not bundled in UNIVERSE releases. Build and license details โ
Take your database into orbit ๐๏ธ
The optional SQLite 3.53.4 static x86-64 CLI executes real SQL
queries and file-backed transactions. Tests check indexes, joins,
Unicode text and blobs, rollback, delete/truncate journals, VACUUM,
native database reopen and lock contention in interpreter/JIT paths.
Database files require --allow-files.
python3 scripts/sqlite.py
python3 tests/sqlite.py
./zig-out/bin/universe artifacts/sqlite-x86_64 -batch :memory: 'select 6 * 7;'
# 42
Uses checksum-pinned, unmodified upstream source with threads and extension loading disabled. WAL and interrupted-commit recovery remain unverified, along with SQLite signal interruption and host Ctrl-C forwarding. Build, tests and boundaries โ
A shared library joins the mission ๐
Current main verifies dynamic x86-64, AArch64 and RISC-V LP64 executables and PIE with upstream musl 1.2.5, a separate guest library, a constructor and single-thread TLS, both from startup and guest exec handoffs. The guest linker runs on UNIVERSE's own CPU engine. RISC-V uses the soft-float ABI. Requires Python 3.12+, make, awk and network access.
python3 scripts/musl.py --arch all
python3 tests/musl.py --arch all
./zig-out/bin/universe --allow-files --sysroot artifacts/musl-sysroot \
--env UNIVERSE_TEST=dynamic artifacts/musl-dynamic-pie check
--sysroot prefixes absolute Linux paths; host
symlinks and relative paths can access files elsewhere. It is not
a sandbox.
Build details and tested scope โ
Say hello with the original Linux libraries ๐ง
The unchanged Debian GNU Hello app now runs with its glibc 2.41 loader and shared library on the tested ARM64 Mac. Fetch the pinned packages into the projectโs private sysroot, then launch the app.
python3 scripts/debian.py
./zig-out/bin/universe --allow-files \
--sysroot artifacts/debian-hello-amd64/sysroot \
artifacts/debian-hello-amd64/sysroot/usr/bin/hello
The app prints Hello, world!. The optional
python3 tests/debian.py probe passes 24 checks across
both engines, covering greetings, help, package-specific version/error
output, C-locale conversion errors and default file denial.
Dynamic library opens require --allow-files.
Checked workflows and limits โ.
Sort, hash and inspect real files
Debian coreutils 9.7-3 runs with its original shared libraries. The optional suite checks 94 workflows across both engines for ten utilities, including binary data, Base64, SHA-256, simple and long directory listings, and file/symlink metadata.
python3 scripts/debian.py --coreutils
printf 'z\na\nb\n' | ./zig-out/bin/universe --allow-files \
--sysroot artifacts/debian-coreutils-amd64/sysroot \
artifacts/debian-coreutils-amd64/sysroot/usr/bin/sort
python3 tests/coreutils.py
The sort prints a, b, z,
one per line. Listings use --color=never;
long listings use read-only llistxattr. Other
extended-attribute calls and explicit stat cache policies remain
unsupported. Broader coreutils compatibility
needs separate evidence.
Load a Windows library mid-flight ๐ช
LoadLibraryA/W, GetProcAddress and FreeLibrary execute guest DLLs with attach/detach callbacks, shared references, late forwarders, cyclic imports and repeated reload. The fixture builder supplies every library from source. Use the explicit sysroot and file grant.
./zig-out/bin/universe --allow-files --sysroot artifacts/windows-sysroot \
artifacts/windows-dynamic.exe
Our OLEAUT32 APIs also allocate/free BSTRs and copy/clear scalar, string and by-reference variants. Named and ordinal imports run without external Windows DLLs. USER32 adds UTF-16 unit uppercasing and DBCS cursor navigation. ADVAPI32 adds entropy, process tokens and empty read-only registry roots. Our legacy MSVCRT subset adds memory, original argv/data imports, standard streams and guest initializer/exit callbacks. Our Win32 layer now models shared events/semaphores, recursive critical sections and pending waits that respect execution deadlines. File operations add no-overwrite moves, links, pending deletion, checked metadata and large-file seeking. Calendar/FILETIME conversions, current local/UTC clocks and virtual process timing also run through our own APIs. Terminal input modes and guest Ctrl+C/break callbacks work with real host terminals and signals; output screen buffers remain unsupported. File sections add coherent shared views, private guest-page copy-on-write, dirty-page flushes and independent handle/view lifetimes. These source-built fixtures need no sysroot or file grant; the mapping fixture also checks virtual CPU features and memory availability through allocation/free. The encoding oracle checks every valid Unicode scalar and malformed inputs in both directions. Module checks compare actual load paths, filename buffers and DLL lifetimes. Local memory checks cover fixed/movable allocations, resizing, locks and discarded handles. Message checks compare diagnostics, typed inserts, line widths and locally allocated buffers. Directory checks cover current/temp paths, sysroots and real relative file/DLL behavior. Drive checks cover a mounted virtual C drive, reusable DOS paths and exact A/W drive strings. Enumeration checks cover DOS wildcards, metadata and search lifetimes. Stream checks cover default file data and A/W access through the returned stream name. Metadata handles retain real directory/link identities. Device checks compare checked UTF-16 reparse records with native symbolic-link targets; entry checks verify Win64 home slots:
./zig-out/bin/universe artifacts/windows-automation-ordinal.exe
./zig-out/bin/universe artifacts/windows-text.exe
./zig-out/bin/universe artifacts/windows-security.exe
./zig-out/bin/universe artifacts/windows-crt.exe core '' 'a b' 'a"b' 'tail\' 'รฉ๐'
./zig-out/bin/universe artifacts/windows-sync.exe
./zig-out/bin/universe artifacts/windows-fileops.exe
./zig-out/bin/universe artifacts/windows-time.exe
./zig-out/bin/universe artifacts/windows-console.exe
./zig-out/bin/universe artifacts/windows-mapping.exe
python3 tests/windows-encoding.py
python3 tests/windows-modules.py
python3 tests/windows-local.py
python3 tests/windows-message.py
python3 tests/windows-directory.py
python3 tests/windows-find.py
python3 tests/windows-stream.py
python3 tests/windows-drives.py
python3 tests/windows-metadata.py
python3 tests/windows-device.py
python3 tests/windows-stack.py
Uppercasing uses bundled Unicode 17.0.0 BMP simple mappings;
supplementary casing and Windows NLS version parity are unverified.
The virtual token has no assigned Windows privileges; file ACL
calls fail explicitly without changing host permissions.
Windows 7-Zip now binds OLEAUT32, USER32, ADVAPI32 and all 39 MSVCRT imports.
All static imports now bind, including DeviceIoControl.
Both engines complete 17 Windows 7-Zip archive/hash/error workflows each.
Our bounded C++ profile executes POD throws, real cleanup/catch funclets and checked continuations.
Nested throws, rethrows, nontrivial exception-object lifetimes and SEH/RTTI still fail explicitly;
guest threads and broad CRT support remain missing.
Windows API scope and loader limits โ
The file-operation fixture defaults to denied access. Local integration checks grant files in isolated temporary directories and compare actual file bytes, hard links and host timestamps in both engines. Cross-volume moves, progress callbacks and broader Windows attributes remain unsupported. Time checks cover Gregorian/DOS dates, current time-zone offsets and actual file timestamp updates. Files still need a grant; native Windows timezone/filesystem parity is unverified.
Mach-O joins the orbit ๐
On macOS, Apple command-line tools build five library-free x86-64 and AArch64 guests. UNIVERSE executes their machine code and translates a small Darwin BSD syscall subset.
python3 scripts/macos.py
./zig-out/bin/universe artifacts/macos/x86_64/hello
./zig-out/bin/universe --env KEY=value artifacts/macos/aarch64/arguments foo
Dyld and LibSystem imports remain unsupported. Native builds of the same syscall test source are compared only on a matching CPU. Loading, ABI and validation boundaries โ
03 / Take the controls
./zig-out/bin/universe inspect artifacts/guests/x86_64/hello-asm
./zig-out/bin/universe inspect --ir --count 8 artifacts/guests/x86_64/hello-asm
./zig-out/bin/universe trace artifacts/hello.exe
./zig-out/bin/universe --stats --jit artifacts/guests/riscv64/benchmark
./zig-out/bin/universe debug artifacts/guests/x86_64/hello-asm
The debugger supports run, continue,
step, one break point,
registers, memory, stack,
disasm, ir, syscalls and
quit. Single stepping uses the interpreter.
Guest exit codes pass through. Runtime faults return 125 with a named error, guest PC and instruction bytes. Debugger reference โ
04 / Inside the runtime
Validated ELF64, PE32+ or Mach-O64 bytes are mapped into checked guest memory. The x86-64, RV64IMAC plus selected F/D/CSR, or AArch64 decoder creates typed UIR operations. The interpreter executes those operations and translates Linux/Darwin syscalls or the Windows API subset into host services.
The optional ARM64-host JIT emits native code for eligible register-only blocks. Flags, memory accesses, branches, vector operations and syscalls remain interpreted. Pages transition from RW to RX; guest code writes and mapping changes invalidate the cache.
The file data and guest backing allocations have explicit lifetimes. A guest address is never cast into an arbitrary host pointer.
05 / Know the boundaries
Current main verifies private regular-file snapshots, fixed-address
mappings and selected file mutations on all three Linux guest
CPUs. These are included in v0.2.0.
Shared mappings and coherence with later file changes are
unsupported. Linux creation, removal, rename and timestamp changes
remain behind --allow-files.
| Guest | Verified scope |
|---|---|
| Official jq / ripgrep / 7-Zip / fd / BusyBox Linux binaries | Unchanged static x86-64 binaries; JSON/text, ZIP/7z archives, file hashing, searches, BusyBox utilities/file copies, virtual identity, selected shell scripts, external commands and error exits in both engines |
| Official 7-Zip Windows release | Unchanged x86-64 PE32+ binary; 34 archive/hash/error workflows pass, including denied-access C++ cleanup/catch |
| Linux x86-64 ELF64 | Static assembly/C fixtures, PIE, static musl Hello World, POPCNT/BSWAP, SSE4.2 CRC32C/PCMPGTQ and selected SSE2/SSE3/SSSE3/ SSE4.1 integer and floating-point instruction subsets |
| Dynamic musl x86-64 / AArch64 / RISC-V LP64 | ET_EXEC/PIE, separate DSO, constructor and TLS fixture |
| Linux RV64IM / RV64IMC ELF64 | Twelve C fixtures in both variants, atomics and a separate hard-float F/D transfer/five-mode arithmetic/conversion/CSR fixture |
| Linux AArch64 ELF64 | Integer C fixtures; partial opcode coverage |
| Windows x86-64 PE32+ | Terminal input/control callbacks, shared file views, fixed/movable local memory, message diagnostics, current/temp directories, logical C drive, directory/link reparse metadata, file/stream enumeration, loaded module paths, UTF-8/UTF-16 conversion, virtual CPU/memory and disk-space queries, file mutations/metadata/times, calendar/local clocks, runtime guest DLLs, static TLS and 64-slot dynamic TLS APIs, OLEAUT32/USER32/ADVAPI32 subsets and legacy CRT and single-thread events/semaphores/waits/locks |
| BusyBox x86-64 | Selected static text and file applets; tested cases include grep/sed/tr/uniq and touch |
| SQLite 3.53.4 x86-64 | Static batch CLI: persisted transactions, rollback, VACUUM, native reopen and lock contention |
| Mach-O64 x86-64/ARM64 | Five library-free console, argv/env, memory and file fixtures |
No full CPU instruction set, arbitrary application, full shell functionality or complete OS compatibility is advertised.
Linux accepts little-endian ET_EXEC and PIE, with non-overlapping
load pages. Dynamic x86-64, AArch64 and soft-float RISC-V musl
are verified for the fixture above. The unchanged Debian Hello/glibc
app also runs with its original loader and shared library, passing
24 application/profile checks across both engines.
Read the reproducible glibc application check โ.
Arbitrary dynamic applications and sockets remain unsupported. Standard guest signals use
checked frames, masks, pending sets and handler return. Linux
shared-memory threads run with separate CPU/TLS state, real futex queues and blocking pipes.
Pipes have a 4 KiB queue with atomic small writes, shared nonblocking flags, checked FIONREAD
and EOF/EPIPE results. Broken writers queue guest SIGPIPE; generic ppoll remains unsupported.
Fork copies only the calling context into private memory/descriptors; wait4 reaps exits
and schedules blocking waits. Checked exec replaces a same-architecture ELF, validates argv/environment,
preserves PID/parent/masks and closes CLOEXEC descriptors after successful loading.
It requires file permission and executable inputs; failed loads preserve the old image.
JIT blocks clear on process switches and exec. Broader clone profiles,
clone3, vfork, waitid, resource-usage output, real-time signals and stop/continue remain unsupported.
Windows accepts small kernel32/kernelbase, OLEAUT32,
USER32, ADVAPI32 and legacy MSVCRT API subsets
and guest DLL imports with named/ordinal exports, rebasing and
forwarding. Runtime load/unload, attach/detach callbacks and
rollback are verified. Static TLS templates, per-module indices,
process callbacks and 64-slot dynamic TLS APIs work for the initial
guest thread. Events/semaphores share named-object state, and pending waits honor runtime
timeouts. Critical sections are recursive on the initial thread; affinity
describes one virtual CPU and uptime/performance clocks use monotonic time.
Processor-feature queries agree with guest CPUID; memory-status queries track
the 256 MiB guest budget and available virtual address space as mappings change.
Disk-space queries use the host volume's allocation unit and 64-bit counters;
they require a file grant, and legacy cluster counts saturate at DWORD limits.
UTF-8/UTF-16 conversion follows the virtual UTF-8 ANSI/OEM policy,
with strict validation or replacement and checked buffer sizing.
Legacy code pages remain unsupported; native Windows NLS parity is unverified.
Module filename queries retain absolute host load paths, including
Unicode names and truncation by bytes or UTF-16 units.
Built-in API modules have no file and fail explicitly.
Local-memory checks compare 84 full byte sequences per engine, including
resize, zero filling, locks, discarded handles and checked use-after-free faults.
Message formatting checks compare 1,428 exact byte cases per engine against
native numeric and Python text oracles. The English diagnostic catalog is ours;
vendor message resources and broad localization remain unsupported.
Current/temp directory checks compare physical Unicode paths, exact UTF-16
buffer capacities, sysroot round trips and guest DLLs after directory changes.
Explicit TMP/TEMP/USERPROFILE settings select temporary paths; host variables
are never inherited. The fallback is C:\tmp\ in the guest path namespace.
File enumeration checks 9,112 SDK replies per engine against recursive
wildcard and host metadata oracles, including Unicode names, symlinks,
files larger than 4 GiB and searches retained after directory changes.
Search output and cursor checks cover allocation and write failures.
Short-name aliases remain unsupported; native Windows filesystem parity is unverified.
Default stream checks compare 2,145 exact SDK replies per engine,
including real Unicode A/W reads and writes through ::$DATA,
shared identities, resizing and pending deletion. File and stream searches
share 1,024 checked slots. Named alternate streams remain unsupported.
Drive enumeration checks 189 exact A/W replies per engine, including double NUL
terminators and real disk/file round trips through the returned C:\ root.
Other drives and UNC/device namespaces remain unavailable.
Metadata checks compare 182 directory/link SDK replies per engine, including dangling links,
sharing, rename and pending deletion. Device checks compare 1,226 exact SDK replies per engine
with native readlink records, Unicode targets and checked buffer failures.
Reparse writes, raw devices and driver passthrough remain unsupported.
Unchanged Windows 7-Zip completes 34 archive/hash/error workflows across both engines;
denied-access exits execute the app's own C++ catches. Global IPC,
inheritance, guest thread creation, thread notifications, TLS expansion slots,
FLS, loader search/flags,
broad CRT compatibility, broader C++ exceptions/SEH/RTTI, environment APIs and GUI remain unsupported.
Owning COM objects, SAFEARRAYs and records return E_NOTIMPL.
Windows command lines use UTF-8 for A APIs and UTF-16 for W APIs.
Process heap allocation and synchronous regular-file APIs are
verified with source-built PE guests. Files require
--allow-files; the virtual C drive maps to the sysroot or host root.
Canonical absolute \\?\C:\... names use the same mount;
extended paths with dot/parent components, repeated separators or forward slashes fail explicitly.
POSIX aliases remain accepted; guest sharing
checks do not provide a Windows filesystem or host-wide locks.
Same-volume moves preserve existing destinations unless replacement is requested;
shared deletion stays pending until final close. The read-only attribute maps
to host write bits on regular files. Directory permissions and identity are preserved;
opaque non-setter bits are ignored, and other setter attributes fail explicitly.
File-time updates require write/attribute rights. The legacy local/UTC pair uses
the current host time-zone/DST offset, including for older dates.
Stdin terminal modes support processed/line/echo input. Ctrl+C/break handlers
run serially on the initial guest thread and restore interrupted CPU state,
LastError and pending waits. Console code pages are UTF-8 only;
output modes, screen buffers and native Windows handler-thread scheduling remain unsupported.
File sections support coherent shared views and private 4 KiB copy-on-write pages,
with checked sparse offsets and dirty-page flushes. Executable paging views run
through our CPU engine. External changes are not synchronized with cached views;
image/reserve/large-page sections, file execute rights and global IPC remain unsupported.
Guest DLLs require both an explicit --sysroot and file
access; their code runs through UNIVERSE's CPU engine. Startup imports
retain dependencies, and loader calls from DllMain are rejected.
Mach-O accepts thin x86-64/AArch64 executables without libraries
or fixups. Console I/O, arguments/environment, private mappings
and regular files are verified. Dyld, LibSystem, TLS, Mach IPC
and GUI frameworks remain unsupported. Files need
--allow-files; the path prefix is not confinement.
The x86 SIMD support is a tested SSE integer and transfer subset plus packed/scalar single/double add, subtract, multiply, divide, square root, minimum, maximum and all eight legacy CMP predicates. Minimum/maximum select source 2 for NaNs and equal values. Guest COMI/UCOMI set EFLAGS for ordered/unordered comparisons. Scalar signed integer conversions support CVT using the current MXCSR rounding mode and CVTT truncation. Legacy MOVSS/MOVSD move scalar values while preserving upper XMM lanes for register moves; CVTSS2SD/CVTSD2SS convert scalar float formats. Packed SSE2 conversions cover four-lane single/integer and two-lane single/double/integer formats. AVX is unsupported. SSE3 MOVSLDUP/MOVSHDUP/MOVDDUP duplicate scalar lanes; LDDQU loads an unaligned 128-bit memory source. HADDPS/PD and HSUBPS/PD cover horizontal arithmetic, while ADDSUBPS/PD alternate subtraction and addition by lane. POPCNT counts 16-, 32- and 64-bit register or memory sources and sets ZF when the source is zero. BSWAP reverses 32- and 64-bit registers, including extended GPRs, without changing flags. SSE4.2 CRC32 checks byte/word/dword/qword forms against a scalar CRC32C oracle, including high-byte operands, zero-extension and unchanged CF/ZF/PF/OF/SF. PCMPGTQ compares both signed qword lanes from registers or aligned memory. AArch64 includes vector transfers, integer immediate patterns, DUP, lane moves, modular NEON ADD/SUB/MUL, AND/BIC/ORR/EOR, MVN, and signed CMGT/CMEQ across B/H/S/D lanes in D/Q arrangements. TBL/TBX handles one-to-four-register tables and wrap; integer MLA/MLS supports aliased accumulators. MUL/MLA/MLS supports B/H/S lanes only. Table/accumulate checks match scalar and native ARM64 destination bytes on 8,448 queries per engine across 228 instruction views. Floating-point arithmetic and the rest of NEON remain unsupported. Exact instructions, syscalls and application coverage โ
The implemented SSE arithmetic and conversions honor all four MXCSR
rounding modes, signed-zero DAZ/FTZ handling, NaN rules and sticky
exception flags. Exact rational oracles check arithmetic, conversions,
comparisons, horizontal operations, ROUND and dot products. New
unmasked conditions stop with SimdFloatingPointException
and preserve destinations; CPU fault-to-signal delivery remains unsupported.
Original MMX operations now run against exact scalar oracles, using 64-bit registers and shared physical x87 data. Paired CMPXCHG8B/16B check both memory halves and write on success or failure. Bounded FXSAVE/FXRSTOR preserve raw x87/MMX data and all 16 XMM registers; LDMXCSR/STMXCSR accept rounding controls, DAZ/FTZ, exception masks and stored status bits. The fixed virtual CPU profile exposes FPU, CX8, MMX, CX16, FXSR, SSE and SSE2 through a recognized instruction vendor. The unchanged glibc app now passes its CPU discovery and ISA checks. Newer feature families, native fault-state parity and CPU fault-to-signal delivery remain open. Baseline instruction inventory โ.
x87 stack transfers, raw 80-bit values, integer/float conversions, rounding controls and deferred exceptions now pass exact rational oracles; basic add/subtract/multiply/divide, square roots, integral rounding and ordered/unordered comparisons, conditional moves, all seven constants and exact FXTRACT significand/exponent outputs, FPREM/FPREM1 remainders and FSCALE power-of-two scaling, plus F2XM1 exponential-minus-one and FYL2X/FYL2XP1 scaled logarithms, FPATAN angles, FSIN/FCOS and paired FPTAN/FSINCOS, now pass 358,129 Fraction/decimal/bit queries per engine across 90 decoded forms. Arithmetic supports 24/53/64-bit precision and four rounding modes across the full extended exponent range. Register overflow/underflow store biased results before deferring exceptions. FXTRACT normalizes denormals and preserves both results on unmasked operand/stack faults. Remainders expose quotient bits and C2; guests repeat partial reductions until complete. FSCALE truncates its exponent toward zero and retains full significand precision regardless of precision control. It handles gradual underflow, biased exceptions and massive overflow/underflow; FXTRACT followed by FSCALE reconstructs the original finite value. Another 648 remainder and 252 scaling numeric cases match the host binary64 math library; native x87 hardware and flag parity remain unverified. Real apps also exercise 32-bit wrapped addresses, XADD, SHUFPS/PD, UNPCKL/HPS/PD and MOVMSKPS/PD. Linux adds bounded poll, resource queries, alternate-stack metadata, descriptor duplication and futex waits/wakes integrated with guest scheduling. Optional unavailable services return Linux errors; CPU fault-to-signal delivery remains unsupported.
F2XM1 computes 2^ST(0) - 1 over the specified
[-1, 1] range. A normalized 113-bit approximation
retains tiny extended inputs and exponent-biased underflow results,
preserves signed zero and honors rounding control regardless of
precision control. Unmasked operand faults preserve the destination;
precision and underflow results commit before deferring exceptions.
Both engines pass 18,013 new decimal/bit queries and 16 sampled
monotonicity sequences. Another 257 host-math comparisons agree
within three binary64 ulps. Universal correct rounding and native
x87 numeric/flag parity remain unverified; out-of-range inputs have
undefined numeric results. FPTAN and FSINCOS now execute both stack
outputs; broader CPU coverage and native x87 numeric/flag verification
remain future work.
FYL2X computes ST(1) * log2(ST(0)) and pops after
committing the result. Centered reduction retains inputs adjacent
to one; normalized multiplication retains tiny values and biased
underflow across the extended argument and multiplier ranges.
Rounding control applies to a 113-bit approximation independently
of precision control. Unmasked operand faults preserve both registers and
TOP; precision, overflow and underflow results commit and pop
before deferring exceptions. Both engines pass 22,872 new
decimal/bit queries and 32 sampled increasing/decreasing sequences.
Another 384 host-math comparisons agree within three binary64 ulps.
Sixteen constructed tiny-result cases retain underflow and precision
flags even when the approximation appears exact: nearest matches
Decimal and all modes stay within one subnormal destination step.
C1 follows the approximation's rounding; universal correct rounding
and native x87 numeric/flag parity remain unverified.
FYL2XP1 computes ST(1) * log2(1 + ST(0)) over
[-(1 - sqrt(2)/2), +(1 - sqrt(2)/2)] and pops after
committing the result. The shared logarithmic series avoids
forming 1 + ST(0); normalization retains products of
two minimum subnormals before gradual or exponent-biased rounding.
It preserves signed zero, ignores precision control and honors
rounding control. Unmasked operand faults preserve registers and TOP;
computed precision and underflow results commit and pop before
deferred faults. Outside the specified domain numeric results are
undefined; our profile retains ST(1) and still pops, and excludes
those inputs from the numeric oracle. Both engines pass 35,353
new decimal/bit queries and 32 sampled increasing/decreasing
sequences; 225 bounded host log1p comparisons agree within three
binary64 ulps. Universal correct rounding
and native x87 numeric/flag parity remain unverified.
FPATAN computes atan2(ST(1), ST(0)) across the full
extended operand ranges and pops after committing its result.
Both operand signs select the quadrant, including signed-zero
and infinity combinations. Zero/zero and infinity/infinity have
defined angles and do not invent division exceptions. Regular
angles reuse the 113-bit series with pi/4 reduction; tiny angles
use normalized integer division and 192 fractional bits to retain
ratios below binary128's range and the correction below
representable inputs. Precision control is ignored; rounding
control applies. Unmasked operand faults preserve registers and
TOP; computed precision/underflow results commit and pop before
deferred faults. Both engines pass 29,289 new Decimal/Fraction/bit
queries and 48 sampled monotonicity sequences within continuous
angle branches. Another 1,089 bounded host atan2 comparisons
agree within three binary64 ulps. Universal correct rounding and native x87
numeric/flag parity remain unverified.
FSIN and FCOS cover the strict finite range
-2^63 < ST(0) < 2^63. Integer pi/2 reduction
with 256 fractional bits preserves large-angle residuals before
the 113-bit series. Tiny inputs and residuals use 192-bit fractional
Taylor terms, retaining corrections below the input and below one,
including neighbors of pi/2 and pi. Precision control is ignored;
rounding control applies. Finite out-of-range inputs set C2 and
preserve ST(0); accepted computations clear C2. Infinity raises
invalid. Unmasked operand faults preserve ST(0), TOP and prior C2;
precision results commit before deferred exceptions. These instructions
do not raise underflow: tiny sine results retain gradual rounding
even when underflow is unmasked, without biased exponents.
Existing sticky underflow remains intact. Both engines pass 35,250
new independent Decimal/Fraction/bit queries, 48 sampled monotonicity
sequences and 1,536 bounded host sin/cos comparisons within three
binary64 ulps. Mathematical pi reduction can differ from hardware
x87's approximation at large angles. Universal correct rounding
and native x87 numeric/flag parity remain unverified.
FPTAN and FSINCOS now compute both stack results throughout the strict finite range below 2^63, given a valid source and a free pushed slot. FPTAN leaves tangent in ST(1) and one in ST(0); FSINCOS leaves sine in ST(1) and cosine in ST(0). Both ignore precision control and honor rounding control. Tangent uses unrounded 113-bit sine/cosine series and reciprocal reduction near poles; tiny inputs/residuals retain the positive correction with 192 fractional bits. Unlike FSIN/FCOS, these instructions retain gradual or exponent-biased underflow. Computed precision/ underflow results commit both slots and decrement TOP before deferred faults. Unmasked operand faults preserve the stack; masked stack faults produce indefinite in both destinations. Stack faults precede the numeric range check. With a valid stack, finite out-of-range values set C2 without a push or register change. C1 follows sine for FSINCOS and tangent for FPTAN in our profile; unmasked operand faults retain prior C2. Both engines pass 37,584 new FSINCOS and 38,352 new FPTAN Decimal/Fraction/bit queries, 64 sampled monotonicity sequences and 768 bounded host tan comparisons within three binary64 ulps. Universal correct rounding and native x87 numeric/flag parity remain unverified; broader CPU/SIMD and application compatibility work remains open.
FBLD and FBSTP now handle signed 18-digit packed BCD values. Loads are exact and preserve negative zero; stores honor all four rounding modes and the rounded decimal range limit. Invalid stores produce BCD indefinite when masked and preserve the destination and stack when unmasked. Precision faults still commit the store and pop. Both engines pass 65,613 transfer queries, including 35,800 BCD load/store/round-trip cases and every unused sign-byte pattern. Malformed decimal digits have undefined numeric results and are excluded from the numeric oracle. Native x87 hardware parity remains unverified.
Legacy x87 FLDENV/FNSTENV and FRSTOR/FNSAVE now save and restore protected-format environments and complete 80-bit stack images. Both operand layouts pass 22,304 exact image/state queries and eight deferred-fault checks per engine, covering every stack position, occupancy mask, pointer truncation and reconstructed register tags. Environment-only stores mask exceptions; full saves reset x87 state. Waiting stores and save/restore sequences execute through our own engine. Memory and allocation failures preserve state and output bytes; XMM registers and MXCSR stay intact. These legacy layouts truncate pointers, while the 16-bit layout has no opcode field. Native x87 hardware parity remains unverified.
ANDNPS/ANDNPD now route raw NaN, denormal and signed-zero bits through checked bitwise operations. MOVNTPS/MOVNTPD/MOVNTDQ write 16 aligned bytes, while MOVNTQ and MOVNTI write exact eight- and four/eight-byte values. MASKMOVDQU/MASKMOVQ honor each mask byte's MSB, RDI/EDI, FS/GS overrides and register aliases. Only selected bytes need writable mappings. COW pages and bookkeeping are reserved before any byte is published; faults preserve data and CPU state. Our all-zero mask profile suppresses memory faults, while MASKMOVQ still enters MMX state. Intel permits implementation-dependent zero-mask faults. Streaming hints use synchronous guest writes; hardware cache performance is not modeled. The independent byte oracle checks 91,072 queries per engine, including all 65,536 XMM and 256 MMX selection patterns, guard bytes, unaligned offsets, aliases, MXCSR and unchanged flags.
PUSHFW/PUSHFQ now save the modeled CF/PF/AF/ZF/SF/DF/OF flags through checked stack writes. Auxiliary carry follows integer arithmetic, XADD and CMPXCHG; arithmetic and rotate flag updates wait for successful destination writes. Fixed bit 1 is set, while RF/VM and unmodeled control flags are zero in this virtual profile. POPF and trap-flag delivery remain unsupported. Guest CPU fault-to-signal delivery remains open; CPUID claims stay conservative. Native full-RFLAGS parity is unverified.
RCPPS/RCPSS and RSQRTPS/RSQRTSS now execute all four legacy single-precision reciprocal forms. Packed memory sources require 16-byte alignment; scalar sources read exactly four unaligned bytes and preserve upper lanes. Signed zeros and denormals produce signed infinities, NaNs become quiet with their payload intact, and negative normal or infinite RSQRT inputs produce the indefinite NaN. These instructions preserve MXCSR and flags, ignoring rounding controls and exception masks. A binary64 approximation is rounded to binary32; tiny RCP results are flushed to signed zero in our profile. The independent rational and integer-root oracle checks 85,996 queries per engine, all normal exponents, underflow boundaries, midpoint neighbors, aliases and 12 encoding views. Native x86 lookup-table bits and universal correct rounding remain unverified; the CPU baseline stays conservative.
MOVDQ2Q/MOVQ2DQ now bridge MMX and extended XMM registers. CVTPI2PS/PD, CVTPS/PD2PI and CVTTPS/PD2PI convert two signed integer or floating lanes with checked rounding and exception state. PS and integer memory sources read exactly eight unaligned bytes; floating PD sources read 16 aligned bytes. CVTPI2PS preserves the upper XMM quadword, while CVTPI2PD replaces both halves exactly. The CVTPI2PD memory form preserves x87 state and ignores pending x87 exceptions; its register form and the other new instructions enter MMX state. Pending x87 exceptions precede memory checks, and new unmasked SIMD faults preserve destinations and MMX state. An independent rational/byte oracle checks 24,653 queries and 33 fault exits per engine across 14 encoding views, all eight TOP positions, raw physical x87 data, NaNs, integer limits, DAZ/FTZ, sticky flags and unchanged FLAGS. Native fault-state parity and CPU fault-to-signal delivery remain open; CPUID stays conservative.
Fifteen SSE/SSE2 MMX integer forms now cover PADDQ/PSUBQ, PMULUDQ/PMULHUW, PAVGB/W, PMINUB/PMAXUB, PMINSW/PMAXSW, PSADBW, PSHUFW, PINSRW, PEXTRW and PMOVMSKB. Binary and shuffle sources read exactly eight unaligned bytes; word insertion reads two. Selectors wrap within four words, general-purpose register fields retain REX extensions, and extraction/mask results clear all upper scalar bits. MXCSR and FLAGS stay unchanged. Pending x87 or memory faults preserve the destination and MMX state. The mixed oracle covers 49,303 integer/state cases alongside the 24,653 rational/bridge cases: 73,956 queries and 121 fault exits per engine, across 102 views. Read-only guest instruction tables exercise every immediate byte; all 256 byte masks, aliases and all 80 physical x87 bytes are checked. Fault delivery and the broader CPU baseline remain future work.
Sixteen SSSE3 MMX forms add PSHUFB, PALIGNR, PABS/PSIGN B/W/D, PHADD/PHSUB W/D/SW, PMADDUBSW and PMULHRSW through the same vector executor. Memory sources read exactly eight unaligned bytes. Byte shuffles use three-bit indices and the control byte's high bit to select zero; alignment shifts concatenate the original destination and source, returning zero for counts of 16 or more while still checking source memory. Signed saturation, negation wrapping, absolute-value minima, rounded-product ties and the extreme 0x8000 product are checked. MMX fields ignore REX extensions, MXCSR/FLAGS remain unchanged, and pending x87 faults precede source reads. The guest oracle retains every earlier case and adds 27,255 integer/state queries, all PALIGNR immediates, every PSHUFB control byte and zero mask, aliases and pending-fault exits. Guest CPU fault-to-signal delivery, native fault parity and broader ISA auditing remain open; VEX/AVX forms are unsupported and CPUID stays conservative.
RISC-V also executes mixed compressed and standard integer
instructions. The core fixture builder supplies both variants:
try artifacts/guests/riscv64/compressed/compute with
the same runtime. Word/doubleword atomics use checked memory and
conservative reservations cleared on writes, mapping changes and guest thread switches.
The tested F/D subset covers loads/stores, register moves,
sign-injection, classification, comparisons, five-mode arithmetic and
fused multiply-add, integer conversions and compressed D
transfers. Arithmetic and fused operations support all five
standard rounding modes. Float-to-integer conversions
and integer-to-float conversions support all five standard
modes. Zicsr supports only fflags,
frm and fcsr. Other CSRs and compressed
EBREAK trap handling remain unsupported.
06 / Verify it locally
./scripts/check.sh
python3 scripts/benchmark.py
The local check covers formatting, build, Zig unit/fuzz-seed tests, guest output/status/filesystem behavior, debugger, JIT comparisons, malformed inputs, memory faults and deterministic mutations. On macOS, it also rebuilds Mach-O guests and compares matching-host native syscall source builds. The NEON table/accumulate oracle compares 8,448 exact destination-byte results per engine with scalar results and, on ARM64 macOS, native hardware. Optional BusyBox, SQLite, dynamic musl and downloaded-app checks are separate. GitHub Actions remains disabled.
The v0.2.1 local check passes 222/222 Zig tests, the complete source-guest and CPU/API oracle suite, 10,000 corpus mutations and 30,000 random decoder cases. Separate unchanged-app suites pass 474/474 workflows across both engines. A clean source build also passes. These are bounded deterministic checks, not a coverage-guided fuzz campaign.
The benchmark compares the same integer algorithm across native host C, three guest architectures and interpreter/JIT modes. It reports seven-run medians, with startup and loading included in wall time. The JIT improves this RISC-V workload but slows down the measured x86/AArch64 cases.
07 / Before you launch
UNIVERSE is not a security sandbox. Guest memory and syscall buffers are checked, but no independent security review has been performed.
The guest environment is empty unless you supply
--env KEY=value. Host files are denied by default.
--allow-files grants host-user file privileges,
including creation and truncation; it is not a confined
filesystem.
Default limits: 256 MiB guest memory, 64 MiB binary input, 1 MiB stack, 16 MiB heap reservation, 10 million guest instructions and 10 seconds execution. Blocking host I/O is not interrupted by the execution timeout.