diff options
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/archive.rs | 63 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/common.rs | 9 |
3 files changed, 70 insertions, 37 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 2f48c1fbf0d..e83bfa7b70d 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -26,6 +26,35 @@ use crate::errors::{ DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile, }; +/// An item to be included in an import library. +/// This is a slimmed down version of `COFFShortExport` from `ar-archive-writer`. +pub struct ImportLibraryItem { + /// The name to be exported. + pub name: String, + /// The ordinal to be exported, if any. + pub ordinal: Option<u16>, + /// The original, decorated name if `name` is not decorated. + pub symbol_name: Option<String>, + /// True if this is a data export, false if it is a function export. + pub is_data: bool, +} + +impl From<ImportLibraryItem> for COFFShortExport { + fn from(item: ImportLibraryItem) -> Self { + COFFShortExport { + name: item.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, + private: false, + constant: false, + } + } +} + pub trait ArchiveBuilderBuilder { fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a>; @@ -38,7 +67,7 @@ pub trait ArchiveBuilderBuilder { &self, sess: &Session, lib_name: &str, - import_name_and_ordinal_vector: Vec<(String, Option<u16>)>, + items: Vec<ImportLibraryItem>, output_path: &Path, ) { if common::is_mingw_gnu_toolchain(&sess.target) { @@ -47,21 +76,16 @@ pub trait ArchiveBuilderBuilder { // 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, - ); + create_mingw_dll_import_lib(sess, lib_name, items, 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 + items .iter() - .map(|(name, _ordinal)| name.clone()) + .map(|ImportLibraryItem { name, .. }| name.clone()) .collect::<Vec<_>>() .join(", "), ); @@ -79,20 +103,7 @@ pub trait ArchiveBuilderBuilder { .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 exports = items.into_iter().map(Into::into).collect::<Vec<_>>(); let machine = match &*sess.target.arch { "x86_64" => MachineTypes::AMD64, "x86" => MachineTypes::I386, @@ -160,16 +171,16 @@ pub trait ArchiveBuilderBuilder { fn create_mingw_dll_import_lib( sess: &Session, lib_name: &str, - import_name_and_ordinal_vector: Vec<(String, Option<u16>)>, + items: Vec<ImportLibraryItem>, output_path: &Path, ) { let def_file_path = output_path.with_extension("def"); let def_file_content = format!( "EXPORTS\n{}", - import_name_and_ordinal_vector + items .into_iter() - .map(|(name, ordinal)| { + .map(|ImportLibraryItem { name, ordinal, .. }| { match ordinal { Some(n) => format!("{name} @{n} NONAME"), None => name, diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 44581cfa64b..8f754debaf0 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -45,7 +45,7 @@ use rustc_target::spec::{ use tempfile::Builder as TempFileBuilder; use tracing::{debug, info, warn}; -use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; +use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder, ImportLibraryItem}; use super::command::Command; use super::linker::{self, Linker}; use super::metadata::{MetadataPosition, create_wrapper_file}; @@ -495,16 +495,35 @@ fn create_dll_import_libs<'a>( let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&sess.target); - let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = raw_dylib_imports + let items: Vec<ImportLibraryItem> = raw_dylib_imports .iter() .map(|import: &DllImport| { if sess.target.arch == "x86" { - ( - common::i686_decorated_name(import, mingw_gnu_toolchain, false), - import.ordinal(), - ) + ImportLibraryItem { + name: common::i686_decorated_name( + import, + mingw_gnu_toolchain, + false, + false, + ), + ordinal: import.ordinal(), + symbol_name: import.is_missing_decorations().then(|| { + common::i686_decorated_name( + import, + mingw_gnu_toolchain, + false, + true, + ) + }), + is_data: !import.is_fn, + } } else { - (import.name.to_string(), import.ordinal()) + ImportLibraryItem { + name: import.name.to_string(), + ordinal: import.ordinal(), + symbol_name: None, + is_data: !import.is_fn, + } } }) .collect(); @@ -512,7 +531,7 @@ fn create_dll_import_libs<'a>( archive_builder_builder.create_dll_import_lib( sess, &raw_dylib_name, - import_name_and_ordinal_vector, + items, &output_path, ); diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 582a2a87e48..965bd34ac14 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -187,12 +187,15 @@ pub fn i686_decorated_name( dll_import: &DllImport, mingw: bool, disable_name_mangling: bool, + force_fully_decorated: bool, ) -> String { let name = dll_import.name.as_str(); - let (add_prefix, add_suffix) = match dll_import.import_name_type { - Some(PeImportNameType::NoPrefix) => (false, true), - Some(PeImportNameType::Undecorated) => (false, false), + let (add_prefix, add_suffix) = match (force_fully_decorated, dll_import.import_name_type) { + // No prefix is a bit weird, in that LLVM/ar_archive_writer won't emit it, so we will + // ignore `force_fully_decorated` and always partially decorate it. + (_, Some(PeImportNameType::NoPrefix)) => (false, true), + (false, Some(PeImportNameType::Undecorated)) => (false, false), _ => (true, true), }; |
