Skip to content

Commit 32ded4b

Browse files
committed
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.
1 parent 1dea922 commit 32ded4b

File tree

8 files changed

+199
-94
lines changed

8 files changed

+199
-94
lines changed

Cargo.lock

+12-3
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,11 @@ dependencies = [
210210

211211
[[package]]
212212
name = "ar_archive_writer"
213-
version = "0.2.0"
213+
version = "0.3.0"
214214
source = "registry+https://github.com/rust-lang/crates.io-index"
215-
checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a"
215+
checksum = "f8412a2d690663356cba5a2532f3ed55d1e8090743bc6695b88403b27df67733"
216216
dependencies = [
217-
"object 0.32.2",
217+
"object 0.35.0",
218218
]
219219

220220
[[package]]
@@ -2658,6 +2658,15 @@ dependencies = [
26582658
"ruzstd 0.6.0",
26592659
]
26602660

2661+
[[package]]
2662+
name = "object"
2663+
version = "0.35.0"
2664+
source = "registry+https://github.com/rust-lang/crates.io-index"
2665+
checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e"
2666+
dependencies = [
2667+
"memchr",
2668+
]
2669+
26612670
[[package]]
26622671
name = "odht"
26632672
version = "0.3.1"

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(

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(

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

2222
use rustc_session::cstore::DllImport;
@@ -114,7 +114,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
114114
if true {
115115
Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
116116
} else {
117-
Box::new(ArArchiveBuilder::new(sess, get_llvm_object_symbols))
117+
Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
118118
}
119119
}
120120

@@ -296,59 +296,84 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
296296

297297
// The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
298298
// As such we need to use LLVM for them.
299+
300+
static LLVM_OBJECT_READER: ObjectReader = ObjectReader {
301+
get_symbols: get_llvm_object_symbols,
302+
is_64_bit_object_file: llvm_is_64_bit_object_file,
303+
is_ec_object_file: llvm_is_ec_object_file,
304+
get_xcoff_member_alignment: DEFAULT_OBJECT_READER.get_xcoff_member_alignment,
305+
};
306+
307+
fn should_use_llvm_reader(buf: &[u8]) -> bool {
308+
let is_bitcode = unsafe { llvm::LLVMRustIsBitcode(buf.as_ptr(), buf.len()) };
309+
310+
// COFF bigobj file, msvc LTO file or import library. See
311+
// https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
312+
let is_unsupported_windows_obj_file = buf.get(0..4) == Some(b"\0\0\xFF\xFF");
313+
314+
is_bitcode || is_unsupported_windows_obj_file
315+
}
316+
299317
#[deny(unsafe_op_in_unsafe_fn)]
300318
fn get_llvm_object_symbols(
301319
buf: &[u8],
302320
f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
303321
) -> io::Result<bool> {
304-
let is_bitcode = unsafe { llvm::LLVMRustIsBitcode(buf.as_ptr(), buf.len()) };
322+
if !should_use_llvm_reader(buf) {
323+
return (DEFAULT_OBJECT_READER.get_symbols)(buf, f);
324+
}
305325

306-
// COFF bigobj file, msvc LTO file or import library. See
307-
// https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
308-
let is_unsupported_windows_obj_file = buf.get(0..4) == Some(b"\0\0\xFF\xFF");
326+
let mut state = Box::new(f);
309327

310-
if is_bitcode || is_unsupported_windows_obj_file {
311-
let mut state = Box::new(f);
312-
313-
let err = unsafe {
314-
llvm::LLVMRustGetSymbols(
315-
buf.as_ptr(),
316-
buf.len(),
317-
std::ptr::addr_of_mut!(*state) as *mut c_void,
318-
callback,
319-
error_callback,
320-
)
321-
};
328+
let err = unsafe {
329+
llvm::LLVMRustGetSymbols(
330+
buf.as_ptr(),
331+
buf.len(),
332+
std::ptr::addr_of_mut!(*state) as *mut c_void,
333+
callback,
334+
error_callback,
335+
)
336+
};
322337

323-
if err.is_null() {
324-
return Ok(true);
325-
} else {
326-
return Err(unsafe { *Box::from_raw(err as *mut io::Error) });
327-
}
338+
if err.is_null() {
339+
return Ok(true);
340+
} else {
341+
return Err(unsafe { *Box::from_raw(err as *mut io::Error) });
342+
}
328343

329-
unsafe extern "C" fn callback(
330-
state: *mut c_void,
331-
symbol_name: *const c_char,
332-
) -> *mut c_void {
333-
let f = unsafe { &mut *(state as *mut &mut dyn FnMut(&[u8]) -> io::Result<()>) };
334-
match f(unsafe { CStr::from_ptr(symbol_name) }.to_bytes()) {
335-
Ok(()) => std::ptr::null_mut(),
336-
Err(err) => Box::into_raw(Box::new(err)) as *mut c_void,
337-
}
344+
unsafe extern "C" fn callback(state: *mut c_void, symbol_name: *const c_char) -> *mut c_void {
345+
let f = unsafe { &mut *(state as *mut &mut dyn FnMut(&[u8]) -> io::Result<()>) };
346+
match f(unsafe { CStr::from_ptr(symbol_name) }.to_bytes()) {
347+
Ok(()) => std::ptr::null_mut(),
348+
Err(err) => Box::into_raw(Box::new(err)) as *mut c_void,
338349
}
350+
}
339351

340-
unsafe extern "C" fn error_callback(error: *const c_char) -> *mut c_void {
341-
let error = unsafe { CStr::from_ptr(error) };
342-
Box::into_raw(Box::new(io::Error::new(
343-
io::ErrorKind::Other,
344-
format!("LLVM error: {}", error.to_string_lossy()),
345-
))) as *mut c_void
346-
}
347-
} else {
348-
get_native_object_symbols(buf, f)
352+
unsafe extern "C" fn error_callback(error: *const c_char) -> *mut c_void {
353+
let error = unsafe { CStr::from_ptr(error) };
354+
Box::into_raw(Box::new(io::Error::new(
355+
io::ErrorKind::Other,
356+
format!("LLVM error: {}", error.to_string_lossy()),
357+
))) as *mut c_void
349358
}
350359
}
351360

361+
fn llvm_is_64_bit_object_file(buf: &[u8]) -> bool {
362+
if !should_use_llvm_reader(buf) {
363+
return (DEFAULT_OBJECT_READER.is_64_bit_object_file)(buf);
364+
}
365+
366+
unsafe { llvm::LLVMRustIs64BitSymbolicFile(buf.as_ptr(), buf.len()) }
367+
}
368+
369+
fn llvm_is_ec_object_file(buf: &[u8]) -> bool {
370+
if !should_use_llvm_reader(buf) {
371+
return (DEFAULT_OBJECT_READER.is_ec_object_file)(buf);
372+
}
373+
374+
unsafe { llvm::LLVMRustIsECObject(buf.as_ptr(), buf.len()) }
375+
}
376+
352377
impl<'a> LlvmArchiveBuilder<'a> {
353378
fn build_with_llvm(&mut self, output: &Path) -> io::Result<bool> {
354379
let kind = &*self.sess.target.archive_format;

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2427,4 +2427,8 @@ extern "C" {
24272427
callback: GetSymbolsCallback,
24282428
error_callback: GetSymbolsErrorCallback,
24292429
) -> *mut c_void;
2430+
2431+
pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool;
2432+
2433+
pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool;
24302434
}

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
bitflags = "2.4.1"
1010
cc = "1.0.90"
1111
itertools = "0.12"

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,
@@ -285,7 +278,13 @@ impl<'a> ArArchiveBuilder<'a> {
285278
.tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
286279
.map_err(|err| io_error_context("couldn't create a temp file", err))?;
287280

288-
write_archive_to_stream(archive_tmpfile.as_file_mut(), &entries, archive_kind, false)?;
281+
write_archive_to_stream(
282+
archive_tmpfile.as_file_mut(),
283+
&entries,
284+
archive_kind,
285+
false,
286+
self.sess.target.arch == "arm64ec",
287+
)?;
289288

290289
let any_entries = !entries.is_empty();
291290
drop(entries);

0 commit comments

Comments
 (0)