Skip to content

Commit b9717b9

Browse files
hkratzlu-zero
authored andcommitted
Implement proper subroutine call detection for x86, x86_64, aarch64 and wasm32.
1 parent 6cc580c commit b9717b9

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

crates/stdarch-test/src/lib.rs

+21-13
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,25 @@ pub fn assert(shim_addr: usize, fnname: &str, expected: &str) {
9090
// function, e.g., tzcntl in tzcntl %rax,%rax.
9191
let found = instrs.iter().any(|s| s.starts_with(expected));
9292

93-
// Look for `call` instructions in the disassembly to detect whether
94-
// inlining failed: all intrinsics are `#[inline(always)]`, so
95-
// calling one intrinsic from another should not generate `call`
96-
// instructions.
97-
let inlining_failed = instrs.windows(2).any(|s| {
98-
// On 32-bit x86 position independent code will call itself and be
99-
// immediately followed by a `pop` to learn about the current address.
100-
// Let's not take that into account when considering whether a function
101-
// failed inlining something.
102-
s[0].contains("call") && (!cfg!(target_arch = "x86") || s[1].contains("pop"))
103-
});
93+
// Look for subroutine call instructions in the disassembly to detect whether
94+
// inlining failed: all intrinsics are `#[inline(always)]`, so calling one
95+
// intrinsic from another should not generate subroutine call instructions.
96+
let inlining_failed = if cfg!(target_arch = "x86_64") || cfg!(target_arch = "wasm32") {
97+
instrs.iter().any(|s| s.starts_with("call "))
98+
} else if cfg!(target_arch = "x86") {
99+
instrs.windows(2).any(|s| {
100+
// On 32-bit x86 position independent code will call itself and be
101+
// immediately followed by a `pop` to learn about the current address.
102+
// Let's not take that into account when considering whether a function
103+
// failed inlining something.
104+
s[0].starts_with("call ") && s[1].starts_with("pop") // FIXME: original logic but does not match comment
105+
})
106+
} else if cfg!(target_arch = "aarch64") {
107+
instrs.iter().any(|s| s.starts_with("bl "))
108+
} else {
109+
// FIXME: Add detection for other archs
110+
false
111+
};
104112

105113
let instruction_limit = std::env::var("STDARCH_ASSERT_INSTR_LIMIT")
106114
.ok()
@@ -167,8 +175,8 @@ pub fn assert(shim_addr: usize, fnname: &str, expected: &str) {
167175
);
168176
} else if inlining_failed {
169177
panic!(
170-
"instruction found, but the disassembly contains `call` \
171-
instructions, which hint that inlining failed"
178+
"instruction found, but the disassembly contains subroutine \
179+
call instructions, which hint that inlining failed"
172180
);
173181
}
174182
}

0 commit comments

Comments
 (0)