@@ -14,7 +14,7 @@ use tempfile::Builder as TempFileBuilder;
1414
1515use std:: error:: Error ;
1616use std:: fs:: File ;
17- use std:: io:: { self , Write } ;
17+ use std:: io;
1818use std:: path:: { Path , PathBuf } ;
1919
2020// Re-exporting for rustc_codegen_llvm::back::archive
@@ -116,51 +116,42 @@ impl<'a> ArArchiveBuilder<'a> {
116116 }
117117}
118118
119- fn try_filter_fat_archs (
119+ fn try_filter_fat_archs < ' a > (
120120 archs : object:: read:: Result < & [ impl FatArch ] > ,
121121 target_arch : object:: Architecture ,
122- archive_path : & Path ,
123- archive_map_data : & [ u8 ] ,
124- ) -> io:: Result < Option < PathBuf > > {
122+ archive_map_data : & ' a [ u8 ] ,
123+ ) -> io:: Result < Option < ( & ' a [ u8 ] , u64 ) > > {
125124 let archs = archs. map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ?;
126125
127126 let desired = match archs. iter ( ) . filter ( |a| a. architecture ( ) == target_arch) . next ( ) {
128127 Some ( a) => a,
129128 None => return Ok ( None ) ,
130129 } ;
131130
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 (
131+ Ok ( Some ( (
139132 desired. data ( archive_map_data) . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ?,
140- ) ?;
141-
142- Ok ( Some ( extracted_path) )
133+ desired. offset ( ) . into ( ) ,
134+ ) ) )
143135}
144136
145- pub fn try_extract_macho_fat_archive (
137+ pub fn try_extract_macho_fat_archive < ' a > (
146138 sess : & Session ,
147- archive_path : & Path ,
148- ) -> io:: Result < Option < PathBuf > > {
149- let archive_map = unsafe { Mmap :: map ( File :: open ( & archive_path) ?) ? } ;
139+ archive_bytes : & ' a [ u8 ] ,
140+ ) -> io:: Result < Option < ( & ' a [ u8 ] , u64 ) > > {
150141 let target_arch = match sess. target . arch . as_ref ( ) {
151142 "aarch64" => object:: Architecture :: Aarch64 ,
152143 "x86_64" => object:: Architecture :: X86_64 ,
153144 _ => return Ok ( None ) ,
154145 } ;
155146
156- match object:: macho:: FatHeader :: parse ( & * archive_map ) {
147+ match object:: macho:: FatHeader :: parse ( archive_bytes ) {
157148 Ok ( h) if h. magic . get ( object:: endian:: BigEndian ) == object:: macho:: FAT_MAGIC => {
158- let archs = object:: macho:: FatHeader :: parse_arch32 ( & * archive_map ) ;
159- try_filter_fat_archs ( archs, target_arch, archive_path , & * archive_map )
149+ let archs = object:: macho:: FatHeader :: parse_arch32 ( archive_bytes ) ;
150+ try_filter_fat_archs ( archs, target_arch, archive_bytes )
160151 }
161152 Ok ( h) if h. magic . get ( object:: endian:: BigEndian ) == object:: macho:: FAT_MAGIC_64 => {
162- let archs = object:: macho:: FatHeader :: parse_arch64 ( & * archive_map ) ;
163- try_filter_fat_archs ( archs, target_arch, archive_path , & * archive_map )
153+ let archs = object:: macho:: FatHeader :: parse_arch64 ( archive_bytes ) ;
154+ try_filter_fat_archs ( archs, target_arch, archive_bytes )
164155 }
165156 // Not a FatHeader at all, just return None.
166157 _ => Ok ( None ) ,
@@ -173,21 +164,24 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
173164 archive_path : & Path ,
174165 mut skip : Box < dyn FnMut ( & str ) -> bool + ' static > ,
175166 ) -> io:: Result < ( ) > {
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-
167+ let archive_map = unsafe { Mmap :: map ( File :: open ( & archive_path) ?) ? } ;
185168 if self . src_archives . iter ( ) . any ( |archive| archive. 0 == archive_path) {
186169 return Ok ( ( ) ) ;
187170 }
188171
189- let archive_map = unsafe { Mmap :: map ( File :: open ( & archive_path) ?) ? } ;
190- let archive = ArchiveFile :: parse ( & * archive_map)
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)
191185 . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
192186 let archive_index = self . src_archives . len ( ) ;
193187
@@ -196,9 +190,13 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
196190 let file_name = String :: from_utf8 ( entry. name ( ) . to_vec ( ) )
197191 . map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
198192 if !skip ( & file_name) {
193+ let mut range = entry. file_range ( ) ;
194+ if let Some ( offset) = offset {
195+ range. 0 += offset;
196+ }
199197 self . entries . push ( (
200198 file_name. into_bytes ( ) ,
201- ArchiveEntry :: FromArchive { archive_index, file_range : entry . file_range ( ) } ,
199+ ArchiveEntry :: FromArchive { archive_index, file_range : range } ,
202200 ) ) ;
203201 }
204202 }
0 commit comments