@@ -14,7 +14,7 @@ use tempfile::Builder as TempFileBuilder;
14
14
15
15
use std:: error:: Error ;
16
16
use std:: fs:: File ;
17
- use std:: io;
17
+ use std:: io:: { self , Write } ;
18
18
use std:: path:: { Path , PathBuf } ;
19
19
20
20
// Re-exporting for rustc_codegen_llvm::back::archive
@@ -116,42 +116,51 @@ impl<'a> ArArchiveBuilder<'a> {
116
116
}
117
117
}
118
118
119
- fn try_filter_fat_archs < ' a > (
119
+ fn try_filter_fat_archs (
120
120
archs : object:: read:: Result < & [ impl FatArch ] > ,
121
121
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 > > {
124
125
let archs = archs. map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ?;
125
126
126
127
let desired = match archs. iter ( ) . find ( |a| a. architecture ( ) == target_arch) {
127
128
Some ( a) => a,
128
129
None => return Ok ( None ) ,
129
130
} ;
130
131
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 (
132
139
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) )
135
143
}
136
144
137
- pub fn try_extract_macho_fat_archive < ' a > (
145
+ pub fn try_extract_macho_fat_archive (
138
146
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) ?) ? } ;
141
150
let target_arch = match sess. target . arch . as_ref ( ) {
142
151
"aarch64" => object:: Architecture :: Aarch64 ,
143
152
"x86_64" => object:: Architecture :: X86_64 ,
144
153
_ => return Ok ( None ) ,
145
154
} ;
146
155
147
- match object:: macho:: FatHeader :: parse ( archive_bytes ) {
156
+ match object:: macho:: FatHeader :: parse ( & * archive_map ) {
148
157
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 )
151
160
}
152
161
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 )
155
164
}
156
165
// Not a FatHeader at all, just return None.
157
166
_ => Ok ( None ) ,
@@ -164,24 +173,21 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
164
173
archive_path : & Path ,
165
174
mut skip : Box < dyn FnMut ( & str ) -> bool + ' static > ,
166
175
) -> 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
+
168
185
if self . src_archives . iter ( ) . any ( |archive| archive. 0 == archive_path) {
169
186
return Ok ( ( ) ) ;
170
187
}
171
188
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)
185
191
. map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
186
192
let archive_index = self . src_archives . len ( ) ;
187
193
@@ -190,13 +196,9 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
190
196
let file_name = String :: from_utf8 ( entry. name ( ) . to_vec ( ) )
191
197
. map_err ( |err| io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ?;
192
198
if !skip ( & file_name) {
193
- let mut range = entry. file_range ( ) ;
194
- if let Some ( offset) = offset {
195
- range. 0 += offset;
196
- }
197
199
self . entries . push ( (
198
200
file_name. into_bytes ( ) ,
199
- ArchiveEntry :: FromArchive { archive_index, file_range : range } ,
201
+ ArchiveEntry :: FromArchive { archive_index, file_range : entry . file_range ( ) } ,
200
202
) ) ;
201
203
}
202
204
}
0 commit comments