@@ -132,7 +132,25 @@ fn get_llvm_object_symbols(
132132 if err. is_null ( ) {
133133 return Ok ( true ) ;
134134 } else {
135- return Err ( unsafe { * Box :: from_raw ( err as * mut io:: Error ) } ) ;
135+ let error = unsafe { * Box :: from_raw ( err as * mut String ) } ;
136+ // These are the magic constants for LLVM bitcode files:
137+ // https://github.com/llvm/llvm-project/blob/7eadc1960d199676f04add402bb0aa6f65b7b234/llvm/lib/BinaryFormat/Magic.cpp#L90-L97
138+ if buf. starts_with ( & [ 0xDE , 0xCE , 0x17 , 0x0B ] ) || buf. starts_with ( b"BC\xC0 \xDE " ) {
139+ // For LLVM bitcode, failure to read the symbols is not fatal. The bitcode may have been
140+ // produced by a newer LLVM version that the one linked to rustc. This is fine provided
141+ // that the linker does use said newer LLVM version. We skip writing the symbols for the
142+ // bitcode to the symbol table of the archive. Traditional linkers don't like this, but
143+ // newer linkers like lld, mold and wild ignore the symbol table anyway, so if they link
144+ // against a new enough LLVM it will work out in the end.
145+ // LLVM's archive writer also has this same behavior of only warning about invalid
146+ // bitcode since https://github.com/llvm/llvm-project/pull/96848
147+
148+ // We don't have access to the DiagCtxt here to produce a nice warning in the correct format.
149+ eprintln ! ( "warning: Failed to read symbol table from LLVM bitcode: {}" , error) ;
150+ return Ok ( true ) ;
151+ } else {
152+ return Err ( io:: Error :: new ( io:: ErrorKind :: Other , format ! ( "LLVM error: {}" , error) ) ) ;
153+ }
136154 }
137155
138156 unsafe extern "C" fn callback ( state : * mut c_void , symbol_name : * const c_char ) -> * mut c_void {
@@ -145,10 +163,7 @@ fn get_llvm_object_symbols(
145163
146164 unsafe extern "C" fn error_callback ( error : * const c_char ) -> * mut c_void {
147165 let error = unsafe { CStr :: from_ptr ( error) } ;
148- Box :: into_raw ( Box :: new ( io:: Error :: new (
149- io:: ErrorKind :: Other ,
150- format ! ( "LLVM error: {}" , error. to_string_lossy( ) ) ,
151- ) ) ) as * mut c_void
166+ Box :: into_raw ( Box :: new ( error. to_string_lossy ( ) ) ) as * mut c_void
152167 }
153168}
154169
0 commit comments