diff options
| author | Patrick Walton <pcwalton@fb.com> | 2021-08-20 16:42:45 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@fb.com> | 2021-08-20 17:10:41 -0700 |
| commit | c17b1904a90002b5bdb6e2fdcd76e61a1ad3cd7a (patch) | |
| tree | 397ea63daee94ae13a6ccf866f43fb6f9bc7a547 /compiler/rustc_codegen_llvm/src/mono_item.rs | |
| parent | a0035916e01d8e644ccd44554c57f0874cef8c8c (diff) | |
| download | rust-c17b1904a90002b5bdb6e2fdcd76e61a1ad3cd7a.tar.gz rust-c17b1904a90002b5bdb6e2fdcd76e61a1ad3cd7a.zip | |
Stop emitting the `dso_local` LLVM attribute for external symbols under the static relocation model on macOS.
This matches Clang's behavior: https://github.com/llvm/llvm-project/blob/973cb2c326be9f256da0897c4d2ef117dc22761d/clang/lib/CodeGen/CodeGenModule.cpp#L1038-L1040 Even if `dso_local` were properly supported in this way on macOS, it seems incorrect to add this annotation as liberally as we did. The `dso_local` annotation is for symbols that ultimately end up in the same linkage unit, but we were adding this annotation even for `static` values inside `extern` blocks marked with `#[link(type="framework")]`, which should be considered dynamically linked. Note that Clang likewise avoids emitting `dso_local` for `dllimport` symbols: https://github.com/llvm/llvm-project/blob/973cb2c326be9f256da0897c4d2ef117dc22761d/clang/lib/CodeGen/CodeGenModule.cpp#L1005-L1007 This issue caused breakage in the `ring` crate, which links to a symbol defined in `Security.framework` that ultimately resolves to address `0x0`: https://github.com/briansmith/ring/blob/b94d61e044b42827fefd71d5f61e8c58a7659870/src/rand.rs#L390 For this symbol, the use of `dso_local` causes LLVM to emit a relocation of type `X86_64_RELOC_SIGNED`, which is a 32-bit signed PC-relative offset. If the binary is large enough, `0x0` might be out of range, and the link will fail. Avoiding `dso_local` causes LLVM to use the GOT instead, emitting a relocation of type `X86_64_RELOC_GOT_LOAD`, which will properly handle the large offset and cause the link to succeed. As a side note, the static relocation model is effectively deprecated for security reasons on macOS, as it prohibits PIE. It's also completely unsupported on Apple Silicon, so I don't think it's worth going to the effort of properly supporting this model on that platform.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/mono_item.rs')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/mono_item.rs | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 93456443aa0..8a8ece640fc 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -135,6 +135,11 @@ impl CodegenCx<'ll, 'tcx> { return false; } + // Match clang by only supporting COFF and ELF for now. + if self.tcx.sess.target.is_like_osx { + return false; + } + // Static relocation model should force copy relocations everywhere. if self.tcx.sess.relocation_model() == RelocModel::Static { return true; |
