1
1
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
2
2
//! standalone executable.
3
3
4
- use std:: io:: { self , Write } ;
4
+ use std:: io:: Write ;
5
5
use std:: path:: PathBuf ;
6
6
use std:: process:: { Command , Stdio } ;
7
+ use std:: sync:: Arc ;
7
8
8
9
use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
9
10
use rustc_hir:: ItemId ;
10
- use rustc_session:: config:: OutputType ;
11
+ use rustc_session:: config:: { OutputFilenames , OutputType } ;
11
12
12
13
use crate :: prelude:: * ;
13
14
@@ -31,52 +32,68 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
31
32
}
32
33
}
33
34
35
+ #[ derive( Debug ) ]
36
+ pub ( crate ) struct GlobalAsmConfig {
37
+ asm_enabled : bool ,
38
+ assembler : PathBuf ,
39
+ linker : PathBuf ,
40
+ output_filenames : Arc < OutputFilenames > ,
41
+ }
42
+
43
+ impl GlobalAsmConfig {
44
+ pub ( crate ) fn new ( tcx : TyCtxt < ' _ > ) -> Self {
45
+ let asm_enabled = cfg ! ( feature = "inline_asm" )
46
+ && !tcx. sess . target . is_like_osx
47
+ && !tcx. sess . target . is_like_windows ;
48
+
49
+ GlobalAsmConfig {
50
+ asm_enabled,
51
+ assembler : crate :: toolchain:: get_toolchain_binary ( tcx. sess , "as" ) ,
52
+ linker : crate :: toolchain:: get_toolchain_binary ( tcx. sess , "ld" ) ,
53
+ output_filenames : tcx. output_filenames ( ( ) ) . clone ( ) ,
54
+ }
55
+ }
56
+ }
57
+
34
58
pub ( crate ) fn compile_global_asm (
35
- tcx : TyCtxt < ' _ > ,
59
+ config : & GlobalAsmConfig ,
36
60
cgu_name : & str ,
37
61
global_asm : & str ,
38
- ) -> io :: Result < ( ) > {
62
+ ) -> Result < ( ) , String > {
39
63
if global_asm. is_empty ( ) {
40
64
return Ok ( ( ) ) ;
41
65
}
42
66
43
- if cfg ! ( not( feature = "inline_asm" ) )
44
- || tcx. sess . target . is_like_osx
45
- || tcx. sess . target . is_like_windows
46
- {
67
+ if !config. asm_enabled {
47
68
if global_asm. contains ( "__rust_probestack" ) {
48
69
return Ok ( ( ) ) ;
49
70
}
50
71
51
72
// FIXME fix linker error on macOS
52
73
if cfg ! ( not( feature = "inline_asm" ) ) {
53
- return Err ( io :: Error :: new (
54
- io :: ErrorKind :: Unsupported ,
55
- "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift" ,
56
- ) ) ;
74
+ return Err (
75
+ "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift"
76
+ . to_owned ( ) ,
77
+ ) ;
57
78
} else {
58
- return Err ( io:: Error :: new (
59
- io:: ErrorKind :: Unsupported ,
60
- "asm! and global_asm! are not yet supported on macOS and Windows" ,
61
- ) ) ;
79
+ return Err (
80
+ "asm! and global_asm! are not yet supported on macOS and Windows" . to_owned ( )
81
+ ) ;
62
82
}
63
83
}
64
84
65
- let assembler = crate :: toolchain:: get_toolchain_binary ( tcx. sess , "as" ) ;
66
- let linker = crate :: toolchain:: get_toolchain_binary ( tcx. sess , "ld" ) ;
67
-
68
85
// Remove all LLVM style comments
69
86
let global_asm = global_asm
70
87
. lines ( )
71
88
. map ( |line| if let Some ( index) = line. find ( "//" ) { & line[ 0 ..index] } else { line } )
72
89
. collect :: < Vec < _ > > ( )
73
90
. join ( "\n " ) ;
74
91
75
- let output_object_file = tcx . output_filenames ( ( ) ) . temp_path ( OutputType :: Object , Some ( cgu_name) ) ;
92
+ let output_object_file = config . output_filenames . temp_path ( OutputType :: Object , Some ( cgu_name) ) ;
76
93
77
94
// Assemble `global_asm`
78
95
let global_asm_object_file = add_file_stem_postfix ( output_object_file. clone ( ) , ".asm" ) ;
79
- let mut child = Command :: new ( assembler)
96
+ let mut child = Command :: new ( & config . assembler )
80
97
. arg ( "-o" )
81
98
. arg ( & global_asm_object_file)
82
99
. stdin ( Stdio :: piped ( ) )
@@ -85,16 +102,13 @@ pub(crate) fn compile_global_asm(
85
102
child. stdin . take ( ) . unwrap ( ) . write_all ( global_asm. as_bytes ( ) ) . unwrap ( ) ;
86
103
let status = child. wait ( ) . expect ( "Failed to wait for `as`." ) ;
87
104
if !status. success ( ) {
88
- return Err ( io:: Error :: new (
89
- io:: ErrorKind :: Other ,
90
- format ! ( "Failed to assemble `{}`" , global_asm) ,
91
- ) ) ;
105
+ return Err ( format ! ( "Failed to assemble `{}`" , global_asm) ) ;
92
106
}
93
107
94
108
// Link the global asm and main object file together
95
109
let main_object_file = add_file_stem_postfix ( output_object_file. clone ( ) , ".main" ) ;
96
110
std:: fs:: rename ( & output_object_file, & main_object_file) . unwrap ( ) ;
97
- let status = Command :: new ( linker)
111
+ let status = Command :: new ( & config . linker )
98
112
. arg ( "-r" ) // Create a new object file
99
113
. arg ( "-o" )
100
114
. arg ( output_object_file)
@@ -103,13 +117,10 @@ pub(crate) fn compile_global_asm(
103
117
. status ( )
104
118
. unwrap ( ) ;
105
119
if !status. success ( ) {
106
- return Err ( io:: Error :: new (
107
- io:: ErrorKind :: Other ,
108
- format ! (
109
- "Failed to link `{}` and `{}` together" ,
110
- main_object_file. display( ) ,
111
- global_asm_object_file. display( ) ,
112
- ) ,
120
+ return Err ( format ! (
121
+ "Failed to link `{}` and `{}` together" ,
122
+ main_object_file. display( ) ,
123
+ global_asm_object_file. display( ) ,
113
124
) ) ;
114
125
}
115
126
0 commit comments