kit

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

Image Inspection (planned work)

kit can read relocatable objects through kit_obj_open, and it has been extended to also inspect linked images -- executables and shared objects -- across the same neutral API. ELF and Mach-O reading have landed; the remaining work is the COFF/PE image reader plus a handful of follow-ups. This doc captures the goal, what is already baseline, and what is left, so the PE work and any later refinements parallelize against a settled contract. The matching design lives in ../OBJ.md; see also LINKER.md for the linker side and ../DBG.md / ../DWARF.md for the debug-info flow that rides on it.

Goal

One kit_obj_open call inspects any of: a relocatable object, an executable, or a shared object, for ELF, Mach-O, and COFF/PE. Sections and symbols keep working where the format still carries them; linked images additionally expose segments, an entry point and image base, an interpreter / SONAME, library dependencies and rpaths, and a dynamic symbol/relocation table. objdump and the inherited tools (nm, size, addr2line) operate on images the same way they operate on objects, with no per-format special-casing in the driver.

Why this is a real extension, not a flag

The original reader was relocatable-object-shaped. kit_obj_open -> kit_detect_target -> impl->read, and the ELF backend rejected anything but ET_REL. There were DSO readers (read_elf_dso, read_coff_dso, a Mach-O dylib stub) but they were wired only into the linker's input path, not the public impl->read / kit_obj_open surface; ET_EXEC had no reader at all. The in-memory model (ObjBuilder) was section / symbol / reloc oriented with no notion of a segment (PT_LOAD), the dynamic table (DT_NEEDED / SONAME / RPATH), an entry point, image base, imports, or data directories -- which is exactly what image inspection is about. The fix is a new image dimension on the model plus neutral iterators, not a flag.

Baseline (done)

The neutral API and internal model are in place, and ELF + Mach-O image reading work end to end:

Remaining work

COFF/PE image reader (primary gap)

PE is the one format whose linked images do not yet open through kit_obj_open. The COFF backend's read does not populate ObjImage, and read_coff_dso is still wired only into the linker. As a result objdump keeps a hand-rolled pe_parse_image raw-byte walker (driver/cmd/objdump.c:392) behind a KIT_BIN_PE special-case (driver/cmd/objdump.c:1831) that serves -f / -h / -p and soft-errors -t / -d / -r / -s. The plan:

Escape hatch for format-specific raw fields

Some inspection needs format-specific values that do not fit the neutral model: raw DT_* tag values, raw Mach-O load commands, PE data-directory entries. Surface these through a per-format escape hatch in the spirit of the existing kit_obj_section_format_flags, keeping the neutral API clean rather than widening it per format.

Mach-O classic-format breadth (deferred)

The Mach-O reader deliberately supports only the modern fixup path (LC_DYLD_CHAINED_FIXUPS, with the symbol table as the authoritative dynamic-symbol source) and LC_DYLD_EXPORTS_TRIE. Classic LC_DYLD_INFO opcode/trie reading and the exports trie remain out of scope; reading older dylibs is a separate, lower-priority effort. Revisit only if a real input demands it.

Out of scope

Design notes carried forward

Test strategy

The compiler links its own ELF / Mach-O / PE images, so tests round-trip: link a small program, open it via kit_obj_open, and assert kind/entry/segments/deps/dynsyms against what the linker emitted, cross-checked against host readelf / objdump in smoke tests where available. ELF and Mach-O goldens live under test/objdump/; PE corpora land under test/{coff,pe}/ with the reader. Dynamic NEEDED/SONAME/dynsym paths fully exercise once -shared / dynamic linking emit populated tables; the empty-table rendering is already covered. See ../TESTING.md.