brintos

brintos / hwjs-cc public Read only

0
0

wasmld.split member-granular pool-pull silently drops a late-demanded archive member on duplicate member names (libclangCodeGen.a Targets/X.cpp.o vs TargetBuiltins/X.cpp.o) #13

Open sasha opened this issue · 0 comments
S sasha commented

Summary

libclangCodeGen.a contains TWO members named X86.cpp.o (and ARM/RISCV/…): one from clang/lib/CodeGen/Targets/X86.cpp (defines createX86TargetCodeGenInfo, demanded EARLY) and one from clang/lib/CodeGen/TargetBuiltins/X86.cpp (defines EmitX86BuiltinExpr, demanded LATE — only by EmitTargetBuiltinExpr). The member-granular pool-pull binds the Targets/ member and never pulls the TargetBuiltins/ twin, so all 21 EmitBuiltinExpr (X86/ARM/AArch64/RISCV/PPC/Hexagon/NVPTX/AMDGPU/ SPIRV/DirectX/SystemZ/BPF/WebAssembly + Cpu init/supports) go UNDEFINED → phantom env imports at the final link. Silent wrong output — no error, just missing symbols.

Evidence

The LTO module (merged.bc) had exactly 34 undefined = these 21 emitters + 13 legit host imports. The 21 are U in merged.bc even though libclangCodeGen.a DEFINES them (verified: EmitX86BuiltinExpr is T in the archive). ar x X86.cpp.o also extracts the WRONG twin — the same duplicate-member-name hazard.

Workaround (ours)

llvm-link the 11 CodeGen/TargetBuiltins/*.cpp.o FROM THE BUILD TREE (not via ar x) into the module → all 21 defined; then coroutinize+link as usual.

Suggested fix

Pool-pull should resolve members by (member, defining-symbol), not by member NAME, so a late-demanded symbol pulls the correct twin even when two members share a name. Alternatively, the LLVM CMake build should give TargetBuiltins objects distinct archive names.

Proposed fix targets brintos/hwjs-cc only — no distro submodule pins moved. All distros share one lineage, so pin bumps are coordinated on merge, not per-engineer.