about summary refs log tree commit diff
path: root/src/librustc_metadata
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2016-11-11 10:00:33 +1300
committerNick Cameron <ncameron@mozilla.com>2016-11-23 12:50:39 +1300
commitaf1b19555ce636788c19dba979b57536792d90e9 (patch)
treef9059918dedbaf3e22c775e1ba96c3f8188c9115 /src/librustc_metadata
parentbaedc3b70ff8ac14a1411b5780112eadd1d63413 (diff)
downloadrust-af1b19555ce636788c19dba979b57536792d90e9.tar.gz
rust-af1b19555ce636788c19dba979b57536792d90e9.zip
Rebasing and review changes
Diffstat (limited to 'src/librustc_metadata')
-rw-r--r--src/librustc_metadata/creader.rs3
-rw-r--r--src/librustc_metadata/cstore.rs3
-rw-r--r--src/librustc_metadata/decoder.rs3
-rw-r--r--src/librustc_metadata/locator.rs55
4 files changed, 38 insertions, 26 deletions
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 693b04ae661..12a70da636d 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -67,8 +67,7 @@ fn dump_crates(cstore: &CStore) {
         dylib.map(|dl| info!("  dylib: {}", dl.0.display()));
         rlib.map(|rl|  info!("   rlib: {}", rl.0.display()));
         rmeta.map(|rl| info!("   rmeta: {}", rl.0.display()));
-        });
-    })
+    });
 }
 
 #[derive(Debug)]
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index e5f7964d7eb..c2ed7ca7ce0 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -43,6 +43,7 @@ pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
 pub enum MetadataBlob {
     Inflated(Bytes),
     Archive(locator::ArchiveMetadata),
+    Raw(Vec<u8>),
 }
 
 /// Holds information about a syntax_pos::FileMap imported from another crate.
@@ -203,7 +204,7 @@ impl CStore {
                 let path = match path {
                     Some(p) => LibSource::Some(p),
                     None => {
-                        if data.rmeta.is_some() {
+                        if data.source.rmeta.is_some() {
                             LibSource::MetadataOnly
                         } else {
                             LibSource::None
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 3af9d291ae5..3ba899f41d8 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -88,8 +88,9 @@ pub trait Metadata<'a, 'tcx>: Copy {
 impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
     fn raw_bytes(self) -> &'a [u8] {
         match *self {
-            MetadataBlob::Inflated(ref vec) => &vec[..],
+            MetadataBlob::Inflated(ref vec) => vec,
             MetadataBlob::Archive(ref ar) => ar.as_slice(),
+            MetadataBlob::Raw(ref vec) => vec,
         }
     }
 }
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 6cdd8b46464..2b06851cb8b 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -53,8 +53,8 @@
 //! is a platform-defined dynamic library. Each library has a metadata somewhere
 //! inside of it.
 //!
-//! A third kind of dependency is an rmeta file. These are rlibs, which contain
-//! metadata, but no code. To a first approximation, these are treated in the
+//! A third kind of dependency is an rmeta file. These are metadata files and do
+//! not contain any code, etc. To a first approximation, these are treated in the
 //! same way as rlibs. Where there is both an rlib and an rmeta file, the rlib
 //! gets priority (even if the rmeta file is newer). An rmeta file is only
 //! useful for checking a downstream crate, attempting to link one will cause an
@@ -239,8 +239,8 @@ use rustc_back::target::Target;
 
 use std::cmp;
 use std::fmt;
-use std::fs;
-use std::io;
+use std::fs::{self, File};
+use std::io::{self, Read};
 use std::path::{Path, PathBuf};
 use std::ptr;
 use std::slice;
@@ -462,22 +462,23 @@ impl<'a> Context<'a> {
                 None => return FileDoesntMatch,
                 Some(file) => file,
             };
-            let (hash, found_kind) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
-                (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
-            } else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") {
-                (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
-            } else if file.starts_with(&dylib_prefix) &&
-                                         file.ends_with(&dypair.1) {
-                (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
-            } else {
-                if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
-                    staticlibs.push(CrateMismatch {
-                        path: path.to_path_buf(),
-                        got: "static".to_string(),
-                    });
-                }
-                return FileDoesntMatch;
-            };
+            let (hash, found_kind) =
+                if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
+                    (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
+                } else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") {
+                    (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
+                } else if file.starts_with(&dylib_prefix) &&
+                                             file.ends_with(&dypair.1) {
+                    (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
+                } else {
+                    if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
+                        staticlibs.push(CrateMismatch {
+                            path: path.to_path_buf(),
+                            got: "static".to_string(),
+                        });
+                    }
+                    return FileDoesntMatch;
+                };
             info!("lib candidate: {}", path.display());
 
             let hash_str = hash.to_string();
@@ -731,7 +732,8 @@ impl<'a> Context<'a> {
                         return false;
                     }
                 };
-                if file.starts_with("lib") && file.ends_with(".rlib") {
+                if file.starts_with("lib") &&
+                   (file.ends_with(".rlib") || file.ends_with(".rmeta")) {
                     return true;
                 } else {
                     let (ref prefix, ref suffix) = dylibname;
@@ -846,7 +848,7 @@ fn get_metadata_section_imp(target: &Target,
     if !filename.exists() {
         return Err(format!("no such file: '{}'", filename.display()));
     }
-    if flavor == CrateFlavor::Rlib || flavor == CrateFlavor::Rmeta {
+    if flavor == CrateFlavor::Rlib {
         // 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.
@@ -864,6 +866,15 @@ fn get_metadata_section_imp(target: &Target,
                 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);