@@ -15,8 +15,8 @@ use crate::errors::{
15
15
use crate :: llvm:: archive_ro:: { ArchiveRO , Child } ;
16
16
use crate :: llvm:: { self , ArchiveKind , LLVMMachineType , LLVMRustCOFFShortExport } ;
17
17
use rustc_codegen_ssa:: back:: archive:: {
18
- get_native_object_symbols , try_extract_macho_fat_archive, ArArchiveBuilder ,
19
- ArchiveBuildFailure , ArchiveBuilder , ArchiveBuilderBuilder , UnknownArchiveKind ,
18
+ try_extract_macho_fat_archive, ArArchiveBuilder , ArchiveBuildFailure , ArchiveBuilder ,
19
+ ArchiveBuilderBuilder , ObjectReader , UnknownArchiveKind , DEFAULT_OBJECT_READER ,
20
20
} ;
21
21
22
22
use rustc_session:: cstore:: DllImport ;
@@ -114,7 +114,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
114
114
if true {
115
115
Box :: new ( LlvmArchiveBuilder { sess, additions : Vec :: new ( ) } )
116
116
} else {
117
- Box :: new ( ArArchiveBuilder :: new ( sess, get_llvm_object_symbols ) )
117
+ Box :: new ( ArArchiveBuilder :: new ( sess, & LLVM_OBJECT_READER ) )
118
118
}
119
119
}
120
120
@@ -296,59 +296,84 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
296
296
297
297
// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
298
298
// As such we need to use LLVM for them.
299
+
300
+ static LLVM_OBJECT_READER : ObjectReader = ObjectReader {
301
+ get_symbols : get_llvm_object_symbols,
302
+ is_64_bit_object_file : llvm_is_64_bit_object_file,
303
+ is_ec_object_file : llvm_is_ec_object_file,
304
+ get_xcoff_member_alignment : DEFAULT_OBJECT_READER . get_xcoff_member_alignment ,
305
+ } ;
306
+
307
+ fn should_use_llvm_reader ( buf : & [ u8 ] ) -> bool {
308
+ let is_bitcode = unsafe { llvm:: LLVMRustIsBitcode ( buf. as_ptr ( ) , buf. len ( ) ) } ;
309
+
310
+ // COFF bigobj file, msvc LTO file or import library. See
311
+ // https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
312
+ let is_unsupported_windows_obj_file = buf. get ( 0 ..4 ) == Some ( b"\0 \0 \xFF \xFF " ) ;
313
+
314
+ is_bitcode || is_unsupported_windows_obj_file
315
+ }
316
+
299
317
#[ deny( unsafe_op_in_unsafe_fn) ]
300
318
fn get_llvm_object_symbols (
301
319
buf : & [ u8 ] ,
302
320
f : & mut dyn FnMut ( & [ u8 ] ) -> io:: Result < ( ) > ,
303
321
) -> io:: Result < bool > {
304
- let is_bitcode = unsafe { llvm:: LLVMRustIsBitcode ( buf. as_ptr ( ) , buf. len ( ) ) } ;
322
+ if !should_use_llvm_reader ( buf) {
323
+ return ( DEFAULT_OBJECT_READER . get_symbols ) ( buf, f) ;
324
+ }
305
325
306
- // COFF bigobj file, msvc LTO file or import library. See
307
- // https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
308
- let is_unsupported_windows_obj_file = buf. get ( 0 ..4 ) == Some ( b"\0 \0 \xFF \xFF " ) ;
326
+ let mut state = Box :: new ( f) ;
309
327
310
- if is_bitcode || is_unsupported_windows_obj_file {
311
- let mut state = Box :: new ( f) ;
312
-
313
- let err = unsafe {
314
- llvm:: LLVMRustGetSymbols (
315
- buf. as_ptr ( ) ,
316
- buf. len ( ) ,
317
- std:: ptr:: addr_of_mut!( * state) as * mut c_void ,
318
- callback,
319
- error_callback,
320
- )
321
- } ;
328
+ let err = unsafe {
329
+ llvm:: LLVMRustGetSymbols (
330
+ buf. as_ptr ( ) ,
331
+ buf. len ( ) ,
332
+ std:: ptr:: addr_of_mut!( * state) as * mut c_void ,
333
+ callback,
334
+ error_callback,
335
+ )
336
+ } ;
322
337
323
- if err. is_null ( ) {
324
- return Ok ( true ) ;
325
- } else {
326
- return Err ( unsafe { * Box :: from_raw ( err as * mut io:: Error ) } ) ;
327
- }
338
+ if err. is_null ( ) {
339
+ return Ok ( true ) ;
340
+ } else {
341
+ return Err ( unsafe { * Box :: from_raw ( err as * mut io:: Error ) } ) ;
342
+ }
328
343
329
- unsafe extern "C" fn callback (
330
- state : * mut c_void ,
331
- symbol_name : * const c_char ,
332
- ) -> * mut c_void {
333
- let f = unsafe { & mut * ( state as * mut & mut dyn FnMut ( & [ u8 ] ) -> io:: Result < ( ) > ) } ;
334
- match f ( unsafe { CStr :: from_ptr ( symbol_name) } . to_bytes ( ) ) {
335
- Ok ( ( ) ) => std:: ptr:: null_mut ( ) ,
336
- Err ( err) => Box :: into_raw ( Box :: new ( err) ) as * mut c_void ,
337
- }
344
+ unsafe extern "C" fn callback ( state : * mut c_void , symbol_name : * const c_char ) -> * mut c_void {
345
+ let f = unsafe { & mut * ( state as * mut & mut dyn FnMut ( & [ u8 ] ) -> io:: Result < ( ) > ) } ;
346
+ match f ( unsafe { CStr :: from_ptr ( symbol_name) } . to_bytes ( ) ) {
347
+ Ok ( ( ) ) => std:: ptr:: null_mut ( ) ,
348
+ Err ( err) => Box :: into_raw ( Box :: new ( err) ) as * mut c_void ,
338
349
}
350
+ }
339
351
340
- unsafe extern "C" fn error_callback ( error : * const c_char ) -> * mut c_void {
341
- let error = unsafe { CStr :: from_ptr ( error) } ;
342
- Box :: into_raw ( Box :: new ( io:: Error :: new (
343
- io:: ErrorKind :: Other ,
344
- format ! ( "LLVM error: {}" , error. to_string_lossy( ) ) ,
345
- ) ) ) as * mut c_void
346
- }
347
- } else {
348
- get_native_object_symbols ( buf, f)
352
+ unsafe extern "C" fn error_callback ( error : * const c_char ) -> * mut c_void {
353
+ let error = unsafe { CStr :: from_ptr ( error) } ;
354
+ Box :: into_raw ( Box :: new ( io:: Error :: new (
355
+ io:: ErrorKind :: Other ,
356
+ format ! ( "LLVM error: {}" , error. to_string_lossy( ) ) ,
357
+ ) ) ) as * mut c_void
349
358
}
350
359
}
351
360
361
+ fn llvm_is_64_bit_object_file ( buf : & [ u8 ] ) -> bool {
362
+ if !should_use_llvm_reader ( buf) {
363
+ return ( DEFAULT_OBJECT_READER . is_64_bit_object_file ) ( buf) ;
364
+ }
365
+
366
+ unsafe { llvm:: LLVMRustIs64BitSymbolicFile ( buf. as_ptr ( ) , buf. len ( ) ) }
367
+ }
368
+
369
+ fn llvm_is_ec_object_file ( buf : & [ u8 ] ) -> bool {
370
+ if !should_use_llvm_reader ( buf) {
371
+ return ( DEFAULT_OBJECT_READER . is_ec_object_file ) ( buf) ;
372
+ }
373
+
374
+ unsafe { llvm:: LLVMRustIsECObject ( buf. as_ptr ( ) , buf. len ( ) ) }
375
+ }
376
+
352
377
impl < ' a > LlvmArchiveBuilder < ' a > {
353
378
fn build_with_llvm ( & mut self , output : & Path ) -> io:: Result < bool > {
354
379
let kind = & * self . sess . target . archive_format ;
0 commit comments