kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

Dynamic/shared libraries (Linux first)

Goal: make kit produce loadable shared libraries, with Linux/aarch64 as the first supported target. The useful first result is:

kit ld -shared -soname libfoo.so.1 -o libfoo.so foo.pic.o
kit cc -shared -fPIC -Wl,-soname,libfoo.so.1 -o libfoo.so foo.c

where readelf -h reports ET_DYN, there is no required entry point, no PT_INTERP, DT_SONAME is present when requested, exported symbols are in .dynsym, unresolved imports become runtime relocations, and a normal Linux loader can use the .so as a dependency of an executable.

Current state

kit already has most of the dynamic-executable substrate:

The missing part is not "all dynamic linking"; it is a distinct DSO output mode. PIE executables and DSOs are both ET_DYN, but they differ in entry requirements, interpreter headers, exported-symbol policy, undefined-symbol defaults, dynamic tags, relocation legality, and driver behavior.

Scope

Linux/aarch64 MVP

Explicitly later

Implementation checklist

1. Split PIE-executable mode from DSO mode

Acceptance:

2. Entry and ELF header behavior

Acceptance:

3. Program headers for DSOs

Acceptance:

4. Dynamic section tags

Acceptance:

5. Exported dynamic symbols

Acceptance:

6. Undefined symbols and imports

Acceptance:

7. Relocation legality and runtime relocations

Acceptance:

8. AArch64 PIC codegen from kit

Acceptance:

9. Driver behavior

Acceptance:

10. Test sequencing

Prefer red-green targeted tests. Add small ELF/aarch64 cases before broad matrix runs. The sequencing is part of the design: prove the test harness with the system toolchain first, then replace one kit component at a time.

Likely milestone order

  1. All-clang harness baseline: write the aarch64 shared-library fixture and prove it with clang compile, clang -shared, clang/system consumer link, readelf assertions, and runtime execution. No kit linker/codegen work is considered validated until this lane is green.
  2. ELF linker skeleton: internal shared mode, no entry, no interpreter, ET_DYN DSO headers.
  3. Dynamic metadata: SONAME/RPATH/RUNPATH plumbing and dynstr layout.
  4. Swap in kit ld -shared: keep clang PIC library objects, but produce the .so with kit. Make imports/exports, PLT/GOT, DT_NEEDED, and runtime relocations work in this isolated lane.
  5. Diagnostics: reject non-PIC/textrel inputs clearly under kit ld -shared.
  6. Enable kit ld -shared: remove the driver gate for object/archive/DSO inputs once the clang-object linker-swap lane is green.
  7. Swap in kit codegen: compile the same library sources with kit cc -fPIC, audit/fix aarch64 interposition choices, and keep the DSO linked by kit. This creates the all-kit library path.
  8. Enable kit cc -shared: compile and link source to .so through the driver, with no executable startup objects.
  9. All-kit consumer lane: link the consumer with kit as well, so the full compile/link/run path is kit-produced except for the host loader/sysroot.
  10. Broaden: x86-64/riscv64, build-lib dynamic mode, and additional ELF linker compatibility flags.

Open design decisions