Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::fs::File;
use std::path::{Path, PathBuf};

use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
use rustc_codegen_ssa::METADATA_FILENAME;
use rustc_codegen_ssa::{METADATA_FILE_EXTENSION, METADATA_FILE_PREFIX};
use rustc_session::Session;

use object::{Object, SymbolKind};
Expand Down Expand Up @@ -116,7 +116,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {

self.add_archive(rlib.to_owned(), move |fname: &str| {
// Ignore metadata files, no matter the name.
if fname == METADATA_FILENAME {
if fname.starts_with(METADATA_FILE_PREFIX) && fname.ends_with(METADATA_FILE_EXTENSION) {
return true;
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_cranelift/src/driver/aot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ pub(super) fn run_aot(
Box::new((
CodegenResults {
crate_name: tcx.crate_name(LOCAL_CRATE),
crate_hash: tcx.crate_hash(LOCAL_CRATE),
modules,
allocator_module,
metadata_module,
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_codegen_cranelift/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::convert::TryFrom;
use std::fs::File;
use std::path::Path;

use rustc_codegen_ssa::METADATA_FILENAME;
use rustc_codegen_ssa::{METADATA_FILE_EXTENSION, METADATA_FILE_PREFIX};
use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::rustc_erase_owner;
use rustc_data_structures::sync::MetadataRef;
Expand All @@ -23,7 +23,10 @@ impl MetadataLoader for CraneliftMetadataLoader {
// Iterate over all entries in the archive:
while let Some(entry_result) = archive.next_entry() {
let mut entry = entry_result.map_err(|e| format!("{:?}", e))?;
if entry.header().identifier() == METADATA_FILENAME.as_bytes() {
let filename = String::from_utf8_lossy(entry.header().identifier());
if filename.starts_with(METADATA_FILE_PREFIX)
&& filename.ends_with(METADATA_FILE_EXTENSION)
{
let mut buf = Vec::with_capacity(
usize::try_from(entry.header().size())
.expect("Rlib metadata file too big to load into memory."),
Expand Down Expand Up @@ -94,9 +97,7 @@ pub(crate) fn write_metadata<P: WriteMetadata>(

assert!(kind == MetadataKind::Compressed);
let mut compressed = tcx.metadata_encoding_version();
FrameEncoder::new(&mut compressed)
.write_all(&metadata.raw_data)
.unwrap();
FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();

product.add_rustc_section(
rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx),
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_codegen_llvm/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use std::str;
use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind};
use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME};
use rustc_codegen_ssa::{
looks_like_rust_object_file, METADATA_FILE_EXTENSION, METADATA_FILE_PREFIX,
};
use rustc_session::Session;
use rustc_span::symbol::Symbol;

Expand Down Expand Up @@ -130,7 +132,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {

self.add_archive(rlib, move |fname: &str| {
// Ignore metadata files, no matter the name.
if fname == METADATA_FILENAME {
if fname.starts_with(METADATA_FILE_PREFIX) && fname.ends_with(METADATA_FILE_EXTENSION) {
return true;
}

Expand Down
42 changes: 42 additions & 0 deletions compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ use rustc_codegen_ssa::mono_item::MonoItemExt;
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind};
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_data_structures::svh::Svh;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::dep_graph;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::cstore::EncodedMetadata;
Expand Down Expand Up @@ -70,6 +72,9 @@ pub fn write_compressed_metadata<'tcx>(
let directive = format!(".section {}", section_name);
llvm::LLVMSetModuleInlineAsm2(metadata_llmod, directive.as_ptr().cast(), directive.len())
}

let svh = tcx.crate_hash(LOCAL_CRATE);
add_svh_symbol(tcx, &llvm_module, &svh);
}

pub struct ValueIter<'ll> {
Expand All @@ -93,6 +98,42 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> {
unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), step: llvm::LLVMGetNextGlobal } }
}

pub fn svh_symbol_name(
tcx: TyCtxt<'_>,
svh: &Svh, //, cgu_name: Symbol
) -> String {
format!("rust_svh_{}_{}", tcx.original_crate_name(LOCAL_CRATE), svh)
}

fn add_svh_symbol(tcx: TyCtxt<'tcx>, llvm_module: &'ll ModuleLlvm, svh: &Svh) {
let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod());

let svh_bytes: Vec<u8> = format!("{}", svh).as_bytes().to_vec();
let llconst = common::bytes_in_context(metadata_llcx, &svh_bytes);
let name = svh_symbol_name(tcx, &svh); //cgu_name
let buf = CString::new(name).unwrap();
let llglobal =
unsafe { llvm::LLVMAddGlobal(metadata_llmod, common::val_ty(llconst), buf.as_ptr()) };
unsafe {
llvm::LLVMSetInitializer(llglobal, llconst);
let section_name =
if tcx.sess.target.options.is_like_osx { "__DATA,.rust_svh" } else { ".rust_svh" };

let name = SmallCStr::new(&section_name);
llvm::LLVMSetSection(llglobal, name.as_ptr());

// Also generate a .section directive to force no
// flags, at least for ELF outputs, so that the
// metadata doesn't get loaded into memory.
let directive = format!(".section {}", section_name);
llvm::LLVMRustAppendModuleInlineAsm(
metadata_llmod,
directive.as_ptr().cast(),
directive.len(),
)
}
}

pub fn compile_codegen_unit(
tcx: TyCtxt<'tcx>,
cgu_name: Symbol,
Expand All @@ -116,6 +157,7 @@ pub fn compile_codegen_unit(
let llvm_module = ModuleLlvm::new(tcx, &cgu_name.as_str());
{
let cx = CodegenCx::new(tcx, cgu, &llvm_module);

let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx);
for &(mono_item, (linkage, visibility)) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
Expand Down
20 changes: 14 additions & 6 deletions compiler/rustc_codegen_llvm/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::llvm;
use crate::llvm::archive_ro::ArchiveRO;
use crate::llvm::{mk_section_iter, False, ObjectFile};
use rustc_middle::middle::cstore::MetadataLoader;
use rustc_target::spec::Target;

use rustc_codegen_ssa::METADATA_FILENAME;
use rustc_codegen_ssa::{METADATA_FILE_EXTENSION, METADATA_FILE_PREFIX};
use rustc_data_structures::owning_ref::OwningRef;
use rustc_data_structures::rustc_erase_owner;
use rustc_middle::middle::cstore::MetadataLoader;
use rustc_target::spec::Target;
use tracing::debug;

use rustc_fs_util::path_to_c_string;
Expand All @@ -30,10 +29,19 @@ impl MetadataLoader for LlvmMetadataLoader {
let buf: OwningRef<_, [u8]> = archive.try_map(|ar| {
ar.iter()
.filter_map(|s| s.ok())
.find(|sect| sect.name() == Some(METADATA_FILENAME))
.find(|sect| {
if let Some(n) = sect.name() {
n.starts_with(METADATA_FILE_PREFIX) && n.ends_with(METADATA_FILE_EXTENSION)
} else {
false
}
})
.map(|s| s.data())
.ok_or_else(|| {
debug!("didn't find '{}' in the archive", METADATA_FILENAME);
debug!(
"didn't find '{}*{}' in the archive",
METADATA_FILE_PREFIX, METADATA_FILE_EXTENSION
);
format!("failed to read rlib metadata: '{}'", filename.display())
})
})?;
Expand Down
28 changes: 23 additions & 5 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_fs_util::fix_windows_verbatim_for_gcc;
use rustc_hir::def_id::CrateNum;
Expand All @@ -21,7 +22,10 @@ use super::archive::ArchiveBuilder;
use super::command::Command;
use super::linker::{self, Linker};
use super::rpath::{self, RPathConfig};
use crate::{looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FILENAME};
use crate::{
looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FILE_EXTENSION,
METADATA_FILE_PREFIX,
};

use cc::windows_registry;
use tempfile::Builder as TempFileBuilder;
Expand Down Expand Up @@ -268,8 +272,16 @@ pub fn each_linked_rlib(
/// building an `.rlib` (stomping over one another), or writing an `.rmeta` into a
/// directory being searched for `extern crate` (observing an incomplete file).
/// The returned path is the temporary file containing the complete metadata.
pub fn emit_metadata(sess: &Session, metadata: &EncodedMetadata, tmpdir: &MaybeTempDir) -> PathBuf {
let out_filename = tmpdir.as_ref().join(METADATA_FILENAME);
pub fn emit_metadata(
sess: &Session,
metadata: &EncodedMetadata,
tmpdir: &MaybeTempDir,
crate_name: &str,
svh: &Svh,
) -> PathBuf {
let out_filename = tmpdir
.as_ref()
.join(format!("{}{}-{}{}", METADATA_FILE_PREFIX, crate_name, svh, METADATA_FILE_EXTENSION));
let result = fs::write(&out_filename, &metadata.raw_data);

if let Err(e) = result {
Expand Down Expand Up @@ -358,7 +370,13 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
RlibFlavor::Normal => {
// Instead of putting the metadata in an object file section, rlibs
// contain the metadata in a separate file.
ab.add_file(&emit_metadata(sess, &codegen_results.metadata, tmpdir));
ab.add_file(&emit_metadata(
sess,
&codegen_results.metadata,
tmpdir,
&codegen_results.crate_name.as_str(),
&codegen_results.crate_hash,
));

// After adding all files to the archive, we need to update the
// symbol table of the archive. This currently dies on macOS (see
Expand Down Expand Up @@ -1912,7 +1930,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(

let mut any_objects = false;
for f in archive.src_files() {
if f == METADATA_FILENAME {
if f.starts_with(METADATA_FILE_PREFIX) && f.ends_with(METADATA_FILE_EXTENSION) {
archive.remove_file(&f);
continue;
}
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_hir::Node;
use rustc_index::vec::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
metadata_symbol_name, svh_symbol_name, ExportedSymbol, SymbolExportLevel,
};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
Expand Down Expand Up @@ -218,6 +218,11 @@ fn exported_symbols_provider_local(
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));

symbols.push((exported_symbol, SymbolExportLevel::Rust));

let symbol_name = svh_symbol_name(tcx);
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));

symbols.push((exported_symbol, SymbolExportLevel::C));
}

if tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics() {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::profiling::TimingGuard;
use rustc_data_structures::profiling::VerboseTimingGuard;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::Emitter;
use rustc_errors::{DiagnosticId, FatalError, Handler, Level};
Expand Down Expand Up @@ -414,6 +415,7 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
let sess = tcx.sess;

let crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_hash = tcx.crate_hash(LOCAL_CRATE);
let no_builtins = tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::no_builtins);
let is_compiler_builtins =
tcx.sess.contains_name(&tcx.hir().krate().item.attrs, sym::compiler_builtins);
Expand Down Expand Up @@ -466,6 +468,7 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
windows_subsystem,
linker_info,
crate_info,
crate_hash,

coordinator_send,
codegen_worker_receive,
Expand Down Expand Up @@ -1712,6 +1715,7 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
pub windows_subsystem: Option<String>,
pub linker_info: LinkerInfo,
pub crate_info: CrateInfo,
pub crate_hash: Svh,
pub coordinator_send: Sender<Box<dyn Any + Send>>,
pub codegen_worker_receive: Receiver<Message<B>>,
pub shared_emitter_main: SharedEmitterMain,
Expand Down Expand Up @@ -1753,6 +1757,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
(
CodegenResults {
crate_name: self.crate_name,
crate_hash: self.crate_hash,
metadata: self.metadata,
windows_subsystem: self.windows_subsystem,
linker_info: self.linker_info,
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extern crate tracing;
extern crate rustc_middle;

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
use rustc_hir::def_id::CrateNum;
use rustc_hir::LangItem;
Expand Down Expand Up @@ -56,8 +57,8 @@ pub struct ModuleCodegen<M> {
pub kind: ModuleKind,
}

// FIXME(eddyb) maybe include the crate name in this?
pub const METADATA_FILENAME: &str = "lib.rmeta";
pub const METADATA_FILE_PREFIX: &str = "lib";
pub const METADATA_FILE_EXTENSION: &str = ".rmeta";

impl<M> ModuleCodegen<M> {
pub fn into_compiled_module(
Expand Down Expand Up @@ -130,6 +131,7 @@ pub struct CrateInfo {
#[derive(Encodable, Decodable)]
pub struct CodegenResults {
pub crate_name: Symbol,
pub crate_hash: Svh,
pub modules: Vec<CompiledModule>,
pub allocator_module: Option<CompiledModule>,
pub metadata_module: Option<CompiledModule>,
Expand Down
Loading