Skip to content

Commit a85700a

Browse files
committed
Handle .init_array link_section specially on wasm
1 parent 2dbd623 commit a85700a

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

compiler/rustc_codegen_llvm/src/consts.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,14 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
481481
}
482482

483483
// Wasm statics with custom link sections get special treatment as they
484-
// go into custom sections of the wasm executable.
485-
if self.tcx.sess.target.is_like_wasm {
484+
// go into custom sections of the wasm executable. The exception to this
485+
// is the `.init_array` section which are treated specially by the wasm linker.
486+
if self.tcx.sess.target.is_like_wasm
487+
&& attrs
488+
.link_section
489+
.map(|link_section| !link_section.as_str().starts_with(".init_array"))
490+
.unwrap_or(true)
491+
{
486492
if let Some(section) = attrs.link_section {
487493
let section = llvm::LLVMMDStringInContext2(
488494
self.llcx,

compiler/rustc_hir_analysis/src/check/mod.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -159,21 +159,27 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
159159
return;
160160
}
161161

162-
// For the wasm32 target statics with `#[link_section]` are placed into custom
163-
// sections of the final output file, but this isn't link custom sections of
164-
// other executable formats. Namely we can only embed a list of bytes,
165-
// nothing with provenance (pointers to anything else). If any provenance
166-
// show up, reject it here.
162+
// For the wasm32 target statics with `#[link_section]` other than `.init_array`
163+
// are placed into custom sections of the final output file, but this isn't link
164+
// custom sections of other executable formats. Namely we can only embed a list
165+
// of bytes, nothing with provenance (pointers to anything else). If any
166+
// provenance show up, reject it here.
167167
// `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
168168
// the consumer's responsibility to ensure all bytes that have been read
169169
// have defined values.
170170
if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
171171
&& alloc.inner().provenance().ptrs().len() != 0
172172
{
173-
let msg = "statics with a custom `#[link_section]` must be a \
173+
if attrs
174+
.link_section
175+
.map(|link_section| !link_section.as_str().starts_with(".init_array"))
176+
.unwrap_or(true)
177+
{
178+
let msg = "statics with a custom `#[link_section]` must be a \
174179
simple list of bytes on the wasm target with no \
175180
extra levels of indirection such as references";
176-
tcx.dcx().span_err(tcx.def_span(id), msg);
181+
tcx.dcx().span_err(tcx.def_span(id), msg);
182+
}
177183
}
178184
}
179185

0 commit comments

Comments
 (0)