Skip to content

Commit dbd7ada

Browse files
michaelwoeristernikomatsakis
authored andcommitted
---
yaml --- r: 273567 b: refs/heads/beta c: 2475707 h: refs/heads/master i: 273565: f092c18 273563: a00cb80 273559: 05ae575 273551: c7cf30e 273535: 8f913f2
1 parent d5f2315 commit dbd7ada

File tree

15 files changed

+242
-10
lines changed

15 files changed

+242
-10
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: 82b5f1d8690ec538557ce3f355add91e3809ba51
26+
refs/heads/beta: 247570732205fd226981082ee5c96c0abf5fed21
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: e06d2ad9fcd5027bcaac5b08fc9aa39a49d0ecd3
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/librustc/middle/cstore.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,11 @@ pub trait CrateStore<'tcx> : Any {
204204
fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool;
205205
fn is_allocator(&self, cnum: ast::CrateNum) -> bool;
206206
fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>;
207+
/// The name of the crate as it is referred to in source code of the current
208+
/// crate.
207209
fn crate_name(&self, cnum: ast::CrateNum) -> InternedString;
210+
/// The name of the crate as it is stored in the crate's metadata.
211+
fn original_crate_name(&self, cnum: ast::CrateNum) -> InternedString;
208212
fn crate_hash(&self, cnum: ast::CrateNum) -> Svh;
209213
fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString;
210214
fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)
@@ -385,6 +389,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
385389
fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>
386390
{ unimplemented!() }
387391
fn crate_name(&self, cnum: ast::CrateNum) -> InternedString { unimplemented!() }
392+
fn original_crate_name(&self, cnum: ast::CrateNum) -> InternedString {
393+
unimplemented!()
394+
}
388395
fn crate_hash(&self, cnum: ast::CrateNum) -> Svh { unimplemented!() }
389396
fn crate_disambiguator(&self, cnum: ast::CrateNum) -> InternedString { unimplemented!() }
390397
fn crate_struct_field_attrs(&self, cnum: ast::CrateNum)

branches/beta/src/librustc_metadata/creader.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,10 @@ impl<'a> CrateReader<'a> {
277277
}
278278

279279
fn verify_no_symbol_conflicts(&self,
280-
crate_name: &str,
281280
span: Span,
282281
metadata: &MetadataBlob) {
283282
let disambiguator = decoder::get_crate_disambiguator(metadata.as_slice());
283+
let crate_name = decoder::get_crate_name(metadata.as_slice());
284284

285285
// Check for (potential) conflicts with the local crate
286286
if self.local_crate_name == crate_name &&
@@ -318,7 +318,7 @@ impl<'a> CrateReader<'a> {
318318
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
319319
cstore::CrateSource) {
320320
self.verify_rustc_version(name, span, &lib.metadata);
321-
self.verify_no_symbol_conflicts(name, span, &lib.metadata);
321+
self.verify_no_symbol_conflicts(span, &lib.metadata);
322322

323323
// Claim this crate number and cache it
324324
let cnum = self.next_crate_num;

branches/beta/src/librustc_metadata/csearch.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
339339
token::intern_and_get_ident(&self.get_crate_data(cnum).name[..])
340340
}
341341

342+
fn original_crate_name(&self, cnum: ast::CrateNum) -> token::InternedString
343+
{
344+
token::intern_and_get_ident(&self.get_crate_data(cnum).name())
345+
}
346+
342347
fn crate_hash(&self, cnum: ast::CrateNum) -> Svh
343348
{
344349
let cdata = self.get_crate_data(cnum);

branches/beta/src/librustc_metadata/cstore.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ impl CStore {
248248

249249
impl crate_metadata {
250250
pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
251-
pub fn name(&self) -> String { decoder::get_crate_name(self.data()) }
251+
pub fn name(&self) -> &str { decoder::get_crate_name(self.data()) }
252252
pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
253253
pub fn disambiguator(&self) -> &str {
254254
decoder::get_crate_disambiguator(self.data())

branches/beta/src/librustc_metadata/decoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,10 +1288,10 @@ pub fn get_crate_hash(data: &[u8]) -> Svh {
12881288
Svh::new(hashdoc.as_str_slice())
12891289
}
12901290

1291-
pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
1291+
pub fn maybe_get_crate_name(data: &[u8]) -> Option<&str> {
12921292
let cratedoc = rbml::Doc::new(data);
12931293
reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
1294-
doc.as_str_slice().to_string()
1294+
doc.as_str_slice()
12951295
})
12961296
}
12971297

@@ -1308,7 +1308,7 @@ pub fn get_crate_triple(data: &[u8]) -> Option<String> {
13081308
triple_doc.map(|s| s.as_str().to_string())
13091309
}
13101310

1311-
pub fn get_crate_name(data: &[u8]) -> String {
1311+
pub fn get_crate_name(data: &[u8]) -> &str {
13121312
maybe_get_crate_name(data).expect("no crate name in crate")
13131313
}
13141314

branches/beta/src/librustc_trans/back/linker.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use session::config::CrateTypeDylib;
2323
use session::config;
2424
use syntax::ast;
2525
use trans::CrateTranslation;
26+
use trans::link_guard;
2627

2728
/// Linker abstraction used by back::link to build up the command to invoke a
2829
/// linker.
@@ -359,6 +360,26 @@ impl<'a> Linker for MsvcLinker<'a> {
359360
for symbol in symbols {
360361
writeln!(f, " {}", symbol)?;
361362
}
363+
364+
// Add link-guard symbols
365+
{
366+
// local crate
367+
let symbol = link_guard::link_guard_name(&trans.link.crate_name[..],
368+
&trans.link.crate_hash);
369+
try!(writeln!(f, " {}", symbol));
370+
}
371+
// statically linked dependencies
372+
for (i, format) in formats[&CrateTypeDylib].iter().enumerate() {
373+
if *format == Linkage::Static {
374+
let cnum = (i + 1) as ast::CrateNum;
375+
let crate_name = cstore.original_crate_name(cnum);
376+
let svh = cstore.crate_hash(cnum);
377+
378+
let symbol = link_guard::link_guard_name(&crate_name[..], &svh);
379+
try!(writeln!(f, " {}", symbol));
380+
}
381+
}
382+
362383
Ok(())
363384
})();
364385
if let Err(e) = res {

branches/beta/src/librustc_trans/trans/base.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ use trans::expr;
7979
use trans::glue;
8080
use trans::inline;
8181
use trans::intrinsic;
82+
use trans::link_guard;
8283
use trans::machine;
8384
use trans::machine::{llalign_of_min, llsize_of, llsize_of_real};
8485
use trans::meth;
@@ -2382,6 +2383,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) {
23822383
unsafe {
23832384
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
23842385

2386+
link_guard::insert_reference_to_link_guard(ccx, llbb);
23852387
debuginfo::gdb::insert_reference_to_gdb_debug_scripts_section_global(ccx);
23862388

23872389
let (start_fn, args) = if use_start_lang_item {
@@ -2758,6 +2760,8 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27582760
collector::print_collection_results(&ccx);
27592761
}
27602762

2763+
emit_link_guard_if_necessary(&shared_ccx);
2764+
27612765
for ccx in shared_ccx.iter() {
27622766
if ccx.sess().opts.debuginfo != NoDebugInfo {
27632767
debuginfo::finalize(&ccx);
@@ -2818,6 +2822,8 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
28182822
if sess.entry_fn.borrow().is_some() {
28192823
reachable_symbols.push("main".to_string());
28202824
}
2825+
reachable_symbols.push(link_guard::link_guard_name(&link_meta.crate_name,
2826+
&link_meta.crate_hash));
28212827

28222828
// For the purposes of LTO, we add to the reachable set all of the upstream
28232829
// reachable extern fns. These functions are all part of the public ABI of
@@ -2861,6 +2867,24 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
28612867
}
28622868
}
28632869

2870+
fn emit_link_guard_if_necessary(shared_ccx: &SharedCrateContext) {
2871+
let link_meta = shared_ccx.link_meta();
2872+
let link_guard_name = link_guard::link_guard_name(&link_meta.crate_name,
2873+
&link_meta.crate_hash);
2874+
let link_guard_name = CString::new(link_guard_name).unwrap();
2875+
2876+
// Check if the link-guard has already been emitted in a codegen unit
2877+
let link_guard_already_emitted = shared_ccx.iter().any(|ccx| {
2878+
let link_guard = unsafe { llvm::LLVMGetNamedValue(ccx.llmod(),
2879+
link_guard_name.as_ptr()) };
2880+
!link_guard.is_null()
2881+
});
2882+
2883+
if !link_guard_already_emitted {
2884+
link_guard::get_or_insert_link_guard(&shared_ccx.get_ccx(0));
2885+
}
2886+
}
2887+
28642888
/// We visit all the items in the krate and translate them. We do
28652889
/// this in two walks. The first walk just finds module items. It then
28662890
/// walks the full contents of those module items and translates all
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use back::svh::Svh;
12+
use libc::c_uint;
13+
use llvm;
14+
use std::ffi::CString;
15+
use std::ptr;
16+
use trans::attributes;
17+
use trans::builder;
18+
use trans::CrateContext;
19+
use trans::declare;
20+
use trans::type_::Type;
21+
22+
const GUARD_PREFIX: &'static str = "__rustc_link_guard_";
23+
24+
pub fn link_guard_name(crate_name: &str, crate_svh: &Svh) -> String {
25+
26+
let mut guard_name = String::new();
27+
28+
guard_name.push_str(GUARD_PREFIX);
29+
guard_name.push_str(crate_name);
30+
guard_name.push_str("_");
31+
guard_name.push_str(crate_svh.as_str());
32+
33+
guard_name
34+
}
35+
36+
pub fn get_or_insert_link_guard<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>)
37+
-> llvm::ValueRef {
38+
39+
let guard_name = link_guard_name(&ccx.tcx().crate_name[..],
40+
&ccx.link_meta().crate_hash);
41+
42+
let guard_function = unsafe {
43+
let guard_name_c_string = CString::new(&guard_name[..]).unwrap();
44+
llvm::LLVMGetNamedValue(ccx.llmod(), guard_name_c_string.as_ptr())
45+
};
46+
47+
if guard_function != ptr::null_mut() {
48+
return guard_function;
49+
}
50+
51+
let llfty = Type::func(&[], &Type::void(ccx));
52+
let guard_function = declare::define_cfn(ccx,
53+
&guard_name[..],
54+
llfty,
55+
ccx.tcx().mk_nil()).unwrap_or_else(|| {
56+
ccx.sess().bug("Link guard already defined.");
57+
});
58+
59+
attributes::emit_uwtable(guard_function, true);
60+
attributes::unwind(guard_function, false);
61+
62+
let bld = ccx.raw_builder();
63+
unsafe {
64+
let llbb = llvm::LLVMAppendBasicBlockInContext(ccx.llcx(),
65+
guard_function,
66+
"link_guard_top\0".as_ptr() as *const _);
67+
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
68+
69+
for crate_num in ccx.sess().cstore.crates() {
70+
if !ccx.sess().cstore.is_explicitly_linked(crate_num) {
71+
continue;
72+
}
73+
74+
let crate_name = ccx.sess().cstore.original_crate_name(crate_num);
75+
let svh = ccx.sess().cstore.crate_hash(crate_num);
76+
77+
let dependency_guard_name = link_guard_name(&crate_name[..], &svh);
78+
79+
let decl = declare::declare_cfn(ccx,
80+
&dependency_guard_name[..],
81+
llfty,
82+
ccx.tcx().mk_nil());
83+
attributes::unwind(decl, false);
84+
85+
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
86+
87+
let args: &[llvm::ValueRef] = &[];
88+
llvm::LLVMRustBuildCall(bld,
89+
decl,
90+
args.as_ptr(),
91+
args.len() as c_uint,
92+
0 as *mut _,
93+
builder::noname());
94+
}
95+
96+
llvm::LLVMBuildRetVoid(bld);
97+
}
98+
99+
guard_function
100+
}
101+
102+
pub fn insert_reference_to_link_guard<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
103+
llbb: llvm::BasicBlockRef) {
104+
let guard_function = get_or_insert_link_guard(ccx);
105+
106+
unsafe {
107+
llvm::LLVMPositionBuilderAtEnd(ccx.raw_builder(), llbb);
108+
let args: &[llvm::ValueRef] = &[];
109+
llvm::LLVMRustBuildCall(ccx.raw_builder(),
110+
guard_function,
111+
args.as_ptr(),
112+
args.len() as c_uint,
113+
0 as *mut _,
114+
builder::noname());
115+
}
116+
}

branches/beta/src/librustc_trans/trans/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ mod expr;
5353
mod glue;
5454
mod inline;
5555
mod intrinsic;
56+
pub mod link_guard;
5657
mod machine;
5758
mod _match;
5859
mod meth;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-include ../tools.mk
2+
3+
all:
4+
-mkdir -p $(TMPDIR)/good
5+
-mkdir -p $(TMPDIR)/bad
6+
$(BARE_RUSTC) ./good/lib.rs -C prefer-dynamic --out-dir="$(TMPDIR)/good"
7+
$(BARE_RUSTC) ./bad/lib.rs -C prefer-dynamic --out-dir="$(TMPDIR)/bad"
8+
$(BARE_RUSTC) -L "$(TMPDIR)/good" -C prefer-dynamic -Crpath ./main.rs --out-dir="$(TMPDIR)"
9+
# This should succeed because the correct library is in LD_LIBRARY_PATH
10+
$(LD_LIB_PATH_ENVVAR)="$(TMPDIR)/good:$($(LD_LIB_PATH_ENVVAR))" $(TMPDIR)/main
11+
# This should fail because the wrong library is in LD_LIBRARY_PATH
12+
OUTPUT=`$(LD_LIB_PATH_ENVVAR)="$(TMPDIR)/bad:$($(LD_LIB_PATH_ENVVAR))" $(TMPDIR)/main || exit 0`
13+
if ["$(OUTPUT)" == "bad"]; then exit 1; fi
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![crate_name="thelibrary"]
12+
#![crate_type="dylib"]
13+
14+
pub fn some_library_function() {
15+
println!("bad");
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![crate_name="thelibrary"]
12+
#![crate_type="dylib"]
13+
14+
pub fn some_library_function() {
15+
println!("bad");
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern crate thelibrary;
12+
13+
fn main() {
14+
thelibrary::some_library_function();
15+
}

branches/beta/src/test/run-make/relocation-model/Makefile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ all: others
77
$(RUSTC) -C relocation-model=default foo.rs
88
$(call RUN,foo)
99

10-
$(RUSTC) -C relocation-model=default --crate-type=dylib foo.rs
11-
$(RUSTC) -C relocation-model=dynamic-no-pic --crate-type=dylib foo.rs
10+
$(RUSTC) -C relocation-model=dynamic-no-pic --crate-type=dylib foo.rs --emit=link,obj
1211

1312
ifdef IS_MSVC
1413
# FIXME(#28026)
@@ -17,5 +16,4 @@ else
1716
others:
1817
$(RUSTC) -C relocation-model=static foo.rs
1918
$(call RUN,foo)
20-
$(RUSTC) -C relocation-model=static --crate-type=dylib foo.rs
2119
endif

0 commit comments

Comments
 (0)