ucontext implementation featuring glibc-compatible ABI
 
 
 
 
Go to file
osy 9b1d8f01a6 aarch64: remove usage of FUNC macro for clang
Clang's arm64 assembler does not support multiple directives on a single
line. C macros ALWAYS expand to a single line.
2021-03-08 15:13:34 -08:00
arch aarch64: remove usage of FUNC macro for clang 2021-03-08 15:13:34 -08:00
doc add manual page 2020-12-07 18:14:35 -07:00
examples add cooperative threading example 2020-12-07 18:15:18 -07:00
include/libucontext include: missing stddef.h include for size_t 2021-01-08 03:04:01 -07:00
.gitignore test POSIX ABI compatibility in libucontext itself, too 2021-01-08 02:37:47 -07:00
.mailmap update copyright statements, add mailmap 2020-03-27 09:23:49 +00:00
LICENSE update copyright statements, add mailmap 2020-03-27 09:23:49 +00:00
Makefile project: move freestanding include headers 2021-03-08 13:02:27 -08:00
NEWS add NEWS for libucontext 1.0 2021-01-09 00:56:37 -07:00
README.md riscv64: port to C trampoline 2020-12-12 00:08:48 -07:00
VERSION libucontext 1.0. 2021-01-09 00:57:00 -07:00
libucontext.pc.in build: generate libucontext pkg-config file 2020-12-06 04:10:14 -06:00
libucontext_posix.c libucontext_posix: fix build under glibc 2020-12-11 11:12:47 +00:00
meson.build project: move freestanding include headers 2021-03-08 13:02:27 -08:00
meson_options.txt build: add meson build 2021-01-08 04:25:56 -07:00
test_libucontext.c test program: use libucontext-prefixed symbols 2020-12-06 03:32:09 -06:00
test_libucontext_posix.c add libucontext_posix test program 2020-12-09 01:40:12 +00:00

README.md

libucontext

libucontext is a library which provides the ucontext.h C API. Unlike other implementations, it faithfully follows the kernel process ABI when doing context swaps.

Notably, when combined with gcompat, it provides a fully compatible implementation of the ucontext functions that are ABI compatible with glibc.

Since version 0.13, for some architectures, you can deploy to bare metal using newlib via the FREESTANDING=yes make option. Systems which use a syscall cannot work this way. The table below shows which architecture ports have been adapted to build with FREESTANDING=yes.

Adding support for new architectures is easy, but you need to know assembly language for the target to do it.

supported features

Architecture Works on musl Syscall Supports FREESTANDING Common trampoline
aarch64
arm
m68k
mips
mips64
ppc
ppc64
riscv64
s390x
sh
x86
x86_64

building

libucontext uses a simple makefile build system. You should define ARCH= at build time, otherwise the build system will attempt to guess using uname -m.

$ make ARCH=x86_64
$ make ARCH=x86_64 check
$ make ARCH=x86_64 DESTDIR=out install

There are a few options:

  • ARCH: The architecture libucontext is being built for. Must be set to one of the architectures listed in the feature support table. If unset, the build system will attempt to guess based on what architecture the host is running. Setting this option explicitly is highly recommended.

  • FREESTANDING: If this is set to yes, the system ucontext.h headers will not be used. Instead, the headers in arch/${ARCH}/freestanding will be used for definitions where appropriate. Default is no.

  • EXPORT_UNPREFIXED: If this is set to yes, the POSIX 2004 names getcontext, setcontext, swapcontext and makecontext will be provided as weak symbols aliased against their libucontext_ namespaced equivalents. This is necessary for libucontext to provide these functions on musl systems, but you may wish to disable this when using FREESTANDING mode to avoid conflicts with the target's libc. Default is yes.

  • DESTDIR: If this variable is set, the installed files will be installed to the specified path instead of the system root.

If you have scdoc installed, you can build manpages and install them:

$ make docs
$ make DESTDIR=out install_docs

caveats

libucontext, while largely functionally equivalent does have some differences over traditional POSIX ucontext functions:

  • Saving and restoring the signal mask is not implemented. This is largely a non-issue because most uses of these functions did not modify the signal mask anyway, but saving/restoring the signal mask (even though it is unmodified in basically all cases in practice) induces a significant performance penalty due to having to make kernel syscalls.

  • Only basic GPR registers are saved and restored when context swapping. The glibc implementation uses hardware capability detection to save/restore other register groups, such as the FPU registers or vector processing (AltiVec/AVX/NEON) registers. Adding this capability detection would significantly increase the complexity of the project and thus is not implemented. Support for compiling in code to save/restore FPU registers or vector registers may be added in a later release as a build-time setting -- for now, we assume a soft-float ABI with no optional processor features. In practice, this does not really matter, code using these functions are unlikely to be impacted by this design assumption.