kit

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

test/elf — ELF format roundtrip harness

Data-driven testing for emit_elf / read_elf (and, eventually, link_emit_image_writer for ET_DYN executables).

Layout

unit/   *.c       hand-built ObjBuilder roundtrip tests (link libkit.a)
cases/  *.c       clang-oracle cases: clang -c → kit-roundtrip → diff
bad/    *.elf     malformed inputs; *.expect carries the panic substring
exec/             ET_DYN exec tests (empty until link_resolve lands)
kit-roundtrip.c read_elf → emit_elf test driver
normalize.py      readelf/objdump output canonicalizer for structural diff
run.sh            top-level driver, invoked by `make test`

Running

make test

Skipped tests are surfaced and treated as failures by default. To allow skips (e.g. on a host without qemu-aarch64-static), run:

KIT_TEST_ALLOW_SKIP=1 make test

Adding a case

  1. Drop cases/NN_short_name.c — a tiny self-contained C program (no external libs unless they're listed in the harness clang -static step).
  2. Run make test. The harness will:
    • clang --target=aarch64-linux-gnu -c your file → golden.o
    • run kit-roundtrip golden.o rt.o
    • normalize llvm-readelf -aW output of both and diff
    • if qemu-aarch64-static is available: link both with clang and compare stdout/stderr/exit code.
  3. If your case exercises a reloc kind kit doesn't yet support, drop an empty NN_short_name.xfail next to the .c. The harness expects the case to fail; if it starts passing, remove the .xfail (or the harness will fail loudly with XPASS).

Adding a unit test

Drop unit/<name>.c that builds an ObjBuilder programmatically, calls emit_elf to a memory writer, then read_elf, and asserts shape. Exit 0 on success, non-zero on failure. See unit/smoke.c for the template.

Adding a negative test

  1. Produce a malformed ELF blob in bad/<name>.elf (hand-crafted or objcopy --corrupt).
  2. Write bad/<name>.expect containing a substring that should appear in kit-roundtrip's stderr after the panic. The harness asserts non-zero exit and the substring presence (and zero signals — a segfault is a hard fail).

Host requirements

Optional but each unlocks a layer: