Remove rustc_llvm dependency from rustc_metadata

Move the code for loading metadata from rlibs and dylibs from
rustc_metadata into rustc_trans, and introduce a trait to avoid
introducing a direct dependency on rustc_trans.

This means rustc_metadata is no longer rebuilt when LLVM changes.
This commit is contained in:
Robin Kruppe 2017-04-26 23:22:45 +02:00
parent 9f15631c36
commit 1a24a591dd
22 changed files with 276 additions and 219 deletions

19
src/Cargo.lock generated
View File

@ -316,6 +316,14 @@ name = "open"
version = "1.2.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "owning_ref"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "panic_abort" name = "panic_abort"
version = "0.0.0" version = "0.0.0"
@ -442,6 +450,7 @@ dependencies = [
"fmt_macros 0.0.0", "fmt_macros 0.0.0",
"graphviz 0.0.0", "graphviz 0.0.0",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_back 0.0.0", "rustc_back 0.0.0",
"rustc_bitflags 0.0.0", "rustc_bitflags 0.0.0",
"rustc_const_math 0.0.0", "rustc_const_math 0.0.0",
@ -626,13 +635,13 @@ version = "0.0.0"
dependencies = [ dependencies = [
"flate 0.0.0", "flate 0.0.0",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc_macro 0.0.0", "proc_macro 0.0.0",
"rustc 0.0.0", "rustc 0.0.0",
"rustc_back 0.0.0", "rustc_back 0.0.0",
"rustc_const_math 0.0.0", "rustc_const_math 0.0.0",
"rustc_data_structures 0.0.0", "rustc_data_structures 0.0.0",
"rustc_errors 0.0.0", "rustc_errors 0.0.0",
"rustc_llvm 0.0.0",
"serialize 0.0.0", "serialize 0.0.0",
"syntax 0.0.0", "syntax 0.0.0",
"syntax_ext 0.0.0", "syntax_ext 0.0.0",
@ -734,6 +743,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"flate 0.0.0", "flate 0.0.0",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0", "rustc 0.0.0",
"rustc_back 0.0.0", "rustc_back 0.0.0",
"rustc_bitflags 0.0.0", "rustc_bitflags 0.0.0",
@ -820,6 +830,11 @@ dependencies = [
name = "serialize" name = "serialize"
version = "0.0.0" version = "0.0.0"
[[package]]
name = "stable_deref_trait"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "std" name = "std"
version = "0.0.0" version = "0.0.0"
@ -1015,6 +1030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
"checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" "checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167"
"checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842" "checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
"checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973" "checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973"
"checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41" "checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41"
@ -1026,6 +1042,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0" "checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0"
"checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f" "checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f"
"checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e" "checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a" "checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"

View File

@ -13,6 +13,7 @@ arena = { path = "../libarena" }
fmt_macros = { path = "../libfmt_macros" } fmt_macros = { path = "../libfmt_macros" }
graphviz = { path = "../libgraphviz" } graphviz = { path = "../libgraphviz" }
log = "0.3" log = "0.3"
owning_ref = "0.3.3"
rustc_back = { path = "../librustc_back" } rustc_back = { path = "../librustc_back" }
rustc_bitflags = { path = "../librustc_bitflags" } rustc_bitflags = { path = "../librustc_bitflags" }
rustc_const_math = { path = "../librustc_const_math" } rustc_const_math = { path = "../librustc_const_math" }

View File

@ -54,6 +54,7 @@ extern crate fmt_macros;
extern crate getopts; extern crate getopts;
extern crate graphviz; extern crate graphviz;
extern crate libc; extern crate libc;
extern crate owning_ref;
extern crate rustc_llvm as llvm; extern crate rustc_llvm as llvm;
extern crate rustc_back; extern crate rustc_back;
extern crate rustc_data_structures; extern crate rustc_data_structures;

View File

@ -36,8 +36,9 @@ use session::search_paths::PathKind;
use util::nodemap::{NodeSet, DefIdMap}; use util::nodemap::{NodeSet, DefIdMap};
use std::any::Any; use std::any::Any;
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::rc::Rc; use std::rc::Rc;
use owning_ref::ErasedBoxRef;
use syntax::ast; use syntax::ast;
use syntax::ext::base::SyntaxExtension; use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol; use syntax::symbol::Symbol;
@ -201,11 +202,33 @@ impl EncodedMetadataHashes {
} }
} }
/// The backend's way to give the crate store access to the metadata in a library.
/// Note that it returns the raw metadata bytes stored in the library file, whether
/// it is compressed, uncompressed, some weird mix, etc.
/// rmeta files are backend independent and not handled here.
///
/// At the time of this writing, there is only one backend and one way to store
/// metadata in library -- this trait just serves to decouple rustc_metadata from
/// the archive reader, which depends on LLVM.
pub trait MetadataLoader {
fn get_rlib_metadata(&self,
target: &Target,
filename: &Path)
-> Result<ErasedBoxRef<[u8]>, String>;
fn get_dylib_metadata(&self,
target: &Target,
filename: &Path)
-> Result<ErasedBoxRef<[u8]>, String>;
}
/// A store of Rust crates, through with their metadata /// A store of Rust crates, through with their metadata
/// can be accessed. /// can be accessed.
pub trait CrateStore { pub trait CrateStore {
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>; fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>;
// access to the metadata loader
fn metadata_loader(&self) -> &MetadataLoader;
// item info // item info
fn visibility(&self, def: DefId) -> ty::Visibility; fn visibility(&self, def: DefId) -> ty::Visibility;
fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>>; fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
@ -275,8 +298,6 @@ pub trait CrateStore {
fn used_link_args(&self) -> Vec<String>; fn used_link_args(&self) -> Vec<String>;
// utility functions // utility functions
fn metadata_filename(&self) -> &str;
fn metadata_section_name(&self, target: &Target) -> &str;
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>; fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource; fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>; fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
@ -413,8 +434,6 @@ impl CrateStore for DummyCrateStore {
fn used_link_args(&self) -> Vec<String> { vec![] } fn used_link_args(&self) -> Vec<String> { vec![] }
// utility functions // utility functions
fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
{ vec![] } { vec![] }
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") } fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
@ -427,6 +446,9 @@ impl CrateStore for DummyCrateStore {
bug!("encode_metadata") bug!("encode_metadata")
} }
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") } fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
// access to the metadata loader
fn metadata_loader(&self) -> &MetadataLoader { bug!("metadata_loader") }
} }
pub trait CrateLoader { pub trait CrateLoader {

View File

@ -204,7 +204,7 @@ pub fn run_compiler<'a>(args: &[String],
}; };
let dep_graph = DepGraph::new(sopts.build_dep_graph()); let dep_graph = DepGraph::new(sopts.build_dep_graph());
let cstore = Rc::new(CStore::new(&dep_graph)); let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let loader = file_loader.unwrap_or(box RealFileLoader); let loader = file_loader.unwrap_or(box RealFileLoader);
let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping())); let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));
@ -409,7 +409,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
return None; return None;
} }
let dep_graph = DepGraph::new(sopts.build_dep_graph()); let dep_graph = DepGraph::new(sopts.build_dep_graph());
let cstore = Rc::new(CStore::new(&dep_graph)); let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let mut sess = build_session(sopts.clone(), let mut sess = build_session(sopts.clone(),
&dep_graph, &dep_graph,
None, None,
@ -558,7 +558,11 @@ impl RustcDefaultCalls {
&Input::File(ref ifile) => { &Input::File(ref ifile) => {
let path = &(*ifile); let path = &(*ifile);
let mut v = Vec::new(); let mut v = Vec::new();
locator::list_file_metadata(&sess.target.target, path, &mut v).unwrap(); locator::list_file_metadata(&sess.target.target,
path,
sess.cstore.metadata_loader(),
&mut v)
.unwrap();
println!("{}", String::from_utf8(v).unwrap()); println!("{}", String::from_utf8(v).unwrap());
} }
&Input::Str { .. } => { &Input::Str { .. } => {

View File

@ -14,6 +14,7 @@ use driver;
use rustc::dep_graph::DepGraph; use rustc::dep_graph::DepGraph;
use rustc_lint; use rustc_lint;
use rustc_resolve::MakeGlobMap; use rustc_resolve::MakeGlobMap;
use rustc_trans;
use rustc::middle::lang_items; use rustc::middle::lang_items;
use rustc::middle::free_region::FreeRegionMap; use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::region::{CodeExtent, RegionMaps}; use rustc::middle::region::{CodeExtent, RegionMaps};
@ -104,7 +105,7 @@ fn test_env<F>(source_string: &str,
let dep_graph = DepGraph::new(false); let dep_graph = DepGraph::new(false);
let _ignore = dep_graph.in_ignore(); let _ignore = dep_graph.in_ignore();
let cstore = Rc::new(CStore::new(&dep_graph)); let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let sess = session::build_session_(options, let sess = session::build_session_(options,
&dep_graph, &dep_graph,
None, None,

View File

@ -11,13 +11,13 @@ crate-type = ["dylib"]
[dependencies] [dependencies]
flate = { path = "../libflate" } flate = { path = "../libflate" }
log = "0.3" log = "0.3"
owning_ref = "0.3.3"
proc_macro = { path = "../libproc_macro" } proc_macro = { path = "../libproc_macro" }
rustc = { path = "../librustc" } rustc = { path = "../librustc" }
rustc_back = { path = "../librustc_back" } rustc_back = { path = "../librustc_back" }
rustc_const_math = { path = "../librustc_const_math" } rustc_const_math = { path = "../librustc_const_math" }
rustc_data_structures = { path = "../librustc_data_structures" } rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" } rustc_errors = { path = "../librustc_errors" }
rustc_llvm = { path = "../librustc_llvm" }
serialize = { path = "../libserialize" } serialize = { path = "../libserialize" }
syntax = { path = "../libsyntax" } syntax = { path = "../libsyntax" }
syntax_ext = { path = "../libsyntax_ext" } syntax_ext = { path = "../libsyntax_ext" }

View File

@ -393,6 +393,7 @@ impl<'a> CrateLoader<'a> {
rejected_via_filename: vec![], rejected_via_filename: vec![],
should_match_name: true, should_match_name: true,
is_proc_macro: Some(false), is_proc_macro: Some(false),
metadata_loader: &*self.cstore.metadata_loader,
}; };
self.load(&mut locate_ctxt).or_else(|| { self.load(&mut locate_ctxt).or_else(|| {
@ -554,6 +555,7 @@ impl<'a> CrateLoader<'a> {
rejected_via_filename: vec![], rejected_via_filename: vec![],
should_match_name: true, should_match_name: true,
is_proc_macro: None, is_proc_macro: None,
metadata_loader: &*self.cstore.metadata_loader,
}; };
let library = self.load(&mut locate_ctxt).or_else(|| { let library = self.load(&mut locate_ctxt).or_else(|| {
if !is_cross { if !is_cross {

View File

@ -11,21 +11,20 @@
// The crate store - a central repo for information collected about external // The crate store - a central repo for information collected about external
// crates and libraries // crates and libraries
use locator;
use schema::{self, Tracked}; use schema::{self, Tracked};
use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind}; use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId}; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId};
use rustc::hir::map::definitions::DefPathTable; use rustc::hir::map::definitions::DefPathTable;
use rustc::hir::svh::Svh; use rustc::hir::svh::Svh;
use rustc::middle::cstore::{DepKind, ExternCrate}; use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
use rustc_back::PanicStrategy; use rustc_back::PanicStrategy;
use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::indexed_vec::IndexVec;
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap}; use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap};
use std::cell::{RefCell, Cell}; use std::cell::{RefCell, Cell};
use std::rc::Rc; use std::rc::Rc;
use flate::Bytes; use owning_ref::ErasedBoxRef;
use syntax::{ast, attr}; use syntax::{ast, attr};
use syntax::ext::base::SyntaxExtension; use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol; use syntax::symbol::Symbol;
@ -43,11 +42,7 @@ pub use cstore_impl::provide;
// own crate numbers. // own crate numbers.
pub type CrateNumMap = IndexVec<CrateNum, CrateNum>; pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
pub enum MetadataBlob { pub struct MetadataBlob(pub ErasedBoxRef<[u8]>);
Inflated(Bytes),
Archive(locator::ArchiveMetadata),
Raw(Vec<u8>),
}
/// Holds information about a syntax_pos::FileMap imported from another crate. /// Holds information about a syntax_pos::FileMap imported from another crate.
/// See `imported_filemaps()` for more information. /// See `imported_filemaps()` for more information.
@ -103,10 +98,11 @@ pub struct CStore {
statically_included_foreign_items: RefCell<FxHashSet<DefIndex>>, statically_included_foreign_items: RefCell<FxHashSet<DefIndex>>,
pub dllimport_foreign_items: RefCell<FxHashSet<DefIndex>>, pub dllimport_foreign_items: RefCell<FxHashSet<DefIndex>>,
pub visible_parent_map: RefCell<DefIdMap<DefId>>, pub visible_parent_map: RefCell<DefIdMap<DefId>>,
pub metadata_loader: Box<MetadataLoader>,
} }
impl CStore { impl CStore {
pub fn new(dep_graph: &DepGraph) -> CStore { pub fn new(dep_graph: &DepGraph, metadata_loader: Box<MetadataLoader>) -> CStore {
CStore { CStore {
dep_graph: dep_graph.clone(), dep_graph: dep_graph.clone(),
metas: RefCell::new(FxHashMap()), metas: RefCell::new(FxHashMap()),
@ -116,6 +112,7 @@ impl CStore {
statically_included_foreign_items: RefCell::new(FxHashSet()), statically_included_foreign_items: RefCell::new(FxHashSet()),
dllimport_foreign_items: RefCell::new(FxHashSet()), dllimport_foreign_items: RefCell::new(FxHashSet()),
visible_parent_map: RefCell::new(FxHashMap()), visible_parent_map: RefCell::new(FxHashMap()),
metadata_loader: metadata_loader,
} }
} }

View File

@ -10,12 +10,11 @@
use cstore; use cstore;
use encoder; use encoder;
use locator;
use schema; use schema;
use rustc::dep_graph::DepTrackingMapConfig; use rustc::dep_graph::DepTrackingMapConfig;
use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind,
ExternCrate, NativeLibrary, LinkMeta, ExternCrate, NativeLibrary, MetadataLoader, LinkMeta,
LinkagePreference, LoadedMacro, EncodedMetadata}; LinkagePreference, LoadedMacro, EncodedMetadata};
use rustc::hir::def; use rustc::hir::def;
use rustc::middle::lang_items; use rustc::middle::lang_items;
@ -38,7 +37,6 @@ use syntax::parse::filemap_to_stream;
use syntax::symbol::Symbol; use syntax::symbol::Symbol;
use syntax_pos::{Span, NO_EXPANSION}; use syntax_pos::{Span, NO_EXPANSION};
use rustc::hir::svh::Svh; use rustc::hir::svh::Svh;
use rustc_back::target::Target;
use rustc::hir; use rustc::hir;
macro_rules! provide { macro_rules! provide {
@ -135,6 +133,10 @@ impl CrateStore for cstore::CStore {
self.get_crate_data(krate) self.get_crate_data(krate)
} }
fn metadata_loader(&self) -> &MetadataLoader {
&*self.metadata_loader
}
fn visibility(&self, def: DefId) -> ty::Visibility { fn visibility(&self, def: DefId) -> ty::Visibility {
self.dep_graph.read(DepNode::MetaData(def)); self.dep_graph.read(DepNode::MetaData(def));
self.get_crate_data(def.krate).get_visibility(def.index) self.get_crate_data(def.krate).get_visibility(def.index)
@ -420,17 +422,6 @@ impl CrateStore for cstore::CStore {
{ {
self.get_used_link_args().borrow().clone() self.get_used_link_args().borrow().clone()
} }
fn metadata_filename(&self) -> &str
{
locator::METADATA_FILENAME
}
fn metadata_section_name(&self, target: &Target) -> &str
{
locator::meta_section_name(target)
}
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
{ {
self.do_get_used_crates(prefer) self.do_get_used_crates(prefer)
@ -522,4 +513,4 @@ impl CrateStore for cstore::CStore {
drop(visible_parent_map); drop(visible_parent_map);
self.visible_parent_map.borrow() self.visible_parent_map.borrow()
} }
} }

View File

@ -77,11 +77,7 @@ pub trait Metadata<'a, 'tcx>: Copy {
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
fn raw_bytes(self) -> &'a [u8] { fn raw_bytes(self) -> &'a [u8] {
match *self { &self.0
MetadataBlob::Inflated(ref vec) => vec,
MetadataBlob::Archive(ref ar) => ar.as_slice(),
MetadataBlob::Raw(ref vec) => vec,
}
} }
} }

View File

@ -37,6 +37,7 @@ extern crate syntax;
extern crate syntax_pos; extern crate syntax_pos;
extern crate flate; extern crate flate;
extern crate serialize as rustc_serialize; // used by deriving extern crate serialize as rustc_serialize; // used by deriving
extern crate owning_ref;
extern crate rustc_errors as errors; extern crate rustc_errors as errors;
extern crate syntax_ext; extern crate syntax_ext;
extern crate proc_macro; extern crate proc_macro;
@ -46,7 +47,6 @@ extern crate rustc;
extern crate rustc_back; extern crate rustc_back;
extern crate rustc_const_math; extern crate rustc_const_math;
extern crate rustc_data_structures; extern crate rustc_data_structures;
extern crate rustc_llvm;
mod diagnostics; mod diagnostics;

View File

@ -224,15 +224,12 @@ use creader::Library;
use schema::{METADATA_HEADER, rustc_version}; use schema::{METADATA_HEADER, rustc_version};
use rustc::hir::svh::Svh; use rustc::hir::svh::Svh;
use rustc::middle::cstore::MetadataLoader;
use rustc::session::{config, Session}; use rustc::session::{config, Session};
use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
use rustc::session::search_paths::PathKind; use rustc::session::search_paths::PathKind;
use rustc::util::common;
use rustc::util::nodemap::FxHashMap; use rustc::util::nodemap::FxHashMap;
use rustc_llvm as llvm;
use rustc_llvm::{False, ObjectFile, mk_section_iter};
use rustc_llvm::archive_ro::ArchiveRO;
use errors::DiagnosticBuilder; use errors::DiagnosticBuilder;
use syntax::symbol::Symbol; use syntax::symbol::Symbol;
use syntax_pos::Span; use syntax_pos::Span;
@ -243,11 +240,10 @@ use std::fmt;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::{self, Read}; use std::io::{self, Read};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::ptr;
use std::slice;
use std::time::Instant; use std::time::Instant;
use flate; use flate;
use owning_ref::{ErasedBoxRef, OwningRef};
pub struct CrateMismatch { pub struct CrateMismatch {
path: PathBuf, path: PathBuf,
@ -272,12 +268,7 @@ pub struct Context<'a> {
pub rejected_via_filename: Vec<CrateMismatch>, pub rejected_via_filename: Vec<CrateMismatch>,
pub should_match_name: bool, pub should_match_name: bool,
pub is_proc_macro: Option<bool>, pub is_proc_macro: Option<bool>,
} pub metadata_loader: &'a MetadataLoader,
pub struct ArchiveMetadata {
_archive: ArchiveRO,
// points into self._archive
data: *const [u8],
} }
pub struct CratePaths { pub struct CratePaths {
@ -287,8 +278,6 @@ pub struct CratePaths {
pub rmeta: Option<PathBuf>, pub rmeta: Option<PathBuf>,
} }
pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq)]
enum CrateFlavor { enum CrateFlavor {
Rlib, Rlib,
@ -596,20 +585,21 @@ impl<'a> Context<'a> {
let mut err: Option<DiagnosticBuilder> = None; let mut err: Option<DiagnosticBuilder> = None;
for (lib, kind) in m { for (lib, kind) in m {
info!("{} reading metadata from: {}", flavor, lib.display()); info!("{} reading metadata from: {}", flavor, lib.display());
let (hash, metadata) = match get_metadata_section(self.target, flavor, &lib) { let (hash, metadata) =
Ok(blob) => { match get_metadata_section(self.target, flavor, &lib, self.metadata_loader) {
if let Some(h) = self.crate_matches(&blob, &lib) { Ok(blob) => {
(h, blob) if let Some(h) = self.crate_matches(&blob, &lib) {
} else { (h, blob)
info!("metadata mismatch"); } else {
info!("metadata mismatch");
continue;
}
}
Err(err) => {
info!("no metadata found: {}", err);
continue; continue;
} }
} };
Err(err) => {
info!("no metadata found: {}", err);
continue;
}
};
// If we see multiple hashes, emit an error about duplicate candidates. // If we see multiple hashes, emit an error about duplicate candidates.
if slot.as_ref().map_or(false, |s| s.0 != hash) { if slot.as_ref().map_or(false, |s| s.0 != hash) {
let mut e = struct_span_err!(self.sess, let mut e = struct_span_err!(self.sess,
@ -833,50 +823,14 @@ pub fn note_crate_name(err: &mut DiagnosticBuilder, name: &str) {
err.note(&format!("crate name: {}", name)); err.note(&format!("crate name: {}", name));
} }
impl ArchiveMetadata {
fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
let data = {
let section = ar.iter()
.filter_map(|s| s.ok())
.find(|sect| sect.name() == Some(METADATA_FILENAME));
match section {
Some(s) => s.data() as *const [u8],
None => {
debug!("didn't find '{}' in the archive", METADATA_FILENAME);
return None;
}
}
};
Some(ArchiveMetadata {
_archive: ar,
data: data,
})
}
pub fn as_slice<'a>(&'a self) -> &'a [u8] {
unsafe { &*self.data }
}
}
fn verify_decompressed_encoding_version(blob: &MetadataBlob,
filename: &Path)
-> Result<(), String> {
if !blob.is_compatible() {
Err((format!("incompatible metadata version found: '{}'",
filename.display())))
} else {
Ok(())
}
}
// Just a small wrapper to time how long reading metadata takes. // Just a small wrapper to time how long reading metadata takes.
fn get_metadata_section(target: &Target, fn get_metadata_section(target: &Target,
flavor: CrateFlavor, flavor: CrateFlavor,
filename: &Path) filename: &Path,
loader: &MetadataLoader)
-> Result<MetadataBlob, String> { -> Result<MetadataBlob, String> {
let start = Instant::now(); let start = Instant::now();
let ret = get_metadata_section_imp(target, flavor, filename); let ret = get_metadata_section_imp(target, flavor, filename, loader);
info!("reading {:?} => {:?}", info!("reading {:?} => {:?}",
filename.file_name().unwrap(), filename.file_name().unwrap(),
start.elapsed()); start.elapsed());
@ -885,118 +839,61 @@ fn get_metadata_section(target: &Target,
fn get_metadata_section_imp(target: &Target, fn get_metadata_section_imp(target: &Target,
flavor: CrateFlavor, flavor: CrateFlavor,
filename: &Path) filename: &Path,
loader: &MetadataLoader)
-> Result<MetadataBlob, String> { -> Result<MetadataBlob, String> {
if !filename.exists() { if !filename.exists() {
return Err(format!("no such file: '{}'", filename.display())); return Err(format!("no such file: '{}'", filename.display()));
} }
if flavor == CrateFlavor::Rlib { let raw_bytes: ErasedBoxRef<[u8]> = match flavor {
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap CrateFlavor::Rlib => loader.get_rlib_metadata(target, filename)?,
// internally to read the file. We also avoid even using a memcpy by CrateFlavor::Dylib => {
// just keeping the archive along while the metadata is in use. let buf = loader.get_dylib_metadata(target, filename)?;
let archive = match ArchiveRO::open(filename) { // The header is uncompressed
Some(ar) => ar, let header_len = METADATA_HEADER.len();
None => { debug!("checking {} bytes of metadata-version stamp", header_len);
debug!("llvm didn't like `{}`", filename.display()); let header = &buf[..cmp::min(header_len, buf.len())];
return Err(format!("failed to read rlib metadata: '{}'", filename.display())); if header != METADATA_HEADER {
return Err(format!("incompatible metadata version found: '{}'",
filename.display()));
} }
};
return match ArchiveMetadata::new(archive).map(|ar| MetadataBlob::Archive(ar)) {
None => Err(format!("failed to read rlib metadata: '{}'", filename.display())),
Some(blob) => {
verify_decompressed_encoding_version(&blob, filename)?;
Ok(blob)
}
};
} else if flavor == CrateFlavor::Rmeta {
let mut file = File::open(filename).map_err(|_|
format!("could not open file: '{}'", filename.display()))?;
let mut buf = vec![];
file.read_to_end(&mut buf).map_err(|_|
format!("failed to read rlib metadata: '{}'", filename.display()))?;
let blob = MetadataBlob::Raw(buf);
verify_decompressed_encoding_version(&blob, filename)?;
return Ok(blob);
}
unsafe {
let buf = common::path2cstr(filename);
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
if mb as isize == 0 {
return Err(format!("error reading library: '{}'", filename.display()));
}
let of = match ObjectFile::new(mb) {
Some(of) => of,
_ => {
return Err((format!("provided path not an object file: '{}'", filename.display())))
}
};
let si = mk_section_iter(of.llof);
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
let mut name_buf = ptr::null();
let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec();
let name = String::from_utf8(name).unwrap();
debug!("get_metadata_section: name {}", name);
if read_meta_section_name(target) == name {
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
let csz = llvm::LLVMGetSectionSize(si.llsi) as usize;
let cvbuf: *const u8 = cbuf as *const u8;
let vlen = METADATA_HEADER.len();
debug!("checking {} bytes of metadata-version stamp", vlen);
let minsz = cmp::min(vlen, csz);
let buf0 = slice::from_raw_parts(cvbuf, minsz);
let version_ok = buf0 == METADATA_HEADER;
if !version_ok {
return Err((format!("incompatible metadata version found: '{}'",
filename.display())));
}
let cvbuf1 = cvbuf.offset(vlen as isize); // Header is okay -> inflate the actual metadata
debug!("inflating {} bytes of compressed metadata", csz - vlen); let compressed_bytes = &buf[header_len..];
let bytes = slice::from_raw_parts(cvbuf1, csz - vlen); debug!("inflating {} bytes of compressed metadata", compressed_bytes.len());
match flate::inflate_bytes(bytes) { match flate::inflate_bytes(compressed_bytes) {
Ok(inflated) => { Ok(inflated) => {
let blob = MetadataBlob::Inflated(inflated); let buf = unsafe { OwningRef::new_assert_stable_address(inflated) };
verify_decompressed_encoding_version(&blob, filename)?; buf.map_owner_box().erase_owner()
return Ok(blob); }
} Err(_) => {
Err(_) => {} return Err(format!("failed to decompress metadata: {}", filename.display()));
} }
} }
llvm::LLVMMoveToNextSection(si.llsi);
} }
Err(format!("metadata not found: '{}'", filename.display())) CrateFlavor::Rmeta => {
} let mut file = File::open(filename).map_err(|_|
} format!("could not open file: '{}'", filename.display()))?;
let mut buf = vec![];
pub fn meta_section_name(target: &Target) -> &'static str { file.read_to_end(&mut buf).map_err(|_|
// Historical note: format!("failed to read rmeta metadata: '{}'", filename.display()))?;
// OwningRef::new(buf).map_owner_box().erase_owner()
// When using link.exe it was seen that the section name `.note.rustc` }
// was getting shortened to `.note.ru`, and according to the PE and COFF };
// specification: let blob = MetadataBlob(raw_bytes);
// if blob.is_compatible() {
// > Executable images do not use a string table and do not support Ok(blob)
// > section names longer than 8 characters
//
// https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx
//
// As a result, we choose a slightly shorter name! As to why
// `.note.rustc` works on MinGW, that's another good question...
if target.options.is_like_osx {
"__DATA,.rustc"
} else { } else {
".rustc" Err(format!("incompatible metadata version found: '{}'", filename.display()))
} }
} }
pub fn read_meta_section_name(_target: &Target) -> &'static str {
".rustc"
}
// A diagnostic function for dumping crate metadata to an output stream // A diagnostic function for dumping crate metadata to an output stream
pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> io::Result<()> { pub fn list_file_metadata(target: &Target,
path: &Path,
loader: &MetadataLoader,
out: &mut io::Write)
-> io::Result<()> {
let filename = path.file_name().unwrap().to_str().unwrap(); let filename = path.file_name().unwrap().to_str().unwrap();
let flavor = if filename.ends_with(".rlib") { let flavor = if filename.ends_with(".rlib") {
CrateFlavor::Rlib CrateFlavor::Rlib
@ -1005,7 +902,7 @@ pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) ->
} else { } else {
CrateFlavor::Dylib CrateFlavor::Dylib
}; };
match get_metadata_section(target, flavor, path) { match get_metadata_section(target, flavor, path, loader) {
Ok(metadata) => metadata.list_crate_metadata(out), Ok(metadata) => metadata.list_crate_metadata(out),
Err(msg) => write!(out, "{}\n", msg), Err(msg) => write!(out, "{}\n", msg),
} }

View File

@ -12,6 +12,7 @@ test = false
[dependencies] [dependencies]
flate = { path = "../libflate" } flate = { path = "../libflate" }
log = "0.3" log = "0.3"
owning_ref = "0.3.3"
rustc = { path = "../librustc" } rustc = { path = "../librustc" }
rustc_back = { path = "../librustc_back" } rustc_back = { path = "../librustc_back" }
rustc_bitflags = { path = "../librustc_bitflags" } rustc_bitflags = { path = "../librustc_bitflags" }

View File

@ -20,6 +20,7 @@ use std::str;
use libc; use libc;
use llvm::archive_ro::{ArchiveRO, Child}; use llvm::archive_ro::{ArchiveRO, Child};
use llvm::{self, ArchiveKind}; use llvm::{self, ArchiveKind};
use metadata::METADATA_FILENAME;
use rustc::session::Session; use rustc::session::Session;
pub struct ArchiveConfig<'a> { pub struct ArchiveConfig<'a> {
@ -158,11 +159,9 @@ impl<'a> ArchiveBuilder<'a> {
// Ignoring all bytecode files, no matter of // Ignoring all bytecode files, no matter of
// name // name
let bc_ext = ".bytecode.deflate"; let bc_ext = ".bytecode.deflate";
let metadata_filename =
self.config.sess.cstore.metadata_filename().to_owned();
self.add_archive(rlib, move |fname: &str| { self.add_archive(rlib, move |fname: &str| {
if fname.ends_with(bc_ext) || fname == metadata_filename { if fname.ends_with(bc_ext) || fname == METADATA_FILENAME {
return true return true
} }

View File

@ -13,6 +13,7 @@ use super::linker::Linker;
use super::rpath::RPathConfig; use super::rpath::RPathConfig;
use super::rpath; use super::rpath;
use super::msvc; use super::msvc;
use metadata::METADATA_FILENAME;
use session::config; use session::config;
use session::config::NoDebugInfo; use session::config::NoDebugInfo;
use session::config::{OutputFilenames, Input, OutputType}; use session::config::{OutputFilenames, Input, OutputType};
@ -521,7 +522,7 @@ fn link_rlib<'a>(sess: &'a Session,
// contain the metadata in a separate file. We use a temp directory // contain the metadata in a separate file. We use a temp directory
// here so concurrent builds in the same directory don't try to use // here so concurrent builds in the same directory don't try to use
// the same filename for metadata (stomping over one another) // the same filename for metadata (stomping over one another)
let metadata = tmpdir.join(sess.cstore.metadata_filename()); let metadata = tmpdir.join(METADATA_FILENAME);
emit_metadata(sess, trans, &metadata); emit_metadata(sess, trans, &metadata);
ab.add_file(&metadata); ab.add_file(&metadata);
@ -1141,8 +1142,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
archive.update_symbols(); archive.update_symbols();
for f in archive.src_files() { for f in archive.src_files() {
if f.ends_with("bytecode.deflate") || if f.ends_with("bytecode.deflate") || f == METADATA_FILENAME {
f == sess.cstore.metadata_filename() {
archive.remove_file(&f); archive.remove_file(&f);
continue continue
} }
@ -1217,8 +1217,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
let mut any_objects = false; let mut any_objects = false;
for f in archive.src_files() { for f in archive.src_files() {
if f.ends_with("bytecode.deflate") || if f.ends_with("bytecode.deflate") || f == METADATA_FILENAME {
f == sess.cstore.metadata_filename() {
archive.remove_file(&f); archive.remove_file(&f);
continue continue
} }

View File

@ -34,6 +34,7 @@ use back::linker::LinkerInfo;
use back::symbol_export::{self, ExportedSymbols}; use back::symbol_export::{self, ExportedSymbols};
use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param}; use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param};
use llvm; use llvm;
use metadata;
use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::def_id::LOCAL_CRATE;
use middle::lang_items::StartFnLangItem; use middle::lang_items::StartFnLangItem;
use middle::cstore::EncodedMetadata; use middle::cstore::EncodedMetadata;
@ -778,8 +779,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
}; };
unsafe { unsafe {
llvm::LLVMSetInitializer(llglobal, llconst); llvm::LLVMSetInitializer(llglobal, llconst);
let section_name = let section_name = metadata::metadata_section_name(&tcx.sess.target.target);
tcx.sess.cstore.metadata_section_name(&tcx.sess.target.target);
let name = CString::new(section_name).unwrap(); let name = CString::new(section_name).unwrap();
llvm::LLVMSetSection(llglobal, name.as_ptr()); llvm::LLVMSetSection(llglobal, name.as_ptr());

View File

@ -45,6 +45,7 @@ use syntax_pos::symbol::Symbol;
extern crate flate; extern crate flate;
extern crate libc; extern crate libc;
extern crate owning_ref;
#[macro_use] extern crate rustc; #[macro_use] extern crate rustc;
extern crate rustc_back; extern crate rustc_back;
extern crate rustc_data_structures; extern crate rustc_data_structures;
@ -70,6 +71,8 @@ pub use rustc::util;
pub use base::trans_crate; pub use base::trans_crate;
pub use back::symbol_names::provide; pub use back::symbol_names::provide;
pub use metadata::LlvmMetadataLoader;
pub mod back { pub mod back {
pub use rustc::hir::svh; pub use rustc::hir::svh;
@ -120,6 +123,7 @@ mod declare;
mod glue; mod glue;
mod intrinsic; mod intrinsic;
mod machine; mod machine;
mod metadata;
mod meth; mod meth;
mod mir; mod mir;
mod monomorphize; mod monomorphize;

View File

@ -0,0 +1,122 @@
// 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.
use rustc::util::common;
use rustc::middle::cstore::MetadataLoader;
use rustc_back::target::Target;
use llvm;
use llvm::{False, ObjectFile, mk_section_iter};
use llvm::archive_ro::ArchiveRO;
use owning_ref::{ErasedBoxRef, OwningRef};
use std::path::Path;
use std::ptr;
use std::slice;
pub const METADATA_FILENAME: &str = "rust.metadata.bin";
pub struct LlvmMetadataLoader;
impl MetadataLoader for LlvmMetadataLoader {
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
// internally to read the file. We also avoid even using a memcpy by
// just keeping the archive along while the metadata is in use.
let archive = ArchiveRO::open(filename)
.map(|ar| OwningRef::new(box ar))
.ok_or_else(|| {
debug!("llvm didn't like `{}`", filename.display());
format!("failed to read rlib metadata: '{}'", filename.display())
})?;
let buf: OwningRef<_, [u8]> = archive
.try_map(|ar| {
ar.iter()
.filter_map(|s| s.ok())
.find(|sect| sect.name() == Some(METADATA_FILENAME))
.map(|s| s.data())
.ok_or_else(|| {
debug!("didn't find '{}' in the archive", METADATA_FILENAME);
format!("failed to read rlib metadata: '{}'",
filename.display())
})
})?;
Ok(buf.erase_owner())
}
fn get_dylib_metadata(&self,
target: &Target,
filename: &Path)
-> Result<ErasedBoxRef<[u8]>, String> {
unsafe {
let buf = common::path2cstr(filename);
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
if mb as isize == 0 {
return Err(format!("error reading library: '{}'", filename.display()));
}
let of = ObjectFile::new(mb)
.map(|of| OwningRef::new(box of))
.ok_or_else(|| format!("provided path not an object file: '{}'",
filename.display()))?;
let buf = of.try_map(|of| search_meta_section(of, target, filename))?;
Ok(buf.erase_owner())
}
}
}
fn search_meta_section<'a>(of: &'a ObjectFile,
target: &Target,
filename: &Path)
-> Result<&'a [u8], String> {
unsafe {
let si = mk_section_iter(of.llof);
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
let mut name_buf = ptr::null();
let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec();
let name = String::from_utf8(name).unwrap();
debug!("get_metadata_section: name {}", name);
if read_metadata_section_name(target) == name {
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
let csz = llvm::LLVMGetSectionSize(si.llsi) as usize;
// The buffer is valid while the object file is around
let buf: &'a [u8] = slice::from_raw_parts(cbuf as *const u8, csz);
return Ok(buf);
}
llvm::LLVMMoveToNextSection(si.llsi);
}
}
Err(format!("metadata not found: '{}'", filename.display()))
}
pub fn metadata_section_name(target: &Target) -> &'static str {
// Historical note:
//
// When using link.exe it was seen that the section name `.note.rustc`
// was getting shortened to `.note.ru`, and according to the PE and COFF
// specification:
//
// > Executable images do not use a string table and do not support
// > section names longer than 8 characters
//
// https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx
//
// As a result, we choose a slightly shorter name! As to why
// `.note.rustc` works on MinGW, that's another good question...
if target.options.is_like_osx {
"__DATA,.rustc"
} else {
".rustc"
}
}
fn read_metadata_section_name(_target: &Target) -> &'static str {
".rustc"
}

View File

@ -19,6 +19,7 @@ use rustc::ty::{self, TyCtxt, GlobalArenas};
use rustc::hir::map as hir_map; use rustc::hir::map as hir_map;
use rustc::lint; use rustc::lint;
use rustc::util::nodemap::FxHashMap; use rustc::util::nodemap::FxHashMap;
use rustc_trans;
use rustc_trans::back::link; use rustc_trans::back::link;
use rustc_resolve as resolve; use rustc_resolve as resolve;
use rustc_metadata::cstore::CStore; use rustc_metadata::cstore::CStore;
@ -138,7 +139,7 @@ pub fn run_core(search_paths: SearchPaths,
let dep_graph = DepGraph::new(false); let dep_graph = DepGraph::new(false);
let _ignore = dep_graph.in_ignore(); let _ignore = dep_graph.in_ignore();
let cstore = Rc::new(CStore::new(&dep_graph)); let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let mut sess = session::build_session_( let mut sess = session::build_session_(
sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone() sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone()
); );

View File

@ -34,6 +34,7 @@ use rustc_driver::{self, driver, Compilation};
use rustc_driver::driver::phase_2_configure_and_expand; use rustc_driver::driver::phase_2_configure_and_expand;
use rustc_metadata::cstore::CStore; use rustc_metadata::cstore::CStore;
use rustc_resolve::MakeGlobMap; use rustc_resolve::MakeGlobMap;
use rustc_trans;
use rustc_trans::back::link; use rustc_trans::back::link;
use syntax::ast; use syntax::ast;
use syntax::codemap::CodeMap; use syntax::codemap::CodeMap;
@ -81,7 +82,7 @@ pub fn run(input: &str,
let dep_graph = DepGraph::new(false); let dep_graph = DepGraph::new(false);
let _ignore = dep_graph.in_ignore(); let _ignore = dep_graph.in_ignore();
let cstore = Rc::new(CStore::new(&dep_graph)); let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let mut sess = session::build_session_( let mut sess = session::build_session_(
sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(), sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(),
); );
@ -229,7 +230,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter); let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter);
let dep_graph = DepGraph::new(false); let dep_graph = DepGraph::new(false);
let cstore = Rc::new(CStore::new(&dep_graph)); let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let mut sess = session::build_session_( let mut sess = session::build_session_(
sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(), sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(),
); );

View File

@ -15,6 +15,7 @@ extern crate rustc_driver;
extern crate rustc_lint; extern crate rustc_lint;
extern crate rustc_metadata; extern crate rustc_metadata;
extern crate rustc_errors; extern crate rustc_errors;
extern crate rustc_trans;
extern crate syntax; extern crate syntax;
use rustc::dep_graph::DepGraph; use rustc::dep_graph::DepGraph;
@ -58,7 +59,7 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) {
let descriptions = Registry::new(&rustc::DIAGNOSTICS); let descriptions = Registry::new(&rustc::DIAGNOSTICS);
let dep_graph = DepGraph::new(opts.build_dep_graph()); let dep_graph = DepGraph::new(opts.build_dep_graph());
let cstore = Rc::new(CStore::new(&dep_graph)); let cstore = Rc::new(CStore::new(&dep_graph, Box::new(rustc_trans::LlvmMetadataLoader)));
let sess = build_session(opts, &dep_graph, None, descriptions, cstore.clone()); let sess = build_session(opts, &dep_graph, None, descriptions, cstore.clone());
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
(sess, cstore) (sess, cstore)