about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-08-12 12:27:47 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-08-12 12:27:47 +0000
commite45f6000a0bd46d4b7580db59c86f3d30adbc270 (patch)
treece327ebdff50d6a26b5a644d8b27e8a9ff822e19 /src
parent48b312f04a89c72cf6db2cbb08bbc7fe6fce9bdb (diff)
downloadrust-e45f6000a0bd46d4b7580db59c86f3d30adbc270.tar.gz
rust-e45f6000a0bd46d4b7580db59c86f3d30adbc270.zip
Remove the partial linking hack for global asm support
Diffstat (limited to 'src')
-rw-r--r--src/driver/aot.rs102
-rw-r--r--src/global_asm.rs34
2 files changed, 87 insertions, 49 deletions
diff --git a/src/driver/aot.rs b/src/driver/aot.rs
index 0ca634affb4..4122ce18224 100644
--- a/src/driver/aot.rs
+++ b/src/driver/aot.rs
@@ -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);
         }
diff --git a/src/global_asm.rs b/src/global_asm.rs
index 14288e99242..8e711988f81 100644
--- a/src/global_asm.rs
+++ b/src/global_asm.rs
@@ -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() {