@@ -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