Skip to content

Commit 86e9370

Browse files
authored
Merge pull request #4504 from RalfJung/link-section-arrays
lookup_link_section: support arrays of function pointers
2 parents 9176fee + d409694 commit 86e9370

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

src/tools/miri/src/helpers.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,8 +1087,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10871087
"failed to evaluate static in required link_section: {def_id:?}\n{err:?}"
10881088
)
10891089
});
1090-
let val = this.read_immediate(&const_val)?;
1091-
array.push(val);
1090+
match const_val.layout.ty.kind() {
1091+
ty::FnPtr(..) => {
1092+
array.push(this.read_immediate(&const_val)?);
1093+
}
1094+
ty::Array(elem_ty, _) if matches!(elem_ty.kind(), ty::FnPtr(..)) => {
1095+
let mut elems = this.project_array_fields(&const_val)?;
1096+
while let Some((_idx, elem)) = elems.next(this)? {
1097+
array.push(this.read_immediate(&elem)?);
1098+
}
1099+
}
1100+
_ =>
1101+
throw_unsup_format!(
1102+
"only function pointers and arrays of function pointers are supported in well-known linker sections"
1103+
),
1104+
}
10921105
}
10931106
interp_ok(())
10941107
})?;

src/tools/miri/tests/pass/shims/ctor.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use std::sync::atomic::{AtomicUsize, Ordering};
22

33
static COUNT: AtomicUsize = AtomicUsize::new(0);
44

5-
unsafe extern "C" fn ctor() {
6-
COUNT.fetch_add(1, Ordering::Relaxed);
5+
unsafe extern "C" fn ctor<const N: usize>() {
6+
COUNT.fetch_add(N, Ordering::Relaxed);
77
}
88

99
#[rustfmt::skip]
1010
macro_rules! ctor {
11-
($ident:ident = $ctor:ident) => {
11+
($ident:ident: $ty:ty = $ctor:expr) => {
1212
#[cfg_attr(
1313
all(any(
1414
target_os = "linux",
@@ -33,14 +33,13 @@ macro_rules! ctor {
3333
link_section = "__DATA,__mod_init_func"
3434
)]
3535
#[used]
36-
static $ident: unsafe extern "C" fn() = $ctor;
36+
static $ident: $ty = $ctor;
3737
};
3838
}
3939

40-
ctor! { CTOR1 = ctor }
41-
ctor! { CTOR2 = ctor }
42-
ctor! { CTOR3 = ctor }
40+
ctor! { CTOR1: unsafe extern "C" fn() = ctor::<1> }
41+
ctor! { CTOR2: [unsafe extern "C" fn(); 2] = [ctor::<2>, ctor::<3>] }
4342

4443
fn main() {
45-
assert_eq!(COUNT.load(Ordering::Relaxed), 3, "ctors did not run");
44+
assert_eq!(COUNT.load(Ordering::Relaxed), 6, "ctors did not run");
4645
}

0 commit comments

Comments
 (0)