kit

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

commit a877e58f06163ff693abc10716c8e269327134d3
parent a976537e1fa0e161c3acad8c8b347c4171813800
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue,  9 Jun 2026 19:32:48 -0700

test/driver: fix ld-hosted-lc-sysroot broken by -shared rejection

Commit 05eaf7ef intentionally rejects `ld -shared`, but the
ld-hosted-lc-sysroot test built its fake sysroot libc.so via that very
path, so its setup now fails. Replace it with a checked-in minimal
x86_64 ET_DYN fixture (.dynsym exporting libc_marker + DT_SONAME=libc.so
-- just enough for read_elf_dso to load it and record DT_NEEDED), plus a
gen_libc_so.py regenerator mirroring gen_rpath.py.

Also repurpose the now-vacuous ld-no-undefined case (which passed only
because -shared is rejected before --no-undefined is evaluated) into
ld-shared-rejected, asserting the rejection + its diagnostic.

Diffstat:
Atest/driver/fixtures/gen_libc_so.py | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/driver/fixtures/libc.so | 0
Mtest/driver/run.sh | 16++++++----------
3 files changed, 75 insertions(+), 10 deletions(-)

diff --git a/test/driver/fixtures/gen_libc_so.py b/test/driver/fixtures/gen_libc_so.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +# Minimal x86_64 ET_DYN "libc.so": a .dynsym exporting libc_marker, a .dynstr, +# and a .dynamic carrying DT_SONAME=libc.so. Just enough for kit's read_elf_dso +# to load it as a DSO (it requires SHT_DYNSYM) and record DT_NEEDED from the +# soname. kit can't emit a shared object yet, so this is hand-built like +# test/objdump/aarch64/cases/gen_rpath.py and test/dwarf/dwarf.o. +import struct, sys +EM_X86_64 = 62 +def u16(x): return struct.pack('<H', x) +def u32(x): return struct.pack('<I', x) +def u64(x): return struct.pack('<Q', x) + +SHT_STRTAB, SHT_DYNAMIC, SHT_DYNSYM = 3, 6, 11 +STB_GLOBAL, STT_FUNC = 1, 2 +DT_SONAME, DT_STRTAB, DT_SYMTAB, DT_STRSZ, DT_SYMENT, DT_NULL = 14, 5, 6, 10, 11, 0 +SHN_ABS = 0xfff1 + +shstr = b'\x00.dynsym\x00.dynstr\x00.dynamic\x00.shstrtab\x00' +n_dynsym = shstr.index(b'.dynsym') +n_dynstr = shstr.index(b'.dynstr') +n_dynamic = shstr.index(b'.dynamic') +n_shstrtab = shstr.index(b'.shstrtab') + +dynstr = b'\x00libc_marker\x00libc.so\x00' +o_marker = dynstr.index(b'libc_marker') +o_soname = dynstr.index(b'libc.so') + +def sym(name, info, other, shndx, value, size): + return u32(name) + bytes([info, other]) + u16(shndx) + u64(value) + u64(size) +dynsym = (sym(0, 0, 0, 0, 0, 0) + + sym(o_marker, (STB_GLOBAL << 4) | STT_FUNC, 0, SHN_ABS, 0, 0)) + +EH = SH = 64 +off_dynsym = (EH + 7) & ~7 +off_dynstr = off_dynsym + len(dynsym) +off_dynamic = (off_dynstr + len(dynstr) + 7) & ~7 + +def dyn(tag, val): return u64(tag) + u64(val) +dynamic = (dyn(DT_SONAME, o_soname) + dyn(DT_SYMTAB, off_dynsym) + + dyn(DT_STRTAB, off_dynstr) + dyn(DT_STRSZ, len(dynstr)) + + dyn(DT_SYMENT, 24) + dyn(DT_NULL, 0)) + +off_shstr = (off_dynamic + len(dynamic) + 7) & ~7 +off_sht = (off_shstr + len(shstr) + 7) & ~7 + +# section indices: 0 NULL, 1 .dynsym, 2 .dynstr, 3 .dynamic, 4 .shstrtab +IDX_DYNSTR = 2 +def shdr(name, typ, off, size, link, info, align, ent): + return (u32(name) + u32(typ) + u64(0) + u64(0) + u64(off) + u64(size) + + u32(link) + u32(info) + u64(align) + u64(ent)) +sht = (shdr(0, 0, 0, 0, 0, 0, 0, 0) + + shdr(n_dynsym, SHT_DYNSYM, off_dynsym, len(dynsym), IDX_DYNSTR, 1, 8, 24) + + shdr(n_dynstr, SHT_STRTAB, off_dynstr, len(dynstr), 0, 0, 1, 0) + + shdr(n_dynamic, SHT_DYNAMIC, off_dynamic, len(dynamic), IDX_DYNSTR, 0, 8, 16) + + shdr(n_shstrtab, SHT_STRTAB, off_shstr, len(shstr), 0, 0, 1, 0)) + +eh = (b'\x7fELF' + bytes([2, 1, 1, 0]) + b'\x00' * 8 + u16(3) + u16(EM_X86_64) + + u32(1) + u64(0) + u64(0) + u64(off_sht) + u32(0) + u16(EH) + u16(0) + + u16(0) + u16(SH) + u16(5) + u16(4)) + +buf = bytearray(off_sht + len(sht)) +buf[0:64] = eh +buf[off_dynsym:off_dynsym + len(dynsym)] = dynsym +buf[off_dynstr:off_dynstr + len(dynstr)] = dynstr +buf[off_dynamic:off_dynamic + len(dynamic)] = dynamic +buf[off_shstr:off_shstr + len(shstr)] = shstr +buf[off_sht:off_sht + len(sht)] = sht +out = sys.argv[1] if len(sys.argv) > 1 else 'libc.so' +open(out, 'wb').write(buf) diff --git a/test/driver/fixtures/libc.so b/test/driver/fixtures/libc.so Binary files differ. diff --git a/test/driver/run.sh b/test/driver/run.sh @@ -346,7 +346,7 @@ else not_ok "ld-long-output" "$work/ld-long-output.err" fi -# ---- ld --no-undefined rejects unresolved refs in a shared object ---- +# ---- ld -shared is rejected (shared-object emission not yet supported) ---- cat > "$work/shared-undef.c" <<'SRC' int missing(void); int f(void) { return missing(); } @@ -354,10 +354,12 @@ SRC if "$KIT" cc -target x86_64-linux -fPIC -c "$work/shared-undef.c" \ -o "$work/shared-undef.o" > "$work/shared-undef-cc.out" \ 2> "$work/shared-undef-cc.err"; then - run_fail "ld-no-undefined" "$KIT" ld -shared --no-undefined \ + run_fail "ld-shared-rejected" "$KIT" ld -shared --no-undefined \ "$work/shared-undef.o" -o "$work/shared-undef.so" + contains "ld-shared-rejected-diag" "$work/ld-shared-rejected.err" \ + "not yet supported" else - not_ok "ld-no-undefined" "$work/shared-undef-cc.err" + not_ok "ld-shared-rejected" "$work/shared-undef-cc.err" fi # ---- ld -lc expands hosted CRT/libc from --sysroot ---- @@ -393,12 +395,7 @@ if "$KIT" cc -target x86_64-linux -fPIE -c "$work/ld-hosted-main.c" \ "$KIT" cc -target x86_64-linux -c "$work/ld-hosted-crtn.c" \ -o "$work/ld-hosted-sr/lib/crtn.o" > "$work/ld-hosted-crtn.out" \ 2> "$work/ld-hosted-crtn.err" && - "$KIT" cc -target x86_64-linux -fPIC -c "$work/ld-hosted-libc.c" \ - -o "$work/ld-hosted-libc-pic.o" > "$work/ld-hosted-libc-pic.out" \ - 2> "$work/ld-hosted-libc-pic.err" && - "$KIT" ld -shared -nostdlib -e libc_marker "$work/ld-hosted-libc-pic.o" \ - -o "$work/ld-hosted-sr/lib/libc.so" > "$work/ld-hosted-so.out" \ - 2> "$work/ld-hosted-so.err" && + cp "$script_dir/fixtures/libc.so" "$work/ld-hosted-sr/lib/libc.so" && "$KIT" cc -target x86_64-linux -fno-PIC -c "$work/ld-hosted-libc.c" \ -o "$work/ld-hosted-libc-static.o" > "$work/ld-hosted-libc-static.out" \ 2> "$work/ld-hosted-libc-static.err" && @@ -428,7 +425,6 @@ else sed 's/^/crt1: /' "$work/ld-hosted-crt1.err" 2>/dev/null sed 's/^/crti: /' "$work/ld-hosted-crti.err" 2>/dev/null sed 's/^/crtn: /' "$work/ld-hosted-crtn.err" 2>/dev/null - sed 's/^/so: /' "$work/ld-hosted-so.err" 2>/dev/null sed 's/^/ar: /' "$work/ld-hosted-ar.err" 2>/dev/null; } \ > "$work/ld-hosted-setup.diag" not_ok "ld-hosted-lc-sysroot" "$work/ld-hosted-setup.diag"