Skip to content

Commit 7d8c84b

Browse files
committed
---
yaml --- r: 233214 b: refs/heads/beta c: e648c96 h: refs/heads/master v: v3
1 parent 06c6e0d commit 7d8c84b

File tree

15 files changed

+228
-92
lines changed

15 files changed

+228
-92
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: 18607149fbb0836059a96981c78e10ca52d23cd5
26+
refs/heads/beta: e648c96c5f9b69022ae416040cf0558221a11d77
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: 370fe2786109360f7c35b8ba552b83b773dd71d6
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/mk/platform.mk

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,15 @@ $(foreach target,$(CFG_TARGET), \
277277
# Fun times!
278278
#
279279
# [1]: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
280+
#
281+
# FIXME(stage0): remove this macro and the usage below (and the commments above)
282+
# when a new snapshot is available. Also remove the
283+
# RUSTFLAGS$(1)_.._T_ variable in mk/target.mk along with
284+
# CUSTOM_DEPS (as they were only added for this)
280285
define ADD_RUSTC_LLVM_DEF_TO_MSVC
281286
ifeq ($$(findstring msvc,$(1)),msvc)
282-
RUSTFLAGS_rustc_llvm_T_$(1) += -C link-args="-DEF:$(1)/rt/rustc_llvm.def"
283-
CUSTOM_DEPS_rustc_llvm_T_$(1) += $(1)/rt/rustc_llvm.def
287+
RUSTFLAGS0_rustc_llvm_T_$(1) += -C link-args="-DEF:$(1)/rt/rustc_llvm.def"
288+
CUSTOM_DEPS0_rustc_llvm_T_$(1) += $(1)/rt/rustc_llvm.def
284289

285290
$(1)/rt/rustc_llvm.def: $$(S)src/etc/mklldef.py $$(S)src/librustc_llvm/lib.rs
286291
$$(CFG_PYTHON) $$^ $$@ rustc_llvm-$$(CFG_FILENAME_EXTRA)

branches/beta/mk/target.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4) := \
4040
$$(RT_OUTPUT_DIR_$(2))/$$(dep)) \
4141
$$(foreach dep,$$(NATIVE_TOOL_DEPS_$(4)_T_$(2)), \
4242
$$(TBIN$(1)_T_$(3)_H_$(3))/$$(dep)) \
43-
$$(CUSTOM_DEPS_$(4)_T_$(2))
43+
$$(CUSTOM_DEPS$(1)_$(4)_T_$(2))
4444
endef
4545

4646
$(foreach host,$(CFG_HOST), \
@@ -92,7 +92,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
9292
$$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \
9393
$$(LLVM_STDCPP_RUSTFLAGS_$(2)) \
9494
$$(RUSTFLAGS_$(4)) \
95-
$$(RUSTFLAGS_$(4)_T_$(2)) \
95+
$$(RUSTFLAGS$(1)_$(4)_T_$(2)) \
9696
--out-dir $$(@D) \
9797
-C extra-filename=-$$(CFG_FILENAME_EXTRA) \
9898
$$<

branches/beta/src/compiletest/procsrv.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
2626
// Add the new dylib search path var
2727
let var = DynamicLibrary::envvar();
2828
let newpath = DynamicLibrary::create_path(&path);
29-
let newpath = newpath.to_str().unwrap().to_string();
30-
cmd.env(var, &newpath);
29+
cmd.env(var, newpath);
3130
}
3231

3332
pub struct Result {pub status: ExitStatus, pub out: String, pub err: String}

branches/beta/src/librustc/metadata/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ pub const tag_plugin_registrar_fn: usize = 0x10b; // top-level only
205205
pub const tag_method_argument_names: usize = 0x85;
206206
pub const tag_method_argument_name: usize = 0x86;
207207

208-
pub const tag_reachable_extern_fns: usize = 0x10c; // top-level only
209-
pub const tag_reachable_extern_fn_id: usize = 0x87;
208+
pub const tag_reachable_ids: usize = 0x10c; // top-level only
209+
pub const tag_reachable_id: usize = 0x87;
210210

211211
pub const tag_items_data_item_stability: usize = 0x88;
212212

branches/beta/src/librustc/metadata/csearch.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,11 @@ pub fn get_method_arg_names(cstore: &cstore::CStore, did: ast::DefId)
352352
decoder::get_method_arg_names(&*cdata, did.node)
353353
}
354354

355-
pub fn get_reachable_extern_fns(cstore: &cstore::CStore, cnum: ast::CrateNum)
355+
pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum)
356356
-> Vec<ast::DefId>
357357
{
358358
let cdata = cstore.get_crate_data(cnum);
359-
decoder::get_reachable_extern_fns(&*cdata)
359+
decoder::get_reachable_ids(&*cdata)
360360
}
361361

362362
pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool {
@@ -400,3 +400,9 @@ pub fn is_default_impl(cstore: &cstore::CStore, impl_did: ast::DefId) -> bool {
400400
let cdata = cstore.get_crate_data(impl_did.krate);
401401
decoder::is_default_impl(&*cdata, impl_did.node)
402402
}
403+
404+
pub fn is_extern_fn(cstore: &cstore::CStore, did: ast::DefId,
405+
tcx: &ty::ctxt) -> bool {
406+
let cdata = cstore.get_crate_data(did.krate);
407+
decoder::is_extern_fn(&*cdata, did.node, tcx)
408+
}

branches/beta/src/librustc/metadata/decoder.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use std::str;
4545
use rbml::reader;
4646
use rbml;
4747
use serialize::Decodable;
48+
use syntax::abi;
4849
use syntax::attr;
4950
use syntax::parse::token::{IdentInterner, special_idents};
5051
use syntax::parse::token;
@@ -1418,10 +1419,10 @@ pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<String> {
14181419
}
14191420
}
14201421

1421-
pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec<ast::DefId> {
1422+
pub fn get_reachable_ids(cdata: Cmd) -> Vec<ast::DefId> {
14221423
let items = reader::get_doc(rbml::Doc::new(cdata.data()),
1423-
tag_reachable_extern_fns);
1424-
reader::tagged_docs(items, tag_reachable_extern_fn_id).map(|doc| {
1424+
tag_reachable_ids);
1425+
reader::tagged_docs(items, tag_reachable_id).map(|doc| {
14251426
ast::DefId {
14261427
krate: cdata.cnum,
14271428
node: reader::doc_as_u32(doc),
@@ -1543,3 +1544,21 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
15431544
Decodable::decode(&mut decoder).unwrap()
15441545
}).collect()
15451546
}
1547+
1548+
pub fn is_extern_fn(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> bool {
1549+
let root_doc = rbml::Doc::new(cdata.data());
1550+
let items = reader::get_doc(root_doc, tag_items);
1551+
let item_doc = match maybe_find_item(id, items) {
1552+
Some(doc) => doc,
1553+
None => return false,
1554+
};
1555+
if let Fn = item_family(item_doc) {
1556+
let ty::TypeScheme { generics, ty } = get_type(cdata, id, tcx);
1557+
generics.types.is_empty() && match ty.sty {
1558+
ty::TyBareFn(_, fn_ty) => fn_ty.abi != abi::Rust,
1559+
_ => false,
1560+
}
1561+
} else {
1562+
false
1563+
}
1564+
}

branches/beta/src/librustc/metadata/encoder.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,9 +1781,8 @@ fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
17811781
// FIXME (#2166): This is not nearly enough to support correct versioning
17821782
// but is enough to get transitive crate dependencies working.
17831783
rbml_w.start_tag(tag_crate_deps);
1784-
let r = get_ordered_deps(cstore);
1785-
for dep in &r {
1786-
encode_crate_dep(rbml_w, (*dep).clone());
1784+
for dep in &get_ordered_deps(cstore) {
1785+
encode_crate_dep(rbml_w, dep);
17871786
}
17881787
rbml_w.end_tag();
17891788
}
@@ -1971,24 +1970,22 @@ fn encode_misc_info(ecx: &EncodeContext,
19711970
rbml_w.end_tag();
19721971
}
19731972

1974-
fn encode_reachable_extern_fns(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1975-
rbml_w.start_tag(tag_reachable_extern_fns);
1976-
1973+
// Encodes all reachable symbols in this crate into the metadata.
1974+
//
1975+
// This pass is seeded off the reachability list calculated in the
1976+
// middle::reachable module but filters out items that either don't have a
1977+
// symbol associated with them (they weren't translated) or if they're an FFI
1978+
// definition (as that's not defined in this crate).
1979+
fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) {
1980+
rbml_w.start_tag(tag_reachable_ids);
19771981
for id in ecx.reachable {
1978-
if let Some(ast_map::NodeItem(i)) = ecx.tcx.map.find(*id) {
1979-
if let ast::ItemFn(_, _, _, abi, ref generics, _) = i.node {
1980-
if abi != abi::Rust && !generics.is_type_parameterized() {
1981-
rbml_w.wr_tagged_u32(tag_reachable_extern_fn_id, *id);
1982-
}
1983-
}
1984-
}
1982+
rbml_w.wr_tagged_u32(tag_reachable_id, *id);
19851983
}
1986-
19871984
rbml_w.end_tag();
19881985
}
19891986

19901987
fn encode_crate_dep(rbml_w: &mut Encoder,
1991-
dep: decoder::CrateDep) {
1988+
dep: &decoder::CrateDep) {
19921989
rbml_w.start_tag(tag_crate_dep);
19931990
rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name);
19941991
rbml_w.wr_tagged_str(tag_crate_dep_hash, dep.hash.as_str());
@@ -2170,7 +2167,7 @@ fn encode_metadata_inner(wr: &mut Cursor<Vec<u8>>,
21702167
// Encode miscellaneous info.
21712168
i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
21722169
encode_misc_info(&ecx, krate, &mut rbml_w);
2173-
encode_reachable_extern_fns(&ecx, &mut rbml_w);
2170+
encode_reachable(&ecx, &mut rbml_w);
21742171
stats.misc_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
21752172

21762173
// Encode and index the items.

branches/beta/src/librustc_llvm/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#![feature(link_args)]
3232
#![feature(staged_api)]
3333
#![feature(vec_push_all)]
34+
#![cfg_attr(not(stage0), feature(linked_from))]
3435

3536
extern crate libc;
3637
#[macro_use] #[no_link] extern crate rustc_bitflags;
@@ -598,6 +599,7 @@ pub mod debuginfo {
598599
// automatically updated whenever LLVM is updated to include an up-to-date
599600
// set of the libraries we need to link to LLVM for.
600601
#[link(name = "rustllvm", kind = "static")]
602+
#[cfg_attr(not(stage0), linked_from = "rustllvm")] // not quite true but good enough
601603
extern {
602604
/* Create and destroy contexts. */
603605
pub fn LLVMContextCreate() -> ContextRef;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,12 @@ fn link_args(cmd: &mut Linker,
902902
}
903903
cmd.output_filename(out_filename);
904904

905+
// If we're building a dynamic library then some platforms need to make sure
906+
// that all symbols are exported correctly from the dynamic library.
907+
if dylib {
908+
cmd.export_symbols(sess, trans, tmpdir);
909+
}
910+
905911
// When linking a dynamic library, we put the metadata into a section of the
906912
// executable. This metadata is in a separate object file from the main
907913
// object file, so we link that in here.

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

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,21 @@
99
// except according to those terms.
1010

1111
use std::ffi::OsString;
12+
use std::fs::{self, File};
13+
use std::io::{self, BufWriter};
14+
use std::io::prelude::*;
1215
use std::path::{Path, PathBuf};
1316
use std::process::Command;
14-
use std::fs;
1517

1618
use back::archive;
19+
use metadata::csearch;
20+
use metadata::cstore;
1721
use session::Session;
18-
use session::config;
1922
use session::config::DebugInfoLevel::{NoDebugInfo, LimitedDebugInfo, FullDebugInfo};
23+
use session::config::CrateTypeDylib;
24+
use session::config;
25+
use syntax::ast;
26+
use trans::CrateTranslation;
2027

2128
/// Linker abstraction used by back::link to build up the command to invoke a
2229
/// linker.
@@ -48,6 +55,8 @@ pub trait Linker {
4855
fn hint_dynamic(&mut self);
4956
fn whole_archives(&mut self);
5057
fn no_whole_archives(&mut self);
58+
fn export_symbols(&mut self, sess: &Session, trans: &CrateTranslation,
59+
tmpdir: &Path);
5160
}
5261

5362
pub struct GnuLinker<'a> {
@@ -192,6 +201,10 @@ impl<'a> Linker for GnuLinker<'a> {
192201
if !self.takes_hints() { return }
193202
self.cmd.arg("-Wl,-Bdynamic");
194203
}
204+
205+
fn export_symbols(&mut self, _: &Session, _: &CrateTranslation, _: &Path) {
206+
// noop, visibility in object files takes care of this
207+
}
195208
}
196209

197210
pub struct MsvcLinker<'a> {
@@ -301,4 +314,61 @@ impl<'a> Linker for MsvcLinker<'a> {
301314
// we do on Unix platforms.
302315
fn hint_static(&mut self) {}
303316
fn hint_dynamic(&mut self) {}
317+
318+
// Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
319+
// export symbols from a dynamic library. When building a dynamic library,
320+
// however, we're going to want some symbols exported, so this function
321+
// generates a DEF file which lists all the symbols.
322+
//
323+
// The linker will read this `*.def` file and export all the symbols from
324+
// the dynamic library. Note that this is not as simple as just exporting
325+
// all the symbols in the current crate (as specified by `trans.reachable`)
326+
// but rather we also need to possibly export the symbols of upstream
327+
// crates. Upstream rlibs may be linked statically to this dynamic library,
328+
// in which case they may continue to transitively be used and hence need
329+
// their symbols exported.
330+
fn export_symbols(&mut self, sess: &Session, trans: &CrateTranslation,
331+
tmpdir: &Path) {
332+
let path = tmpdir.join("lib.def");
333+
let res = (|| -> io::Result<()> {
334+
let mut f = BufWriter::new(try!(File::create(&path)));
335+
336+
// Start off with the standard module name header and then go
337+
// straight to exports.
338+
try!(writeln!(f, "LIBRARY"));
339+
try!(writeln!(f, "EXPORTS"));
340+
341+
// Write out all our local symbols
342+
for sym in trans.reachable.iter() {
343+
try!(writeln!(f, " {}", sym));
344+
}
345+
346+
// Take a look at how all upstream crates are linked into this
347+
// dynamic library. For all statically linked libraries we take all
348+
// their reachable symbols and emit them as well.
349+
let cstore = &sess.cstore;
350+
let symbols = trans.crate_formats[&CrateTypeDylib].iter();
351+
let symbols = symbols.enumerate().filter_map(|(i, f)| {
352+
if let Some(cstore::RequireStatic) = *f {
353+
Some((i + 1) as ast::CrateNum)
354+
} else {
355+
None
356+
}
357+
}).flat_map(|cnum| {
358+
csearch::get_reachable_ids(cstore, cnum)
359+
}).map(|did| {
360+
csearch::get_symbol(cstore, did)
361+
});
362+
for symbol in symbols {
363+
try!(writeln!(f, " {}", symbol));
364+
}
365+
Ok(())
366+
})();
367+
if let Err(e) = res {
368+
sess.fatal(&format!("failed to write lib.def file: {}", e));
369+
}
370+
let mut arg = OsString::from("/DEF:");
371+
arg.push(path);
372+
self.cmd.arg(&arg);
373+
}
304374
}

0 commit comments

Comments
 (0)