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