Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #96542

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,33 @@ fn add_linked_symbol_object(
// so add an empty section.
if file.format() == object::BinaryFormat::Coff {
file.add_section(Vec::new(), ".text".into(), object::SectionKind::Text);

// We handle the name decoration of COFF targets in `symbol_export.rs`, so disable the
// default mangler in `object` crate.
file.set_mangling(object::write::Mangling::None);

// Add feature flags to the object file. On MSVC this is optional but LLD will complain if
// not present.
let mut feature = 0;

if file.architecture() == object::Architecture::I386 {
// Indicate that all SEH handlers are registered in .sxdata section.
// We don't have generate any code, so we don't need .sxdata section but LLD still
// expects us to set this bit (see #96498).
// Reference: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
feature |= 1;
}

file.add_symbol(object::write::Symbol {
name: "@feat.00".into(),
value: feature,
size: 0,
kind: object::SymbolKind::Data,
scope: object::SymbolScope::Compilation,
weak: false,
section: object::write::SymbolSection::Absolute,
flags: object::SymbolFlags::None,
});
}

for (sym, kind) in symbols.iter() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ pub(crate) fn linked_symbols(
for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
if info.level.is_below_threshold(export_threshold) || info.used {
symbols.push((
symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum),
symbol_export::linking_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
info.kind,
));
}
Expand Down
72 changes: 71 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_middle::middle::exported_symbols::{
use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance;
use rustc_middle::ty::{SymbolName, TyCtxt};
use rustc_middle::ty::{self, SymbolName, TyCtxt};
use rustc_session::config::CrateType;
use rustc_target::spec::SanitizerSet;

Expand Down Expand Up @@ -493,6 +493,76 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
}
}

/// This is the symbol name of the given instance as seen by the linker.
///
/// On 32-bit Windows symbols are decorated according to their calling conventions.
pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
tcx: TyCtxt<'tcx>,
symbol: ExportedSymbol<'tcx>,
instantiating_crate: CrateNum,
) -> String {
use rustc_target::abi::call::Conv;

let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);

let target = &tcx.sess.target;
if !target.is_like_windows {
// Mach-O has a global "_" suffix and `object` crate will handle it.
// ELF does not have any symbol decorations.
return undecorated;
}

let x86 = match &target.arch[..] {
"x86" => true,
"x86_64" => false,
// Only x86/64 use symbol decorations.
_ => return undecorated,
};

let instance = match symbol {
ExportedSymbol::NonGeneric(def_id) | ExportedSymbol::Generic(def_id, _)
if tcx.is_static(def_id) =>
{
None
}
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
ExportedSymbol::Generic(def_id, substs) => Some(Instance::new(def_id, substs)),
// DropGlue always use the Rust calling convention and thus follow the target's default
// symbol decoration scheme.
ExportedSymbol::DropGlue(..) => None,
// NoDefId always follow the target's default symbol decoration scheme.
ExportedSymbol::NoDefId(..) => None,
};

let (conv, args) = instance
.map(|i| {
tcx.fn_abi_of_instance(ty::ParamEnv::reveal_all().and((i, ty::List::empty())))
.unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed"))
})
.map(|fnabi| (fnabi.conv, &fnabi.args[..]))
.unwrap_or((Conv::Rust, &[]));

// Decorate symbols with prefices, suffices and total number of bytes of arguments.
// Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170
let (prefix, suffix) = match conv {
Conv::X86Fastcall => ("@", "@"),
Conv::X86Stdcall => ("_", "@"),
Conv::X86VectorCall => ("", "@@"),
_ => {
if x86 {
undecorated.insert(0, '_');
}
return undecorated;
}
};

let args_in_bytes: u64 = args
.iter()
.map(|abi| abi.layout.size.bytes().next_multiple_of(target.pointer_width as u64 / 8))
.sum();
format!("{prefix}{undecorated}{suffix}{args_in_bytes}")
}

fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, String> {
// Build up a map from DefId to a `NativeLib` structure, where
// `NativeLib` internally contains information about
Expand Down
19 changes: 9 additions & 10 deletions compiler/rustc_codegen_ssa/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@

use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
use rustc_session::Session;
use rustc_span::Span;

use crate::base;
use crate::traits::BuilderMethods;
use crate::traits::*;

pub enum IntPredicate {
Expand Down Expand Up @@ -118,14 +116,15 @@ mod temp_stable_hash_impls {
}
}

pub fn langcall(tcx: TyCtxt<'_>, span: Option<Span>, msg: &str, li: LangItem) -> DefId {
tcx.lang_items().require(li).unwrap_or_else(|s| {
let msg = format!("{} {}", msg, s);
match span {
Some(span) => tcx.sess.span_fatal(span, &msg),
None => tcx.sess.fatal(&msg),
}
})
pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Bx,
span: Option<Span>,
li: LangItem,
) -> (Bx::FnAbiOfResult, Bx::Value) {
let tcx = bx.tcx();
let def_id = tcx.require_lang_item(li, span);
let instance = ty::Instance::mono(tcx, def_id);
(bx.fn_abi_of_instance(instance, ty::List::empty()), bx.get_fn_addr(instance))
}

// To avoid UB from LLVM, these two functions mask RHS with an
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#![feature(nll)]
#![feature(associated_type_bounds)]
#![feature(strict_provenance)]
#![feature(int_roundings)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

Expand Down
24 changes: 5 additions & 19 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
};

// Obtain the panic entry point.
let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
let instance = ty::Instance::mono(bx.tcx(), def_id);
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
let llfn = bx.get_fn_addr(instance);
let (fn_abi, llfn) = common::build_langcall(&bx, Some(span), lang_item);

// Codegen the actual panic invoke/call.
helper.do_call(self, &mut bx, fn_abi, llfn, &args, None, cleanup);
Expand All @@ -509,10 +505,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.set_debug_loc(&mut bx, terminator.source_info);

// Obtain the panic entry point.
let def_id = common::langcall(bx.tcx(), Some(span), "", LangItem::PanicNoUnwind);
let instance = ty::Instance::mono(bx.tcx(), def_id);
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
let llfn = bx.get_fn_addr(instance);
let (fn_abi, llfn) = common::build_langcall(&bx, Some(span), LangItem::PanicNoUnwind);

// Codegen the actual panic invoke/call.
helper.do_call(self, &mut bx, fn_abi, llfn, &[], None, None);
Expand Down Expand Up @@ -573,12 +566,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let location = self.get_caller_location(bx, source_info).immediate();

// Obtain the panic entry point.
// FIXME: dedup this with `codegen_assert_terminator` above.
let def_id =
common::langcall(bx.tcx(), Some(source_info.span), "", LangItem::Panic);
let instance = ty::Instance::mono(bx.tcx(), def_id);
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
let llfn = bx.get_fn_addr(instance);
let (fn_abi, llfn) =
common::build_langcall(bx, Some(source_info.span), LangItem::Panic);

// Codegen the actual panic invoke/call.
helper.do_call(
Expand Down Expand Up @@ -1440,10 +1429,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let llretty = self.landing_pad_type();
bx.cleanup_landing_pad(llretty, llpersonality);

let def_id = common::langcall(bx.tcx(), None, "", LangItem::PanicNoUnwind);
let instance = ty::Instance::mono(bx.tcx(), def_id);
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
let fn_ptr = bx.get_fn_addr(instance);
let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind);
let fn_ty = bx.fn_decl_backend_type(&fn_abi);

let llret = bx.call(fn_ty, fn_ptr, &[], None);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn target() -> Target {
Target {
llvm_target: "wasm64-unknown-unknown".into(),
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:10:20".into(),
data_layout: "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20".into(),
arch: "wasm64".into(),
options,
}
Expand Down
42 changes: 0 additions & 42 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2987,48 +2987,6 @@ impl<T, const N: usize> From<[T; N]> for Vec<T> {
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vec_from_array_ref", since = "1.61.0")]
impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> {
/// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
///
/// # Examples
///
/// ```
/// assert_eq!(Vec::from(b"raw"), vec![b'r', b'a', b'w']);
/// ```
#[cfg(not(test))]
fn from(s: &[T; N]) -> Vec<T> {
s.to_vec()
}

#[cfg(test)]
fn from(s: &[T; N]) -> Vec<T> {
crate::slice::to_vec(s, Global)
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vec_from_array_ref", since = "1.61.0")]
impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> {
/// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
///
/// # Examples
///
/// ```
/// assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
/// ```
#[cfg(not(test))]
fn from(s: &mut [T; N]) -> Vec<T> {
s.to_vec()
}

#[cfg(test)]
fn from(s: &mut [T; N]) -> Vec<T> {
crate::slice::to_vec(s, Global)
}
}

#[stable(feature = "vec_from_cow_slice", since = "1.14.0")]
impl<'a, T> From<Cow<'a, [T]>> for Vec<T>
where
Expand Down
3 changes: 2 additions & 1 deletion library/alloc/tests/c_str.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::borrow::Cow::{Borrowed, Owned};
use std::ffi::{c_char, CStr};
use std::ffi::CStr;
use std::os::raw::c_char;

#[test]
fn to_str() {
Expand Down
9 changes: 0 additions & 9 deletions library/std/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,6 @@ pub use self::os_str::{OsStr, OsString};
#[stable(feature = "core_c_void", since = "1.30.0")]
pub use core::ffi::c_void;

#[unstable(feature = "core_ffi_c", issue = "94501")]
pub use core::ffi::{
c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,
c_ulong, c_ulonglong, c_ushort,
};

#[unstable(feature = "c_size_t", issue = "88345")]
pub use core::ffi::{c_ptrdiff_t, c_size_t, c_ssize_t};

#[unstable(
feature = "c_variadic",
reason = "the `c_variadic` feature has not been properly tested on \
Expand Down
1 change: 0 additions & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,6 @@
// Only for re-exporting:
#![feature(assert_matches)]
#![feature(async_iterator)]
#![feature(c_size_t)]
#![feature(c_variadic)]
#![feature(cfg_accessible)]
#![feature(cfg_eval)]
Expand Down
8 changes: 8 additions & 0 deletions src/test/run-make/issue-96498/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# only-windows
# needs-rust-lld

-include ../../run-make-fulldeps/tools.mk

# Ensure that LLD can link
all:
$(RUSTC) -C linker=rust-lld foo.rs
4 changes: 4 additions & 0 deletions src/test/run-make/issue-96498/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#![crate_type = "cdylib"]

#[no_mangle]
extern "C" fn foo() {}
13 changes: 13 additions & 0 deletions src/test/ui/symbol-names/x86-stdcall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// build-pass
// only-x86-windows
#![crate_type = "cdylib"]
#![feature(abi_vectorcall)]

#[no_mangle]
extern "stdcall" fn foo(_: bool) {}

#[no_mangle]
extern "fastcall" fn bar(_: u8) {}

#[no_mangle]
extern "vectorcall" fn baz(_: u16) {}