On 7/13/2026 10:56 AM, Ziyang Zhang wrote: > On Mon, 13 Jul 2026 10:53:56 -0700, Pierrick Bouvier wrote: >> On 7/13/2026 9:34 AM, Ziyang Zhang wrote: >>> On Mon, 13 Jul 2026 08:31:18 -0700, Pierrick Bouvier wrote: >>>> The problem is that if that the guest program, or the host library >>>> (host >>>> libhello) may depend on libstdc++. If they do and if they depend on a >>>> (newer) symbol not present in lorelei libstdc++, we break ABI. Same >>>> goes >>>> for libgcc. >>>> >>>> By not doing this, you'll be forced to provide a lorelei devkit >>>> everytime a new libstdc++ is published, or a distribution updates its >>>> gcc. >>>> >>>> The only solution is to embed libstd++ and libgcc statically, or >>>> rely on >>>> host libraries. If you choose the second option, you know have the >>>> opposite problem. So I think the only way to solve it is really static >>>> linking, even if it will slightly increase binaries size. >>>> >>> >>> The devkit already ships libstdc++ and libgcc anyway: its own clang/ >>> LoreTLC link them dynamically, and we bundle them so the toolchain even >>> starts. So bundling libstdc++ for the thunk flow adds no new dependency, >>> it just reuses one the devkit must carry. Static-linking the thunks >>> wouldn't make the devkit any smaller or more self-contained either, >>> since clang still needs the dynamic libstdc++; we'd only be adding >>> static copies on top of it. >>> >> >> There is a difference between the toolchain dependencies, and thunks >> dependency. For the first one, it's perfectly find to provide libstdc++, >> for the second, it can create conflicts at runtime that may be very hard >> to diagnose and solve. >> >>> On the ABI risk itself: libstdc++ keeps a backward-compatible ABI, and >>> the copy we bundle is recent, so a thunked host library only breaks if >>> it was built against a strictly newer libstdc++ and references a new >>> symbol. Even then it needs no new devkit, because the resolution order >>> is the integrator's to choose. On a host newer than our bundle, putting >>> the system libstdc++ ahead of the devkit's on LD_LIBRARY_PATH lets the >>> host library bind the newest one, while clang and the Lorelei runtime >>> keep working against it by backward compatibility. So a gcc update on >>> the host doesn't force us to reship. >>> >> >> Sure can choose indeed. However, he has to find where such libraries are >> located on his system, and prepend that to LD_LIBRARY_PATH. Not the most >> user-friendly thing to guess and debug IMHO. >> >>> There's also an active reason not to static-link. Both the Lorelei >>> runtime and the generated thunk libraries depend on libstdc++. If we >>> statically link libstdc++ into a thunk while the host library it >>> dispatches to links the system libstdc++ dynamically, the process ends >>> up with two libstdc++ copies on the host side, right across the boundary >>> where C++ objects and exceptions pass between the thunk and the real >>> library. That can break: >>> >>> - Exceptions: one thrown in the host library may not be caught in the >>> thunk. The two copies have different std::type_info for the same type, >>> so the match fails and it hits std::terminate. >>> - dynamic_cast / typeid across the boundary: they assume a single >>> type_info per type, so they can start returning null or misidentifying >>> types. >>> - Duplicated global state: two sets of the iostream objects, the locale/ >>> facets, and the exception emergency buffer. >>> >> >> That's a good point, but does lorelei even provide a solution for that? >> I guess that exception raised from an host library and sent back to >> guest binary with target specific types will not result in what is >> expected at the moment. >> >>> Based on the above reasons, I prefer to do that than statically link and >>> grow the big artifact. Does that hold for you? >>> >> >> Ok. >> >>> Thanks, >>> Ziyang Zhang >>> >> >> Regards, >> Pierrick > > > Wait a second. I missed something. > > Sorry, last time I answered without actually checking the libstdc++ > situation on the four distros. You were right to push on it, so I looked > properly. > > You were right that the x86_64 sysroot is the crux: libc6-amd64-cross > gives /usr/x86_64-linux-gnu/ a libc but no libstdc++, so the guest side > has no system libstdc++ to fall back on. That's the side we should keep > providing ourselves, and the devkit already ships the x86_64 libstdc++ > next to the guest runtime for exactly that. It's only a default, though: > if a guest executable needs a newer libstdc++, the user can put a newer > x86_64 libstdc++.so ahead of ours on the guest LD_LIBRARY_PATH (the -E > one) and it takes precedence, while our runtime keeps working against it > by backward compatibility. So we are not locking anyone to our version. > > The host side is different, there libstdc++ is reliably present. I > checked each distro's stock minimal base image, with nothing installed > on top: > > Debian 12: libstdc++6 12.2.0-14+deb12u1 > Ubuntu 24.04: libstdc++6 14.2.0-4ubuntu2~24.04.1 > Fedora 40: libstdc++-14.2.1-3.fc40 > Arch (2024-08 snapshot): libstdc++.so.6 from gcc-libs 14.2.1 > It ships out of the box on all four, and the C compiler pulls it in on > Debian, Ubuntu and Arch. > > So the split I'd propose: provide libstdc++ only on the guest side (the > x86_64 sysroot has none), and on the host side rely on the system's, so > the host thunk and the real host library both bind the host's own > libstdc++ rather than a copy we ship. That directly addresses the ABI > point you raised: nothing we ship shadows the host's libstdc++, so a > thunk never forces an older libstdc++ onto a host library built against > a newer one. > > Does that split sound right to you? >
That's a reasonable default, and Lorelei can be updated for this without having to update anything on QEMU side (or its documentation). If I had to choose, I would still do static linking for guest and host thunks, because I don't think we can handle exceptions correctly anyway. But the most important is that current example already works out of the box, which makes this series ready for upstream. Regards, Pierrick
