@@ -29,12 +29,12 @@ use rustc_hir::LangItem;
29
29
use rustc_middle:: dep_graph:: WorkProduct ;
30
30
use rustc_middle:: middle:: dependency_format:: Dependencies ;
31
31
use rustc_middle:: ty:: query:: { ExternProviders , Providers } ;
32
+ use rustc_serialize:: { opaque, Decodable , Decoder , Encoder } ;
32
33
use rustc_session:: config:: { CrateType , OutputFilenames , OutputType , RUST_CGU_EXT } ;
33
34
use rustc_session:: cstore:: { self , CrateSource } ;
34
35
use rustc_session:: utils:: NativeLibKind ;
35
36
use rustc_span:: symbol:: Symbol ;
36
37
use std:: path:: { Path , PathBuf } ;
37
- use rustc_serialize:: { Decodable , Decoder , Encoder , opaque} ;
38
38
39
39
pub mod back;
40
40
pub mod base;
@@ -192,13 +192,18 @@ pub fn looks_like_rust_object_file(filename: &str) -> bool {
192
192
ext2 == Some ( RUST_CGU_EXT )
193
193
}
194
194
195
- const RLINK_MAGIC : & ' static [ u8 ; 5 ] = b"rlink" ;
195
+ const RLINK_VERSION : u32 = 1 ;
196
+ const RLINK_MAGIC : & [ u8 ] = b"rustlink" ;
197
+
196
198
const RUSTC_VERSION : Option < & str > = option_env ! ( "CFG_VERSION" ) ;
197
199
198
200
impl CodegenResults {
199
201
pub fn serialize_rlink ( codegen_results : & CodegenResults ) -> Vec < u8 > {
200
202
let mut encoder = opaque:: Encoder :: new ( vec ! [ ] ) ;
201
203
encoder. emit_raw_bytes ( RLINK_MAGIC ) . unwrap ( ) ;
204
+ // `emit_raw_bytes` is used to make sure that the version representation does not depend on
205
+ // Encoder's inner representation of `u32`.
206
+ encoder. emit_raw_bytes ( & RLINK_VERSION . to_be_bytes ( ) ) . unwrap ( ) ;
202
207
encoder. emit_str ( RUSTC_VERSION . unwrap ( ) ) . unwrap ( ) ;
203
208
204
209
let mut encoder = rustc_serialize:: opaque:: Encoder :: new ( encoder. into_inner ( ) ) ;
@@ -207,14 +212,29 @@ impl CodegenResults {
207
212
}
208
213
209
214
pub fn deserialize_rlink ( data : Vec < u8 > ) -> Result < Self , String > {
215
+ // The Decodable machinery is not used here because it panics if the input data is invalid
216
+ // and because its internal representation may change.
210
217
if !data. starts_with ( RLINK_MAGIC ) {
211
218
return Err ( "The input does not look like a .rlink file" . to_string ( ) ) ;
212
219
}
213
- let mut decoder = opaque:: Decoder :: new ( & data[ RLINK_MAGIC . len ( ) ..] , 0 ) ;
220
+ let data = & data[ RLINK_MAGIC . len ( ) ..] ;
221
+ if data. len ( ) < 4 {
222
+ return Err ( "The input does not contain version number" . to_string ( ) ) ;
223
+ }
224
+
225
+ let mut version_array: [ u8 ; 4 ] = Default :: default ( ) ;
226
+ version_array. copy_from_slice ( & data[ ..4 ] ) ;
227
+ if u32:: from_be_bytes ( version_array) != RLINK_VERSION {
228
+ return Err ( ".rlink file was produced with encoding version {version_array}, but the current version is {RLINK_VERSION}" . to_string ( ) ) ;
229
+ }
230
+
231
+ let mut decoder = opaque:: Decoder :: new ( & data[ 4 ..] , 0 ) ;
214
232
let rustc_version = decoder. read_str ( ) ;
215
233
let current_version = RUSTC_VERSION . unwrap ( ) ;
216
234
if rustc_version != current_version {
217
- return Err ( format ! ( ".rlink file was produced by rustc version {rustc_version}, but the current version is {current_version}." ) ) ;
235
+ return Err ( format ! (
236
+ ".rlink file was produced by rustc version {rustc_version}, but the current version is {current_version}."
237
+ ) ) ;
218
238
}
219
239
220
240
let codegen_results = CodegenResults :: decode ( & mut decoder) ;
0 commit comments