Skip to content

Commit

Permalink
Rollup merge of rust-lang#108017 - chbaker0:fix-105967, r=chbaker0
Browse files Browse the repository at this point in the history
Add `--no-undefined-version` link flag and fix associated breakage

LLVM upstream sets `--no-undefined-version` by default in lld: https://reviews.llvm.org/D135402.

Due to a bug in how version scripts are generated, this breaks the `dylib` output type for most crates. See rust-lang#105967 (comment) for details.

This PR adds the flag to gcc flavor linkers in anticipation of this LLVM change rolling in, and patches `rustc` to not attempt to export `__rust_*` allocator symbols when they weren't generated.

Fixes rust-lang#105967
  • Loading branch information
matthiaskrgr authored Mar 10, 2023
2 parents 7f5bffa + cb41803 commit c734034
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 40 deletions.
28 changes: 10 additions & 18 deletions compiler/rustc_codegen_cranelift/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use crate::prelude::*;

use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
use rustc_session::config::OomStrategy;
use rustc_span::symbol::sym;

Expand All @@ -13,24 +14,15 @@ pub(crate) fn codegen(
module: &mut impl Module,
unwind_context: &mut UnwindContext,
) -> bool {
let any_dynamic_crate = tcx.dependency_formats(()).iter().any(|(_, list)| {
use rustc_middle::middle::dependency_format::Linkage;
list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
if any_dynamic_crate {
false
} else if let Some(kind) = tcx.allocator_kind(()) {
codegen_inner(
module,
unwind_context,
kind,
tcx.alloc_error_handler_kind(()).unwrap(),
tcx.sess.opts.unstable_opts.oom,
);
true
} else {
false
}
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
codegen_inner(
module,
unwind_context,
kind,
tcx.alloc_error_handler_kind(()).unwrap(),
tcx.sess.opts.unstable_opts.oom,
);
true
}

fn codegen_inner(
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ impl<'a> Linker for GccLinker<'a> {
let mut arg = OsString::from("--version-script=");
arg.push(path);
self.linker_arg(arg);
self.linker_arg("--no-undefined-version");
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::base::allocator_kind_for_codegen;

use std::collections::hash_map::Entry::*;

use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
Expand Down Expand Up @@ -200,7 +202,8 @@ fn exported_symbols_provider_local(
));
}

if tcx.allocator_kind(()).is_some() {
// Mark allocator shim symbols as exported only if they were generated.
if allocator_kind_for_codegen(tcx).is_some() {
for symbol_name in ALLOCATOR_METHODS
.iter()
.map(|method| format!("__rust_{}", method.name))
Expand Down
44 changes: 23 additions & 21 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::mir::place::PlaceRef;
use crate::traits::*;
use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCodegen, ModuleKind};

use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
Expand Down Expand Up @@ -545,6 +546,23 @@ pub fn collect_debugger_visualizers_transitive(
.collect::<BTreeSet<_>>()
}

/// Decide allocator kind to codegen. If `Some(_)` this will be the same as
/// `tcx.allocator_kind`, but it may be `None` in more cases (e.g. if using
/// allocator definitions from a dylib dependency).
pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option<AllocatorKind> {
// If the crate doesn't have an `allocator_kind` set then there's definitely
// no shim to generate. Otherwise we also check our dependency graph for all
// our output crate types. If anything there looks like its a `Dynamic`
// linkage, then it's already got an allocator shim and we'll be using that
// one instead. If nothing exists then it's our job to generate the
// allocator!
let any_dynamic_crate = tcx.dependency_formats(()).iter().any(|(_, list)| {
use rustc_middle::middle::dependency_format::Linkage;
list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
if any_dynamic_crate { None } else { tcx.allocator_kind(()) }
}

pub fn codegen_crate<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
Expand Down Expand Up @@ -615,20 +633,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
);

// Codegen an allocator shim, if necessary.
//
// If the crate doesn't have an `allocator_kind` set then there's definitely
// no shim to generate. Otherwise we also check our dependency graph for all
// our output crate types. If anything there looks like its a `Dynamic`
// linkage, then it's already got an allocator shim and we'll be using that
// one instead. If nothing exists then it's our job to generate the
// allocator!
let any_dynamic_crate = tcx.dependency_formats(()).iter().any(|(_, list)| {
use rustc_middle::middle::dependency_format::Linkage;
list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
let allocator_module = if any_dynamic_crate {
None
} else if let Some(kind) = tcx.allocator_kind(()) {
if let Some(kind) = allocator_kind_for_codegen(tcx) {
let llmod_id =
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
let module_llvm = tcx.sess.time("write_allocator_module", || {
Expand All @@ -642,13 +647,10 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
)
});

Some(ModuleCodegen { name: llmod_id, module_llvm, kind: ModuleKind::Allocator })
} else {
None
};

if let Some(allocator_module) = allocator_module {
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, allocator_module);
ongoing_codegen.submit_pre_codegened_module_to_llvm(
tcx,
ModuleCodegen { name: llmod_id, module_llvm, kind: ModuleKind::Allocator },
);
}

// For better throughput during parallel processing by LLVM, we used to sort
Expand Down

0 comments on commit c734034

Please sign in to comment.