- C11 compiler (GCC or Clang)
- CMake 3.15+
- System headers (no external dependencies)
- On macOS: Xcode Command Line Tools (for Objective-C support)
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build buildThis produces:
| Output | Path |
|---|---|
| Shared library | build/libload.so (Linux) or build/libload.dylib (macOS) |
| Static library | build/libload.a |
| llpack tool | build/llpack |
| Test binaries | build/test_exec, build/testexec, etc. |
| CMake Variable | Default | Description |
|---|---|---|
CMAKE_BUILD_TYPE |
— | Release, Debug, RelWithDebInfo |
CMAKE_C_COMPILER |
system default | C compiler path |
CMAKE_ASM_COMPILER |
system default | Assembler path (Linux only) |
CMAKE_INSTALL_PREFIX |
/usr/local |
Installation prefix |
LIBLOAD_DEBUG |
OFF |
Enable verbose debug logging to stderr |
To enable internal debug output (segment mapping, fixup details, injection steps):
cmake -B build -DLIBLOAD_DEBUG=ON
cmake --build buildArchitecture is selected at compile time. Point CMake at the appropriate cross-compiler toolchain:
cmake -B build -DCMAKE_C_COMPILER=x86_64-linux-gnu-gcc \
-DCMAKE_ASM_COMPILER=x86_64-linux-gnu-gcc
cmake --build buildcmake -B build -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
-DCMAKE_ASM_COMPILER=aarch64-linux-gnu-gcc
cmake --build buildcmake -B build -DCMAKE_C_COMPILER=i686-linux-gnu-gcc \
-DCMAKE_ASM_COMPILER=i686-linux-gnu-gcc
cmake --build buildcmake -B build -DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc \
-DCMAKE_ASM_COMPILER=arm-linux-gnueabi-gcc
cmake --build buildcmake -B build -DCMAKE_C_COMPILER=armeb-linux-gnueabi-gcc \
-DCMAKE_ASM_COMPILER=armeb-linux-gnueabi-gcc
cmake --build buildcmake -B build -DCMAKE_C_COMPILER=mipsel-linux-gnu-gcc \
-DCMAKE_ASM_COMPILER=mipsel-linux-gnu-gcc
cmake --build buildcmake -B build -DCMAKE_C_COMPILER=mips-linux-gnu-gcc \
-DCMAKE_ASM_COMPILER=mips-linux-gnu-gcc
cmake --build buildcmake -B build -DCMAKE_C_COMPILER=sparc-linux-gnu-gcc \
-DCMAKE_ASM_COMPILER=sparc-linux-gnu-gcc
cmake --build buildOn Debian/Ubuntu:
# ARM
sudo apt install gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu
# MIPS
sudo apt install gcc-mipsel-linux-gnu gcc-mips-linux-gnu
# SPARC
sudo apt install gcc-sparc64-linux-gnu
# i386
sudo apt install gcc-i686-linux-gnucmake --install buildInstalls:
- Headers to
${prefix}/include/ - Libraries to
${prefix}/lib/ llpackto${prefix}/bin/
After installation, link against -lload:
gcc -o myapp myapp.c -lload -ldl # Linux
clang -o myapp myapp.c -lload # macOSgcc -o myapp myapp.c -Lbuild -lload -ldl -static # Linuxfind_library(LIBLOAD load)
target_link_libraries(myapp PRIVATE ${LIBLOAD})Or link directly from the build tree:
add_subdirectory(libload)
target_link_libraries(myapp PRIVATE libload_static)- The build uses
enable_language(ASM)to compile entry trampolines (.Sfiles) - All six
.Sfiles are always included in the source list; the assembler only compiles the one matching the target architecture via#ifdefguards - Links against
-ldlfordlsym/dlopen
- Uses
enable_language(OBJC)for Objective-C test files - No assembly files — macOS uses inline assembly for the entry trampoline
- No
-ldlneeded (symbols are in libSystem)
For testing on Linux from a macOS host:
# Build container
docker run --rm -it \
--platform linux/arm64 \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
-v $(pwd):/src \
ubuntu:22.04
# Inside container
apt update && apt install -y cmake gcc
cd /src && cmake -B /tmp/build && cmake --build /tmp/build
cd /tmp/build && ./test_exec /src/examples/testexec--cap-add=SYS_PTRACE is required for injection tests. Use --security-opt seccomp=unconfined to allow process_vm_writev and other syscalls used by the injection code.