-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[mono][interp] Always sign extend small integers to native integer when returning to compiled code #117336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Tagging subscribers to this area: @BrzVlad, @kotlarmilos |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR ensures small integer return values are always sign-extended to the native register size on 64-bit platforms by introducing a specialized conversion function and updating return-value marshaling.
- Adds
stackval_to_data_sign_ext
to handle sign-/zero-extension for 8-, 16-, and 32-bit return types on 64-bit targets. - Replaces calls to
stackval_to_data
withstackval_to_data_sign_ext
ininterp_frame_arg_to_data
andinterp_entry
.
Comments suppressed due to low confidence (1)
src/mono/mono/mini/interp/interp.c:988
- No tests currently verify that small-integer return values are correctly sign-/zero-extended. Consider adding interpreter unit tests that exercise methods returning i1, u1, i2, u2, i4, and u4 on 64-bit platforms to catch any regression.
static void
…en returning to compiled code On amd64 it seems our jit expects i4 to be sign extended to the full 64bit register. On arm64 apple, unlike arm64 linux, callers of methods returning i1,u1,i2 or u2 are expecting a value sign extended to i4. In order to prevent any potential issues around this area, this commit takes on a conservative approach and sign extends every time, since there is no real cost to it. stackval_to_data_sign_ext is called either with a data pointer from a CallContext register or the address of a native int local variable in the `mini_get_interp_in_wrapper`. This means that it should always be safe to write the full value.
b9ea796
to
5334107
Compare
7686515
to
eb3319b
Compare
Those wrappers use the real type as the return, so sign extension shouldn't be needed and it wouldn't be safe, because the wrapper passes the address of the return var of the actual type. Attemptying to sign extend could overflow the storage of this var.
ef0505f
to
4bb2c5e
Compare
backport to release/9.0? |
The bug is not critical enough to backport so late in the release cycle. |
On amd64 it seems our jit expects i4 return to be sign extended to the full 64bit register. On arm64 apple, unlike arm64 linux, callers of methods returning i1,u1,i2 or u2 are expecting a value sign extended to i4. In order to prevent any potential issues around this area, this commit takes on a conservative approach and sign extends every time, since there is no real cost to it.
stackval_to_data_sign_ext is called either with a data pointer from a CallContext register or the address of a native int local variable in the
mini_get_interp_in_wrapper
. This means that it should always be safe to write the full value.Fixes #115859
Fixes #110649
More general alternative to #117306