Skip to content

Commit 32a2e9a

Browse files
michaelwoeristernikomatsakis
authored andcommitted
Compute a salt from arguments passed via -Cmetadata.
1 parent c7e54d7 commit 32a2e9a

File tree

11 files changed

+67
-18
lines changed

11 files changed

+67
-18
lines changed

src/librbml/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,15 @@ impl<'doc> Doc<'doc> {
166166
}
167167
}
168168

169-
pub fn get<'a>(&'a self, tag: usize) -> Doc<'a> {
169+
pub fn get(&self, tag: usize) -> Doc<'doc> {
170170
reader::get_doc(*self, tag)
171171
}
172172

173173
pub fn is_empty(&self) -> bool {
174174
self.start == self.end
175175
}
176176

177-
pub fn as_str_slice<'a>(&'a self) -> &'a str {
177+
pub fn as_str_slice(&self) -> &'doc str {
178178
str::from_utf8(&self.data[self.start..self.end]).unwrap()
179179
}
180180

src/librustc/middle/cstore.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ pub trait CrateStore<'tcx> : Any {
206206
fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>;
207207
fn crate_name(&self, cnum: ast::CrateNum) -> InternedString;
208208
fn crate_hash(&self, cnum: ast::CrateNum) -> Svh;
209+
fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString;
209210
fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
210211
-> FnvHashMap<DefId, Vec<ast::Attribute>>;
211212
fn plugin_registrar_fn(&self, cnum: ast::CrateNum) -> Option<DefId>;
@@ -385,6 +386,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
385386
{ unimplemented!() }
386387
fn crate_name(&self, cnum: ast::CrateNum) -> InternedString { unimplemented!() }
387388
fn crate_hash(&self, cnum: ast::CrateNum) -> Svh { unimplemented!() }
389+
fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString { unimplemented!() }
388390
fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
389391
-> FnvHashMap<DefId, Vec<ast::Attribute>>
390392
{ unimplemented!() }

src/librustc/session/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ pub struct Session {
6464
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
6565
pub crate_types: RefCell<Vec<config::CrateType>>,
6666
pub dependency_formats: RefCell<dependency_format::Dependencies>,
67-
pub crate_metadata: RefCell<Vec<String>>,
67+
// The crate_disambiguator is constructed out of all the `-C metadata`
68+
// arguments passed to the compiler. Its value together with the crate-name
69+
// forms a unique global identifier for the crate. It is used to allow
70+
// multiple crates with the same name to coexist. See the
71+
// trans::back::symbol_names module for more information.
72+
pub crate_disambiguator: RefCell<String>,
6873
pub features: RefCell<feature_gate::Features>,
6974

7075
/// The maximum recursion limit for potentially infinitely recursive
@@ -481,7 +486,7 @@ pub fn build_session_(sopts: config::Options,
481486
plugin_attributes: RefCell::new(Vec::new()),
482487
crate_types: RefCell::new(Vec::new()),
483488
dependency_formats: RefCell::new(FnvHashMap()),
484-
crate_metadata: RefCell::new(Vec::new()),
489+
crate_disambiguator: RefCell::new(String::new()),
485490
features: RefCell::new(feature_gate::Features::new()),
486491
recursion_limit: Cell::new(64),
487492
next_node_id: Cell::new(1),

src/librustc_back/svh.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl Svh {
6666
&self.hash
6767
}
6868

69-
pub fn calculate(metadata: &Vec<String>, krate: &hir::Crate) -> Svh {
69+
pub fn calculate(crate_disambiguator: &str, krate: &hir::Crate) -> Svh {
7070
// FIXME (#14132): This is better than it used to be, but it still not
7171
// ideal. We now attempt to hash only the relevant portions of the
7272
// Crate AST as well as the top-level crate attributes. (However,
@@ -78,9 +78,9 @@ impl Svh {
7878
// avoid collisions.
7979
let mut state = SipHasher::new();
8080

81-
for data in metadata {
82-
data.hash(&mut state);
83-
}
81+
"crate_disambiguator".hash(&mut state);
82+
crate_disambiguator.len().hash(&mut state);
83+
crate_disambiguator.hash(&mut state);
8484

8585
{
8686
let mut visit = svh_visitor::make(&mut state, krate);

src/librustc_driver/driver.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc::middle::privacy::AccessLevels;
2222
use rustc::middle::ty::TyCtxt;
2323
use rustc::util::common::time;
2424
use rustc::util::nodemap::NodeSet;
25+
use rustc_back::sha2::{Sha256, Digest};
2526
use rustc_borrowck as borrowck;
2627
use rustc_resolve as resolve;
2728
use rustc_metadata::macro_import;
@@ -500,7 +501,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
500501
})?;
501502

502503
*sess.crate_types.borrow_mut() = collect_crate_types(sess, &krate.attrs);
503-
*sess.crate_metadata.borrow_mut() = collect_crate_metadata(sess, &krate.attrs);
504+
*sess.crate_disambiguator.borrow_mut() = compute_crate_disambiguator(sess);
504505

505506
time(time_passes, "recursion limit", || {
506507
middle::recursion_limit::update_recursion_limit(sess, &krate);
@@ -1121,8 +1122,34 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
11211122
.collect()
11221123
}
11231124

1124-
pub fn collect_crate_metadata(session: &Session, _attrs: &[ast::Attribute]) -> Vec<String> {
1125-
session.opts.cg.metadata.clone()
1125+
pub fn compute_crate_disambiguator(session: &Session) -> String {
1126+
let mut hasher = Sha256::new();
1127+
1128+
let mut metadata = session.opts.cg.metadata.clone();
1129+
// We don't want the crate_disambiguator to dependent on the order
1130+
// -C metadata arguments, so sort them:
1131+
metadata.sort();
1132+
// Every distinct -C metadata value is only incorporated once:
1133+
metadata.dedup();
1134+
1135+
hasher.input_str("metadata");
1136+
for s in &metadata {
1137+
// Also incorporate the length of a metadata string, so that we generate
1138+
// different values for `-Cmetadata=ab -Cmetadata=c` and
1139+
// `-Cmetadata=a -Cmetadata=bc`
1140+
hasher.input_str(&format!("{}", s.len())[..]);
1141+
hasher.input_str(&s[..]);
1142+
}
1143+
1144+
let mut hash = hasher.result_str();
1145+
1146+
// If this is an executable, add a special suffix, so that we don't get
1147+
// symbol conflicts when linking against a library of the same name.
1148+
if session.crate_types.borrow().contains(&config::CrateTypeExecutable) {
1149+
hash.push_str("-exe");
1150+
}
1151+
1152+
hash
11261153
}
11271154

11281155
pub fn build_output_filenames(input: &Input,

src/librustc_driver/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,8 +568,6 @@ impl RustcDefaultCalls {
568568
continue;
569569
}
570570
let crate_types = driver::collect_crate_types(sess, attrs);
571-
let metadata = driver::collect_crate_metadata(sess, attrs);
572-
*sess.crate_metadata.borrow_mut() = metadata;
573571
for &style in &crate_types {
574572
let fname = link::filename_for_input(sess, style, &id, &t_outputs);
575573
println!("{}",

src/librustc_metadata/common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ pub const tag_crate_dep: usize = 0x35;
7373

7474
pub const tag_crate_hash: usize = 0x103; // top-level only
7575
pub const tag_crate_crate_name: usize = 0x104; // top-level only
76+
pub const tag_crate_disambiguator: usize = 0x113; // top-level only
7677

7778
pub const tag_crate_dep_crate_name: usize = 0x36;
7879
pub const tag_crate_dep_hash: usize = 0x37;

src/librustc_metadata/csearch.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,12 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
345345
decoder::get_crate_hash(cdata.data())
346346
}
347347

348+
fn crate_disambiguator(&self, cnum: ast::CrateNum) -> token::InternedString
349+
{
350+
let cdata = self.get_crate_data(cnum);
351+
token::intern_and_get_ident(decoder::get_crate_disambiguator(cdata.data()))
352+
}
353+
348354
fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
349355
-> FnvHashMap<DefId, Vec<ast::Attribute>>
350356
{

src/librustc_metadata/decoder.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,13 @@ pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
12951295
})
12961296
}
12971297

1298+
pub fn get_crate_disambiguator<'a>(data: &'a [u8]) -> &'a str {
1299+
let crate_doc = rbml::Doc::new(data);
1300+
let salt_doc = reader::get_doc(crate_doc, tag_crate_disambiguator);
1301+
let slice: &'a str = salt_doc.as_str_slice();
1302+
slice
1303+
}
1304+
12981305
pub fn get_crate_triple(data: &[u8]) -> Option<String> {
12991306
let cratedoc = rbml::Doc::new(data);
13001307
let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);

src/librustc_metadata/encoder.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,10 @@ fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
18771877
rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
18781878
}
18791879

1880+
fn encode_crate_disambiguator(rbml_w: &mut Encoder, crate_disambiguator: &str) {
1881+
rbml_w.wr_tagged_str(tag_crate_disambiguator, crate_disambiguator);
1882+
}
1883+
18801884
fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
18811885
rbml_w.wr_tagged_str(tag_crate_triple, triple);
18821886
}
@@ -1987,6 +1991,7 @@ fn encode_metadata_inner(rbml_w: &mut Encoder,
19871991
encode_crate_name(rbml_w, &ecx.link_meta.crate_name);
19881992
encode_crate_triple(rbml_w, &ecx.tcx.sess.opts.target_triple);
19891993
encode_hash(rbml_w, &ecx.link_meta.crate_hash);
1994+
encode_crate_disambiguator(rbml_w, &ecx.tcx.sess.crate_disambiguator.borrow());
19901995
encode_dylib_dependency_formats(rbml_w, &ecx);
19911996

19921997
let mut i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();

src/librustc_trans/back/link.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ pub fn build_link_meta(sess: &Session,
189189
-> LinkMeta {
190190
let r = LinkMeta {
191191
crate_name: name.to_owned(),
192-
crate_hash: Svh::calculate(&sess.opts.cg.metadata, krate),
192+
crate_hash: Svh::calculate(&sess.crate_disambiguator.borrow()[..], krate),
193193
};
194194
info!("{:?}", r);
195195
return r;
@@ -201,7 +201,7 @@ fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String {
201201
output[.. 8].to_hex().to_string()
202202
}
203203

204-
pub fn def_to_string(_tcx: &ty::ctxt, did: DefId) -> String {
204+
pub fn def_to_string(_tcx: &TyCtxt, did: DefId) -> String {
205205
format!("{}:{}", did.krate, did.index.as_usize())
206206
}
207207

@@ -218,9 +218,7 @@ fn symbol_hash<'tcx>(tcx: &TyCtxt<'tcx>,
218218
symbol_hasher.input_str(&link_meta.crate_name);
219219
symbol_hasher.input_str("-");
220220
symbol_hasher.input_str(link_meta.crate_hash.as_str());
221-
for meta in tcx.sess.crate_metadata.borrow().iter() {
222-
symbol_hasher.input_str(&meta[..]);
223-
}
221+
symbol_hasher.input_str(&tcx.sess.crate_disambiguator.borrow()[..]);
224222
symbol_hasher.input_str("-");
225223
symbol_hasher.input(&tcx.sess.cstore.encode_type(tcx, t, def_to_string));
226224
// Prefix with 'h' so that it never blends into adjacent digits

0 commit comments

Comments
 (0)