about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-08-08 01:24:15 +0000
committerbors <bors@rust-lang.org>2018-08-08 01:24:15 +0000
commit26d7b64237c6daa66064c8583b7aecf534c2a9ae (patch)
tree1abd68a78dbab63a894988da5253c07e65ed10f2 /src/librustc_codegen_llvm
parent3f4f18f098183bf60820e4304433c4c4d9cceaaa (diff)
parent7c58ab671fb49200c0cbd1ad9218713a5c3afe0d (diff)
Auto merge of #52993 - alexcrichton:fix-some-vis, r=michaelwoerister
rustc: Tweak visibility of some lang items

This commit tweaks the linker-level visibility of some lang items that rustc
uses and defines. Notably this means that `#[panic_implementation]` and
`#[alloc_error_handler]` functions are never marked as `internal`. It's up to
the linker to eliminate these, not rustc.

Additionally `#[global_allocator]` generated symbols are no longer forced to
`Default` visibility (fully exported), but rather they're relaxed to `Hidden`
visibility). This symbols are *not* needed across DLL boundaries, only as a
local implementation detail of the compiler-injected allocator symbols, so
`Hidden` should suffice.

Closes #51342
Closes #52795
Diffstat (limited to 'src/librustc_codegen_llvm')
-rw-r--r--src/librustc_codegen_llvm/allocator.rs7
-rw-r--r--src/librustc_codegen_llvm/base.rs24
2 files changed, 26 insertions, 5 deletions
diff --git a/src/librustc_codegen_llvm/allocator.rs b/src/librustc_codegen_llvm/allocator.rs
index 2d401da958b..0beb8a8844c 100644
--- a/src/librustc_codegen_llvm/allocator.rs
+++ b/src/librustc_codegen_llvm/allocator.rs
@@ -67,14 +67,15 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind
         if tcx.sess.target.target.options.default_hidden_visibility {
             llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
         }
-       if tcx.sess.target.target.options.requires_uwtable {
-           attributes::emit_uwtable(llfn, true);
-       }
+        if tcx.sess.target.target.options.requires_uwtable {
+            attributes::emit_uwtable(llfn, true);
+        }
 
         let callee = CString::new(kind.fn_name(method.name)).unwrap();
         let callee = llvm::LLVMRustGetOrInsertFunction(llmod,
                                                        callee.as_ptr(),
                                                        ty);
+        llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
 
         let llbb = llvm::LLVMAppendBasicBlockInContext(llcx,
                                                        llfn,
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 41336165684..0a8bc03d8d4 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -809,8 +809,28 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         rx,
         codegen_units.len());
 
-    // Codegen an allocator shim, if any
-    let allocator_module = if let Some(kind) = *tcx.sess.allocator_kind.get() {
+    // Codegen an allocator shim, if necessary.
+    //
+    // If the crate doesn't have an `allocator_kind` set then there's definitely
+    // no shim to generate. Otherwise we also check our dependency graph for all
+    // our output crate types. If anything there looks like its a `Dynamic`
+    // linkage, then it's already got an allocator shim and we'll be using that
+    // one instead. If nothing exists then it's our job to generate the
+    // allocator!
+    let any_dynamic_crate = tcx.sess.dependency_formats.borrow()
+        .iter()
+        .any(|(_, list)| {
+            use rustc::middle::dependency_format::Linkage;
+            list.iter().any(|linkage| {
+                match linkage {
+                    Linkage::Dynamic => true,
+                    _ => false,
+                }
+            })
+        });
+    let allocator_module = if any_dynamic_crate {
+        None
+    } else if let Some(kind) = *tcx.sess.allocator_kind.get() {
         unsafe {
             let llmod_id = "allocator";
             let modules = ModuleLlvm::new(tcx.sess, llmod_id);