about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-01-27 10:01:45 +0000
committerbors <bors@rust-lang.org>2017-01-27 10:01:45 +0000
commit8367fb7ba6abae89ab7e17c1b3987ee321f5bb71 (patch)
tree21b4f4f8b07ec2058229ef9dbbb316a7155fd1b8
parentfece9c735678d152da721711f6f4aba1f0b8ab15 (diff)
parent3d6f263b2a162974725cdcb914ba9ad9c2dbef84 (diff)
downloadrust-8367fb7ba6abae89ab7e17c1b3987ee321f5bb71.tar.gz
rust-8367fb7ba6abae89ab7e17c1b3987ee321f5bb71.zip
Auto merge of #39252 - alexcrichton:less-exports, r=nrc
Hide a few more standard library symbols

These commits touch up some of the symbol visibility rules for some crates related to the standard library, notably:

* Symbols that are `pub extern` and `#[no_mangle]` which are internal-to-rust ABI things are no longer at the `C` export level, but the `Rust` export level. This includes allocators, panic runtimes, and compiler builtins.
* The libbacktrace library is now compiled with `-fvisibility=hidden` to ensure that we don't export those symbols.
-rw-r--r--src/liballoc_jemalloc/build.rs11
-rw-r--r--src/liballoc_jemalloc/lib.rs2
-rw-r--r--src/liballoc_jemalloc/pthread_atfork_dummy.c16
-rw-r--r--src/librustc_trans/back/symbol_export.rs33
-rw-r--r--src/libstd/build.rs5
5 files changed, 63 insertions, 4 deletions
diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs
index 1edcb0b1f24..1143df0c630 100644
--- a/src/liballoc_jemalloc/build.rs
+++ b/src/liballoc_jemalloc/build.rs
@@ -181,4 +181,15 @@ fn main() {
     } else if !target.contains("windows") && !target.contains("musl") {
         println!("cargo:rustc-link-lib=pthread");
     }
+
+    // The pthread_atfork symbols is used by jemalloc on android but the really
+    // old android we're building on doesn't have them defined, so just make
+    // sure the symbols are available.
+    if target.contains("androideabi") {
+        println!("cargo:rerun-if-changed=pthread_atfork_dummy.c");
+        gcc::Config::new()
+            .flag("-fvisibility=hidden")
+            .file("pthread_atfork_dummy.c")
+            .compile("libpthread_atfork_dummy.a");
+    }
 }
diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs
index 241f8149d24..fc8a5455d1d 100644
--- a/src/liballoc_jemalloc/lib.rs
+++ b/src/liballoc_jemalloc/lib.rs
@@ -143,7 +143,7 @@ mod imp {
     // we're building on doesn't have them defined, so just make sure the symbols
     // are available.
     #[no_mangle]
-    #[cfg(target_os = "android")]
+    #[cfg(all(target_os = "android", not(cargobuild)))]
     pub extern "C" fn pthread_atfork(_prefork: *mut u8,
                                      _postfork_parent: *mut u8,
                                      _postfork_child: *mut u8)
diff --git a/src/liballoc_jemalloc/pthread_atfork_dummy.c b/src/liballoc_jemalloc/pthread_atfork_dummy.c
new file mode 100644
index 00000000000..4e3df0ab26c
--- /dev/null
+++ b/src/liballoc_jemalloc/pthread_atfork_dummy.c
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// See comments in build.rs for why this exists
+int pthread_atfork(void* prefork,
+                   void* postfork_parent,
+                   void* postfork_child) {
+  return 0;
+}
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index 81be2d02f12..bea3ca8df70 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -81,11 +81,25 @@ impl ExportedSymbols {
         for cnum in scx.sess().cstore.crates() {
             debug_assert!(cnum != LOCAL_CRATE);
 
+            // If this crate is a plugin and/or a custom derive crate, then
+            // we're not even going to link those in so we skip those crates.
             if scx.sess().cstore.plugin_registrar_fn(cnum).is_some() ||
                scx.sess().cstore.derive_registrar_fn(cnum).is_some() {
                 continue;
             }
 
+            // Check to see if this crate is a "special runtime crate". These
+            // crates, implementation details of the standard library, typically
+            // have a bunch of `pub extern` and `#[no_mangle]` functions as the
+            // ABI between them. We don't want their symbols to have a `C`
+            // export level, however, as they're just implementation details.
+            // Down below we'll hardwire all of the symbols to the `Rust` export
+            // level instead.
+            let special_runtime_crate =
+                scx.sess().cstore.is_allocator(cnum) ||
+                scx.sess().cstore.is_panic_runtime(cnum) ||
+                scx.sess().cstore.is_compiler_builtins(cnum);
+
             let crate_exports = scx
                 .sess()
                 .cstore
@@ -93,7 +107,24 @@ impl ExportedSymbols {
                 .iter()
                 .map(|&def_id| {
                     let name = Instance::mono(scx, def_id).symbol_name(scx);
-                    let export_level = export_level(scx, def_id);
+                    let export_level = if special_runtime_crate {
+                        // We can probably do better here by just ensuring that
+                        // it has hidden visibility rather than public
+                        // visibility, as this is primarily here to ensure it's
+                        // not stripped during LTO.
+                        //
+                        // In general though we won't link right if these
+                        // symbols are stripped, and LTO currently strips them.
+                        if name == "rust_eh_personality" ||
+                           name == "rust_eh_register_frames" ||
+                           name == "rust_eh_unregister_frames" {
+                            SymbolExportLevel::C
+                        } else {
+                            SymbolExportLevel::Rust
+                        }
+                    } else {
+                        export_level(scx, def_id)
+                    };
                     debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level);
                     (name, export_level)
                 })
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 5e1c3a28515..9504194393f 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -87,8 +87,9 @@ fn build_libbacktrace(host: &str, target: &str) {
     let compiler = gcc::Config::new().get_compiler();
     // only msvc returns None for ar so unwrap is okay
     let ar = build_helper::cc2ar(compiler.path(), target).unwrap();
-    let cflags = compiler.args().iter().map(|s| s.to_str().unwrap())
-                         .collect::<Vec<_>>().join(" ");
+    let mut cflags = compiler.args().iter().map(|s| s.to_str().unwrap())
+                             .collect::<Vec<_>>().join(" ");
+    cflags.push_str(" -fvisibility=hidden");
     run(Command::new("sh")
                 .current_dir(&build_dir)
                 .arg(src_dir.join("configure").to_str().unwrap()