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