@@ -14,7 +14,7 @@ use tempfile::Builder as TempFileBuilder;
1414
1515use std:: error:: Error ;
1616use std:: fs:: File ;
17- use std:: io;
17+ use std:: io:: { self , Write } ;
1818use std:: path:: { Path , PathBuf } ;
1919
2020// Re-exporting for rustc_codegen_llvm::back::archive
@@ -116,42 +116,51 @@ impl<'a> ArArchiveBuilder<'a> {
116116 }
117117}
118118
119- fn try_filter_fat_archs < ' a > (
119+ fn try_filter_fat_archs (
120120 archs : object:: read:: Result < & [ impl FatArch ] > ,
121121 target_arch : object:: Architecture ,
122- archive_map_data : & ' a [ u8 ] ,
123- ) -> io:: Result < Option < ( & ' a [ u8 ] , u64 ) > > {
122+ archive_path : & Path ,
123+ archive_map_data : & [ u8 ] ,
124+ ) -> io:: Result < Option < PathBuf > > {
124125 let archs = archs. map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ?;
125126
126127 let desired = match archs. iter ( ) . find ( |a| a. architecture ( ) == target_arch) {
127128 Some ( a) => a,
128129 None => return Ok ( None ) ,
129130 } ;
130131
131- Ok ( Some ( (
132+ let ( mut new_f, extracted_path) = tempfile:: Builder :: new ( )
133+ . suffix ( archive_path. file_name ( ) . unwrap ( ) )
134+ . tempfile ( ) ?
135+ . keep ( )
136+ . unwrap ( ) ;
137+
138+ new_f. write_all (
132139 desired. data ( archive_map_data) . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ?,
133- desired. offset ( ) . into ( ) ,
134- ) ) )
140+ ) ?;
141+
142+ Ok ( Some ( extracted_path) )
135143}
136144
137- pub fn try_extract_macho_fat_archive < ' a > (
145+ pub fn try_extract_macho_fat_archive (
138146 sess : & Session ,
139- archive_bytes : & ' a [ u8 ] ,
140- ) -> io:: Result < Option < ( & ' a [ u8 ] , u64 ) > > {
147+ archive_path : & Path ,
148+ ) -> io:: Result < Option < PathBuf > > {
149+ let archive_map = unsafe { Mmap :: map ( File :: open ( & archive_path) ?) ? } ;
141150 let target_arch = match sess. target . arch . as_ref ( ) {
142151 "aarch64" => object:: Architecture :: Aarch64 ,
143152 "x86_64" => object:: Architecture :: X86_64 ,
144153 _ => return Ok ( None ) ,
145154 } ;
146155
147- match object:: macho:: FatHeader :: parse ( archive_bytes ) {
156+ match object:: macho:: FatHeader :: parse ( & * archive_map ) {
148157 Ok ( h) if h. magic . get ( object:: endian:: BigEndian ) == object:: macho:: FAT_MAGIC => {
149- let archs = object:: macho:: FatHeader :: parse_arch32 ( archive_bytes ) ;
150- try_filter_fat_archs ( archs, target_arch, archive_bytes )
158+ let archs = object:: macho:: FatHeader :: parse_arch32 ( & * archive_map ) ;
159+ try_filter_fat_archs ( archs, target_arch, archive_path , & * archive_map )
151160 }
152161 Ok ( h) if h. magic . get ( object:: endian:: BigEndian ) == object:: macho:: FAT_MAGIC_64 => {
153- let archs = object:: macho:: FatHeader :: parse_arch64 ( archive_bytes ) ;
154- try_filter_fat_archs ( archs, target_arch, archive_bytes )
162+ let archs = object:: macho:: FatHeader :: parse_arch64 ( & * archive_map ) ;
163+ try_filter_fat_archs ( archs, target_arch, archive_path , & * archive_map )
155164 }
156165 // Not a FatHeader at all, just return None.
157166 _ => Ok ( None ) ,
@@ -164,24 +173,21 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
164173 archive_path : & Path ,
165174 mut skip : Box < dyn FnMut ( & str ) -> bool + ' static > ,
166175 ) -> io:: Result < ( ) > {
167- let archive_map = unsafe { Mmap :: map ( File :: open ( & archive_path) ?) ? } ;
176+ let mut archive_path = archive_path. to_path_buf ( ) ;
177+ if self . sess . target . llvm_target . contains ( "-apple-macosx" ) {
178+ if let Some ( new_archive_path) =
179+ try_extract_macho_fat_archive ( & self . sess , & archive_path) ?
180+ {
181+ archive_path = new_archive_path
182+ }
183+ }
184+
168185 if self . src_archives . iter ( ) . any ( |archive| archive. 0 == archive_path) {
169186 return Ok ( ( ) ) ;
170187 }
171188
172- let ( archive_bytes, offset) = if self . sess . target . llvm_target . contains ( "-apple-macosx" ) {
173- if let Some ( ( sub_archive, archive_offset) ) =
174- try_extract_macho_fat_archive ( & self . sess , & * archive_map) ?
175- {
176- ( sub_archive, Some ( archive_offset) )
177- } else {
178- ( & * archive_map, None )
179- }
180- } else {
181- ( & * archive_map, None )
182- } ;
183-
184- let archive = ArchiveFile :: parse ( & * archive_bytes)
189+ let archive_map = unsafe { Mmap :: map ( File :: open ( & archive_path) ?) ? } ;
190+ let archive = ArchiveFile :: parse ( & * archive_map)
185191 . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
186192 let archive_index = self . src_archives . len ( ) ;
187193
@@ -190,13 +196,9 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
190196 let file_name = String :: from_utf8 ( entry. name ( ) . to_vec ( ) )
191197 . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
192198 if !skip ( & file_name) {
193- let mut range = entry. file_range ( ) ;
194- if let Some ( offset) = offset {
195- range. 0 += offset;
196- }
197199 self . entries . push ( (
198200 file_name. into_bytes ( ) ,
199- ArchiveEntry :: FromArchive { archive_index, file_range : range } ,
201+ ArchiveEntry :: FromArchive { archive_index, file_range : entry . file_range ( ) } ,
200202 ) ) ;
201203 }
202204 }
0 commit comments