提交 5d1d2856 编写于 作者: B bors

auto merge of #12758 : rgawdzik/rust/master, r=alexcrichton

Refactored get_metadata_section to return a Result<MetadataBlob,~str> instead of a Option<MetadataBlob>. This provides more clarity to the user through the debug output when using --ls.

This is kind of a continuation of my original closed pull request 2 months ago (#11544), but I think the time-span constitutes a new pull request.
...@@ -299,9 +299,9 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str, ...@@ -299,9 +299,9 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
let lib = m.move_iter().next().unwrap(); let lib = m.move_iter().next().unwrap();
if slot.is_none() { if slot.is_none() {
info!("{} reading meatadata from: {}", flavor, lib.display()); info!("{} reading metadata from: {}", flavor, lib.display());
match get_metadata_section(self.os, &lib) { match get_metadata_section(self.os, &lib) {
Some(blob) => { Ok(blob) => {
if self.crate_matches(blob.as_slice()) { if self.crate_matches(blob.as_slice()) {
*slot = Some(blob); *slot = Some(blob);
} else { } else {
...@@ -309,7 +309,7 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str, ...@@ -309,7 +309,7 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
return None; return None;
} }
} }
None => { Err(_) => {
info!("no metadata found"); info!("no metadata found");
return None return None
} }
...@@ -388,7 +388,7 @@ pub fn as_slice<'a>(&'a self) -> &'a [u8] { self.data } ...@@ -388,7 +388,7 @@ pub fn as_slice<'a>(&'a self) -> &'a [u8] { self.data }
} }
// 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(os: Os, filename: &Path) -> Option<MetadataBlob> { fn get_metadata_section(os: Os, filename: &Path) -> Result<MetadataBlob, ~str> {
let start = time::precise_time_ns(); let start = time::precise_time_ns();
let ret = get_metadata_section_imp(os, filename); let ret = get_metadata_section_imp(os, filename);
info!("reading {} => {}ms", filename.filename_display(), info!("reading {} => {}ms", filename.filename_display(),
...@@ -396,7 +396,10 @@ fn get_metadata_section(os: Os, filename: &Path) -> Option<MetadataBlob> { ...@@ -396,7 +396,10 @@ fn get_metadata_section(os: Os, filename: &Path) -> Option<MetadataBlob> {
return ret; return ret;
} }
fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> { fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, ~str> {
if !filename.exists() {
return Err(format!("no such file: '{}'", filename.display()));
}
if filename.filename_str().unwrap().ends_with(".rlib") { if filename.filename_str().unwrap().ends_with(".rlib") {
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap // 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 // internally to read the file. We also avoid even using a memcpy by
...@@ -405,19 +408,26 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> { ...@@ -405,19 +408,26 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> {
Some(ar) => ar, Some(ar) => ar,
None => { None => {
debug!("llvm didn't like `{}`", filename.display()); debug!("llvm didn't like `{}`", filename.display());
return None; return Err(format!("failed to read rlib metadata: '{}'",
filename.display()));
} }
}; };
return ArchiveMetadata::new(archive).map(|ar| MetadataArchive(ar)); return match ArchiveMetadata::new(archive).map(|ar| MetadataArchive(ar)) {
None => return Err(format!("failed to read rlib metadata: '{}'",
filename.display())),
Some(blob) => return Ok(blob)
}
} }
unsafe { unsafe {
let mb = filename.with_c_str(|buf| { let mb = filename.with_c_str(|buf| {
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf) llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
}); });
if mb as int == 0 { return None } if mb as int == 0 {
return Err(format!("error reading library: '{}'",filename.display()))
}
let of = match ObjectFile::new(mb) { let of = match ObjectFile::new(mb) {
Some(of) => of, Some(of) => of,
_ => return None _ => return Err(format!("provided path not an object file: '{}'", filename.display()))
}; };
let si = mk_section_iter(of.llof); let si = mk_section_iter(of.llof);
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
...@@ -427,7 +437,7 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> { ...@@ -427,7 +437,7 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> {
if read_meta_section_name(os) == name { if read_meta_section_name(os) == name {
let cbuf = llvm::LLVMGetSectionContents(si.llsi); let cbuf = llvm::LLVMGetSectionContents(si.llsi);
let csz = llvm::LLVMGetSectionSize(si.llsi) as uint; let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
let mut found = None; let mut found = Err(format!("metadata not found: '{}'", filename.display()));
let cvbuf: *u8 = cast::transmute(cbuf); let cvbuf: *u8 = cast::transmute(cbuf);
let vlen = encoder::metadata_encoding_version.len(); let vlen = encoder::metadata_encoding_version.len();
debug!("checking {} bytes of metadata-version stamp", debug!("checking {} bytes of metadata-version stamp",
...@@ -435,22 +445,23 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> { ...@@ -435,22 +445,23 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> {
let minsz = cmp::min(vlen, csz); let minsz = cmp::min(vlen, csz);
let version_ok = vec::raw::buf_as_slice(cvbuf, minsz, let version_ok = vec::raw::buf_as_slice(cvbuf, minsz,
|buf0| buf0 == encoder::metadata_encoding_version); |buf0| buf0 == encoder::metadata_encoding_version);
if !version_ok { return None; } if !version_ok { return Err(format!("incompatible metadata version found: '{}'",
filename.display()));}
let cvbuf1 = cvbuf.offset(vlen as int); let cvbuf1 = cvbuf.offset(vlen as int);
debug!("inflating {} bytes of compressed metadata", debug!("inflating {} bytes of compressed metadata",
csz - vlen); csz - vlen);
vec::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| { vec::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {
let inflated = flate::inflate_bytes(bytes); let inflated = flate::inflate_bytes(bytes);
found = Some(MetadataVec(inflated)); found = Ok(MetadataVec(inflated));
}); });
if found.is_some() { if found.is_ok() {
return found; return found;
} }
} }
llvm::LLVMMoveToNextSection(si.llsi); llvm::LLVMMoveToNextSection(si.llsi);
} }
return None; return Err(format!("metadata not found: '{}'", filename.display()));
} }
} }
...@@ -478,9 +489,9 @@ pub fn read_meta_section_name(os: Os) -> &'static str { ...@@ -478,9 +489,9 @@ pub fn read_meta_section_name(os: Os) -> &'static str {
pub fn list_file_metadata(os: Os, path: &Path, pub fn list_file_metadata(os: Os, path: &Path,
out: &mut io::Writer) -> io::IoResult<()> { out: &mut io::Writer) -> io::IoResult<()> {
match get_metadata_section(os, path) { match get_metadata_section(os, path) {
Some(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out), Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),
None => { Err(msg) => {
write!(out, "could not find metadata in {}.\n", path.display()) write!(out, "{}\n", msg)
} }
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册