diff options
| author | Graydon Hoare <graydon@mozilla.com> | 2012-09-05 15:27:22 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2012-09-05 16:53:55 -0700 |
| commit | 81695d85dc9a56392c13db918008d00a7de3c54f (patch) | |
| tree | 94a41efb009aedb16c7047900794660c7b1b92f2 /src/rustc | |
| parent | 31af60b257983da1a77336ee033406350eb14ee9 (diff) | |
| download | rust-81695d85dc9a56392c13db918008d00a7de3c54f.tar.gz rust-81695d85dc9a56392c13db918008d00a7de3c54f.zip | |
Mark crate metadata with a version tag. Close #3390.
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/metadata/encoder.rs | 21 | ||||
| -rw-r--r-- | src/rustc/metadata/loader.rs | 25 | ||||
| -rw-r--r-- | src/rustc/middle/trans/common.rs | 8 |
3 files changed, 49 insertions, 5 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 @@ -972,11 +972,17 @@ 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) }); |
