Skip to content

Commit b7ef674

Browse files
committed
rustc: Use link_section, not wasm_custom_section
This commit transitions definitions of custom sections on the wasm target from the unstable `#[wasm_custom_section]` attribute to the already-stable-for-other-targets `#[link_section]` attribute. Mostly the same restrictions apply as before, except that this now applies only to statics. Closes #51088
1 parent 50702b2 commit b7ef674

26 files changed

+147
-328
lines changed

src/librustc/hir/check_attr.rs

-4
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
8181
self.tcx.sess.span_err(attr.span, "\
8282
must only be attached to foreign modules");
8383
}
84-
} else if attr.check_name("wasm_custom_section") {
85-
if target != Target::Const {
86-
self.tcx.sess.span_err(attr.span, "only allowed on consts");
87-
}
8884
}
8985
}
9086

src/librustc/hir/mod.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -2266,20 +2266,22 @@ pub struct CodegenFnAttrs {
22662266
pub export_name: Option<Symbol>,
22672267
pub target_features: Vec<Symbol>,
22682268
pub linkage: Option<Linkage>,
2269-
pub wasm_custom_section: Option<Symbol>,
2269+
pub link_section: Option<Symbol>,
22702270
}
22712271

22722272
bitflags! {
22732273
#[derive(RustcEncodable, RustcDecodable)]
2274-
pub struct CodegenFnAttrFlags: u8 {
2275-
const COLD = 0b0000_0001;
2276-
const ALLOCATOR = 0b0000_0010;
2277-
const UNWIND = 0b0000_0100;
2278-
const RUSTC_ALLOCATOR_NOUNWIND = 0b0000_1000;
2279-
const NAKED = 0b0001_0000;
2280-
const NO_MANGLE = 0b0010_0000;
2281-
const RUSTC_STD_INTERNAL_SYMBOL = 0b0100_0000;
2282-
const NO_DEBUG = 0b1000_0000;
2274+
pub struct CodegenFnAttrFlags: u32 {
2275+
const COLD = 1 << 0;
2276+
const ALLOCATOR = 1 << 1;
2277+
const UNWIND = 1 << 2;
2278+
const RUSTC_ALLOCATOR_NOUNWIND = 1 << 3;
2279+
const NAKED = 1 << 4;
2280+
const NO_MANGLE = 1 << 5;
2281+
const RUSTC_STD_INTERNAL_SYMBOL = 1 << 6;
2282+
const NO_DEBUG = 1 << 7;
2283+
const THREAD_LOCAL = 1 << 8;
2284+
const USED = 1 << 9;
22832285
}
22842286
}
22852287

@@ -2291,7 +2293,7 @@ impl CodegenFnAttrs {
22912293
export_name: None,
22922294
target_features: vec![],
22932295
linkage: None,
2294-
wasm_custom_section: None,
2296+
link_section: None,
22952297
}
22962298
}
22972299

src/librustc/ich/impls_hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ impl_stable_hash_for!(struct hir::CodegenFnAttrs {
11201120
export_name,
11211121
target_features,
11221122
linkage,
1123-
wasm_custom_section,
1123+
link_section,
11241124
});
11251125

11261126
impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags

src/librustc/middle/dead.rs

-5
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,6 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
313313
return true;
314314
}
315315

316-
// These constants are special for wasm
317-
if attr::contains_name(attrs, "wasm_custom_section") {
318-
return true;
319-
}
320-
321316
tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
322317
}
323318

src/librustc/mir/mono.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ pub enum MonoItem<'tcx> {
2424
Fn(Instance<'tcx>),
2525
Static(DefId),
2626
GlobalAsm(NodeId),
27-
CustomSection(DefId),
2827
}
2928

3029
impl<'tcx> MonoItem<'tcx> {
@@ -38,8 +37,7 @@ impl<'tcx> MonoItem<'tcx> {
3837
// Conservatively estimate the size of a static declaration
3938
// or assembly to be 1.
4039
MonoItem::Static(_) |
41-
MonoItem::GlobalAsm(_) |
42-
MonoItem::CustomSection(_) => 1,
40+
MonoItem::GlobalAsm(_) => 1,
4341
}
4442
}
4543
}
@@ -54,8 +52,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for MonoItem<'tcx> {
5452
MonoItem::Fn(ref instance) => {
5553
instance.hash_stable(hcx, hasher);
5654
}
57-
MonoItem::Static(def_id) |
58-
MonoItem::CustomSection(def_id) => {
55+
MonoItem::Static(def_id) => {
5956
def_id.hash_stable(hcx, hasher);
6057
}
6158
MonoItem::GlobalAsm(node_id) => {

src/librustc_codegen_llvm/base.rs

+9-57
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use back::link;
3333
use back::write::{self, OngoingCodegen, create_target_machine};
3434
use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
3535
use llvm;
36-
use libc::c_uint;
3736
use metadata;
3837
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
3938
use rustc::middle::lang_items::StartFnLangItem;
@@ -87,8 +86,7 @@ use std::sync::mpsc;
8786
use syntax_pos::Span;
8887
use syntax_pos::symbol::InternedString;
8988
use syntax::attr;
90-
use rustc::hir;
91-
use syntax::ast;
89+
use rustc::hir::{self, CodegenFnAttrs};
9290

9391
use mir::operand::OperandValue;
9492

@@ -513,17 +511,14 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'
513511
mir::codegen_mir(cx, lldecl, &mir, instance, sig);
514512
}
515513

516-
pub fn set_link_section(cx: &CodegenCx,
517-
llval: ValueRef,
518-
attrs: &[ast::Attribute]) {
519-
if let Some(sect) = attr::first_attr_value_str_by_name(attrs, "link_section") {
520-
if contains_null(&sect.as_str()) {
521-
cx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", &sect));
522-
}
523-
unsafe {
524-
let buf = CString::new(sect.as_str().as_bytes()).unwrap();
525-
llvm::LLVMSetSection(llval, buf.as_ptr());
526-
}
514+
pub fn set_link_section(llval: ValueRef, attrs: &CodegenFnAttrs) {
515+
let sect = match attrs.link_section {
516+
Some(name) => name,
517+
None => return,
518+
};
519+
unsafe {
520+
let buf = CString::new(sect.as_str().as_bytes()).unwrap();
521+
llvm::LLVMSetSection(llval, buf.as_ptr());
527522
}
528523
}
529524

@@ -613,10 +608,6 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
613608
}
614609
}
615610

616-
fn contains_null(s: &str) -> bool {
617-
s.bytes().any(|b| b == 0)
618-
}
619-
620611
fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
621612
llmod_id: &str,
622613
link_meta: &LinkMeta)
@@ -1369,42 +1360,3 @@ mod temp_stable_hash_impls {
13691360
}
13701361
}
13711362
}
1372-
1373-
pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) {
1374-
use rustc::mir::interpret::GlobalId;
1375-
1376-
assert!(cx.tcx.sess.opts.target_triple.triple().starts_with("wasm32"));
1377-
1378-
info!("loading wasm section {:?}", def_id);
1379-
1380-
let section = cx.tcx.codegen_fn_attrs(def_id).wasm_custom_section.unwrap();
1381-
1382-
let instance = ty::Instance::mono(cx.tcx, def_id);
1383-
let cid = GlobalId {
1384-
instance,
1385-
promoted: None
1386-
};
1387-
let param_env = ty::ParamEnv::reveal_all();
1388-
let val = cx.tcx.const_eval(param_env.and(cid)).unwrap();
1389-
let alloc = cx.tcx.const_value_to_allocation(val);
1390-
1391-
unsafe {
1392-
let section = llvm::LLVMMDStringInContext(
1393-
cx.llcx,
1394-
section.as_str().as_ptr() as *const _,
1395-
section.as_str().len() as c_uint,
1396-
);
1397-
let alloc = llvm::LLVMMDStringInContext(
1398-
cx.llcx,
1399-
alloc.bytes.as_ptr() as *const _,
1400-
alloc.bytes.len() as c_uint,
1401-
);
1402-
let data = [section, alloc];
1403-
let meta = llvm::LLVMMDNodeInContext(cx.llcx, data.as_ptr(), 2);
1404-
llvm::LLVMAddNamedMetadataOperand(
1405-
cx.llmod,
1406-
"wasm.custom_sections\0".as_ptr() as *const _,
1407-
meta,
1408-
);
1409-
}
1410-
}

src/librustc_codegen_llvm/consts.rs

+35-10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use libc::c_uint;
1112
use llvm;
1213
use llvm::{SetUnnamedAddr};
1314
use llvm::{ValueRef, True};
@@ -24,11 +25,9 @@ use type_of::LayoutLlvmExt;
2425
use rustc::ty;
2526
use rustc::ty::layout::{Align, LayoutOf};
2627

27-
use rustc::hir;
28+
use rustc::hir::{self, CodegenFnAttrFlags};
2829

2930
use std::ffi::{CStr, CString};
30-
use syntax::ast;
31-
use syntax::attr;
3231

3332
pub 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

246245
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) {
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);

src/librustc_codegen_llvm/mono_item.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
5454
bug!("Expected Def::Static for {:?}, found nothing", def_id)
5555
}
5656
};
57-
let attrs = tcx.get_attrs(def_id);
58-
59-
consts::codegen_static(&cx, def_id, is_mutable, &attrs);
57+
consts::codegen_static(&cx, def_id, is_mutable);
6058
}
6159
MonoItem::GlobalAsm(node_id) => {
6260
let item = cx.tcx.hir.expect_item(node_id);
@@ -66,9 +64,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
6664
span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
6765
}
6866
}
69-
MonoItem::CustomSection(def_id) => {
70-
base::define_custom_section(cx, def_id);
71-
}
7267
MonoItem::Fn(instance) => {
7368
base::codegen_instance(&cx, instance);
7469
}
@@ -100,7 +95,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
10095
MonoItem::Fn(instance) => {
10196
predefine_fn(cx, instance, linkage, visibility, &symbol_name);
10297
}
103-
MonoItem::CustomSection(..) => {}
10498
MonoItem::GlobalAsm(..) => {}
10599
}
106100

@@ -120,9 +114,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
120114
MonoItem::Static(id) => {
121115
format!("Static({:?})", id)
122116
}
123-
MonoItem::CustomSection(id) => {
124-
format!("CustomSection({:?})", id)
125-
}
126117
MonoItem::GlobalAsm(id) => {
127118
format!("GlobalAsm({:?})", id)
128119
}
@@ -164,10 +155,10 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
164155
!instance.substs.has_param_types());
165156

166157
let mono_ty = instance.ty(cx.tcx);
167-
let attrs = instance.def.attrs(cx.tcx);
158+
let attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
168159
let lldecl = declare::declare_fn(cx, symbol_name, mono_ty);
169160
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
170-
base::set_link_section(cx, lldecl, &attrs);
161+
base::set_link_section(lldecl, &attrs);
171162
if linkage == Linkage::LinkOnceODR ||
172163
linkage == Linkage::WeakODR {
173164
llvm::SetUniqueComdat(cx.llmod, lldecl);

src/librustc_mir/monomorphize/collector.rs

-10
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,6 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
414414
MonoItem::GlobalAsm(..) => {
415415
recursion_depth_reset = None;
416416
}
417-
MonoItem::CustomSection(..) => {
418-
recursion_depth_reset = None;
419-
}
420417
}
421418

422419
record_accesses(tcx, starting_point, &neighbors[..], inlining_map);
@@ -993,13 +990,6 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
993990
hir::ItemKind::Const(..) => {
994991
// const items only generate mono items if they are
995992
// actually used somewhere. Just declaring them is insufficient.
996-
997-
let def_id = self.tcx.hir.local_def_id(item.id);
998-
if self.tcx.sess.opts.target_triple.triple().starts_with("wasm32") &&
999-
self.tcx.codegen_fn_attrs(def_id).wasm_custom_section.is_some()
1000-
{
1001-
self.output.push(MonoItem::CustomSection(def_id));
1002-
}
1003993
}
1004994
hir::ItemKind::Fn(..) => {
1005995
let def_id = self.tcx.hir.local_def_id(item.id);

0 commit comments

Comments
 (0)