]> git.lizzy.rs Git - rust.git/commitdiff
Compute a salt from arguments passed via -Cmetadata.
authorMichael Woerister <michaelwoerister@posteo.net>
Fri, 12 Feb 2016 13:41:30 +0000 (08:41 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 25 Mar 2016 18:07:17 +0000 (14:07 -0400)
src/librbml/lib.rs
src/librustc/middle/cstore.rs
src/librustc/session/mod.rs
src/librustc_back/svh.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_metadata/common.rs
src/librustc_metadata/csearch.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_trans/back/link.rs

index 34726a7a6c8ecbfbe77308ced4f2d72053cee54e..ef89b5d25b8875b04b443af9e220b01371524f76 100644 (file)
@@ -166,7 +166,7 @@ pub fn new(data: &'doc [u8]) -> Doc<'doc> {
         }
     }
 
-    pub fn get<'a>(&'a self, tag: usize) -> Doc<'a> {
+    pub fn get(&self, tag: usize) -> Doc<'doc> {
         reader::get_doc(*self, tag)
     }
 
@@ -174,7 +174,7 @@ pub fn is_empty(&self) -> bool {
         self.start == self.end
     }
 
-    pub fn as_str_slice<'a>(&'a self) -> &'a str {
+    pub fn as_str_slice(&self) -> &'doc str {
         str::from_utf8(&self.data[self.start..self.end]).unwrap()
     }
 
index b89fd92e3c59a67ab550ba9b538460174ae5eed2..718a9fd58dea4a1b84c32680bdb9f78bfa6c5ecd 100644 (file)
@@ -206,6 +206,7 @@ fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
     fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>;
     fn crate_name(&self, cnum: ast::CrateNum) -> InternedString;
     fn crate_hash(&self, cnum: ast::CrateNum) -> Svh;
+    fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString;
     fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
                                 -> FnvHashMap<DefId, Vec<ast::Attribute>>;
     fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>;
@@ -385,6 +386,7 @@ fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>
         { unimplemented!() }
     fn crate_name(&self, cnum: ast::CrateNum) -> InternedString { unimplemented!() }
     fn crate_hash(&self, cnum: ast::CrateNum) -> Svh { unimplemented!() }
+    fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString { unimplemented!() }
     fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
                                 -> FnvHashMap<DefId, Vec<ast::Attribute>>
         { unimplemented!() }
index b198eda181208f2e3a8c7fc52464d017d6200ec4..36dc8eabc89f2509b446ec4f3abba132e42e4641 100644 (file)
@@ -64,7 +64,12 @@ pub struct Session {
     pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
     pub crate_types: RefCell<Vec<config::CrateType>>,
     pub dependency_formats: RefCell<dependency_format::Dependencies>,
-    pub crate_metadata: RefCell<Vec<String>>,
+    // The crate_disambiguator is constructed out of all the `-C metadata`
+    // arguments passed to the compiler. Its value together with the crate-name
+    // forms a unique global identifier for the crate. It is used to allow
+    // multiple crates with the same name to coexist. See the
+    // trans::back::symbol_names module for more information.
+    pub crate_disambiguator: RefCell<String>,
     pub features: RefCell<feature_gate::Features>,
 
     /// The maximum recursion limit for potentially infinitely recursive
@@ -481,7 +486,7 @@ pub fn build_session_(sopts: config::Options,
         plugin_attributes: RefCell::new(Vec::new()),
         crate_types: RefCell::new(Vec::new()),
         dependency_formats: RefCell::new(FnvHashMap()),
-        crate_metadata: RefCell::new(Vec::new()),
+        crate_disambiguator: RefCell::new(String::new()),
         features: RefCell::new(feature_gate::Features::new()),
         recursion_limit: Cell::new(64),
         next_node_id: Cell::new(1),
index 3507a119e5455ebbf12dc79509b01b063001b170..ec607314f45c0f35e9edd146b6ea994a8486aea7 100644 (file)
@@ -66,7 +66,7 @@ pub fn as_str<'a>(&'a self) -> &'a str {
         &self.hash
     }
 
-    pub fn calculate(metadata: &Vec<String>, krate: &hir::Crate) -> Svh {
+    pub fn calculate(crate_disambiguator: &str, krate: &hir::Crate) -> Svh {
         // FIXME (#14132): This is better than it used to be, but it still not
         // ideal. We now attempt to hash only the relevant portions of the
         // Crate AST as well as the top-level crate attributes. (However,
@@ -78,9 +78,9 @@ pub fn calculate(metadata: &Vec<String>, krate: &hir::Crate) -> Svh {
         //        avoid collisions.
         let mut state = SipHasher::new();
 
-        for data in metadata {
-            data.hash(&mut state);
-        }
+        "crate_disambiguator".hash(&mut state);
+        crate_disambiguator.len().hash(&mut state);
+        crate_disambiguator.hash(&mut state);
 
         {
             let mut visit = svh_visitor::make(&mut state, krate);
index 55b873c06630a2b1bb5018efc635fe8ceec1b26f..b75ccb3f7ee8fdc59a06b8c055d725f9a67f71ed 100644 (file)
@@ -22,6 +22,7 @@
 use rustc::middle::ty::TyCtxt;
 use rustc::util::common::time;
 use rustc::util::nodemap::NodeSet;
+use rustc_back::sha2::{Sha256, Digest};
 use rustc_borrowck as borrowck;
 use rustc_resolve as resolve;
 use rustc_metadata::macro_import;
@@ -500,7 +501,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
     })?;
 
     *sess.crate_types.borrow_mut() = collect_crate_types(sess, &krate.attrs);
-    *sess.crate_metadata.borrow_mut() = collect_crate_metadata(sess, &krate.attrs);
+    *sess.crate_disambiguator.borrow_mut() = compute_crate_disambiguator(sess);
 
     time(time_passes, "recursion limit", || {
         middle::recursion_limit::update_recursion_limit(sess, &krate);
@@ -1121,8 +1122,34 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
         .collect()
 }
 
-pub fn collect_crate_metadata(session: &Session, _attrs: &[ast::Attribute]) -> Vec<String> {
-    session.opts.cg.metadata.clone()
+pub fn compute_crate_disambiguator(session: &Session) -> String {
+    let mut hasher = Sha256::new();
+
+    let mut metadata = session.opts.cg.metadata.clone();
+    // We don't want the crate_disambiguator to dependent on the order
+    // -C metadata arguments, so sort them:
+    metadata.sort();
+    // Every distinct -C metadata value is only incorporated once:
+    metadata.dedup();
+
+    hasher.input_str("metadata");
+    for s in &metadata {
+        // Also incorporate the length of a metadata string, so that we generate
+        // different values for `-Cmetadata=ab -Cmetadata=c` and
+        // `-Cmetadata=a -Cmetadata=bc`
+        hasher.input_str(&format!("{}", s.len())[..]);
+        hasher.input_str(&s[..]);
+    }
+
+    let mut hash = hasher.result_str();
+
+    // If this is an executable, add a special suffix, so that we don't get
+    // symbol conflicts when linking against a library of the same name.
+    if session.crate_types.borrow().contains(&config::CrateTypeExecutable) {
+       hash.push_str("-exe");
+    }
+
+    hash
 }
 
 pub fn build_output_filenames(input: &Input,
index dc30b4f91a98532ac77beef3ffe74bf3d255cf3b..9ba6abb962ead169131ec83098efe2681ad9795b 100644 (file)
@@ -568,8 +568,6 @@ fn print_crate_info(sess: &Session,
                         continue;
                     }
                     let crate_types = driver::collect_crate_types(sess, attrs);
-                    let metadata = driver::collect_crate_metadata(sess, attrs);
-                    *sess.crate_metadata.borrow_mut() = metadata;
                     for &style in &crate_types {
                         let fname = link::filename_for_input(sess, style, &id, &t_outputs);
                         println!("{}",
index a0cbba279acc05e3bf88f440f085c425e3a96266..22a5289f02be88961ec8c77788ba6fcdd9e63613 100644 (file)
@@ -73,6 +73,7 @@
 
 pub const tag_crate_hash: usize = 0x103; // top-level only
 pub const tag_crate_crate_name: usize = 0x104; // top-level only
+pub const tag_crate_disambiguator: usize = 0x113; // top-level only
 
 pub const tag_crate_dep_crate_name: usize = 0x36;
 pub const tag_crate_dep_hash: usize = 0x37;
index 9514317056ab3bbfacbee4e18b63c91747a153c2..f9446d7667c6903fd498cbb6f81d9a52e8177e98 100644 (file)
@@ -345,6 +345,12 @@ fn crate_hash(&self, cnum: ast::CrateNum) -> Svh
         decoder::get_crate_hash(cdata.data())
     }
 
+    fn crate_disambiguator(&self, cnum: ast::CrateNum) -> token::InternedString
+    {
+        let cdata = self.get_crate_data(cnum);
+        token::intern_and_get_ident(decoder::get_crate_disambiguator(cdata.data()))
+    }
+
     fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
                                 -> FnvHashMap<DefId, Vec<ast::Attribute>>
     {
index 0c736feeefeee0daa3e956ff8df26bda5dc2ece6..f24c489b7c2af825d3cb6e957a32581070e5cf70 100644 (file)
@@ -1295,6 +1295,13 @@ pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
     })
 }
 
+pub fn get_crate_disambiguator<'a>(data: &'a [u8]) -> &'a str {
+    let crate_doc = rbml::Doc::new(data);
+    let salt_doc = reader::get_doc(crate_doc, tag_crate_disambiguator);
+    let slice: &'a str = salt_doc.as_str_slice();
+    slice
+}
+
 pub fn get_crate_triple(data: &[u8]) -> Option<String> {
     let cratedoc = rbml::Doc::new(data);
     let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
index a082b0f21f11bd1384ea56a80ed7f747c2453634..a58c24eb09fa85cb54cc7c14e96a77257c1f07bd 100644 (file)
@@ -1877,6 +1877,10 @@ fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
     rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
 }
 
+fn encode_crate_disambiguator(rbml_w: &mut Encoder, crate_disambiguator: &str) {
+    rbml_w.wr_tagged_str(tag_crate_disambiguator, crate_disambiguator);
+}
+
 fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
     rbml_w.wr_tagged_str(tag_crate_triple, triple);
 }
@@ -1987,6 +1991,7 @@ struct Stats {
     encode_crate_name(rbml_w, &ecx.link_meta.crate_name);
     encode_crate_triple(rbml_w, &ecx.tcx.sess.opts.target_triple);
     encode_hash(rbml_w, &ecx.link_meta.crate_hash);
+    encode_crate_disambiguator(rbml_w, &ecx.tcx.sess.crate_disambiguator.borrow());
     encode_dylib_dependency_formats(rbml_w, &ecx);
 
     let mut i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
index 20fc74caad9f19f761b5ada6be737d248fd07279..01ef33637d58bd8c038b823ce76b73fec10ce5a0 100644 (file)
@@ -189,7 +189,7 @@ pub fn build_link_meta(sess: &Session,
                        -> LinkMeta {
     let r = LinkMeta {
         crate_name: name.to_owned(),
-        crate_hash: Svh::calculate(&sess.opts.cg.metadata, krate),
+        crate_hash: Svh::calculate(&sess.crate_disambiguator.borrow()[..], krate),
     };
     info!("{:?}", r);
     return r;
@@ -201,7 +201,7 @@ fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String {
     output[.. 8].to_hex().to_string()
 }
 
-pub fn def_to_string(_tcx: &ty::ctxt, did: DefId) -> String {
+pub fn def_to_string(_tcx: &TyCtxt, did: DefId) -> String {
     format!("{}:{}", did.krate, did.index.as_usize())
 }
 
@@ -218,9 +218,7 @@ fn symbol_hash<'tcx>(tcx: &TyCtxt<'tcx>,
     symbol_hasher.input_str(&link_meta.crate_name);
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(link_meta.crate_hash.as_str());
-    for meta in tcx.sess.crate_metadata.borrow().iter() {
-        symbol_hasher.input_str(&meta[..]);
-    }
+    symbol_hasher.input_str(&tcx.sess.crate_disambiguator.borrow()[..]);
     symbol_hasher.input_str("-");
     symbol_hasher.input(&tcx.sess.cstore.encode_type(tcx, t, def_to_string));
     // Prefix with 'h' so that it never blends into adjacent digits