@@ -15,8 +15,8 @@ use crate::errors::{
1515use crate :: llvm:: archive_ro:: { ArchiveRO , Child } ;
1616use crate :: llvm:: { self , ArchiveKind , LLVMMachineType , LLVMRustCOFFShortExport } ;
1717use 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 ,
2020} ;
2121use tracing:: trace;
2222
@@ -115,7 +115,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
115115 if true {
116116 Box :: new ( LlvmArchiveBuilder { sess, additions : Vec :: new ( ) } )
117117 } else {
118- Box :: new ( ArArchiveBuilder :: new ( sess, get_llvm_object_symbols ) )
118+ Box :: new ( ArArchiveBuilder :: new ( sess, & LLVM_OBJECT_READER ) )
119119 }
120120 }
121121
@@ -291,59 +291,84 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
291291
292292// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
293293// 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+
294312#[ deny( unsafe_op_in_unsafe_fn) ]
295313fn get_llvm_object_symbols (
296314 buf : & [ u8 ] ,
297315 f : & mut dyn FnMut ( & [ u8 ] ) -> io:: Result < ( ) > ,
298316) -> 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+ }
300320
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) ;
304322
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+ } ;
317332
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+ }
323338
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 ,
333344 }
345+ }
334346
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
344353 }
345354}
346355
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+
347372impl < ' a > LlvmArchiveBuilder < ' a > {
348373 fn build_with_llvm ( & mut self , output : & Path ) -> io:: Result < bool > {
349374 let kind = & * self . sess . target . archive_format ;
0 commit comments