summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_ssa/src/back
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/back')
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs146
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs69
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs8
6 files changed, 93 insertions, 149 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index d3cd085cf..66ec8f5f5 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -203,7 +203,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
}
}
- self.src_archives.push((archive_path.to_owned(), archive_map));
+ self.src_archives.push((archive_path, archive_map));
Ok(())
}
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 34e042376..8bb143ed3 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -270,10 +270,9 @@ pub fn each_linked_rlib(
/// Create an 'rlib'.
///
-/// An rlib in its current incarnation is essentially a renamed .a file. The rlib primarily contains
-/// the object file of the crate, but it also contains all of the object files from native
-/// libraries. This is done by unzipping native libraries and inserting all of the contents into
-/// this archive.
+/// An rlib in its current incarnation is essentially a renamed .a file (with "dummy" object files).
+/// The rlib primarily contains the object file of the crate, but it also some of the object files
+/// from native libraries.
fn link_rlib<'a>(
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
@@ -347,44 +346,23 @@ fn link_rlib<'a>(
// loaded from the libraries found here and then encode that into the
// metadata of the rlib we're generating somehow.
for lib in codegen_results.crate_info.used_libraries.iter() {
- match lib.kind {
- NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
- if flavor == RlibFlavor::Normal && sess.opts.unstable_opts.packed_bundled_libs => {}
- NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
- if flavor == RlibFlavor::Normal =>
- {
- // Don't allow mixing +bundle with +whole_archive since an rlib may contain
- // multiple native libs, some of which are +whole-archive and some of which are
- // -whole-archive and it isn't clear how we can currently handle such a
- // situation correctly.
- // See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897
- sess.emit_err(errors::IncompatibleLinkingModifiers);
- }
- NativeLibKind::Static { bundle: None | Some(true), .. } => {}
- NativeLibKind::Static { bundle: Some(false), .. }
- | NativeLibKind::Dylib { .. }
- | NativeLibKind::Framework { .. }
- | NativeLibKind::RawDylib
- | NativeLibKind::LinkArg
- | NativeLibKind::Unspecified => continue,
- }
- if let Some(name) = lib.name {
- let location =
+ let NativeLibKind::Static { bundle: None | Some(true), whole_archive } = lib.kind else {
+ continue;
+ };
+ if whole_archive == Some(true) && !codegen_results.crate_info.feature_packed_bundled_libs {
+ sess.emit_err(errors::IncompatibleLinkingModifiers);
+ }
+ if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename {
+ let path = find_native_static_library(filename.as_str(), true, &lib_search_paths, sess);
+ let src = read(path).map_err(|e| sess.emit_fatal(errors::ReadFileError {message: e }))?;
+ let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src);
+ let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
+ packed_bundled_libs.push(wrapper_file);
+ } else if let Some(name) = lib.name {
+ let path =
find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
- if sess.opts.unstable_opts.packed_bundled_libs && flavor == RlibFlavor::Normal {
- let filename = lib.filename.unwrap();
- let lib_path =
- find_native_static_library(filename.as_str(), true, &lib_search_paths, sess);
- let src = read(lib_path)
- .map_err(|e| sess.emit_fatal(errors::ReadFileError { message: e }))?;
- let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src);
- let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
- packed_bundled_libs.push(wrapper_file);
- continue;
- }
- ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| {
- sess.emit_fatal(errors::AddNativeLibrary { library_path: location, error });
- });
+ ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| {
+ sess.emit_fatal(errors::AddNativeLibrary { library_path: path, error })});
}
}
@@ -516,36 +494,14 @@ fn link_staticlib<'a>(
&codegen_results.crate_info,
Some(CrateType::Staticlib),
&mut |cnum, path| {
- let name = codegen_results.crate_info.crate_name[&cnum];
- let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
-
- // Here when we include the rlib into our staticlib we need to make a
- // decision whether to include the extra object files along the way.
- // These extra object files come from statically included native
- // libraries, but they may be cfg'd away with #[link(cfg(..))].
- //
- // This unstable feature, though, only needs liblibc to work. The only
- // use case there is where musl is statically included in liblibc.rlib,
- // so if we don't want the included version we just need to skip it. As
- // a result the logic here is that if *any* linked library is cfg'd away
- // we just skip all object files.
- //
- // Clearly this is not sufficient for a general purpose feature, and
- // we'd want to read from the library's metadata to determine which
- // object files come from where and selectively skip them.
- let skip_object_files = native_libs.iter().any(|lib| {
- matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
- && !relevant_lib(sess, lib)
- });
-
let lto = are_upstream_rust_objects_already_included(sess)
&& !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
- // Ignoring obj file starting with the crate name
- // as simple comparison is not enough - there
- // might be also an extra name suffix
- let obj_start = name.as_str().to_owned();
+ let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter();
+ let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, &lib));
+ let relevant_libs: FxHashSet<_> = relevant.filter_map(|lib| lib.filename).collect();
+ let bundled_libs: FxHashSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
ab.add_archive(
path,
Box::new(move |fname: &str| {
@@ -559,20 +515,25 @@ fn link_staticlib<'a>(
return true;
}
- // Otherwise if this is *not* a rust object and we're skipping
- // objects then skip this file
- if skip_object_files
- && (!fname.starts_with(&obj_start) || !fname.ends_with(".o"))
- {
+ // Skip objects for bundled libs.
+ if bundled_libs.contains(&Symbol::intern(fname)) {
return true;
}
- // ok, don't skip this
false
}),
)
.unwrap();
+ archive_builder_builder
+ .extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs)
+ .unwrap_or_else(|e| sess.emit_fatal(e));
+ for filename in relevant_libs {
+ let joined = tempdir.as_ref().join(filename.as_str());
+ let path = joined.as_path();
+ ab.add_archive(path, Box::new(|_| false)).unwrap();
+ }
+
all_native_libs
.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
},
@@ -599,7 +560,8 @@ fn link_dwarf_object<'a>(
cg_results: &CodegenResults,
executable_out_filename: &Path,
) {
- let dwp_out_filename = executable_out_filename.with_extension("dwp");
+ let mut dwp_out_filename = executable_out_filename.to_path_buf().into_os_string();
+ dwp_out_filename.push(".dwp");
debug!(?dwp_out_filename, ?executable_out_filename);
#[derive(Default)]
@@ -1302,12 +1264,6 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> (bool, bool) {
return (false, false);
}
- // If we're only producing artifacts that are archives, no need to preserve
- // the objects as they're losslessly contained inside the archives.
- if sess.crate_types().iter().all(|&x| x.is_archive()) {
- return (false, false);
- }
-
match (sess.split_debuginfo(), sess.opts.unstable_opts.split_dwarf_kind) {
// If there is no split debuginfo then do not preserve objects.
(SplitDebuginfo::Off, _) => (false, false),
@@ -2070,7 +2026,7 @@ fn linker_with_args<'a>(
.native_libraries
.iter()
.filter_map(|(cnum, libraries)| {
- (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then(|| libraries)
+ (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then_some(libraries)
})
.flatten();
for (raw_dylib_name, raw_dylib_imports) in
@@ -2597,18 +2553,8 @@ fn add_static_crate<'a>(
cmd.link_rlib(&fix_windows_verbatim_for_gcc(path));
};
- // See the comment above in `link_staticlib` and `link_rlib` for why if
- // there's a static library that's not relevant we skip all object
- // files.
- let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
- let skip_native = native_libs.iter().any(|lib| {
- matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
- && !relevant_lib(sess, lib)
- });
-
- if (!are_upstream_rust_objects_already_included(sess)
- || ignored_for_lto(sess, &codegen_results.crate_info, cnum))
- && !skip_native
+ if !are_upstream_rust_objects_already_included(sess)
+ || ignored_for_lto(sess, &codegen_results.crate_info, cnum)
{
link_upstream(cratepath);
return;
@@ -2639,17 +2585,13 @@ fn add_static_crate<'a>(
let is_rust_object =
canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f);
- // If we've been requested to skip all native object files
- // (those not generated by the rust compiler) then we can skip
- // this file. See above for why we may want to do this.
- let skip_because_cfg_say_so = skip_native && !is_rust_object;
-
// If we're performing LTO and this is a rust-generated object
// file, then we don't need the object file as it's part of the
// LTO module. Note that `#![no_builtins]` is excluded from LTO,
// though, so we let that object file slide.
- let skip_because_lto =
- upstream_rust_objects_already_included && is_rust_object && is_builtins;
+ if upstream_rust_objects_already_included && is_rust_object && is_builtins {
+ return true;
+ }
// We skip native libraries because:
// 1. This native libraries won't be used from the generated rlib,
@@ -2660,10 +2602,6 @@ fn add_static_crate<'a>(
return true;
}
- if skip_because_cfg_say_so || skip_because_lto {
- return true;
- }
-
false
}),
) {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index eaf1e9817..52c01b423 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -473,13 +473,13 @@ impl<'a> Linker for GccLinker<'a> {
self.cmd.arg(path);
}
fn full_relro(&mut self) {
- self.linker_args(&["-zrelro", "-znow"]);
+ self.linker_args(&["-z", "relro", "-z", "now"]);
}
fn partial_relro(&mut self) {
- self.linker_arg("-zrelro");
+ self.linker_args(&["-z", "relro"]);
}
fn no_relro(&mut self) {
- self.linker_arg("-znorelro");
+ self.linker_args(&["-z", "norelro"]);
}
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
@@ -758,7 +758,7 @@ impl<'a> Linker for GccLinker<'a> {
if self.sess.target.is_like_windows {
self.linker_arg("--nxcompat");
} else if self.is_gnu {
- self.linker_arg("-znoexecstack");
+ self.linker_args(&["-z", "noexecstack"]);
}
}
@@ -1364,16 +1364,16 @@ impl<'a> Linker for L4Bender<'a> {
}
fn full_relro(&mut self) {
- self.cmd.arg("-zrelro");
- self.cmd.arg("-znow");
+ self.cmd.arg("-z").arg("relro");
+ self.cmd.arg("-z").arg("now");
}
fn partial_relro(&mut self) {
- self.cmd.arg("-zrelro");
+ self.cmd.arg("-z").arg("relro");
}
fn no_relro(&mut self) {
- self.cmd.arg("-znorelro");
+ self.cmd.arg("-z").arg("norelro");
}
fn cmd(&mut self) -> &mut Command {
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 7d3c14fec..019ec0758 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -33,6 +33,7 @@ use rustc_target::spec::{RelocModel, Target};
/// <dt>dylib</dt>
/// <dd>The metadata can be found in the `.rustc` section of the shared library.</dd>
/// </dl>
+#[derive(Debug)]
pub struct DefaultMetadataLoader;
fn load_metadata_with(
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 57a99e74c..067a3e167 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -2,9 +2,8 @@ use std::collections::hash_map::Entry::*;
use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
use rustc_data_structures::fx::FxHashMap;
-use rustc_hir as hir;
+use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
-use rustc_hir::Node;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
@@ -12,7 +11,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::{self, SymbolName, TyCtxt};
+use rustc_middle::ty::{self, DefIdTree, SymbolName, TyCtxt};
use rustc_session::config::{CrateType, OomStrategy};
use rustc_target::spec::SanitizerSet;
@@ -74,32 +73,34 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
//
// As a result, if this id is an FFI item (foreign item) then we only
// let it through if it's included statically.
- match tcx.hir().get_by_def_id(def_id) {
- Node::ForeignItem(..) => {
- tcx.native_library(def_id).map_or(false, |library| library.kind.is_statically_included()).then_some(def_id)
- }
+ if let Some(parent_id) = tcx.opt_local_parent(def_id)
+ && let DefKind::ForeignMod = tcx.def_kind(parent_id)
+ {
+ let library = tcx.native_library(def_id)?;
+ return library.kind.is_statically_included().then_some(def_id);
+ }
- // Only consider nodes that actually have exported symbols.
- Node::Item(&hir::Item {
- kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn(..),
- ..
- })
- | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
- let generics = tcx.generics_of(def_id);
- if !generics.requires_monomorphization(tcx)
- // Functions marked with #[inline] are codegened with "internal"
- // linkage and are not exported unless marked with an extern
- // indicator
- && (!Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx)
- || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator())
- {
- Some(def_id)
- } else {
- None
- }
- }
+ // Only consider nodes that actually have exported symbols.
+ match tcx.def_kind(def_id) {
+ DefKind::Fn | DefKind::Static(_) => {}
+ DefKind::AssocFn if tcx.impl_of_method(def_id.to_def_id()).is_some() => {}
+ _ => return None,
+ };
- _ => None,
+ let generics = tcx.generics_of(def_id);
+ if generics.requires_monomorphization(tcx) {
+ return None;
+ }
+
+ // Functions marked with #[inline] are codegened with "internal"
+ // linkage and are not exported unless marked with an extern
+ // indicator
+ if !Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx)
+ || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator()
+ {
+ Some(def_id)
+ } else {
+ None
}
})
.map(|def_id| {
@@ -118,7 +119,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())),
export_level
);
- (def_id.to_def_id(), SymbolExportInfo {
+ let info = SymbolExportInfo {
level: export_level,
kind: if tcx.is_static(def_id.to_def_id()) {
if codegen_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
@@ -130,8 +131,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
SymbolExportKind::Text
},
used: codegen_attrs.flags.contains(CodegenFnAttrFlags::USED)
- || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) || used,
- })
+ || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
+ || used,
+ };
+ (def_id.to_def_id(), info)
})
.collect();
@@ -370,7 +373,7 @@ fn upstream_monomorphizations_provider(
ExportedSymbol::Generic(def_id, substs) => (def_id, substs),
ExportedSymbol::DropGlue(ty) => {
if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
- (drop_in_place_fn_def_id, tcx.intern_substs(&[ty.into()]))
+ (drop_in_place_fn_def_id, tcx.mk_substs(&[ty.into()]))
} else {
// `drop_in_place` in place does not exist, don't try
// to use it.
@@ -457,9 +460,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel
let target = &tcx.sess.target.llvm_target;
// WebAssembly cannot export data symbols, so reduce their export level
if target.contains("emscripten") {
- if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) =
- tcx.hir().get_if_local(sym_def_id)
- {
+ if let DefKind::Static(_) = tcx.def_kind(sym_def_id) {
return SymbolExportLevel::Rust;
}
}
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 9f1614af7..8508ab875 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -305,8 +305,12 @@ impl TargetMachineFactoryConfig {
}
pub type TargetMachineFactoryFn<B> = Arc<
- dyn Fn(TargetMachineFactoryConfig) -> Result<<B as WriteBackendMethods>::TargetMachine, String>
- + Send
+ dyn Fn(
+ TargetMachineFactoryConfig,
+ ) -> Result<
+ <B as WriteBackendMethods>::TargetMachine,
+ <B as WriteBackendMethods>::TargetMachineError,
+ > + Send
+ Sync,
>;