Skip to content

Commit e45f600

Browse files
committed
Remove the partial linking hack for global asm support
1 parent 48b312f commit e45f600

File tree

2 files changed

+87
-49
lines changed

2 files changed

+87
-49
lines changed

src/driver/aot.rs

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
22
//! standalone executable.
33
4+
use std::path::PathBuf;
45
use std::sync::Arc;
56

67
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
@@ -19,7 +20,11 @@ use cranelift_object::{ObjectBuilder, ObjectModule};
1920
use crate::global_asm::GlobalAsmConfig;
2021
use crate::{prelude::*, BackendConfig};
2122

22-
struct ModuleCodegenResult(CompiledModule, Option<(WorkProductId, WorkProduct)>);
23+
struct ModuleCodegenResult(
24+
CompiledModule,
25+
Option<CompiledModule>,
26+
Option<(WorkProductId, WorkProduct)>,
27+
);
2328

2429
impl<HCX> HashStable<HCX> for ModuleCodegenResult {
2530
fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
@@ -42,11 +47,15 @@ impl OngoingCodegen {
4247
let mut modules = vec![];
4348

4449
for module_codegen_result in self.modules {
45-
let ModuleCodegenResult(module, work_product) = module_codegen_result;
50+
let ModuleCodegenResult(module_regular, module_global_asm, work_product) =
51+
module_codegen_result;
4652
if let Some((work_product_id, work_product)) = work_product {
4753
work_products.insert(work_product_id, work_product);
4854
}
49-
modules.push(module);
55+
modules.push(module_regular);
56+
if let Some(module_global_asm) = module_global_asm {
57+
modules.push(module_global_asm);
58+
}
5059
}
5160

5261
(
@@ -80,6 +89,7 @@ fn emit_module(
8089
module: ObjectModule,
8190
debug: Option<DebugContext<'_>>,
8291
unwind_context: UnwindContext,
92+
global_asm_object_file: Option<PathBuf>,
8393
) -> ModuleCodegenResult {
8494
let mut product = module.finish();
8595

@@ -100,6 +110,12 @@ fn emit_module(
100110

101111
let work_product = if backend_config.disable_incr_cache {
102112
None
113+
} else if let Some(global_asm_object_file) = &global_asm_object_file {
114+
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
115+
tcx.sess,
116+
&name,
117+
&[("o", &tmp_file), ("asm.o", global_asm_object_file)],
118+
)
103119
} else {
104120
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
105121
tcx.sess,
@@ -109,35 +125,78 @@ fn emit_module(
109125
};
110126

111127
ModuleCodegenResult(
112-
CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None },
128+
CompiledModule {
129+
name: name.clone(),
130+
kind,
131+
object: Some(tmp_file),
132+
dwarf_object: None,
133+
bytecode: None,
134+
},
135+
global_asm_object_file.map(|global_asm_object_file| CompiledModule {
136+
name: format!("{name}.asm"),
137+
kind,
138+
object: Some(global_asm_object_file),
139+
dwarf_object: None,
140+
bytecode: None,
141+
}),
113142
work_product,
114143
)
115144
}
116145

117146
fn reuse_workproduct_for_cgu(tcx: TyCtxt<'_>, cgu: &CodegenUnit<'_>) -> ModuleCodegenResult {
118147
let work_product = cgu.previous_work_product(tcx);
119-
let obj_out = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
120-
let source_file = rustc_incremental::in_incr_comp_dir_sess(
148+
let obj_out_regular =
149+
tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
150+
let source_file_regular = rustc_incremental::in_incr_comp_dir_sess(
121151
&tcx.sess,
122152
&work_product.saved_files.get("o").expect("no saved object file in work product"),
123153
);
124-
if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
154+
155+
if let Err(err) = rustc_fs_util::link_or_copy(&source_file_regular, &obj_out_regular) {
125156
tcx.sess.err(&format!(
126157
"unable to copy {} to {}: {}",
127-
source_file.display(),
128-
obj_out.display(),
158+
source_file_regular.display(),
159+
obj_out_regular.display(),
129160
err
130161
));
131162
}
163+
let obj_out_global_asm =
164+
crate::global_asm::add_file_stem_postfix(obj_out_regular.clone(), ".asm");
165+
let has_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") {
166+
let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, asm_o);
167+
if let Err(err) = rustc_fs_util::link_or_copy(&source_file_global_asm, &obj_out_global_asm)
168+
{
169+
tcx.sess.err(&format!(
170+
"unable to copy {} to {}: {}",
171+
source_file_regular.display(),
172+
obj_out_regular.display(),
173+
err
174+
));
175+
}
176+
true
177+
} else {
178+
false
179+
};
132180

133181
ModuleCodegenResult(
134182
CompiledModule {
135183
name: cgu.name().to_string(),
136184
kind: ModuleKind::Regular,
137-
object: Some(obj_out),
185+
object: Some(obj_out_regular),
138186
dwarf_object: None,
139187
bytecode: None,
140188
},
189+
if has_global_asm {
190+
Some(CompiledModule {
191+
name: cgu.name().to_string(),
192+
kind: ModuleKind::Regular,
193+
object: Some(obj_out_global_asm),
194+
dwarf_object: None,
195+
bytecode: None,
196+
})
197+
} else {
198+
None
199+
},
141200
Some((cgu.work_product_id(), work_product)),
142201
)
143202
}
@@ -191,6 +250,15 @@ fn module_codegen(
191250
cgu.is_primary(),
192251
);
193252

253+
let global_asm_object_file = match crate::global_asm::compile_global_asm(
254+
&global_asm_config,
255+
cgu.name().as_str(),
256+
&cx.global_asm,
257+
) {
258+
Ok(global_asm_object_file) => global_asm_object_file,
259+
Err(err) => tcx.sess.fatal(&err),
260+
};
261+
194262
let debug_context = cx.debug_context;
195263
let unwind_context = cx.unwind_context;
196264
let codegen_result = tcx.sess.time("write object file", || {
@@ -202,18 +270,10 @@ fn module_codegen(
202270
module,
203271
debug_context,
204272
unwind_context,
273+
global_asm_object_file,
205274
)
206275
});
207276

208-
match crate::global_asm::compile_global_asm(
209-
&global_asm_config,
210-
cgu.name().as_str(),
211-
&cx.global_asm,
212-
) {
213-
Ok(()) => {}
214-
Err(err) => tcx.sess.fatal(&err),
215-
}
216-
217277
codegen_result
218278
}
219279

@@ -281,15 +341,17 @@ pub(crate) fn run_aot(
281341
crate::allocator::codegen(tcx, &mut allocator_module, &mut allocator_unwind_context);
282342

283343
let allocator_module = if created_alloc_shim {
284-
let ModuleCodegenResult(module, work_product) = emit_module(
344+
let ModuleCodegenResult(module, module_global_asm, work_product) = emit_module(
285345
tcx,
286346
&backend_config,
287347
"allocator_shim".to_string(),
288348
ModuleKind::Allocator,
289349
allocator_module,
290350
None,
291351
allocator_unwind_context,
352+
None,
292353
);
354+
assert!(module_global_asm.is_none());
293355
if let Some((id, product)) = work_product {
294356
work_products.insert(id, product);
295357
}

src/global_asm.rs

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
3636
pub(crate) struct GlobalAsmConfig {
3737
asm_enabled: bool,
3838
assembler: PathBuf,
39-
linker: PathBuf,
4039
output_filenames: Arc<OutputFilenames>,
4140
}
4241

@@ -49,7 +48,6 @@ impl GlobalAsmConfig {
4948
GlobalAsmConfig {
5049
asm_enabled,
5150
assembler: crate::toolchain::get_toolchain_binary(tcx.sess, "as"),
52-
linker: crate::toolchain::get_toolchain_binary(tcx.sess, "ld"),
5351
output_filenames: tcx.output_filenames(()).clone(),
5452
}
5553
}
@@ -59,14 +57,14 @@ pub(crate) fn compile_global_asm(
5957
config: &GlobalAsmConfig,
6058
cgu_name: &str,
6159
global_asm: &str,
62-
) -> Result<(), String> {
60+
) -> Result<Option<PathBuf>, String> {
6361
if global_asm.is_empty() {
64-
return Ok(());
62+
return Ok(None);
6563
}
6664

6765
if !config.asm_enabled {
6866
if global_asm.contains("__rust_probestack") {
69-
return Ok(());
67+
return Ok(None);
7068
}
7169

7270
// FIXME fix linker error on macOS
@@ -105,32 +103,10 @@ pub(crate) fn compile_global_asm(
105103
return Err(format!("Failed to assemble `{}`", global_asm));
106104
}
107105

108-
// Link the global asm and main object file together
109-
let main_object_file = add_file_stem_postfix(output_object_file.clone(), ".main");
110-
std::fs::rename(&output_object_file, &main_object_file).unwrap();
111-
let status = Command::new(&config.linker)
112-
.arg("-r") // Create a new object file
113-
.arg("-o")
114-
.arg(output_object_file)
115-
.arg(&main_object_file)
116-
.arg(&global_asm_object_file)
117-
.status()
118-
.unwrap();
119-
if !status.success() {
120-
return Err(format!(
121-
"Failed to link `{}` and `{}` together",
122-
main_object_file.display(),
123-
global_asm_object_file.display(),
124-
));
125-
}
126-
127-
std::fs::remove_file(global_asm_object_file).unwrap();
128-
std::fs::remove_file(main_object_file).unwrap();
129-
130-
Ok(())
106+
Ok(Some(global_asm_object_file))
131107
}
132108

133-
fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
109+
pub(crate) fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
134110
let mut new_filename = path.file_stem().unwrap().to_owned();
135111
new_filename.push(postfix);
136112
if let Some(extension) = path.extension() {

0 commit comments

Comments
 (0)