Skip to content

Latest commit

 

History

History
113 lines (80 loc) · 3.48 KB

File metadata and controls

113 lines (80 loc) · 3.48 KB

Using elfuse

This document covers the command-line interface, common launch patterns, dynamic linking through --sysroot, and debugger attachment.

Command-Line Synopsis

build/elfuse [options] <elf-path> [args...]

Supported user-facing options:

Option Meaning
-h, --help Print built-in usage help
-V, --version Print the build version and exit
-v, --verbose Enable syscall-level and loader diagnostics
-t, --timeout N Per-iteration vCPU watchdog, in seconds (default 10)
--sysroot PATH Resolve guest absolute paths under PATH first
--gdb PORT Listen for a GDB RSP client on PORT
--gdb-stop-on-entry Stop before the first guest instruction
-- End elfuse option parsing; remaining tokens are guest argv

--timeout is a run-loop watchdog. It does not cap total process runtime. It only bounds a single hv_vcpu_run() iteration before the host regains control, which is what allows host-side timers and signals to be observed promptly.

Common Launch Patterns

Run a statically linked guest binary:

build/elfuse ./build/test-hello

Run with verbose tracing:

build/elfuse --verbose ./guest-program arg1 arg2

Pass guest arguments that begin with -:

build/elfuse -- ./guest-program --guest-flag

Dynamic Linking And Sysroots

Dynamic Linux guests need a sysroot that contains the expected interpreter and shared libraries. elfuse reads PT_INTERP, loads the requested interpreter from the supplied sysroot, and redirects guest absolute-path opens to that tree before falling back to the host filesystem.

Example:

build/elfuse --sysroot /path/to/sysroot ./hello-dynamic

This model supports both musl and glibc guest environments as long as the expected interpreter path (for example /lib/ld-musl-aarch64.so.1 or /lib/ld-linux-aarch64.so.1) exists inside the sysroot.

Practical notes:

  • The sysroot is consulted only for guest absolute paths; relative paths still resolve from the guest working directory.
  • The sysroot setting is preserved across guest fork and execve, so spawned children see the same view of the filesystem.

Debugging With GDB Or LLDB

elfuse includes a built-in GDB Remote Serial Protocol stub.

Start the guest and wait at entry:

build/elfuse --gdb 1234 --gdb-stop-on-entry ./guest-program

Attach with GNU GDB:

aarch64-linux-gnu-gdb -ex "target remote :1234" ./guest-program

Or attach with LLDB:

lldb --batch -o "gdb-remote 1234" ./guest-program

The stub supports all-stop debugging, up to 16 hardware breakpoints, up to 16 watchpoints, single-step (implemented as a temporary breakpoint), full register and memory access, and per-thread inspection. Implementation details, including the snapshot protocol used to keep Hypervisor.framework register access on the owning thread, are documented in internals.md.

Guest Compatibility Model

elfuse is designed for Linux user-space workloads, not for booting a Linux kernel or presenting a complete Linux host environment. Compatibility comes from targeted ABI translation and emulation at the syscall boundary.

That has a few direct implications:

  • /proc and /dev are compatibility surfaces, not passthrough mounts.
  • macOS and Linux file, socket, and signal semantics are normalized in the host syscall layer.
  • Behavior is strongest for normal command-line tools, language runtimes, test binaries, and debugger-driven workflows.