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:
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"