From 3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:43 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_codegen_ssa/src/back/archive.rs | 2 +- compiler/rustc_codegen_ssa/src/back/link.rs | 146 ++++++--------------- compiler/rustc_codegen_ssa/src/back/linker.rs | 16 +-- compiler/rustc_codegen_ssa/src/back/metadata.rs | 1 + .../rustc_codegen_ssa/src/back/symbol_export.rs | 69 +++++----- compiler/rustc_codegen_ssa/src/back/write.rs | 8 +- 6 files changed, 93 insertions(+), 149 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src/back') 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}; ///
dylib
///
The metadata can be found in the `.rustc` section of the shared library.
/// +#[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 = Arc< - dyn Fn(TargetMachineFactoryConfig) -> Result<::TargetMachine, String> - + Send + dyn Fn( + TargetMachineFactoryConfig, + ) -> Result< + ::TargetMachine, + ::TargetMachineError, + > + Send + Sync, >; -- cgit v1.2.3