@@ -125,6 +125,8 @@ fn prefix_and_suffix<'tcx>(
125
125
) -> ( String , String ) {
126
126
use std:: fmt:: Write ;
127
127
128
+ let asm_binary_format = AsmBinaryFormat :: from_target ( & tcx. sess . target ) ;
129
+
128
130
let is_arm = tcx. sess . target . arch == "arm" ;
129
131
let is_thumb = tcx. sess . unstable_target_features . contains ( & sym:: thumb_mode) ;
130
132
@@ -156,30 +158,43 @@ fn prefix_and_suffix<'tcx>(
156
158
let emit_fatal = |msg| tcx. dcx ( ) . span_fatal ( tcx. def_span ( instance. def_id ( ) ) , msg) ;
157
159
158
160
// 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
+ }
177
190
}
191
+
192
+ Ok ( ( ) )
178
193
} ;
179
194
180
195
let mut begin = String :: new ( ) ;
181
196
let mut end = String :: new ( ) ;
182
- match AsmBinaryFormat :: from_target ( & tcx . sess . target ) {
197
+ match asm_binary_format {
183
198
AsmBinaryFormat :: Elf => {
184
199
let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
185
200
@@ -195,9 +210,7 @@ fn prefix_and_suffix<'tcx>(
195
210
196
211
writeln ! ( begin, ".pushsection {section},\" ax\" , {progbits}" ) . unwrap ( ) ;
197
212
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 ( ) ;
201
214
if let Visibility :: Hidden = item_data. visibility {
202
215
writeln ! ( begin, ".hidden {asm_name}" ) . unwrap ( ) ;
203
216
}
@@ -218,9 +231,7 @@ fn prefix_and_suffix<'tcx>(
218
231
let section = link_section. unwrap_or ( "__TEXT,__text" . to_string ( ) ) ;
219
232
writeln ! ( begin, ".pushsection {},regular,pure_instructions" , section) . unwrap ( ) ;
220
233
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 ( ) ;
224
235
if let Visibility :: Hidden = item_data. visibility {
225
236
writeln ! ( begin, ".private_extern {asm_name}" ) . unwrap ( ) ;
226
237
}
@@ -236,9 +247,7 @@ fn prefix_and_suffix<'tcx>(
236
247
let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
237
248
writeln ! ( begin, ".pushsection {},\" xr\" " , section) . unwrap ( ) ;
238
249
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 ( ) ;
242
251
writeln ! ( begin, ".def {asm_name}" ) . unwrap ( ) ;
243
252
writeln ! ( begin, ".scl 2" ) . unwrap ( ) ;
244
253
writeln ! ( begin, ".type 32" ) . unwrap ( ) ;
0 commit comments