[Arm64EC] Only decorate functions with #
This commit is contained in:
parent
f5d3fe273b
commit
6dabf7ea3a
11 changed files with 201 additions and 54 deletions
|
|
@ -364,7 +364,12 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
|
||||
if !def_id.is_local() {
|
||||
let needs_dll_storage_attr = self.use_dll_storage_attrs
|
||||
&& !self.tcx.is_foreign_item(def_id)
|
||||
// If the symbol is a foreign item, then don't automatically apply DLLImport, as
|
||||
// we'll rely on the #[link] attribute instead. BUT, if this is an internal symbol
|
||||
// then it may be generated by the compiler in some crate, so we do need to apply
|
||||
// DLLImport when linking with the MSVC linker.
|
||||
&& (!self.tcx.is_foreign_item(def_id)
|
||||
|| (self.sess().target.is_like_msvc && fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)))
|
||||
// Local definitions can never be imported, so we must not apply
|
||||
// the DLLImport annotation.
|
||||
&& !dso_local
|
||||
|
|
|
|||
|
|
@ -337,7 +337,12 @@ pub(crate) trait Linker {
|
|||
fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]);
|
||||
fn no_crt_objects(&mut self);
|
||||
fn no_default_libraries(&mut self);
|
||||
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
tmpdir: &Path,
|
||||
crate_type: CrateType,
|
||||
symbols: &[(String, SymbolExportKind)],
|
||||
);
|
||||
fn subsystem(&mut self, subsystem: &str);
|
||||
fn linker_plugin_lto(&mut self);
|
||||
fn add_eh_frame_header(&mut self) {}
|
||||
|
|
@ -770,7 +775,12 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
tmpdir: &Path,
|
||||
crate_type: CrateType,
|
||||
symbols: &[(String, SymbolExportKind)],
|
||||
) {
|
||||
// Symbol visibility in object files typically takes care of this.
|
||||
if crate_type == CrateType::Executable {
|
||||
let should_export_executable_symbols =
|
||||
|
|
@ -799,7 +809,7 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
// Write a plain, newline-separated list of symbols
|
||||
let res: io::Result<()> = try {
|
||||
let mut f = File::create_buffered(&path)?;
|
||||
for sym in symbols {
|
||||
for (sym, _) in symbols {
|
||||
debug!(" _{sym}");
|
||||
writeln!(f, "_{sym}")?;
|
||||
}
|
||||
|
|
@ -814,11 +824,12 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
// .def file similar to MSVC one but without LIBRARY section
|
||||
// because LD doesn't like when it's empty
|
||||
writeln!(f, "EXPORTS")?;
|
||||
for symbol in symbols {
|
||||
for (symbol, kind) in symbols {
|
||||
let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" };
|
||||
debug!(" _{symbol}");
|
||||
// Quote the name in case it's reserved by linker in some way
|
||||
// (this accounts for names with dots in particular).
|
||||
writeln!(f, " \"{symbol}\"")?;
|
||||
writeln!(f, " \"{symbol}\"{kind_marker}")?;
|
||||
}
|
||||
};
|
||||
if let Err(error) = res {
|
||||
|
|
@ -831,7 +842,7 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
writeln!(f, "{{")?;
|
||||
if !symbols.is_empty() {
|
||||
writeln!(f, " global:")?;
|
||||
for sym in symbols {
|
||||
for (sym, _) in symbols {
|
||||
debug!(" {sym};");
|
||||
writeln!(f, " {sym};")?;
|
||||
}
|
||||
|
|
@ -1098,7 +1109,12 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
// crates. Upstream rlibs may be linked statically to this dynamic library,
|
||||
// in which case they may continue to transitively be used and hence need
|
||||
// their symbols exported.
|
||||
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
tmpdir: &Path,
|
||||
crate_type: CrateType,
|
||||
symbols: &[(String, SymbolExportKind)],
|
||||
) {
|
||||
// Symbol visibility takes care of this typically
|
||||
if crate_type == CrateType::Executable {
|
||||
let should_export_executable_symbols =
|
||||
|
|
@ -1116,9 +1132,10 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
// straight to exports.
|
||||
writeln!(f, "LIBRARY")?;
|
||||
writeln!(f, "EXPORTS")?;
|
||||
for symbol in symbols {
|
||||
for (symbol, kind) in symbols {
|
||||
let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" };
|
||||
debug!(" _{symbol}");
|
||||
writeln!(f, " {symbol}")?;
|
||||
writeln!(f, " {symbol}{kind_marker}")?;
|
||||
}
|
||||
};
|
||||
if let Err(error) = res {
|
||||
|
|
@ -1259,14 +1276,19 @@ impl<'a> Linker for EmLinker<'a> {
|
|||
self.cc_arg("-nodefaultlibs");
|
||||
}
|
||||
|
||||
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
_tmpdir: &Path,
|
||||
_crate_type: CrateType,
|
||||
symbols: &[(String, SymbolExportKind)],
|
||||
) {
|
||||
debug!("EXPORTED SYMBOLS:");
|
||||
|
||||
self.cc_arg("-s");
|
||||
|
||||
let mut arg = OsString::from("EXPORTED_FUNCTIONS=");
|
||||
let encoded = serde_json::to_string(
|
||||
&symbols.iter().map(|sym| "_".to_owned() + sym).collect::<Vec<_>>(),
|
||||
&symbols.iter().map(|(sym, _)| "_".to_owned() + sym).collect::<Vec<_>>(),
|
||||
)
|
||||
.unwrap();
|
||||
debug!("{encoded}");
|
||||
|
|
@ -1428,8 +1450,13 @@ impl<'a> Linker for WasmLd<'a> {
|
|||
|
||||
fn no_default_libraries(&mut self) {}
|
||||
|
||||
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
|
||||
for sym in symbols {
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
_tmpdir: &Path,
|
||||
_crate_type: CrateType,
|
||||
symbols: &[(String, SymbolExportKind)],
|
||||
) {
|
||||
for (sym, _) in symbols {
|
||||
self.link_args(&["--export", sym]);
|
||||
}
|
||||
|
||||
|
|
@ -1563,7 +1590,7 @@ impl<'a> Linker for L4Bender<'a> {
|
|||
self.cc_arg("-nostdlib");
|
||||
}
|
||||
|
||||
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
|
||||
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[(String, SymbolExportKind)]) {
|
||||
// ToDo, not implemented, copy from GCC
|
||||
self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented);
|
||||
}
|
||||
|
|
@ -1720,12 +1747,17 @@ impl<'a> Linker for AixLinker<'a> {
|
|||
|
||||
fn no_default_libraries(&mut self) {}
|
||||
|
||||
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
tmpdir: &Path,
|
||||
_crate_type: CrateType,
|
||||
symbols: &[(String, SymbolExportKind)],
|
||||
) {
|
||||
let path = tmpdir.join("list.exp");
|
||||
let res: io::Result<()> = try {
|
||||
let mut f = File::create_buffered(&path)?;
|
||||
// FIXME: use llvm-nm to generate export list.
|
||||
for symbol in symbols {
|
||||
for (symbol, _) in symbols {
|
||||
debug!(" _{symbol}");
|
||||
writeln!(f, " {symbol}")?;
|
||||
}
|
||||
|
|
@ -1769,9 +1801,12 @@ fn for_each_exported_symbols_include_dep<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
|
||||
pub(crate) fn exported_symbols(
|
||||
tcx: TyCtxt<'_>,
|
||||
crate_type: CrateType,
|
||||
) -> Vec<(String, SymbolExportKind)> {
|
||||
if let Some(ref exports) = tcx.sess.target.override_export_symbols {
|
||||
return exports.iter().map(ToString::to_string).collect();
|
||||
return exports.iter().map(|name| (name.to_string(), SymbolExportKind::Text)).collect();
|
||||
}
|
||||
|
||||
if let CrateType::ProcMacro = crate_type {
|
||||
|
|
@ -1781,7 +1816,10 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
|
|||
}
|
||||
}
|
||||
|
||||
fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
|
||||
fn exported_symbols_for_non_proc_macro(
|
||||
tcx: TyCtxt<'_>,
|
||||
crate_type: CrateType,
|
||||
) -> Vec<(String, SymbolExportKind)> {
|
||||
let mut symbols = Vec::new();
|
||||
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
|
||||
for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
|
||||
|
|
@ -1789,17 +1827,18 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
|
|||
// from any cdylib. The latter doesn't work anyway as we use hidden visibility for
|
||||
// compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
|
||||
if info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) {
|
||||
symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate(
|
||||
tcx, symbol, cnum,
|
||||
symbols.push((
|
||||
symbol_export::exporting_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
|
||||
info.kind,
|
||||
));
|
||||
symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, cnum);
|
||||
symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, info, cnum);
|
||||
}
|
||||
});
|
||||
|
||||
symbols
|
||||
}
|
||||
|
||||
fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
|
||||
fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<(String, SymbolExportKind)> {
|
||||
// `exported_symbols` will be empty when !should_codegen.
|
||||
if !tcx.sess.opts.output_types.should_codegen() {
|
||||
return Vec::new();
|
||||
|
|
@ -1809,7 +1848,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
|
|||
let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
|
||||
let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
|
||||
|
||||
vec![proc_macro_decls_name, metadata_symbol_name]
|
||||
vec![
|
||||
(proc_macro_decls_name, SymbolExportKind::Text),
|
||||
(metadata_symbol_name, SymbolExportKind::Text),
|
||||
]
|
||||
}
|
||||
|
||||
pub(crate) fn linked_symbols(
|
||||
|
|
@ -1831,7 +1873,9 @@ pub(crate) fn linked_symbols(
|
|||
|| info.used
|
||||
{
|
||||
symbols.push((
|
||||
symbol_export::linking_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
|
||||
symbol_export::linking_symbol_name_for_instance_in_crate(
|
||||
tcx, symbol, info.kind, cnum,
|
||||
),
|
||||
info.kind,
|
||||
));
|
||||
}
|
||||
|
|
@ -1906,7 +1950,13 @@ impl<'a> Linker for PtxLinker<'a> {
|
|||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {}
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
_tmpdir: &Path,
|
||||
_crate_type: CrateType,
|
||||
_symbols: &[(String, SymbolExportKind)],
|
||||
) {
|
||||
}
|
||||
|
||||
fn subsystem(&mut self, _subsystem: &str) {}
|
||||
|
||||
|
|
@ -1975,10 +2025,15 @@ impl<'a> Linker for LlbcLinker<'a> {
|
|||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
_tmpdir: &Path,
|
||||
_crate_type: CrateType,
|
||||
symbols: &[(String, SymbolExportKind)],
|
||||
) {
|
||||
match _crate_type {
|
||||
CrateType::Cdylib => {
|
||||
for sym in symbols {
|
||||
for (sym, _) in symbols {
|
||||
self.link_args(&["--export-symbol", sym]);
|
||||
}
|
||||
}
|
||||
|
|
@ -2052,11 +2107,16 @@ impl<'a> Linker for BpfLinker<'a> {
|
|||
|
||||
fn ehcont_guard(&mut self) {}
|
||||
|
||||
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
|
||||
fn export_symbols(
|
||||
&mut self,
|
||||
tmpdir: &Path,
|
||||
_crate_type: CrateType,
|
||||
symbols: &[(String, SymbolExportKind)],
|
||||
) {
|
||||
let path = tmpdir.join("symbols");
|
||||
let res: io::Result<()> = try {
|
||||
let mut f = File::create_buffered(&path)?;
|
||||
for sym in symbols {
|
||||
for (sym, _) in symbols {
|
||||
writeln!(f, "{sym}")?;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -692,6 +692,7 @@ fn calling_convention_for_symbol<'tcx>(
|
|||
pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
symbol: ExportedSymbol<'tcx>,
|
||||
export_kind: SymbolExportKind,
|
||||
instantiating_crate: CrateNum,
|
||||
) -> String {
|
||||
let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
|
||||
|
|
@ -712,8 +713,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
|
|||
let prefix = match &target.arch[..] {
|
||||
"x86" => Some('_'),
|
||||
"x86_64" => None,
|
||||
"arm64ec" => Some('#'),
|
||||
// Only x86/64 use symbol decorations.
|
||||
// Only functions are decorated for arm64ec.
|
||||
"arm64ec" if export_kind == SymbolExportKind::Text => Some('#'),
|
||||
// Only x86/64 and arm64ec use symbol decorations.
|
||||
_ => return undecorated,
|
||||
};
|
||||
|
||||
|
|
@ -753,9 +755,10 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
|
|||
/// Add it to the symbols list for all kernel functions, so that it is exported in the linked
|
||||
/// object.
|
||||
pub(crate) fn extend_exported_symbols<'tcx>(
|
||||
symbols: &mut Vec<String>,
|
||||
symbols: &mut Vec<(String, SymbolExportKind)>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
symbol: ExportedSymbol<'tcx>,
|
||||
info: SymbolExportInfo,
|
||||
instantiating_crate: CrateNum,
|
||||
) {
|
||||
let (conv, _) = calling_convention_for_symbol(tcx, symbol);
|
||||
|
|
@ -767,7 +770,7 @@ pub(crate) fn extend_exported_symbols<'tcx>(
|
|||
let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
|
||||
|
||||
// Add the symbol for the kernel descriptor (with .kd suffix)
|
||||
symbols.push(format!("{undecorated}.kd"));
|
||||
symbols.push((format!("{undecorated}.kd"), info.kind));
|
||||
}
|
||||
|
||||
fn maybe_emutls_symbol_name<'tcx>(
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
|||
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
|
||||
use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hir::ItemId;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{ItemId, Target};
|
||||
use rustc_metadata::EncodedMetadata;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
|
||||
|
|
@ -1038,21 +1038,35 @@ impl CrateInfo {
|
|||
// by the compiler, but that's ok because all this stuff is unstable anyway.
|
||||
let target = &tcx.sess.target;
|
||||
if !are_upstream_rust_objects_already_included(tcx.sess) {
|
||||
let missing_weak_lang_items: FxIndexSet<Symbol> = info
|
||||
let add_prefix = match (target.is_like_windows, target.arch.as_ref()) {
|
||||
(true, "x86") => |name: String, _: SymbolExportKind| format!("_{name}"),
|
||||
(true, "arm64ec") => {
|
||||
// Only functions are decorated for arm64ec.
|
||||
|name: String, export_kind: SymbolExportKind| match export_kind {
|
||||
SymbolExportKind::Text => format!("#{name}"),
|
||||
_ => name,
|
||||
}
|
||||
}
|
||||
_ => |name: String, _: SymbolExportKind| name,
|
||||
};
|
||||
let missing_weak_lang_items: FxIndexSet<(Symbol, SymbolExportKind)> = info
|
||||
.used_crates
|
||||
.iter()
|
||||
.flat_map(|&cnum| tcx.missing_lang_items(cnum))
|
||||
.filter(|l| l.is_weak())
|
||||
.filter_map(|&l| {
|
||||
let name = l.link_name()?;
|
||||
lang_items::required(tcx, l).then_some(name)
|
||||
let export_kind = match l.target() {
|
||||
Target::Fn => SymbolExportKind::Text,
|
||||
Target::Static => SymbolExportKind::Data,
|
||||
_ => bug!(
|
||||
"Don't know what the export kind is for lang item of kind {:?}",
|
||||
l.target()
|
||||
),
|
||||
};
|
||||
lang_items::required(tcx, l).then_some((name, export_kind))
|
||||
})
|
||||
.collect();
|
||||
let prefix = match (target.is_like_windows, target.arch.as_ref()) {
|
||||
(true, "x86") => "_",
|
||||
(true, "arm64ec") => "#",
|
||||
_ => "",
|
||||
};
|
||||
|
||||
// This loop only adds new items to values of the hash map, so the order in which we
|
||||
// iterate over the values is not important.
|
||||
|
|
@ -1065,10 +1079,13 @@ impl CrateInfo {
|
|||
.for_each(|(_, linked_symbols)| {
|
||||
let mut symbols = missing_weak_lang_items
|
||||
.iter()
|
||||
.map(|item| {
|
||||
.map(|(item, export_kind)| {
|
||||
(
|
||||
format!("{prefix}{}", mangle_internal_symbol(tcx, item.as_str())),
|
||||
SymbolExportKind::Text,
|
||||
add_prefix(
|
||||
mangle_internal_symbol(tcx, item.as_str()),
|
||||
*export_kind,
|
||||
),
|
||||
*export_kind,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
|
@ -1083,12 +1100,12 @@ impl CrateInfo {
|
|||
// errors.
|
||||
linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| {
|
||||
(
|
||||
format!(
|
||||
"{prefix}{}",
|
||||
add_prefix(
|
||||
mangle_internal_symbol(
|
||||
tcx,
|
||||
global_fn_name(method.name).as_str()
|
||||
)
|
||||
global_fn_name(method.name).as_str(),
|
||||
),
|
||||
SymbolExportKind::Text,
|
||||
),
|
||||
SymbolExportKind::Text,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ pub struct CrateInfo {
|
|||
pub target_cpu: String,
|
||||
pub target_features: Vec<String>,
|
||||
pub crate_types: Vec<CrateType>,
|
||||
pub exported_symbols: UnordMap<CrateType, Vec<String>>,
|
||||
pub exported_symbols: UnordMap<CrateType, Vec<(String, SymbolExportKind)>>,
|
||||
pub linked_symbols: FxIndexMap<CrateType, Vec<(String, SymbolExportKind)>>,
|
||||
pub local_crate_name: Symbol,
|
||||
pub compiler_builtins: Option<CrateNum>,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ impl SymbolExportLevel {
|
|||
}
|
||||
|
||||
/// Kind of exported symbols.
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable)]
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable, Hash)]
|
||||
pub enum SymbolExportKind {
|
||||
Text,
|
||||
Data,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,19 @@ use crate::spec::{BinaryFormat, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo
|
|||
pub(crate) fn opts() -> TargetOptions {
|
||||
// Suppress the verbose logo and authorship debugging output, which would needlessly
|
||||
// clog any log files.
|
||||
let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/NOLOGO"]);
|
||||
let pre_link_args = TargetOptions::link_args(
|
||||
LinkerFlavor::Msvc(Lld::No),
|
||||
&[
|
||||
"/NOLOGO",
|
||||
// "Symbol is marked as dllimport, but defined in an object file"
|
||||
// Harmless warning that flags a potential performance improvement: marking a symbol as
|
||||
// dllimport indirects usage via the `__imp_` symbol, which isn't required if the symbol
|
||||
// is in the current binary. This is tripped by __rust_no_alloc_shim_is_unstable as it
|
||||
// is generated by the compiler, but marked as a foreign item (hence the dllimport) in
|
||||
// the standard library.
|
||||
"/IGNORE:4286",
|
||||
],
|
||||
);
|
||||
|
||||
TargetOptions {
|
||||
linker_flavor: LinkerFlavor::Msvc(Lld::No),
|
||||
|
|
|
|||
23
tests/run-make/arm64ec-import-export-static/export.rs
Normal file
23
tests/run-make/arm64ec-import-export-static/export.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#![crate_type = "dylib"]
|
||||
#![allow(internal_features)]
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_core]
|
||||
#![no_std]
|
||||
|
||||
// This is needed because of #![no_core]:
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "sync"]
|
||||
trait Sync {}
|
||||
impl Sync for i32 {}
|
||||
#[lang = "copy"]
|
||||
pub trait Copy {}
|
||||
impl Copy for i32 {}
|
||||
#[lang = "drop_in_place"]
|
||||
pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}
|
||||
#[no_mangle]
|
||||
extern "system" fn _DllMainCRTStartup(_: *const u8, _: u32, _: *const u8) -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
pub static VALUE: i32 = 42;
|
||||
12
tests/run-make/arm64ec-import-export-static/import.rs
Normal file
12
tests/run-make/arm64ec-import-export-static/import.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#![crate_type = "cdylib"]
|
||||
#![allow(internal_features)]
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
|
||||
extern crate export;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn func() -> i32 {
|
||||
export::VALUE
|
||||
}
|
||||
15
tests/run-make/arm64ec-import-export-static/rmake.rs
Normal file
15
tests/run-make/arm64ec-import-export-static/rmake.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Test that a static can be exported from one crate and imported into another.
|
||||
//
|
||||
// This was broken for Arm64EC as only functions, not variables, should be
|
||||
// decorated with `#`.
|
||||
// See https://github.com/rust-lang/rust/issues/138541
|
||||
|
||||
//@ needs-llvm-components: aarch64
|
||||
//@ only-windows
|
||||
|
||||
use run_make_support::rustc;
|
||||
|
||||
fn main() {
|
||||
rustc().input("export.rs").target("aarch64-pc-windows-msvc").panic("abort").run();
|
||||
rustc().input("import.rs").target("aarch64-pc-windows-msvc").panic("abort").run();
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#[cfg_attr(windows, link(name = "library.dll.lib", modifiers = "+verbatim"))]
|
||||
#[cfg_attr(windows, link(name = "library", kind = "raw-dylib"))]
|
||||
#[cfg_attr(not(windows), link(name = "library"))]
|
||||
extern "C" {
|
||||
fn overflow();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue