Git Product home page Git Product logo

limbo's Introduction

limbo

Limbo is an XNU emulator similar to qemu-user; it translates XNU system calls into their Linux equivalent(s). It is capable of executing supported binaries targeting macOS or iOS on Linux without modification.

Limbo is currently only supported on Linux 5.11 or later with the CONFIG_GENERIC_ENTRY option enabled. This is required to capture system calls made by the guest program.

Sufficiently advanced programs, such as Apple Clang, are capable of compiling binaries which can also be run in Limbo.

Installation

Before installing, read the BSD-2-Clause license.

To install, ensure Meson is installed and run the following commands:

meson build
ninja -C build install

This will install Limbo and the associated documentation, but you must install the binfmt.d(5) handlers by copying etc/binfmt.d/Mach-O.conf to /etc/binfmt.d/Mach-O.conf. For development, omit the install option and review CONTRIBUTING.md. The Development section describes how to set up a development environment. The Internals section of the README gives an overview of how Limbo works.

User's Guide

Limbo relies on a userspace like macOS or iOS to operate, so your chroot must be populated, or "bootstrapped", before use. There are a number of options available depending on your use-case. All examples assume that there is an empty folder at $CHROOT, the target chroot.

It does not matter what architecture your bootstrapping Mac is, because Big Sur ships most utilities as Fat Mach-O binaries. However, non-Fat Mach-O binaries are also supported by Limbo, but must match your architecture.

Minimalist

For simple binaries like echo, only the dyld cache and dyld itself is required. Thus on a Big Sur Mac, using scp or rsync, copy dyld_shared_cache_x86_64 into your chroot:

On the Limbo host:

mkdir -p $CHROOT/System/Library/dyld $CHROOT/bin $CHROOT/usr/lib

On the Big Sur Mac:

scp /System/Library/dyld/dyld_shared_cache_x86_64 $HOST:$CHROOT/System/Library/dyld/dyld_shared_cache_x86_64
scp /usr/lib/dyld $HOST:$CHROOT/usr/lib/dyld
scp $(which echo) $HOST:$CHROOT/bin/echo

Then run the program on the Limbo host:

sudo chroot $CHROOT /bin/echo Hello, world

Which should print "Hello, world".

Xcode

Xcode command-line tools are a work-in-progress, but you will find that most tools like clang or ld64 work as expected in their basic configuration if invoked without xcrun (though xcrun itself does work, xcodebuild does not, yet).

First follow the Minimalist guide.

Ensure Xcode.app is installed, then copy it into the chroot with rsync (must be installed on the Limbo host as well). Xcode is large so this may take some time.

scp $(which file) $HOST:$CHROOT/bin/file
rsync -Pav /Applications/Xcode.app $HOST:$CHROOT/Applications

Set your Xcode location for xcrun:

cd $CHROOT
mkdir -p var/db
ln -s /Applications/Xcode.app/Contents/Developer/ var/db/xcode_select_link

Then, compile a C file and check its format with file:

echo "int main() { return 0; }" > $CHROOT/example.c
sudo chroot $CHROOT /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -c example.c -o example.o
sudo chroot $CHROOT /bin/file example.o

Internals

Limbo at its core is fundamentally simple, the complexity comes from the incongruity between Linux and the XNU kernel.

When an application is spawned by the kernel and it detects Mach-O magic, it spawns Limbo to "wrap" the executable by passing the path to the target program as an argument to Limbo.

The first thing Limbo does is parse its own ELF header and enumerates the executable segments to notify the kernel of the memory regions that are allowed to perform system calls using a Linux 5.11 feature known as Syscall User Dispatch. Any system calls that occur outside of this region result in a SIGSYS. Limbo then sets a SIGSYS handler as the entry point into the XNU emulation routine.

Next, Limbo loads the dyld shared cache and rebases it to the load address. However, on Linux, the stack address actually collides with the default load address of the dyld cache, so Limbo remaps its own stack out of the way in a two-stage setup process. As well, the [vdso] and [vvar] special mappings also overlap, so they are simply unmapped (though this introduces some complications and reduces the glibc wrappers Limbo can call).

Limbo then parses the Mach-O file and reads the load commands to look for the LC_LOAD_DYLINKER which specifies the program invoked by the kernel to link the target application. Then, that program is mapped into memory, the stack is set up, and Limbo executes the entry point of dyld.

Once dyld is started, it takes over the process and Limbo code is only entered when a system call is made.

The XNU kernel is a hybrid kernel with a BSD and Mach subsystem, which is reflected in Limbo's structure: bsd, osfmk (Mach) and mdep (Machine-dependent). When Limbo is interrupted, it determines the subsystem of the syscall and dispatches it into its appropriate handler, the subsystem then determines which syscall was executed and dispatches it again where it is handled.


Special thanks to David Weinstein for suggesting the name Limbo.

limbo's People

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.