Rollup merge of #128206 - bjorn3:import_lib_writing_refactor, r=jieyouxu

Make create_dll_import_lib easier to implement

This will make it easier to implement raw-dylib support in cg_clif and cg_gcc. This PR doesn't yet include an create_dll_import_lib implementation for cg_clif as I need to correctly implement dllimport in cg_clif first before raw-dylib can work at all with cg_clif.

Required for https://github.com/rust-lang/rustc_codegen_cranelift/issues/1345
This commit is contained in:
Guillaume Gomez
2024-08-07 15:59:35 +02:00
committed by GitHub
15 changed files with 332 additions and 317 deletions

View File

@@ -4,7 +4,9 @@ use rustc_hir::LangItem;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Instance, TyCtxt};
use rustc_middle::{bug, mir, span_bug};
use rustc_session::cstore::{DllCallingConvention, DllImport, PeImportNameType};
use rustc_span::Span;
use rustc_target::spec::Target;
use crate::traits::*;
@@ -176,3 +178,66 @@ pub fn asm_const_to_str<'tcx>(
_ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty),
}
}
pub fn is_mingw_gnu_toolchain(target: &Target) -> bool {
target.vendor == "pc" && target.os == "windows" && target.env == "gnu" && target.abi.is_empty()
}
pub fn i686_decorated_name(
dll_import: &DllImport,
mingw: bool,
disable_name_mangling: 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),
_ => (true, true),
};
// Worst case: +1 for disable name mangling, +1 for prefix, +4 for suffix (@@__).
let mut decorated_name = String::with_capacity(name.len() + 6);
if disable_name_mangling {
// LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be disabled.
decorated_name.push('\x01');
}
let prefix = if add_prefix && dll_import.is_fn {
match dll_import.calling_convention {
DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None,
DllCallingConvention::Stdcall(_) => (!mingw
|| dll_import.import_name_type == Some(PeImportNameType::Decorated))
.then_some('_'),
DllCallingConvention::Fastcall(_) => Some('@'),
}
} else if !dll_import.is_fn && !mingw {
// For static variables, prefix with '_' on MSVC.
Some('_')
} else {
None
};
if let Some(prefix) = prefix {
decorated_name.push(prefix);
}
decorated_name.push_str(name);
if add_suffix && dll_import.is_fn {
use std::fmt::Write;
match dll_import.calling_convention {
DllCallingConvention::C => {}
DllCallingConvention::Stdcall(arg_list_size)
| DllCallingConvention::Fastcall(arg_list_size) => {
write!(&mut decorated_name, "@{arg_list_size}").unwrap();
}
DllCallingConvention::Vectorcall(arg_list_size) => {
write!(&mut decorated_name, "@@{arg_list_size}").unwrap();
}
}
}
decorated_name
}