11use rustc_attr:: InstructionSetAttr ;
2- use rustc_middle:: mir:: mono:: { MonoItem , MonoItemData , Visibility } ;
2+ use rustc_middle:: mir:: mono:: { Linkage , MonoItem , MonoItemData , Visibility } ;
33use rustc_middle:: mir:: { Body , InlineAsmOperand } ;
44use rustc_middle:: ty:: layout:: { HasTyCtxt , HasTypingEnv , LayoutOf } ;
55use rustc_middle:: ty:: { Instance , TyCtxt } ;
@@ -153,6 +153,30 @@ fn prefix_and_suffix<'tcx>(
153153 ( "" , "" )
154154 } ;
155155
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+
156180 let mut begin = String :: new ( ) ;
157181 let mut end = String :: new ( ) ;
158182 match AsmBinaryFormat :: from_target ( & tcx. sess . target ) {
@@ -171,7 +195,9 @@ fn prefix_and_suffix<'tcx>(
171195
172196 writeln ! ( begin, ".pushsection {section},\" ax\" , {progbits}" ) . unwrap ( ) ;
173197 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+ }
175201 if let Visibility :: Hidden = item_data. visibility {
176202 writeln ! ( begin, ".hidden {asm_name}" ) . unwrap ( ) ;
177203 }
@@ -181,6 +207,8 @@ fn prefix_and_suffix<'tcx>(
181207 }
182208 writeln ! ( begin, "{asm_name}:" ) . unwrap ( ) ;
183209
210+ eprintln ! ( "{}" , & begin) ;
211+
184212 writeln ! ( end) . unwrap ( ) ;
185213 writeln ! ( end, ".size {asm_name}, . - {asm_name}" ) . unwrap ( ) ;
186214 writeln ! ( end, ".popsection" ) . unwrap ( ) ;
@@ -192,7 +220,9 @@ fn prefix_and_suffix<'tcx>(
192220 let section = link_section. unwrap_or ( "__TEXT,__text" . to_string ( ) ) ;
193221 writeln ! ( begin, ".pushsection {},regular,pure_instructions" , section) . unwrap ( ) ;
194222 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+ }
196226 if let Visibility :: Hidden = item_data. visibility {
197227 writeln ! ( begin, ".private_extern {asm_name}" ) . unwrap ( ) ;
198228 }
@@ -208,7 +238,9 @@ fn prefix_and_suffix<'tcx>(
208238 let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
209239 writeln ! ( begin, ".pushsection {},\" xr\" " , section) . unwrap ( ) ;
210240 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+ }
212244 writeln ! ( begin, ".def {asm_name}" ) . unwrap ( ) ;
213245 writeln ! ( begin, ".scl 2" ) . unwrap ( ) ;
214246 writeln ! ( begin, ".type 32" ) . unwrap ( ) ;
0 commit comments