about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Denton <chris@chrisdenton.dev>2024-08-16 19:32:22 +0000
committerChris Denton <chris@chrisdenton.dev>2024-08-17 19:10:46 +0000
commit0156eb57a152003c0c82552229747b3d04e1fddc (patch)
tree249846c9486615f1e2434cfbf0ac0995260389f5
parent27b93da8de2477b3a41811b0ee486cffa99fa00e (diff)
downloadrust-0156eb57a152003c0c82552229747b3d04e1fddc.tar.gz
rust-0156eb57a152003c0c82552229747b3d04e1fddc.zip
Always use ar_archive_writer for import libs
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_codegen_cranelift/src/archive.rs83
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/messages.ftl3
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs94
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs7
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl3
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs86
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs7
10 files changed, 100 insertions, 190 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1aa0b2ea4a3..ae5d3e12e3a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -205,9 +205,9 @@ dependencies = [
 
 [[package]]
 name = "ar_archive_writer"
-version = "0.3.3"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f2bcb7cf51decfbbfc7ef476e28b0775b13e5eb1190f8b7df145cd53d4f4374"
+checksum = "de11a9d32db3327f981143bdf699ade4d637c6887b13b97e6e91a9154666963c"
 dependencies = [
  "object 0.36.2",
 ]
diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs
index 5eedab4f2cb..c7725e49c94 100644
--- a/compiler/rustc_codegen_cranelift/src/archive.rs
+++ b/compiler/rustc_codegen_cranelift/src/archive.rs
@@ -1,13 +1,6 @@
-use std::borrow::Borrow;
-use std::fs;
-use std::path::Path;
-
-use ar_archive_writer::{COFFShortExport, MachineTypes};
 use rustc_codegen_ssa::back::archive::{
-    create_mingw_dll_import_lib, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
-    DEFAULT_OBJECT_READER,
+    ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
 };
-use rustc_codegen_ssa::common::is_mingw_gnu_toolchain;
 use rustc_session::Session;
 
 pub(crate) struct ArArchiveBuilderBuilder;
@@ -16,78 +9,4 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
         Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
     }
-
-    fn create_dll_import_lib(
-        &self,
-        sess: &Session,
-        lib_name: &str,
-        import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
-        output_path: &Path,
-    ) {
-        if is_mingw_gnu_toolchain(&sess.target) {
-            // The binutils linker used on -windows-gnu targets cannot read the import
-            // libraries generated by LLVM: in our attempts, the linker produced an .EXE
-            // that loaded but crashed with an AV upon calling one of the imported
-            // functions. Therefore, use binutils to create the import library instead,
-            // by writing a .DEF file to the temp dir and calling binutils's dlltool.
-            create_mingw_dll_import_lib(
-                sess,
-                lib_name,
-                import_name_and_ordinal_vector,
-                output_path,
-            );
-        } else {
-            let mut file =
-                match fs::OpenOptions::new().write(true).create_new(true).open(&output_path) {
-                    Ok(file) => file,
-                    Err(error) => {
-                        sess.dcx().fatal(format!(
-                            "failed to create import library file `{path}`: {error}",
-                            path = output_path.display(),
-                        ));
-                    }
-                };
-
-            let machine = match sess.target.arch.borrow() {
-                "x86" => MachineTypes::I386,
-                "x86_64" => MachineTypes::AMD64,
-                "arm" => MachineTypes::ARMNT,
-                "aarch64" => MachineTypes::ARM64,
-                _ => {
-                    sess.dcx().fatal(format!(
-                        "unsupported target architecture `{arch}`",
-                        arch = sess.target.arch,
-                    ));
-                }
-            };
-
-            let exports = import_name_and_ordinal_vector
-                .iter()
-                .map(|(name, ordinal)| COFFShortExport {
-                    name: name.to_string(),
-                    ext_name: None,
-                    symbol_name: None,
-                    alias_target: None,
-                    ordinal: ordinal.unwrap_or(0),
-                    noname: ordinal.is_some(),
-                    data: false,
-                    private: false,
-                    constant: false,
-                })
-                .collect::<Vec<_>>();
-
-            if let Err(error) = ar_archive_writer::write_import_library(
-                &mut file,
-                lib_name,
-                &exports,
-                machine,
-                !sess.target.is_like_msvc,
-            ) {
-                sess.dcx().fatal(format!(
-                    "failed to create import library `{path}`: `{error}`",
-                    path = output_path.display(),
-                ));
-            }
-        }
-    }
 }
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 21930fa2ddb..f737af25b62 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -12,7 +12,6 @@
 #![warn(unused_lifetimes)]
 // tidy-alphabetical-end
 
-extern crate ar_archive_writer;
 extern crate jobserver;
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl
index 267da9325c3..df2198df14b 100644
--- a/compiler/rustc_codegen_llvm/messages.ftl
+++ b/compiler/rustc_codegen_llvm/messages.ftl
@@ -5,9 +5,6 @@ codegen_llvm_dynamic_linking_with_lto =
     .note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO
 
 
-codegen_llvm_error_creating_import_library =
-    Error creating import library for {$lib_name}: {$error}
-
 codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
 
 codegen_llvm_from_llvm_diag = {$message}
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 2120fc1815c..c0ec4f86b4d 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -5,17 +5,13 @@ use std::path::{Path, PathBuf};
 use std::{io, mem, ptr, str};
 
 use rustc_codegen_ssa::back::archive::{
-    create_mingw_dll_import_lib, try_extract_macho_fat_archive, ArArchiveBuilder,
-    ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind,
-    DEFAULT_OBJECT_READER,
+    try_extract_macho_fat_archive, ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder,
+    ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, DEFAULT_OBJECT_READER,
 };
-use rustc_codegen_ssa::common;
 use rustc_session::Session;
-use tracing::trace;
 
-use crate::errors::ErrorCreatingImportLibrary;
 use crate::llvm::archive_ro::{ArchiveRO, Child};
-use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
+use crate::llvm::{self, ArchiveKind};
 
 /// Helper for adding many files to an archive.
 #[must_use = "must call build() to finish building the archive"]
@@ -44,18 +40,6 @@ fn is_relevant_child(c: &Child<'_>) -> bool {
     }
 }
 
-/// Map machine type strings to values of LLVM's MachineTypes enum.
-fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
-    match cpu {
-        "x86_64" => LLVMMachineType::AMD64,
-        "x86" => LLVMMachineType::I386,
-        "aarch64" => LLVMMachineType::ARM64,
-        "arm64ec" => LLVMMachineType::ARM64EC,
-        "arm" => LLVMMachineType::ARM,
-        _ => panic!("unsupported cpu type {cpu}"),
-    }
-}
-
 impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
     fn add_archive(
         &mut self,
@@ -116,78 +100,6 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
             Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
         }
     }
-
-    fn create_dll_import_lib(
-        &self,
-        sess: &Session,
-        lib_name: &str,
-        import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
-        output_path: &Path,
-    ) {
-        if common::is_mingw_gnu_toolchain(&sess.target) {
-            // The binutils linker used on -windows-gnu targets cannot read the import
-            // libraries generated by LLVM: in our attempts, the linker produced an .EXE
-            // that loaded but crashed with an AV upon calling one of the imported
-            // functions. Therefore, use binutils to create the import library instead,
-            // by writing a .DEF file to the temp dir and calling binutils's dlltool.
-            create_mingw_dll_import_lib(
-                sess,
-                lib_name,
-                import_name_and_ordinal_vector,
-                output_path,
-            );
-        } else {
-            // we've checked for \0 characters in the library name already
-            let dll_name_z = CString::new(lib_name).unwrap();
-
-            let output_path_z = rustc_fs_util::path_to_c_string(&output_path);
-
-            trace!("invoking LLVMRustWriteImportLibrary");
-            trace!("  dll_name {:#?}", dll_name_z);
-            trace!("  output_path {}", output_path.display());
-            trace!(
-                "  import names: {}",
-                import_name_and_ordinal_vector
-                    .iter()
-                    .map(|(name, _ordinal)| name.clone())
-                    .collect::<Vec<_>>()
-                    .join(", "),
-            );
-
-            // All import names are Rust identifiers and therefore cannot contain \0 characters.
-            // FIXME: when support for #[link_name] is implemented, ensure that the import names
-            // still don't contain any \0 characters. Also need to check that the names don't
-            // contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
-            // in definition files.
-            let cstring_import_name_and_ordinal_vector: Vec<(CString, Option<u16>)> =
-                import_name_and_ordinal_vector
-                    .into_iter()
-                    .map(|(name, ordinal)| (CString::new(name).unwrap(), ordinal))
-                    .collect();
-
-            let ffi_exports: Vec<LLVMRustCOFFShortExport> = cstring_import_name_and_ordinal_vector
-                .iter()
-                .map(|(name_z, ordinal)| LLVMRustCOFFShortExport::new(name_z.as_ptr(), *ordinal))
-                .collect();
-            let result = unsafe {
-                crate::llvm::LLVMRustWriteImportLibrary(
-                    dll_name_z.as_ptr(),
-                    output_path_z.as_ptr(),
-                    ffi_exports.as_ptr(),
-                    ffi_exports.len(),
-                    llvm_machine_type(&sess.target.arch) as u16,
-                    !sess.target.is_like_msvc,
-                )
-            };
-
-            if result == crate::llvm::LLVMRustResult::Failure {
-                sess.dcx().emit_fatal(ErrorCreatingImportLibrary {
-                    lib_name,
-                    error: llvm::last_error().unwrap_or("unknown LLVM error".to_string()),
-                });
-            }
-        }
-    }
 }
 
 // The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index 7e53d32ce8c..e0ec9cdca56 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -40,13 +40,6 @@ pub(crate) enum PossibleFeature<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_llvm_error_creating_import_library)]
-pub(crate) struct ErrorCreatingImportLibrary<'a> {
-    pub lib_name: &'a str,
-    pub error: String,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_llvm_symbol_already_defined)]
 pub(crate) struct SymbolAlreadyDefined<'a> {
     #[primary_span]
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 6e1c323cbd0..0af34a1b9fa 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-ar_archive_writer = "0.3.3"
+ar_archive_writer = "0.4.0"
 arrayvec = { version = "0.7", default-features = false }
 bitflags = "2.4.1"
 cc = "1.0.90"
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index 80f25d42a08..8a6a2acd87d 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -32,6 +32,9 @@ codegen_ssa_dlltool_fail_import_library =
 codegen_ssa_error_calling_dlltool =
     Error calling dlltool '{$dlltool_path}': {$error}
 
+codegen_ssa_error_creating_import_library =
+    Error creating import library for {$lib_name}: {$error}
+
 codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
 
 codegen_ssa_error_writing_def_file =
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 8eb44d12016..38a440a707a 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -5,7 +5,9 @@ use std::fs::{self, File};
 use std::io::{self, Write};
 use std::path::{Path, PathBuf};
 
-use ar_archive_writer::{write_archive_to_stream, ArchiveKind, NewArchiveMember};
+use ar_archive_writer::{
+    write_archive_to_stream, ArchiveKind, COFFShortExport, MachineTypes, NewArchiveMember,
+};
 pub use ar_archive_writer::{ObjectReader, DEFAULT_OBJECT_READER};
 use object::read::archive::ArchiveFile;
 use object::read::macho::FatArch;
@@ -14,11 +16,15 @@ use rustc_data_structures::memmap::Mmap;
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
 use tempfile::Builder as TempFileBuilder;
+use tracing::trace;
 
 use super::metadata::search_for_section;
+use crate::common;
 // Re-exporting for rustc_codegen_llvm::back::archive
 pub use crate::errors::{ArchiveBuildFailure, ExtractBundledLibsError, UnknownArchiveKind};
-use crate::errors::{DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorWritingDEFFile};
+use crate::errors::{
+    DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile,
+};
 
 pub trait ArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a>;
@@ -34,7 +40,81 @@ pub trait ArchiveBuilderBuilder {
         lib_name: &str,
         import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
         output_path: &Path,
-    );
+    ) {
+        if common::is_mingw_gnu_toolchain(&sess.target) {
+            // The binutils linker used on -windows-gnu targets cannot read the import
+            // libraries generated by LLVM: in our attempts, the linker produced an .EXE
+            // that loaded but crashed with an AV upon calling one of the imported
+            // functions. Therefore, use binutils to create the import library instead,
+            // by writing a .DEF file to the temp dir and calling binutils's dlltool.
+            create_mingw_dll_import_lib(
+                sess,
+                lib_name,
+                import_name_and_ordinal_vector,
+                output_path,
+            );
+        } else {
+            trace!("creating import library");
+            trace!("  dll_name {:#?}", lib_name);
+            trace!("  output_path {}", output_path.display());
+            trace!(
+                "  import names: {}",
+                import_name_and_ordinal_vector
+                    .iter()
+                    .map(|(name, _ordinal)| name.clone())
+                    .collect::<Vec<_>>()
+                    .join(", "),
+            );
+
+            // All import names are Rust identifiers and therefore cannot contain \0 characters.
+            // FIXME: when support for #[link_name] is implemented, ensure that the import names
+            // still don't contain any \0 characters. Also need to check that the names don't
+            // contain substrings like " @" or "NONAME" that are keywords or otherwise reserved
+            // in definition files.
+
+            let mut file = match fs::File::create_new(&output_path) {
+                Ok(file) => file,
+                Err(error) => sess
+                    .dcx()
+                    .emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() }),
+            };
+
+            let exports = import_name_and_ordinal_vector
+                .iter()
+                .map(|(name, ordinal)| COFFShortExport {
+                    name: name.to_string(),
+                    ext_name: None,
+                    symbol_name: None,
+                    alias_target: None,
+                    ordinal: ordinal.unwrap_or(0),
+                    noname: ordinal.is_some(),
+                    data: false,
+                    private: false,
+                    constant: false,
+                })
+                .collect::<Vec<_>>();
+            let machine = match &*sess.target.arch {
+                "x86_64" => MachineTypes::AMD64,
+                "x86" => MachineTypes::I386,
+                "aarch64" => MachineTypes::ARM64,
+                "arm64ec" => MachineTypes::ARM64EC,
+                "arm" => MachineTypes::ARMNT,
+                cpu => panic!("unsupported cpu type {cpu}"),
+            };
+
+            if let Err(error) = ar_archive_writer::write_import_library(
+                &mut file,
+                lib_name,
+                &exports,
+                machine,
+                !sess.target.is_like_msvc,
+                /*comdat=*/ false,
+            ) {
+                sess.dcx()
+                    .emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() });
+            }
+        }
+    }
 
     fn extract_bundled_libs<'a>(
         &'a self,
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 94bf0ab34e2..573a8cf7cbe 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -1060,3 +1060,10 @@ pub struct CompilerBuiltinsCannotCall {
     pub caller: String,
     pub callee: String,
 }
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_error_creating_import_library)]
+pub(crate) struct ErrorCreatingImportLibrary<'a> {
+    pub lib_name: &'a str,
+    pub error: String,
+}