diff --git a/Cargo.lock b/Cargo.lock index 8b9c243879caf..a8df53f3a4113 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,11 +158,11 @@ checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "ar_archive_writer" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4" +checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b" dependencies = [ - "object 0.36.7", + "object 0.37.3", ] [[package]] diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 7a340ae83f3da..f9dc48e3aba3f 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -26,6 +26,7 @@ static LLVM_OBJECT_READER: ObjectReader = ObjectReader { get_symbols: get_llvm_object_symbols, is_64_bit_object_file: llvm_is_64_bit_object_file, is_ec_object_file: llvm_is_ec_object_file, + is_any_arm64_coff: llvm_is_any_arm64_coff, get_xcoff_member_alignment: DEFAULT_OBJECT_READER.get_xcoff_member_alignment, }; @@ -95,3 +96,7 @@ fn llvm_is_64_bit_object_file(buf: &[u8]) -> bool { fn llvm_is_ec_object_file(buf: &[u8]) -> bool { unsafe { llvm::LLVMRustIsECObject(buf.as_ptr(), buf.len()) } } + +fn llvm_is_any_arm64_coff(buf: &[u8]) -> bool { + unsafe { llvm::LLVMRustIsAnyArm64Coff(buf.as_ptr(), buf.len()) } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index ba590851dbd5e..b66fc157b3cb2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2686,6 +2686,8 @@ unsafe extern "C" { pub(crate) fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool; + pub(crate) fn LLVMRustIsAnyArm64Coff(buf_ptr: *const u8, buf_len: usize) -> bool; + pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value); pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value); } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 57e1fee2c0a67..6f87b5749c6d5 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -ar_archive_writer = "0.4.2" +ar_archive_writer = "0.5" bitflags.workspace = true bstr = "1.11.3" # `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 84a56f6b0b558..cfd8ceac3a604 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -40,16 +40,18 @@ pub struct ImportLibraryItem { pub is_data: bool, } -impl From for COFFShortExport { - fn from(item: ImportLibraryItem) -> Self { +impl ImportLibraryItem { + fn into_coff_short_export(self, sess: &Session) -> COFFShortExport { + let import_name = (sess.target.arch == "arm64ec").then(|| self.name.clone()); COFFShortExport { - name: item.name, + name: self.name, ext_name: None, - symbol_name: item.symbol_name, - alias_target: None, - ordinal: item.ordinal.unwrap_or(0), - noname: item.ordinal.is_some(), - data: item.is_data, + symbol_name: self.symbol_name, + import_name, + export_as: None, + ordinal: self.ordinal.unwrap_or(0), + noname: self.ordinal.is_some(), + data: self.is_data, private: false, constant: false, } @@ -113,7 +115,8 @@ pub trait ArchiveBuilderBuilder { .emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() }), }; - let exports = items.into_iter().map(Into::into).collect::>(); + let exports = + items.into_iter().map(|item| item.into_coff_short_export(sess)).collect::>(); let machine = match &*sess.target.arch { "x86_64" => MachineTypes::AMD64, "x86" => MachineTypes::I386, @@ -134,6 +137,7 @@ pub trait ArchiveBuilderBuilder { // when linking a rust staticlib using `/WHOLEARCHIVE`. // See #129020 true, + &[], ) { sess.dcx() .emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() }); @@ -527,7 +531,7 @@ impl<'a> ArArchiveBuilder<'a> { &entries, archive_kind, false, - /* is_ec = */ self.sess.target.arch == "arm64ec", + /* is_ec = */ Some(self.sess.target.arch == "arm64ec"), )?; archive_tmpfile.flush()?; drop(archive_tmpfile); diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp index a910e78d48952..fccfff65cfc38 100644 --- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp @@ -103,14 +103,14 @@ LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State, #define TRUE_PTR (void *)1 #define FALSE_PTR (void *)0 -extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) { +bool withBufferAsSymbolicFile( + char *BufPtr, size_t BufLen, + std::function Callback) { std::unique_ptr Buf = MemoryBuffer::getMemBuffer( StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false); SmallString<0> SymNameBuf; auto SymName = raw_svector_ostream(SymNameBuf); - // Code starting from this line is copied from s64BitSymbolicFile in - // ArchiveWriter.cpp. // In the scenario when LLVMContext is populated SymbolicFile will contain a // reference to it, thus SymbolicFile should be destroyed first. LLVMContext Context; @@ -120,48 +120,63 @@ extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) { return false; } std::unique_ptr Obj = std::move(*ObjOrErr); - - return Obj != nullptr ? Obj->is64Bit() : false; -} - -extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) { - std::unique_ptr Buf = MemoryBuffer::getMemBuffer( - StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false); - SmallString<0> SymNameBuf; - auto SymName = raw_svector_ostream(SymNameBuf); - - // In the scenario when LLVMContext is populated SymbolicFile will contain a - // reference to it, thus SymbolicFile should be destroyed first. - LLVMContext Context; - Expected> ObjOrErr = - getSymbolicFile(Buf->getMemBufferRef(), Context); - if (!ObjOrErr) { - return false; - } - std::unique_ptr Obj = std::move(*ObjOrErr); - if (Obj == nullptr) { return false; } + return Callback(*Obj); +} - // Code starting from this line is copied from isECObject in - // ArchiveWriter.cpp with an extra #if to work with LLVM 17. - if (Obj->isCOFF()) - return cast(&*Obj)->getMachine() != - COFF::IMAGE_FILE_MACHINE_ARM64; - - if (Obj->isCOFFImportFile()) - return cast(&*Obj)->getMachine() != - COFF::IMAGE_FILE_MACHINE_ARM64; - - if (Obj->isIR()) { - Expected TripleStr = - getBitcodeTargetTriple(Obj->getMemoryBufferRef()); - if (!TripleStr) - return false; - Triple T(*TripleStr); - return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64; - } +extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) { + return withBufferAsSymbolicFile( + BufPtr, BufLen, [](object::SymbolicFile &Obj) { return Obj.is64Bit(); }); +} + +extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) { + return withBufferAsSymbolicFile( + BufPtr, BufLen, [](object::SymbolicFile &Obj) { + // Code starting from this line is copied from isECObject in + // ArchiveWriter.cpp with an extra #if to work with LLVM 17. + if (Obj.isCOFF()) + return cast(&Obj)->getMachine() != + COFF::IMAGE_FILE_MACHINE_ARM64; + + if (Obj.isCOFFImportFile()) + return cast(&Obj)->getMachine() != + COFF::IMAGE_FILE_MACHINE_ARM64; + + if (Obj.isIR()) { + Expected TripleStr = + getBitcodeTargetTriple(Obj.getMemoryBufferRef()); + if (!TripleStr) + return false; + Triple T(*TripleStr); + return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64; + } + + return false; + }); +} - return false; +extern "C" bool LLVMRustIsAnyArm64Coff(char *BufPtr, size_t BufLen) { + return withBufferAsSymbolicFile( + BufPtr, BufLen, [](object::SymbolicFile &Obj) { + // Code starting from this line is copied from isAnyArm64COFF in + // ArchiveWriter.cpp. + if (Obj.isCOFF()) + return COFF::isAnyArm64(cast(&Obj)->getMachine()); + + if (Obj.isCOFFImportFile()) + return COFF::isAnyArm64(cast(&Obj)->getMachine()); + + if (Obj.isIR()) { + Expected TripleStr = + getBitcodeTargetTriple(Obj.getMemoryBufferRef()); + if (!TripleStr) + return false; + Triple T(*TripleStr); + return T.isOSWindows() && T.getArch() == Triple::aarch64; + } + + return false; + }); }