@@ -14,6 +14,7 @@ use rustc_codegen_ssa::traits::*;
1414use rustc_codegen_ssa:: { ModuleCodegen , ModuleKind , looks_like_rust_object_file} ;
1515use rustc_data_structures:: fx:: FxHashMap ;
1616use rustc_data_structures:: memmap:: Mmap ;
17+ use rustc_data_structures:: owned_slice:: { OwnedSlice , slice_owned} ;
1718use rustc_errors:: DiagCtxtHandle ;
1819use rustc_middle:: bug;
1920use rustc_middle:: dep_graph:: WorkProduct ;
@@ -56,10 +57,13 @@ fn prepare_lto(
5657 let mut upstream_modules = Vec :: new ( ) ;
5758 if cgcx. lto != Lto :: ThinLocal {
5859 for path in each_linked_rlib_for_lto {
59- let archive_data = unsafe {
60- Mmap :: map ( std:: fs:: File :: open ( & path) . expect ( "couldn't open rlib" ) )
61- . expect ( "couldn't map rlib" )
62- } ;
60+ let archive_data = slice_owned (
61+ unsafe {
62+ Mmap :: map ( std:: fs:: File :: open ( & path) . expect ( "couldn't open rlib" ) )
63+ . expect ( "couldn't map rlib" )
64+ } ,
65+ |data| & * data,
66+ ) ;
6367 let archive = ArchiveFile :: parse ( & * archive_data) . expect ( "wanted an rlib" ) ;
6468 let obj_files = archive
6569 . members ( )
@@ -71,12 +75,14 @@ fn prepare_lto(
7175 . filter ( |& ( name, _) | looks_like_rust_object_file ( name) ) ;
7276 for ( name, child) in obj_files {
7377 info ! ( "adding bitcode from {}" , name) ;
74- match get_bitcode_slice_from_object_data (
75- child. data ( & * archive_data) . expect ( "corrupt rlib" ) ,
76- cgcx,
77- ) {
78+ let ( offset, size) = child. file_range ( ) ;
79+ let child_data = archive_data. clone ( ) . slice ( |data| {
80+ data. get ( offset as usize ..offset as usize + size as usize )
81+ . expect ( "corrupt rlib" )
82+ } ) ;
83+ match get_bitcode_slice_from_object_data ( child_data, cgcx) {
7884 Ok ( data) => {
79- let module = SerializedModule :: FromRlib ( data. to_vec ( ) ) ;
85+ let module = SerializedModule :: FromFile ( data) ;
8086 upstream_modules. push ( ( module, CString :: new ( name) . unwrap ( ) ) ) ;
8187 }
8288 Err ( e) => dcx. emit_fatal ( e) ,
@@ -88,29 +94,33 @@ fn prepare_lto(
8894 ( symbols_below_threshold, upstream_modules)
8995}
9096
91- fn get_bitcode_slice_from_object_data < ' a > (
92- obj : & ' a [ u8 ] ,
97+ fn get_bitcode_slice_from_object_data (
98+ data : OwnedSlice ,
9399 cgcx : & CodegenContext < LlvmCodegenBackend > ,
94- ) -> Result < & ' a [ u8 ] , LtoBitcodeFromRlib > {
100+ ) -> Result < OwnedSlice , LtoBitcodeFromRlib > {
95101 // We're about to assume the data here is an object file with sections, but if it's raw LLVM IR
96102 // that won't work. Fortunately, if that's what we have we can just return the object directly,
97103 // so we sniff the relevant magic strings here and return.
98- if obj . starts_with ( b"\xDE \xC0 \x17 \x0B " ) || obj . starts_with ( b"BC\xC0 \xDE " ) {
99- return Ok ( obj ) ;
104+ if data . starts_with ( b"\xDE \xC0 \x17 \x0B " ) || data . starts_with ( b"BC\xC0 \xDE " ) {
105+ return Ok ( data ) ;
100106 }
101107 // We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment
102108 // name" which in the public API for sections gets treated as part of the section name, but
103109 // internally in MachOObjectFile.cpp gets treated separately.
104110 let section_name = bitcode_section_name ( cgcx) . to_str ( ) . unwrap ( ) . trim_start_matches ( "__LLVM," ) ;
105111
106112 let obj =
107- object:: File :: parse ( obj ) . map_err ( |err| LtoBitcodeFromRlib { err : err. to_string ( ) } ) ?;
113+ object:: File :: parse ( & * data ) . map_err ( |err| LtoBitcodeFromRlib { err : err. to_string ( ) } ) ?;
108114
109115 let section = obj
110116 . section_by_name ( section_name)
111117 . ok_or_else ( || LtoBitcodeFromRlib { err : format ! ( "Can't find section {section_name}" ) } ) ?;
112118
113- section. data ( ) . map_err ( |err| LtoBitcodeFromRlib { err : err. to_string ( ) } )
119+ if let Some ( ( offset, size) ) = section. file_range ( ) {
120+ Ok ( data. slice ( |data| & data[ offset as usize ..offset as usize + size as usize ] ) )
121+ } else {
122+ Err ( LtoBitcodeFromRlib { err : format ! ( "Section {section_name} doesn't have contents" ) } )
123+ }
114124}
115125
116126/// Performs fat LTO by merging all modules into a single one and returning it
0 commit comments