Skip to content

Commit 0bd7aa1

Browse files
committed
Move metadata object generation for dylibs to the linker code
This deduplicates some code between codegen backends and may in the future allow adding extra metadata that is only known at link time.
1 parent badabab commit 0bd7aa1

File tree

17 files changed

+92
-220
lines changed

17 files changed

+92
-220
lines changed

compiler/rustc_codegen_cranelift/src/driver/aot.rs

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,13 @@ use std::thread::JoinHandle;
1111
use cranelift_object::{ObjectBuilder, ObjectModule};
1212
use rustc_codegen_ssa::assert_module_sources::CguReuse;
1313
use rustc_codegen_ssa::back::link::ensure_removed;
14-
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
1514
use rustc_codegen_ssa::base::determine_cgu_reuse;
1615
use rustc_codegen_ssa::{
1716
CodegenResults, CompiledModule, CrateInfo, ModuleKind, errors as ssa_errors,
1817
};
1918
use rustc_data_structures::profiling::SelfProfilerRef;
2019
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
2120
use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
22-
use rustc_metadata::EncodedMetadata;
2321
use rustc_metadata::fs::copy_to_stdout;
2422
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
2523
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
@@ -61,7 +59,6 @@ impl<HCX> HashStable<HCX> for OngoingModuleCodegen {
6159
pub(crate) struct OngoingCodegen {
6260
modules: Vec<OngoingModuleCodegen>,
6361
allocator_module: Option<CompiledModule>,
64-
metadata_module: Option<CompiledModule>,
6562
crate_info: CrateInfo,
6663
concurrency_limiter: ConcurrencyLimiter,
6764
}
@@ -133,7 +130,6 @@ impl OngoingCodegen {
133130
let codegen_results = CodegenResults {
134131
modules,
135132
allocator_module: self.allocator_module,
136-
metadata_module: self.metadata_module,
137133
crate_info: self.crate_info,
138134
};
139135

@@ -644,42 +640,6 @@ fn module_codegen(
644640
}))
645641
}
646642

647-
fn emit_metadata_module(tcx: TyCtxt<'_>, metadata: &EncodedMetadata) -> CompiledModule {
648-
use rustc_middle::mir::mono::CodegenUnitNameBuilder;
649-
650-
let _timer = tcx.sess.timer("write compressed metadata");
651-
652-
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
653-
let metadata_cgu_name = cgu_name_builder
654-
.build_cgu_name(LOCAL_CRATE, ["crate"], Some("metadata"))
655-
.as_str()
656-
.to_string();
657-
658-
let tmp_file = tcx.output_filenames(()).temp_path_for_cgu(
659-
OutputType::Metadata,
660-
&metadata_cgu_name,
661-
tcx.sess.invocation_temp.as_deref(),
662-
);
663-
664-
let symbol_name = rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx);
665-
let obj = create_compressed_metadata_file(tcx.sess, metadata, &symbol_name);
666-
667-
if let Err(err) = std::fs::write(&tmp_file, obj) {
668-
tcx.dcx().fatal(format!("error writing metadata object file: {}", err));
669-
}
670-
671-
CompiledModule {
672-
name: metadata_cgu_name,
673-
kind: ModuleKind::Metadata,
674-
object: Some(tmp_file),
675-
dwarf_object: None,
676-
bytecode: None,
677-
assembly: None,
678-
llvm_ir: None,
679-
links_from_incr_cache: Vec::new(),
680-
}
681-
}
682-
683643
fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option<CompiledModule> {
684644
let mut allocator_module = make_module(tcx.sess, "allocator_shim".to_string());
685645
let created_alloc_shim = crate::allocator::codegen(tcx, &mut allocator_module);
@@ -704,7 +664,7 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option<CompiledModule> {
704664
}
705665
}
706666

707-
pub(crate) fn run_aot(tcx: TyCtxt<'_>, metadata: Option<&EncodedMetadata>) -> Box<OngoingCodegen> {
667+
pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box<OngoingCodegen> {
708668
// FIXME handle `-Ctarget-cpu=native`
709669
let target_cpu = match tcx.sess.opts.cg.target_cpu {
710670
Some(ref name) => name,
@@ -720,7 +680,6 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>, metadata: Option<&EncodedMetadata>) -> Bo
720680
return Box::new(OngoingCodegen {
721681
modules: vec![],
722682
allocator_module: None,
723-
metadata_module: None,
724683
crate_info: CrateInfo::new(tcx, target_cpu),
725684
concurrency_limiter: ConcurrencyLimiter::new(0),
726685
});
@@ -780,12 +739,9 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>, metadata: Option<&EncodedMetadata>) -> Bo
780739

781740
let allocator_module = emit_allocator_module(tcx);
782741

783-
let metadata_module = metadata.map(|metadata| emit_metadata_module(tcx, metadata));
784-
785742
Box::new(OngoingCodegen {
786743
modules,
787744
allocator_module,
788-
metadata_module,
789745
crate_info: CrateInfo::new(tcx, target_cpu),
790746
concurrency_limiter: concurrency_limiter.0,
791747
})

compiler/rustc_codegen_cranelift/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ use cranelift_codegen::isa::TargetIsa;
4646
use cranelift_codegen::settings::{self, Configurable};
4747
use rustc_codegen_ssa::traits::CodegenBackend;
4848
use rustc_codegen_ssa::{CodegenResults, TargetConfig};
49-
use rustc_metadata::EncodedMetadata;
5049
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
5150
use rustc_session::Session;
5251
use rustc_session::config::OutputFilenames;
@@ -238,7 +237,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
238237
println!("Cranelift version: {}", cranelift_codegen::VERSION);
239238
}
240239

241-
fn codegen_crate(&self, tcx: TyCtxt<'_>, metadata: Option<&EncodedMetadata>) -> Box<dyn Any> {
240+
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
242241
info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE));
243242
let config = self.config.clone().unwrap_or_else(|| {
244243
BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
@@ -251,7 +250,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
251250
#[cfg(not(feature = "jit"))]
252251
tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift");
253252
} else {
254-
driver::aot::run_aot(tcx, metadata)
253+
driver::aot::run_aot(tcx)
255254
}
256255
}
257256

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ extern crate rustc_index;
4848
#[cfg(feature = "master")]
4949
extern crate rustc_interface;
5050
extern crate rustc_macros;
51-
extern crate rustc_metadata;
5251
extern crate rustc_middle;
5352
extern crate rustc_session;
5453
extern crate rustc_span;
@@ -106,7 +105,6 @@ use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetCon
106105
use rustc_data_structures::fx::FxIndexMap;
107106
use rustc_data_structures::sync::IntoDynSyncSend;
108107
use rustc_errors::DiagCtxtHandle;
109-
use rustc_metadata::EncodedMetadata;
110108
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
111109
use rustc_middle::ty::TyCtxt;
112110
use rustc_middle::util::Providers;
@@ -230,9 +228,9 @@ impl CodegenBackend for GccCodegenBackend {
230228
providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess, true)
231229
}
232230

233-
fn codegen_crate(&self, tcx: TyCtxt<'_>, metadata: Option<&EncodedMetadata>) -> Box<dyn Any> {
231+
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
234232
let target_cpu = target_cpu(tcx.sess);
235-
let res = codegen_crate(self.clone(), tcx, target_cpu.to_string(), metadata);
233+
let res = codegen_crate(self.clone(), tcx, target_cpu.to_string());
236234

237235
Box::new(res)
238236
}

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,11 @@ impl CodegenBackend for LlvmCodegenBackend {
341341
target_config(sess)
342342
}
343343

344-
fn codegen_crate<'tcx>(
345-
&self,
346-
tcx: TyCtxt<'tcx>,
347-
metadata: Option<&EncodedMetadata>,
348-
) -> Box<dyn Any> {
344+
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
349345
Box::new(rustc_codegen_ssa::base::codegen_crate(
350346
LlvmCodegenBackend(()),
351347
tcx,
352348
crate::llvm_util::target_cpu(tcx.sess).to_string(),
353-
metadata,
354349
))
355350
}
356351

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,6 @@ codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status
200200
codegen_ssa_malformed_cgu_name =
201201
found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case).
202202
203-
codegen_ssa_metadata_object_file_write = error writing metadata object file: {$error}
204-
205203
codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload
206204
207205
codegen_ssa_missing_features = add the missing features in a `target_feature` attribute

compiler/rustc_codegen_ssa/src/back/archive.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ use object::read::macho::FatArch;
1414
use rustc_data_structures::fx::FxIndexSet;
1515
use rustc_data_structures::memmap::Mmap;
1616
use rustc_fs_util::TempDirBuilder;
17+
use rustc_metadata::EncodedMetadata;
1718
use rustc_session::Session;
1819
use rustc_span::Symbol;
1920
use tracing::trace;
2021

21-
use super::metadata::search_for_section;
22+
use super::metadata::{create_compressed_metadata_file, search_for_section};
2223
use crate::common;
2324
// Re-exporting for rustc_codegen_llvm::back::archive
2425
pub use crate::errors::{ArchiveBuildFailure, ExtractBundledLibsError, UnknownArchiveKind};
@@ -58,6 +59,15 @@ impl From<ImportLibraryItem> for COFFShortExport {
5859
pub trait ArchiveBuilderBuilder {
5960
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a>;
6061

62+
fn create_dylib_metadata_wrapper(
63+
&self,
64+
sess: &Session,
65+
metadata: &EncodedMetadata,
66+
symbol_name: &str,
67+
) -> Vec<u8> {
68+
create_compressed_metadata_file(sess, metadata, symbol_name)
69+
}
70+
6171
/// Creates a DLL Import Library <https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-creation#creating-an-import-library>.
6272
/// and returns the path on disk to that import library.
6373
/// This functions doesn't take `self` so that it can be called from

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ pub fn link_binary(
167167
crate_type,
168168
&out_filename,
169169
&codegen_results,
170+
&metadata,
170171
path.as_ref(),
171172
);
172173
}
@@ -230,11 +231,7 @@ pub fn link_binary(
230231
let remove_temps_from_module =
231232
|module: &CompiledModule| maybe_remove_temps_from_module(false, false, module);
232233

233-
// Otherwise, always remove the metadata and allocator module temporaries.
234-
if let Some(ref metadata_module) = codegen_results.metadata_module {
235-
remove_temps_from_module(metadata_module);
236-
}
237-
234+
// Otherwise, always remove the allocator module temporaries.
238235
if let Some(ref allocator_module) = codegen_results.allocator_module {
239236
remove_temps_from_module(allocator_module);
240237
}
@@ -326,7 +323,7 @@ fn link_rlib<'a>(
326323
RlibFlavor::Normal => {
327324
let (metadata, metadata_position) =
328325
create_wrapper_file(sess, ".rmeta".to_string(), metadata.stub_or_full());
329-
let metadata = emit_wrapper_file(sess, &metadata, tmpdir, METADATA_FILENAME);
326+
let metadata = emit_wrapper_file(sess, &metadata, tmpdir.as_ref(), METADATA_FILENAME);
330327
match metadata_position {
331328
MetadataPosition::First => {
332329
// Most of the time metadata in rlib files is wrapped in a "dummy" object
@@ -394,7 +391,7 @@ fn link_rlib<'a>(
394391
let src = read(path)
395392
.unwrap_or_else(|e| sess.dcx().emit_fatal(errors::ReadFileError { message: e }));
396393
let (data, _) = create_wrapper_file(sess, ".bundled_lib".to_string(), &src);
397-
let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
394+
let wrapper_file = emit_wrapper_file(sess, &data, tmpdir.as_ref(), filename.as_str());
398395
packed_bundled_libs.push(wrapper_file);
399396
} else {
400397
let path = find_native_static_library(lib.name.as_str(), lib.verbatim, sess);
@@ -698,6 +695,7 @@ fn link_natively(
698695
crate_type: CrateType,
699696
out_filename: &Path,
700697
codegen_results: &CodegenResults,
698+
metadata: &EncodedMetadata,
701699
tmpdir: &Path,
702700
) {
703701
info!("preparing {:?} to {:?}", crate_type, out_filename);
@@ -722,6 +720,7 @@ fn link_natively(
722720
tmpdir,
723721
temp_filename,
724722
codegen_results,
723+
metadata,
725724
self_contained_components,
726725
);
727726

@@ -2098,17 +2097,25 @@ fn add_local_crate_allocator_objects(cmd: &mut dyn Linker, codegen_results: &Cod
20982097
/// Add object files containing metadata for the current crate.
20992098
fn add_local_crate_metadata_objects(
21002099
cmd: &mut dyn Linker,
2100+
sess: &Session,
2101+
archive_builder_builder: &dyn ArchiveBuilderBuilder,
21012102
crate_type: CrateType,
2103+
tmpdir: &Path,
21022104
codegen_results: &CodegenResults,
2105+
metadata: &EncodedMetadata,
21032106
) {
21042107
// When linking a dynamic library, we put the metadata into a section of the
21052108
// executable. This metadata is in a separate object file from the main
2106-
// object file, so we link that in here.
2107-
if matches!(crate_type, CrateType::Dylib | CrateType::ProcMacro)
2108-
&& let Some(m) = &codegen_results.metadata_module
2109-
&& let Some(obj) = &m.object
2110-
{
2111-
cmd.add_object(obj);
2109+
// object file, so we create and link it in here.
2110+
if matches!(crate_type, CrateType::Dylib | CrateType::ProcMacro) {
2111+
let data = archive_builder_builder.create_dylib_metadata_wrapper(
2112+
sess,
2113+
&metadata,
2114+
&codegen_results.crate_info.metadata_symbol,
2115+
);
2116+
let obj = emit_wrapper_file(sess, &data, tmpdir, "rmeta.o");
2117+
2118+
cmd.add_object(&obj);
21122119
}
21132120
}
21142121

@@ -2198,6 +2205,7 @@ fn linker_with_args(
21982205
tmpdir: &Path,
21992206
out_filename: &Path,
22002207
codegen_results: &CodegenResults,
2208+
metadata: &EncodedMetadata,
22012209
self_contained_components: LinkSelfContainedComponents,
22022210
) -> Command {
22032211
let self_contained_crt_objects = self_contained_components.is_crt_objects_enabled();
@@ -2272,7 +2280,15 @@ fn linker_with_args(
22722280
// in this DAG so far because they can only depend on other native libraries
22732281
// and such dependencies are also required to be specified.
22742282
add_local_crate_regular_objects(cmd, codegen_results);
2275-
add_local_crate_metadata_objects(cmd, crate_type, codegen_results);
2283+
add_local_crate_metadata_objects(
2284+
cmd,
2285+
sess,
2286+
archive_builder_builder,
2287+
crate_type,
2288+
tmpdir,
2289+
codegen_results,
2290+
metadata,
2291+
);
22762292
add_local_crate_allocator_objects(cmd, codegen_results);
22772293

22782294
// Avoid linking to dynamic libraries unless they satisfy some undefined symbols

0 commit comments

Comments
 (0)