Skip to content
This repository has been archived by the owner on Nov 10, 2022. It is now read-only.

Functions that return twice are UB #1

Open
Amanieu opened this issue Aug 24, 2020 · 2 comments
Open

Functions that return twice are UB #1

Amanieu opened this issue Aug 24, 2020 · 2 comments
Labels
question Further information is requested

Comments

@Amanieu
Copy link

Amanieu commented Aug 24, 2020

Rust does not support calling functions like setjmp which return twice. I would recommend changing the API to a single swap_context operation implemented in inline assembly.

@npmccallum
Copy link
Contributor

@Amanieu Thanks for the issue report!

I'm not entirely sure what you mean by "does not support." Besides the calling convention, there are only two other invariants at play - both of which the caller MUST ensure (this is why load() is unsafe): the original stack position and the return address at the save() call MUST remain valid.

Since Rust MUST obey the calling convention and the caller MUST ensure the remaining two invariants, I'm not sure what's missing...

@Amanieu
Copy link
Author

Amanieu commented Aug 24, 2020

See rust-lang/libc#1574 for an example where returning twice causes a miscompilation. The main issue is that the compiler will re-use stack slots after the setjmp call for variables that it believes are no longer. Having a function return twice will cause unrelated variables to be clobbered (playground). Because of inlining this is not something that you can even control with unsafe: it's always unsound.

The only reason this even works in C is because compilers bend over backwards to support it by disabling many optimizations in any function that calls a function marked with __attribute__((returns_twice)).

@mbestavros mbestavros added the question Further information is requested label Aug 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants