@@ -125,6 +125,8 @@ fn prefix_and_suffix<'tcx>(
125125) -> ( String , String ) {
126126 use std:: fmt:: Write ;
127127
128+ let asm_binary_format = AsmBinaryFormat :: from_target ( & tcx. sess . target ) ;
129+
128130 let is_arm = tcx. sess . target . arch == "arm" ;
129131 let is_thumb = tcx. sess . unstable_target_features . contains ( & sym:: thumb_mode) ;
130132
@@ -156,30 +158,43 @@ fn prefix_and_suffix<'tcx>(
156158 let emit_fatal = |msg| tcx. dcx ( ) . span_fatal ( tcx. def_span ( instance. def_id ( ) ) , msg) ;
157159
158160 // 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" )
161+ let write_linkage = |w : & mut String | -> std:: fmt:: Result {
162+ match item_data. linkage {
163+ Linkage :: External => {
164+ writeln ! ( w, ".globl {asm_name}" ) ?;
165+ }
166+ Linkage :: LinkOnceAny | Linkage :: LinkOnceODR | Linkage :: WeakAny | Linkage :: WeakODR => {
167+ match asm_binary_format {
168+ AsmBinaryFormat :: Elf | AsmBinaryFormat :: Coff => {
169+ writeln ! ( w, ".weak {asm_name}" ) ?;
170+ }
171+ AsmBinaryFormat :: Macho => {
172+ writeln ! ( w, ".globl {asm_name}" ) ?;
173+ writeln ! ( w, ".weak_definition {asm_name}" ) ?;
174+ }
175+ }
176+ }
177+ Linkage :: Internal | Linkage :: Private => {
178+ // write nothing
179+ }
180+ Linkage :: Appending => emit_fatal ( "Only global variables can have appending linkage!" ) ,
181+ Linkage :: Common => emit_fatal ( "Functions may not have common linkage" ) ,
182+ Linkage :: AvailableExternally => {
183+ // this would make the function equal an extern definition
184+ emit_fatal ( "Functions may not have available_externally linkage" )
185+ }
186+ Linkage :: ExternalWeak => {
187+ // FIXME: actually this causes a SIGILL in LLVM
188+ emit_fatal ( "Functions may not have external weak linkage" )
189+ }
177190 }
191+
192+ Ok ( ( ) )
178193 } ;
179194
180195 let mut begin = String :: new ( ) ;
181196 let mut end = String :: new ( ) ;
182- match AsmBinaryFormat :: from_target ( & tcx . sess . target ) {
197+ match asm_binary_format {
183198 AsmBinaryFormat :: Elf => {
184199 let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
185200
@@ -195,9 +210,7 @@ fn prefix_and_suffix<'tcx>(
195210
196211 writeln ! ( begin, ".pushsection {section},\" ax\" , {progbits}" ) . unwrap ( ) ;
197212 writeln ! ( begin, ".balign {align}" ) . unwrap ( ) ;
198- if let Some ( linkage) = linkage {
199- writeln ! ( begin, "{linkage} {asm_name}" ) . unwrap ( ) ;
200- }
213+ write_linkage ( & mut begin) . unwrap ( ) ;
201214 if let Visibility :: Hidden = item_data. visibility {
202215 writeln ! ( begin, ".hidden {asm_name}" ) . unwrap ( ) ;
203216 }
@@ -218,9 +231,7 @@ fn prefix_and_suffix<'tcx>(
218231 let section = link_section. unwrap_or ( "__TEXT,__text" . to_string ( ) ) ;
219232 writeln ! ( begin, ".pushsection {},regular,pure_instructions" , section) . unwrap ( ) ;
220233 writeln ! ( begin, ".balign {align}" ) . unwrap ( ) ;
221- if let Some ( linkage) = linkage {
222- writeln ! ( begin, "{linkage} {asm_name}" ) . unwrap ( ) ;
223- }
234+ write_linkage ( & mut begin) . unwrap ( ) ;
224235 if let Visibility :: Hidden = item_data. visibility {
225236 writeln ! ( begin, ".private_extern {asm_name}" ) . unwrap ( ) ;
226237 }
@@ -236,9 +247,7 @@ fn prefix_and_suffix<'tcx>(
236247 let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
237248 writeln ! ( begin, ".pushsection {},\" xr\" " , section) . unwrap ( ) ;
238249 writeln ! ( begin, ".balign {align}" ) . unwrap ( ) ;
239- if let Some ( linkage) = linkage {
240- writeln ! ( begin, "{linkage} {asm_name}" ) . unwrap ( ) ;
241- }
250+ write_linkage ( & mut begin) . unwrap ( ) ;
242251 writeln ! ( begin, ".def {asm_name}" ) . unwrap ( ) ;
243252 writeln ! ( begin, ".scl 2" ) . unwrap ( ) ;
244253 writeln ! ( begin, ".type 32" ) . unwrap ( ) ;
0 commit comments