8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use libc:: c_uint;
11
12
use llvm;
12
13
use llvm:: { SetUnnamedAddr } ;
13
14
use llvm:: { ValueRef , True } ;
@@ -24,11 +25,9 @@ use type_of::LayoutLlvmExt;
24
25
use rustc:: ty;
25
26
use rustc:: ty:: layout:: { Align , LayoutOf } ;
26
27
27
- use rustc:: hir;
28
+ use rustc:: hir:: { self , CodegenFnAttrFlags } ;
28
29
29
30
use std:: ffi:: { CStr , CString } ;
30
- use syntax:: ast;
31
- use syntax:: attr;
32
31
33
32
pub fn ptrcast ( val : ValueRef , ty : Type ) -> ValueRef {
34
33
unsafe {
@@ -244,18 +243,19 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
244
243
}
245
244
246
245
pub fn codegen_static < ' a , ' tcx > ( cx : & CodegenCx < ' a , ' tcx > ,
247
- def_id : DefId ,
248
- is_mutable : bool ,
249
- attrs : & [ ast:: Attribute ] ) {
246
+ def_id : DefId ,
247
+ is_mutable : bool ) {
250
248
unsafe {
251
- let g = get_static ( cx , def_id) ;
249
+ let attrs = cx . tcx . codegen_fn_attrs ( def_id) ;
252
250
253
251
let ( v, alloc) = match :: mir:: codegen_static_initializer ( cx, def_id) {
254
252
Ok ( v) => v,
255
253
// Error has already been reported
256
254
Err ( _) => return ,
257
255
} ;
258
256
257
+ let g = get_static ( cx, def_id) ;
258
+
259
259
// boolean SSA values are i1, but they have to be stored in i8 slots,
260
260
// otherwise some LLVM optimization passes don't work as expected
261
261
let mut val_llty = val_ty ( v) ;
@@ -307,7 +307,7 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
307
307
308
308
debuginfo:: create_global_var_metadata ( cx, def_id, g) ;
309
309
310
- if attr :: contains_name ( attrs , "thread_local" ) {
310
+ if attrs . flags . contains ( CodegenFnAttrFlags :: THREAD_LOCAL ) {
311
311
llvm:: set_thread_local_mode ( g, cx. tls_model ) ;
312
312
313
313
// Do not allow LLVM to change the alignment of a TLS on macOS.
@@ -349,9 +349,34 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
349
349
}
350
350
}
351
351
352
- base:: set_link_section ( cx, g, attrs) ;
353
352
354
- if attr:: contains_name ( attrs, "used" ) {
353
+ // Wasm statics with custom link sections get special treatment as they
354
+ // go into custom sections of the wasm executable.
355
+ if cx. tcx . sess . opts . target_triple . triple ( ) . starts_with ( "wasm32" ) {
356
+ if let Some ( section) = attrs. link_section {
357
+ let section = llvm:: LLVMMDStringInContext (
358
+ cx. llcx ,
359
+ section. as_str ( ) . as_ptr ( ) as * const _ ,
360
+ section. as_str ( ) . len ( ) as c_uint ,
361
+ ) ;
362
+ let alloc = llvm:: LLVMMDStringInContext (
363
+ cx. llcx ,
364
+ alloc. bytes . as_ptr ( ) as * const _ ,
365
+ alloc. bytes . len ( ) as c_uint ,
366
+ ) ;
367
+ let data = [ section, alloc] ;
368
+ let meta = llvm:: LLVMMDNodeInContext ( cx. llcx , data. as_ptr ( ) , 2 ) ;
369
+ llvm:: LLVMAddNamedMetadataOperand (
370
+ cx. llmod ,
371
+ "wasm.custom_sections\0 " . as_ptr ( ) as * const _ ,
372
+ meta,
373
+ ) ;
374
+ }
375
+ } else {
376
+ base:: set_link_section ( g, & attrs) ;
377
+ }
378
+
379
+ if attrs. flags . contains ( CodegenFnAttrFlags :: USED ) {
355
380
// This static will be stored in the llvm.used variable which is an array of i8*
356
381
let cast = llvm:: LLVMConstPointerCast ( g, Type :: i8p ( cx) . to_ref ( ) ) ;
357
382
cx. used_statics . borrow_mut ( ) . push ( cast) ;
0 commit comments