From 81695d85dc9a56392c13db918008d00a7de3c54f Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 5 Sep 2012 15:27:22 -0700 Subject: [PATCH] Mark crate metadata with a version tag. Close #3390. --- src/rustc/metadata/encoder.rs | 21 ++++++++++++++++++++- src/rustc/metadata/loader.rs | 25 ++++++++++++++++++++++--- src/rustc/middle/trans/common.rs | 8 +++++++- src/test/compile-fail/bad-module.rs | 2 +- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 090fa67b79a..b1b5e081a80 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -27,6 +27,7 @@ export encode_metadata; export encoded_ty; export reachable; export encode_inlined_item; +export metadata_encoding_version; // used by astencode: export def_to_str; @@ -1084,6 +1085,13 @@ fn encode_hash(ebml_w: ebml::Writer, hash: ~str) { ebml_w.end_tag(); } +// NB: Increment this as you change the metadata encoding version. +const metadata_encoding_version : &[u8] = &[0x72, //'r' as u8, + 0x75, //'u' as u8, + 0x73, //'s' as u8, + 0x74, //'t' as u8, + 0, 0, 0, 1 ]; + fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { let buf = io::mem_buffer(); let stats = @@ -1163,7 +1171,18 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { // Pad this, since something (LLVM, presumably) is cutting off the // remaining % 4 bytes. buf_w.write(&[0u8, 0u8, 0u8, 0u8]); - flate::deflate_buf(io::mem_buffer_buf(buf)) + + // FIXME #3396: weird bug here, for reasons unclear this emits random + // looking bytes (mostly 0x1) if we use the version byte-array constant + // above; so we use a string constant inline instead. + // + // Should be: + // + // vec::from_slice(metadata_encoding_version) + + + (do str::as_bytes(~"rust\x00\x00\x00\x01") |bytes| { + vec::slice(bytes, 0, 8) + }) + flate::deflate_buf(io::mem_buffer_buf(buf)) } // Get the encoded string for a type diff --git a/src/rustc/metadata/loader.rs b/src/rustc/metadata/loader.rs index c6f53377f1f..2c16e6a4206 100644 --- a/src/rustc/metadata/loader.rs +++ b/src/rustc/metadata/loader.rs @@ -185,11 +185,30 @@ fn get_metadata_section(os: os, if name == meta_section_name(os) { let cbuf = llvm::LLVMGetSectionContents(si.llsi); let csz = llvm::LLVMGetSectionSize(si.llsi) as uint; + let mut found = None; unsafe { let cvbuf: *u8 = unsafe::reinterpret_cast(&cbuf); - let v = vec::unsafe::from_buf(cvbuf, csz); - let inflated = flate::inflate_buf(v); - return Some(@inflated); + let vlen = vec::len(encoder::metadata_encoding_version); + debug!("checking %u bytes of metadata-version stamp", + vlen); + let minsz = uint::min(vlen, csz); + let mut version_ok = false; + do vec::unsafe::form_slice(cvbuf, minsz) |buf0| { + version_ok = (buf0 == + encoder::metadata_encoding_version); + } + if !version_ok { return None; } + + let cvbuf1 = ptr::offset(cvbuf, vlen); + debug!("inflating %u bytes of compressed metadata", + csz - vlen); + do vec::unsafe::form_slice(cvbuf1, csz-vlen) |buf| { + let inflated = flate::inflate_buf(buf); + found = move Some(@(move inflated)); + } + if found != None { + return found; + } } } llvm::LLVMMoveToNextSection(si.llsi); diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs index 71e1ba8ac16..6edccf0edec 100644 --- a/src/rustc/middle/trans/common.rs +++ b/src/rustc/middle/trans/common.rs @@ -970,13 +970,19 @@ fn C_array(ty: TypeRef, elts: ~[ValueRef]) -> ValueRef unsafe { } fn C_bytes(bytes: ~[u8]) -> ValueRef unsafe { + return llvm::LLVMConstString( + unsafe::reinterpret_cast(&vec::unsafe::to_ptr(bytes)), + bytes.len() as c_uint, True); +} + +fn C_bytes_plus_null(bytes: ~[u8]) -> ValueRef unsafe { return llvm::LLVMConstString( unsafe::reinterpret_cast(&vec::unsafe::to_ptr(bytes)), bytes.len() as c_uint, False); } fn C_shape(ccx: @crate_ctxt, bytes: ~[u8]) -> ValueRef { - let llshape = C_bytes(bytes); + let llshape = C_bytes_plus_null(bytes); let llglobal = str::as_c_str(fmt!("shape%u", ccx.names(~"shape")), |buf| { llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf) }); diff --git a/src/test/compile-fail/bad-module.rs b/src/test/compile-fail/bad-module.rs index 79f12293616..8a49ac79b8b 100644 --- a/src/test/compile-fail/bad-module.rs +++ b/src/test/compile-fail/bad-module.rs @@ -1,3 +1,3 @@ -// error-pattern: unresolved import +// error-pattern: unresolved name fn main() { let foo = thing::len(~[]); }