Skip to content

Commit 63f239c

Browse files
authored
Rollup merge of #124033 - bjorn3:ar_archive_writer_0_3_0, r=davidtwco
Sync ar_archive_writer to LLVM 18.1.3 From LLVM 15.0.0-rc3. This adds support for COFF archives containing Arm64EC object files and has various fixes for AIX big archive files.
2 parents 16b5690 + cd3f2f6 commit 63f239c

File tree

8 files changed

+205
-94
lines changed

8 files changed

+205
-94
lines changed

Diff for: Cargo.lock

+12-3
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,11 @@ checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69"
236236

237237
[[package]]
238238
name = "ar_archive_writer"
239-
version = "0.2.0"
239+
version = "0.3.0"
240240
source = "registry+https://github.com/rust-lang/crates.io-index"
241-
checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a"
241+
checksum = "f8412a2d690663356cba5a2532f3ed55d1e8090743bc6695b88403b27df67733"
242242
dependencies = [
243-
"object 0.32.2",
243+
"object 0.35.0",
244244
]
245245

246246
[[package]]
@@ -2648,6 +2648,15 @@ dependencies = [
26482648
"ruzstd 0.6.0",
26492649
]
26502650

2651+
[[package]]
2652+
name = "object"
2653+
version = "0.35.0"
2654+
source = "registry+https://github.com/rust-lang/crates.io-index"
2655+
checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e"
2656+
dependencies = [
2657+
"memchr",
2658+
]
2659+
26512660
[[package]]
26522661
name = "object"
26532662
version = "0.36.0"

Diff for: compiler/rustc_codegen_cranelift/src/archive.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use std::path::{Path, PathBuf};
22

33
use rustc_codegen_ssa::back::archive::{
4-
get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
4+
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
55
};
66
use rustc_session::Session;
77

88
pub(crate) struct ArArchiveBuilderBuilder;
99

1010
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
1111
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
12-
Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
12+
Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
1313
}
1414

1515
fn create_dll_import_lib(

Diff for: compiler/rustc_codegen_gcc/src/archive.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::path::{Path, PathBuf};
22

33
use rustc_codegen_ssa::back::archive::{
4-
get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
4+
ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
55
};
66
use rustc_session::Session;
77

@@ -11,7 +11,7 @@ pub(crate) struct ArArchiveBuilderBuilder;
1111

1212
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
1313
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
14-
Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
14+
Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
1515
}
1616

1717
fn create_dll_import_lib(

Diff for: compiler/rustc_codegen_llvm/src/back/archive.rs

+67-42
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::errors::{
1515
use crate::llvm::archive_ro::{ArchiveRO, Child};
1616
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
1717
use 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
};
2121
use 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)]
295313
fn 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+
347372
impl<'a> LlvmArchiveBuilder<'a> {
348373
fn build_with_llvm(&mut self, output: &Path) -> io::Result<bool> {
349374
let kind = &*self.sess.target.archive_format;

Diff for: compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2440,4 +2440,8 @@ extern "C" {
24402440
callback: GetSymbolsCallback,
24412441
error_callback: GetSymbolsErrorCallback,
24422442
) -> *mut c_void;
2443+
2444+
pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool;
2445+
2446+
pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool;
24432447
}

Diff for: compiler/rustc_codegen_ssa/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2021"
55

66
[dependencies]
77
# tidy-alphabetical-start
8-
ar_archive_writer = "0.2.0"
8+
ar_archive_writer = "0.3.0"
99
arrayvec = { version = "0.7", default-features = false }
1010
bitflags = "2.4.1"
1111
cc = "1.0.90"

Diff for: compiler/rustc_codegen_ssa/src/back/archive.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use rustc_span::symbol::Symbol;
66

77
use super::metadata::search_for_section;
88

9-
pub use ar_archive_writer::get_native_object_symbols;
109
use ar_archive_writer::{write_archive_to_stream, ArchiveKind, NewArchiveMember};
10+
pub use ar_archive_writer::{ObjectReader, DEFAULT_OBJECT_READER};
1111
use object::read::archive::ArchiveFile;
1212
use object::read::macho::FatArch;
1313
use tempfile::Builder as TempFileBuilder;
@@ -89,8 +89,7 @@ pub trait ArchiveBuilder {
8989
#[must_use = "must call build() to finish building the archive"]
9090
pub struct ArArchiveBuilder<'a> {
9191
sess: &'a Session,
92-
get_object_symbols:
93-
fn(buf: &[u8], f: &mut dyn FnMut(&[u8]) -> io::Result<()>) -> io::Result<bool>,
92+
object_reader: &'static ObjectReader,
9493

9594
src_archives: Vec<(PathBuf, Mmap)>,
9695
// Don't use an `HashMap` here, as the order is important. `lib.rmeta` needs
@@ -105,14 +104,8 @@ enum ArchiveEntry {
105104
}
106105

107106
impl<'a> ArArchiveBuilder<'a> {
108-
pub fn new(
109-
sess: &'a Session,
110-
get_object_symbols: fn(
111-
buf: &[u8],
112-
f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
113-
) -> io::Result<bool>,
114-
) -> ArArchiveBuilder<'a> {
115-
ArArchiveBuilder { sess, get_object_symbols, src_archives: vec![], entries: vec![] }
107+
pub fn new(sess: &'a Session, object_reader: &'static ObjectReader) -> ArArchiveBuilder<'a> {
108+
ArArchiveBuilder { sess, object_reader, src_archives: vec![], entries: vec![] }
116109
}
117110
}
118111

@@ -267,7 +260,7 @@ impl<'a> ArArchiveBuilder<'a> {
267260

268261
entries.push(NewArchiveMember {
269262
buf: data,
270-
get_symbols: self.get_object_symbols,
263+
object_reader: self.object_reader,
271264
member_name: String::from_utf8(entry_name).unwrap(),
272265
mtime: 0,
273266
uid: 0,
@@ -294,7 +287,13 @@ impl<'a> ArArchiveBuilder<'a> {
294287
let mut archive_tmpfile = File::create_new(&archive_tmpfile_path)
295288
.map_err(|err| io_error_context("couldn't create the temp file", err))?;
296289

297-
write_archive_to_stream(&mut archive_tmpfile, &entries, archive_kind, false)?;
290+
write_archive_to_stream(
291+
&mut archive_tmpfile,
292+
&entries,
293+
archive_kind,
294+
false,
295+
/* is_ec = */ self.sess.target.arch == "arm64ec",
296+
)?;
298297

299298
let any_entries = !entries.is_empty();
300299
drop(entries);

0 commit comments

Comments
 (0)