88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11+ use libc:: c_uint;
1112use llvm;
1213use llvm:: { SetUnnamedAddr } ;
1314use llvm:: { ValueRef , True } ;
@@ -24,11 +25,9 @@ use type_of::LayoutLlvmExt;
2425use rustc:: ty;
2526use rustc:: ty:: layout:: { Align , LayoutOf } ;
2627
27- use rustc:: hir;
28+ use rustc:: hir:: { self , CodegenFnAttrFlags } ;
2829
2930use std:: ffi:: { CStr , CString } ;
30- use syntax:: ast;
31- use syntax:: attr;
3231
3332pub fn ptrcast ( val : ValueRef , ty : Type ) -> ValueRef {
3433 unsafe {
@@ -244,18 +243,19 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
244243}
245244
246245pub 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 ) {
250248 unsafe {
251- let g = get_static ( cx , def_id) ;
249+ let attrs = cx . tcx . codegen_fn_attrs ( def_id) ;
252250
253251 let ( v, alloc) = match :: mir:: codegen_static_initializer ( cx, def_id) {
254252 Ok ( v) => v,
255253 // Error has already been reported
256254 Err ( _) => return ,
257255 } ;
258256
257+ let g = get_static ( cx, def_id) ;
258+
259259 // boolean SSA values are i1, but they have to be stored in i8 slots,
260260 // otherwise some LLVM optimization passes don't work as expected
261261 let mut val_llty = val_ty ( v) ;
@@ -307,7 +307,7 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
307307
308308 debuginfo:: create_global_var_metadata ( cx, def_id, g) ;
309309
310- if attr :: contains_name ( attrs , "thread_local" ) {
310+ if attrs . flags . contains ( CodegenFnAttrFlags :: THREAD_LOCAL ) {
311311 llvm:: set_thread_local_mode ( g, cx. tls_model ) ;
312312
313313 // 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>,
349349 }
350350 }
351351
352- base:: set_link_section ( cx, g, attrs) ;
353352
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 ) {
355380 // This static will be stored in the llvm.used variable which is an array of i8*
356381 let cast = llvm:: LLVMConstPointerCast ( g, Type :: i8p ( cx) . to_ref ( ) ) ;
357382 cx. used_statics . borrow_mut ( ) . push ( cast) ;
0 commit comments