Skip to content

Commit 1e3158d

Browse files
committed
add handling for mod_init_funcs linker directive on macOS
1 parent 3597efd commit 1e3158d

File tree

4 files changed

+29
-11
lines changed

4 files changed

+29
-11
lines changed

src/helpers.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12361236
}
12371237

12381238
/// Lookup an array of immediates stored as a linker section of name `name`.
1239-
fn lookup_link_section(&mut self, name: &str) -> InterpResult<'tcx, Vec<ImmTy<'tcx>>> {
1239+
///
1240+
/// Any sections to which the provided equality function returns `true` will be included.
1241+
fn lookup_link_section(
1242+
&mut self,
1243+
eq: impl Fn(&str) -> bool,
1244+
) -> InterpResult<'tcx, Vec<ImmTy<'tcx>>> {
12401245
let this = self.eval_context_mut();
12411246
let tcx = this.tcx.tcx;
12421247

@@ -1247,7 +1252,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12471252
let Some(link_section) = attrs.link_section else {
12481253
return interp_ok(());
12491254
};
1250-
if link_section.as_str() == name {
1255+
if eq(link_section.as_str()) {
12511256
let instance = ty::Instance::mono(tcx, def_id);
12521257
let const_val = this.eval_global(instance).unwrap_or_else(|err| {
12531258
panic!(

src/shims/ctor.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,35 @@ impl<'tcx> GlobalCtorState<'tcx> {
3131
let this = this.eval_context_mut();
3232

3333
// Lookup constructors from the relevant magic link section.
34-
let link_section = match this.tcx.sess.target.binary_format {
34+
let ctors = match this.tcx.sess.target.binary_format {
3535
// Read the CRT library section on Windows.
36-
BinaryFormat::Coff => ".CRT$XCU",
37-
38-
// Read `__mod_init_func` on macOS.
39-
BinaryFormat::MachO => "__DATA,__mod_init_func",
36+
BinaryFormat::Coff =>
37+
this.lookup_link_section(|section| section == ".CRT$XCU")?,
38+
39+
// Read the `__mod_init_func` section on macOS.
40+
BinaryFormat::MachO =>
41+
this.lookup_link_section(|section| {
42+
let mut section = section.splitn(3, ',');
43+
let (segment_name, section_name, section_type) =
44+
(section.next(), section.next(), section.next());
45+
46+
segment_name == Some("__DATA")
47+
&& section_name == Some("__mod_init_func")
48+
// The `mod_init_funcs` directive ensures that the `S_MOD_INIT_FUNC_POINTERS` flag
49+
// is set on the section, but it is not strictly required.
50+
&& matches!(section_type, None | Some("mod_init_funcs"))
51+
})?,
4052

4153
// Read the standard `.init_array` section on platforms that use ELF, or WASM,
4254
// which supports the same linker directive.
43-
BinaryFormat::Elf | BinaryFormat::Wasm => ".init_array",
55+
BinaryFormat::Elf | BinaryFormat::Wasm =>
56+
this.lookup_link_section(|section| section == ".init_array")?,
4457

4558
// Other platforms have no global ctor support.
4659
_ => break 'new_state Done,
4760
};
4861

49-
break 'new_state Ctors(this.lookup_link_section(link_section)?);
62+
break 'new_state Ctors(ctors);
5063
}
5164
Ctors(ctors) => {
5265
if let Some(ctor) = ctors.pop() {

src/shims/tls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
302302

303303
// Windows has a special magic linker section that is run on certain events.
304304
// We don't support most of that, but just enough to make thread-local dtors in `std` work.
305-
interp_ok(this.lookup_link_section(".CRT$XLB")?)
305+
interp_ok(this.lookup_link_section(|section| section == ".CRT$XLB")?)
306306
}
307307

308308
fn schedule_windows_tls_dtor(&mut self, dtor: ImmTy<'tcx>) -> InterpResult<'tcx> {

tests/pass/shims/ctor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ macro_rules! ctor {
2727
#[cfg_attr(windows, link_section = ".CRT$XCU")]
2828
#[cfg_attr(
2929
any(target_os = "macos", target_os = "ios"),
30-
link_section = "__DATA,__mod_init_func"
30+
link_section = "__DATA,__mod_init_func,mod_init_funcs"
3131
)]
3232
#[used]
3333
static $ident: unsafe extern "C" fn() = $ctor;

0 commit comments

Comments
 (0)