Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isolate llvm's C++ symbols in distibution binaries? #63920

Open
jsgf opened this issue Aug 26, 2019 · 7 comments
Open

Isolate llvm's C++ symbols in distibution binaries? #63920

jsgf opened this issue Aug 26, 2019 · 7 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jsgf
Copy link
Contributor

jsgf commented Aug 26, 2019

MIRAI is an abstract interpreter for MIR. It uses the Z3 theorem prover as part of its implementation. Z3 uses C++, and is often used precompiled.

MIRAI also links against rustc. This means that Z3's C++ library conflicts with the libstdc++ linked into rustc (well, libLLVM I think). At best this generates GB of linker errors, at worst something that seems to build but behaves erratically at runtime.

Is there some way to hide all llvm's C++ symbols so that it just becomes an internal implementation details, and a second libstdc++ can coexist in the same address space? Alternatively could it be distributed with a shared libstdc++ so that llvm and Z3 are using a common library?

I can solve this by building everything from source against the same libstdc++, but its a large burden to build rustc from source just to use MIRAI.

cc @hermanventer @alexcrichton

@hermanventer
Copy link

To reproduce this, just clone https://github.com/facebookexperimental/MIRAI and try to cargo build on a Linux system (after installing Z3, which you can do using "brew install z3"). If it builds (which it did not, last time I checked), try to run it with cargo test.

@jonas-schievink jonas-schievink added A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 26, 2019
@alexcrichton
Copy link
Member

We currently ship a compiler with two dynamic libraries that contain C++ code in them. One is LLVM itself, built by LLVM's own build system. I believe the C++ standard library is linked statically into this LLVM dynamic library. The other is librustc_driver.so which contains some C++ shim code compiled so rustc can use bits and pieces of LLVM's C++ interface. (there's a separate issue for removing those shims)

I unfortunately do not know how to instruct LLVM's build system to hide symbols and only expose the ones we want in rustc. I'm not sure it's easily possible either since the C++ APIs that we're using in our shims are probably not super well defined.

@jsgf
Copy link
Contributor Author

jsgf commented Aug 28, 2019

Removing the symbols from rustc_driver will help; then we only need to solve llvm. I wonder if using dlopen(..., RTLD_LOCAL) would help when loading it:

RTLD_LOCAL   Symbols exported from this image (dynamic library or bundle) are generally hidden and only
             availble to dlsym() when directly using the handle returned by this call to dlopen().

I don't know how this applies to transitive dependencies. Maybe statically linking a PIC version libLLVM.a into librustc_codegen_llvm would help in that case? (Or is that already true?)

@jsgf
Copy link
Contributor Author

jsgf commented Aug 28, 2019

@hermanventer BTW, I did a checkout and compile on a current Fedora system using the distro-packaged version of Z3, and it build and ran cleanly without problems.

@alexcrichton
Copy link
Member

Oh right! AFAIK we should now be able to use RTLD_LOCAL. Historically we couldn't because some tests relied on the opposite, loading a dynamic library that linked against LLVM and then using that in the compiler. I think nowadays though we dropped support for that (unstable) test so it should be fine to pass in RTLD_LOCAL when we load codegen backends.

@jsgf
Copy link
Contributor Author

jsgf commented Aug 28, 2019

I'll take a look.

@bjorn3
Copy link
Member

bjorn3 commented Jul 29, 2023

The LLVM backend is now linked into librustc_driver.so, so there is nowhere to pass RTLD_LOCAL anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants