Skip to content

Commit 3992114

Browse files
authored
Unrolled build for rust-lang#137017
Rollup merge of rust-lang#137017 - bjorn3:ignore_invalid_bitcode, r=oli-obk Don't error when adding a staticlib with bitcode files compiled by newer LLVM cc rust-lang#128955 (comment)
2 parents aa3c2d7 + 9f190d7 commit 3992114

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

compiler/rustc_codegen_llvm/src/back/archive.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,33 @@ 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 io::Error) };
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'B', b'C', 0xC0, 0xDE])
139+
{
140+
// For LLVM bitcode, failure to read the symbols is not fatal. The bitcode may have been
141+
// produced by a newer LLVM version that the one linked to rustc. This is fine provided
142+
// that the linker does use said newer LLVM version. We skip writing the symbols for the
143+
// bitcode to the symbol table of the archive. Traditional linkers don't like this, but
144+
// newer linkers like lld, mold and wild ignore the symbol table anyway, so if they link
145+
// against a new enough LLVM it will work out in the end.
146+
// LLVM's archive writer also has this same behavior of only warning about invalid
147+
// bitcode since https://github.com/llvm/llvm-project/pull/96848
148+
149+
// We don't have access to the DiagCtxt here to produce a nice warning in the correct format.
150+
eprintln!("warning: Failed to read symbol table from LLVM bitcode: {}", error);
151+
return Ok(true);
152+
} else {
153+
return Err(error);
154+
}
136155
}
137156

138157
unsafe extern "C" fn callback(state: *mut c_void, symbol_name: *const c_char) -> *mut c_void {
139158
let f = unsafe { &mut *(state as *mut &mut dyn FnMut(&[u8]) -> io::Result<()>) };
140159
match f(unsafe { CStr::from_ptr(symbol_name) }.to_bytes()) {
141160
Ok(()) => std::ptr::null_mut(),
142-
Err(err) => Box::into_raw(Box::new(err)) as *mut c_void,
161+
Err(err) => Box::into_raw(Box::new(err) as Box<io::Error>) as *mut c_void,
143162
}
144163
}
145164

@@ -148,7 +167,7 @@ fn get_llvm_object_symbols(
148167
Box::into_raw(Box::new(io::Error::new(
149168
io::ErrorKind::Other,
150169
format!("LLVM error: {}", error.to_string_lossy()),
151-
))) as *mut c_void
170+
)) as Box<io::Error>) as *mut c_void
152171
}
153172
}
154173

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Regression test for https://github.com/rust-lang/rust/issues/128955#issuecomment-2657811196
2+
// which checks that rustc can read an archive containing LLVM bitcode with a
3+
// newer version from the one rustc links against.
4+
use run_make_support::{llvm_ar, path, rfs, rustc, static_lib_name};
5+
6+
fn main() {
7+
rfs::create_dir("archive");
8+
9+
let mut bitcode = b"BC\xC0\xDE".to_vec();
10+
bitcode.extend(std::iter::repeat(b'a').take(50));
11+
rfs::write("archive/invalid_bitcode.o", &bitcode);
12+
13+
llvm_ar()
14+
.arg("rcuS") // like obj_to_ar() except skips creating a symbol table
15+
.output_input(
16+
path("archive").join(static_lib_name("thin_archive")),
17+
"archive/invalid_bitcode.o",
18+
)
19+
.run();
20+
21+
// Build an rlib which includes the members of this thin archive
22+
rustc().input("rust_lib.rs").library_search_path("archive").run();
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![crate_type = "rlib"]
2+
3+
#[link(name = "thin_archive", kind = "static")]
4+
extern "C" {
5+
pub fn simple_fn();
6+
}

0 commit comments

Comments
 (0)