Skip to content

Commit 1c12171

Browse files
committed
Don't error when adding a staticlib with bitcode files compiled by newer LLVM
1 parent 6dfeab5 commit 1c12171

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

compiler/rustc_codegen_llvm/src/back/archive.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)