openkal-musl 0.3.0
musl 1.2.5 redirected onto openkal, running
on Linux, macOS and Windows.
The package was openkal-libc up to 0.2.0 — a probe of 243 lines exporting 14
names, which was not a C library. The version line continues rather than
restarting: a tag is the one thing in the release chain that cannot be given a
second meaning.
The shape of the port
musl reaches its environment through one seam: seven inline functions in
arch/<arch>/syscall_arch.h, plus __get_tp in pthread_arch.h. Replacing that
one header is the whole of the redirection, and 1345 sources are compiled
unmodified.
musl/PATCHES.md lists the whole of what is not unmodified: four patched
lines and nine replaced sources, each with its reason.
| lines | |
|---|---|
| the system-call correspondence | 923 |
| descriptors and name resolution | 434 |
| startup and the thread pointer | 241 |
setjmp and its relatives |
223 |
| execution contexts and the suspension primitive | 202 |
| starting another program | 163 |
| where per-context state is kept | 128 |
| what two object formats do not provide | 105 |
| how a second name is made | 133 |
| the rest | 241 |
| total | 2793 |
Against 1345 musl sources compiled unmodified. Between the first system and the
third the port grew by 800 lines, and every one of those is about an object
format or a naming convention rather than about a kernel.
Three object formats
| ELF | the reference case |
| PE | measured, with both toolchains: a weak symbol is not a definition there. The 289 aliases are made strongly, and the 46 names musl provides as placeholders are not made at all — decided by the name of the placeholder's target, so no site of musl's is edited |
| Mach-O | the compiler refuses the construct: aliases are not supported on darwin. The assembler's directive makes the name instead, and the same placeholder list applies |
Four findings that only running produced
A C library cannot keep its per-context state in a thread_local variable. On
one toolchain such a variable is reached through a helper that allocates, and the
allocator is what the C library provides.
long double is not a property of the architecture alone. On Apple arm64 it
is 53 bits where musl's arch/aarch64/bits/float.h says 113 — measured on all
four combinations. printf("%.3f", 1.5) stopped in frexpl with the value read
as infinity. port/src/okm_float_assert.c now asserts the agreement.
A program above this library must not have a C++ runtime embedded into it. On
one system the build tool embeds one and runs its initialiser before the entry
point, when the C library has not started.
An object format's linker divides a section into atoms, and a section with no
content has no atom — the four names musl walks between went missing with it.
What runs above it
examples/posix |
32 observations, on all three systems |
examples/wordcount |
the same counts as the system's own wc |
mcpplibs/sbase |
all 97 suckless base utilities, sources unmodified, 50 comparisons |
Continuous integration: Linux (gcc, llvm), macOS (llvm), Windows (gcc, PE).