1
1
use rustc_attr:: InstructionSetAttr ;
2
- use rustc_middle:: mir:: mono:: { MonoItem , MonoItemData , Visibility } ;
2
+ use rustc_middle:: mir:: mono:: { Linkage , MonoItem , MonoItemData , Visibility } ;
3
3
use rustc_middle:: mir:: { Body , InlineAsmOperand } ;
4
4
use rustc_middle:: ty:: layout:: { HasTyCtxt , HasTypingEnv , LayoutOf } ;
5
5
use rustc_middle:: ty:: { Instance , TyCtxt } ;
@@ -153,6 +153,30 @@ fn prefix_and_suffix<'tcx>(
153
153
( "" , "" )
154
154
} ;
155
155
156
+ let emit_fatal = |msg| tcx. dcx ( ) . span_fatal ( tcx. def_span ( instance. def_id ( ) ) , msg) ;
157
+
158
+ // see https://godbolt.org/z/cPK4sxKor.
159
+ // None means the default, which corresponds to internal linkage
160
+ let linkage = match item_data. linkage {
161
+ Linkage :: External => Some ( ".globl" ) ,
162
+ Linkage :: LinkOnceAny => Some ( ".weak" ) ,
163
+ Linkage :: LinkOnceODR => Some ( ".weak" ) ,
164
+ Linkage :: WeakAny => Some ( ".weak" ) ,
165
+ Linkage :: WeakODR => Some ( ".weak" ) ,
166
+ Linkage :: Internal => None ,
167
+ Linkage :: Private => None ,
168
+ Linkage :: Appending => emit_fatal ( "Only global variables can have appending linkage!" ) ,
169
+ Linkage :: Common => emit_fatal ( "Functions may not have common linkage" ) ,
170
+ Linkage :: AvailableExternally => {
171
+ // this would make the function equal an extern definition
172
+ emit_fatal ( "Functions may not have available_externally linkage" )
173
+ }
174
+ Linkage :: ExternalWeak => {
175
+ // FIXME: actually this causes a SIGILL in LLVM
176
+ emit_fatal ( "Functions may not have external weak linkage" )
177
+ }
178
+ } ;
179
+
156
180
let mut begin = String :: new ( ) ;
157
181
let mut end = String :: new ( ) ;
158
182
match AsmBinaryFormat :: from_target ( & tcx. sess . target ) {
@@ -171,7 +195,9 @@ fn prefix_and_suffix<'tcx>(
171
195
172
196
writeln ! ( begin, ".pushsection {section},\" ax\" , {progbits}" ) . unwrap ( ) ;
173
197
writeln ! ( begin, ".balign {align}" ) . unwrap ( ) ;
174
- writeln ! ( begin, ".globl {asm_name}" ) . unwrap ( ) ;
198
+ if let Some ( linkage) = linkage {
199
+ writeln ! ( begin, "{linkage} {asm_name}" ) . unwrap ( ) ;
200
+ }
175
201
if let Visibility :: Hidden = item_data. visibility {
176
202
writeln ! ( begin, ".hidden {asm_name}" ) . unwrap ( ) ;
177
203
}
@@ -181,6 +207,8 @@ fn prefix_and_suffix<'tcx>(
181
207
}
182
208
writeln ! ( begin, "{asm_name}:" ) . unwrap ( ) ;
183
209
210
+ eprintln ! ( "{}" , & begin) ;
211
+
184
212
writeln ! ( end) . unwrap ( ) ;
185
213
writeln ! ( end, ".size {asm_name}, . - {asm_name}" ) . unwrap ( ) ;
186
214
writeln ! ( end, ".popsection" ) . unwrap ( ) ;
@@ -192,7 +220,9 @@ fn prefix_and_suffix<'tcx>(
192
220
let section = link_section. unwrap_or ( "__TEXT,__text" . to_string ( ) ) ;
193
221
writeln ! ( begin, ".pushsection {},regular,pure_instructions" , section) . unwrap ( ) ;
194
222
writeln ! ( begin, ".balign {align}" ) . unwrap ( ) ;
195
- writeln ! ( begin, ".globl {asm_name}" ) . unwrap ( ) ;
223
+ if let Some ( linkage) = linkage {
224
+ writeln ! ( begin, "{linkage} {asm_name}" ) . unwrap ( ) ;
225
+ }
196
226
if let Visibility :: Hidden = item_data. visibility {
197
227
writeln ! ( begin, ".private_extern {asm_name}" ) . unwrap ( ) ;
198
228
}
@@ -208,7 +238,9 @@ fn prefix_and_suffix<'tcx>(
208
238
let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
209
239
writeln ! ( begin, ".pushsection {},\" xr\" " , section) . unwrap ( ) ;
210
240
writeln ! ( begin, ".balign {align}" ) . unwrap ( ) ;
211
- writeln ! ( begin, ".globl {asm_name}" ) . unwrap ( ) ;
241
+ if let Some ( linkage) = linkage {
242
+ writeln ! ( begin, "{linkage} {asm_name}" ) . unwrap ( ) ;
243
+ }
212
244
writeln ! ( begin, ".def {asm_name}" ) . unwrap ( ) ;
213
245
writeln ! ( begin, ".scl 2" ) . unwrap ( ) ;
214
246
writeln ! ( begin, ".type 32" ) . unwrap ( ) ;
0 commit comments