mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Remove the partial linking hack for global asm support
This commit is contained in:
parent
48b312f04a
commit
e45f6000a0
@ -1,6 +1,7 @@
|
||||
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
|
||||
//! standalone executable.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
|
||||
@ -19,7 +20,11 @@ use cranelift_object::{ObjectBuilder, ObjectModule};
|
||||
use crate::global_asm::GlobalAsmConfig;
|
||||
use crate::{prelude::*, BackendConfig};
|
||||
|
||||
struct ModuleCodegenResult(CompiledModule, Option<(WorkProductId, WorkProduct)>);
|
||||
struct ModuleCodegenResult(
|
||||
CompiledModule,
|
||||
Option<CompiledModule>,
|
||||
Option<(WorkProductId, WorkProduct)>,
|
||||
);
|
||||
|
||||
impl<HCX> HashStable<HCX> for ModuleCodegenResult {
|
||||
fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
|
||||
@ -42,11 +47,15 @@ impl OngoingCodegen {
|
||||
let mut modules = vec![];
|
||||
|
||||
for module_codegen_result in self.modules {
|
||||
let ModuleCodegenResult(module, work_product) = module_codegen_result;
|
||||
let ModuleCodegenResult(module_regular, module_global_asm, work_product) =
|
||||
module_codegen_result;
|
||||
if let Some((work_product_id, work_product)) = work_product {
|
||||
work_products.insert(work_product_id, work_product);
|
||||
}
|
||||
modules.push(module);
|
||||
modules.push(module_regular);
|
||||
if let Some(module_global_asm) = module_global_asm {
|
||||
modules.push(module_global_asm);
|
||||
}
|
||||
}
|
||||
|
||||
(
|
||||
@ -80,6 +89,7 @@ fn emit_module(
|
||||
module: ObjectModule,
|
||||
debug: Option<DebugContext<'_>>,
|
||||
unwind_context: UnwindContext,
|
||||
global_asm_object_file: Option<PathBuf>,
|
||||
) -> ModuleCodegenResult {
|
||||
let mut product = module.finish();
|
||||
|
||||
@ -100,6 +110,12 @@ fn emit_module(
|
||||
|
||||
let work_product = if backend_config.disable_incr_cache {
|
||||
None
|
||||
} else if let Some(global_asm_object_file) = &global_asm_object_file {
|
||||
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
|
||||
tcx.sess,
|
||||
&name,
|
||||
&[("o", &tmp_file), ("asm.o", global_asm_object_file)],
|
||||
)
|
||||
} else {
|
||||
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
|
||||
tcx.sess,
|
||||
@ -109,35 +125,78 @@ fn emit_module(
|
||||
};
|
||||
|
||||
ModuleCodegenResult(
|
||||
CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None },
|
||||
CompiledModule {
|
||||
name: name.clone(),
|
||||
kind,
|
||||
object: Some(tmp_file),
|
||||
dwarf_object: None,
|
||||
bytecode: None,
|
||||
},
|
||||
global_asm_object_file.map(|global_asm_object_file| CompiledModule {
|
||||
name: format!("{name}.asm"),
|
||||
kind,
|
||||
object: Some(global_asm_object_file),
|
||||
dwarf_object: None,
|
||||
bytecode: None,
|
||||
}),
|
||||
work_product,
|
||||
)
|
||||
}
|
||||
|
||||
fn reuse_workproduct_for_cgu(tcx: TyCtxt<'_>, cgu: &CodegenUnit<'_>) -> ModuleCodegenResult {
|
||||
let work_product = cgu.previous_work_product(tcx);
|
||||
let obj_out = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
|
||||
let source_file = rustc_incremental::in_incr_comp_dir_sess(
|
||||
let obj_out_regular =
|
||||
tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
|
||||
let source_file_regular = rustc_incremental::in_incr_comp_dir_sess(
|
||||
&tcx.sess,
|
||||
&work_product.saved_files.get("o").expect("no saved object file in work product"),
|
||||
);
|
||||
if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
|
||||
|
||||
if let Err(err) = rustc_fs_util::link_or_copy(&source_file_regular, &obj_out_regular) {
|
||||
tcx.sess.err(&format!(
|
||||
"unable to copy {} to {}: {}",
|
||||
source_file.display(),
|
||||
obj_out.display(),
|
||||
source_file_regular.display(),
|
||||
obj_out_regular.display(),
|
||||
err
|
||||
));
|
||||
}
|
||||
let obj_out_global_asm =
|
||||
crate::global_asm::add_file_stem_postfix(obj_out_regular.clone(), ".asm");
|
||||
let has_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") {
|
||||
let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, asm_o);
|
||||
if let Err(err) = rustc_fs_util::link_or_copy(&source_file_global_asm, &obj_out_global_asm)
|
||||
{
|
||||
tcx.sess.err(&format!(
|
||||
"unable to copy {} to {}: {}",
|
||||
source_file_regular.display(),
|
||||
obj_out_regular.display(),
|
||||
err
|
||||
));
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
ModuleCodegenResult(
|
||||
CompiledModule {
|
||||
name: cgu.name().to_string(),
|
||||
kind: ModuleKind::Regular,
|
||||
object: Some(obj_out),
|
||||
object: Some(obj_out_regular),
|
||||
dwarf_object: None,
|
||||
bytecode: None,
|
||||
},
|
||||
if has_global_asm {
|
||||
Some(CompiledModule {
|
||||
name: cgu.name().to_string(),
|
||||
kind: ModuleKind::Regular,
|
||||
object: Some(obj_out_global_asm),
|
||||
dwarf_object: None,
|
||||
bytecode: None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
},
|
||||
Some((cgu.work_product_id(), work_product)),
|
||||
)
|
||||
}
|
||||
@ -191,6 +250,15 @@ fn module_codegen(
|
||||
cgu.is_primary(),
|
||||
);
|
||||
|
||||
let global_asm_object_file = match crate::global_asm::compile_global_asm(
|
||||
&global_asm_config,
|
||||
cgu.name().as_str(),
|
||||
&cx.global_asm,
|
||||
) {
|
||||
Ok(global_asm_object_file) => global_asm_object_file,
|
||||
Err(err) => tcx.sess.fatal(&err),
|
||||
};
|
||||
|
||||
let debug_context = cx.debug_context;
|
||||
let unwind_context = cx.unwind_context;
|
||||
let codegen_result = tcx.sess.time("write object file", || {
|
||||
@ -202,18 +270,10 @@ fn module_codegen(
|
||||
module,
|
||||
debug_context,
|
||||
unwind_context,
|
||||
global_asm_object_file,
|
||||
)
|
||||
});
|
||||
|
||||
match crate::global_asm::compile_global_asm(
|
||||
&global_asm_config,
|
||||
cgu.name().as_str(),
|
||||
&cx.global_asm,
|
||||
) {
|
||||
Ok(()) => {}
|
||||
Err(err) => tcx.sess.fatal(&err),
|
||||
}
|
||||
|
||||
codegen_result
|
||||
}
|
||||
|
||||
@ -281,7 +341,7 @@ pub(crate) fn run_aot(
|
||||
crate::allocator::codegen(tcx, &mut allocator_module, &mut allocator_unwind_context);
|
||||
|
||||
let allocator_module = if created_alloc_shim {
|
||||
let ModuleCodegenResult(module, work_product) = emit_module(
|
||||
let ModuleCodegenResult(module, module_global_asm, work_product) = emit_module(
|
||||
tcx,
|
||||
&backend_config,
|
||||
"allocator_shim".to_string(),
|
||||
@ -289,7 +349,9 @@ pub(crate) fn run_aot(
|
||||
allocator_module,
|
||||
None,
|
||||
allocator_unwind_context,
|
||||
None,
|
||||
);
|
||||
assert!(module_global_asm.is_none());
|
||||
if let Some((id, product)) = work_product {
|
||||
work_products.insert(id, product);
|
||||
}
|
||||
|
@ -36,7 +36,6 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
|
||||
pub(crate) struct GlobalAsmConfig {
|
||||
asm_enabled: bool,
|
||||
assembler: PathBuf,
|
||||
linker: PathBuf,
|
||||
output_filenames: Arc<OutputFilenames>,
|
||||
}
|
||||
|
||||
@ -49,7 +48,6 @@ impl GlobalAsmConfig {
|
||||
GlobalAsmConfig {
|
||||
asm_enabled,
|
||||
assembler: crate::toolchain::get_toolchain_binary(tcx.sess, "as"),
|
||||
linker: crate::toolchain::get_toolchain_binary(tcx.sess, "ld"),
|
||||
output_filenames: tcx.output_filenames(()).clone(),
|
||||
}
|
||||
}
|
||||
@ -59,14 +57,14 @@ pub(crate) fn compile_global_asm(
|
||||
config: &GlobalAsmConfig,
|
||||
cgu_name: &str,
|
||||
global_asm: &str,
|
||||
) -> Result<(), String> {
|
||||
) -> Result<Option<PathBuf>, String> {
|
||||
if global_asm.is_empty() {
|
||||
return Ok(());
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if !config.asm_enabled {
|
||||
if global_asm.contains("__rust_probestack") {
|
||||
return Ok(());
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// FIXME fix linker error on macOS
|
||||
@ -105,32 +103,10 @@ pub(crate) fn compile_global_asm(
|
||||
return Err(format!("Failed to assemble `{}`", global_asm));
|
||||
}
|
||||
|
||||
// Link the global asm and main object file together
|
||||
let main_object_file = add_file_stem_postfix(output_object_file.clone(), ".main");
|
||||
std::fs::rename(&output_object_file, &main_object_file).unwrap();
|
||||
let status = Command::new(&config.linker)
|
||||
.arg("-r") // Create a new object file
|
||||
.arg("-o")
|
||||
.arg(output_object_file)
|
||||
.arg(&main_object_file)
|
||||
.arg(&global_asm_object_file)
|
||||
.status()
|
||||
.unwrap();
|
||||
if !status.success() {
|
||||
return Err(format!(
|
||||
"Failed to link `{}` and `{}` together",
|
||||
main_object_file.display(),
|
||||
global_asm_object_file.display(),
|
||||
));
|
||||
}
|
||||
|
||||
std::fs::remove_file(global_asm_object_file).unwrap();
|
||||
std::fs::remove_file(main_object_file).unwrap();
|
||||
|
||||
Ok(())
|
||||
Ok(Some(global_asm_object_file))
|
||||
}
|
||||
|
||||
fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
|
||||
pub(crate) fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
|
||||
let mut new_filename = path.file_stem().unwrap().to_owned();
|
||||
new_filename.push(postfix);
|
||||
if let Some(extension) = path.extension() {
|
||||
|
Loading…
Reference in New Issue
Block a user