Fix special case tramp assert in x86/amd64. (#16476)
commitf9be7a67d33d9bdec342401a8ed84885672e9b67
authorJohan Lorensson <lateralusx.github@gmail.com>
Mon, 26 Aug 2019 14:46:43 +0000 (26 16:46 +0200)
committerGitHub <noreply@github.com>
Mon, 26 Aug 2019 14:46:43 +0000 (26 16:46 +0200)
treec54f64d08e300607212657c9e019b7aa6e0fcea2
parent80504b8c983beded10b7968be47ac335560237bc
Fix special case tramp assert in x86/amd64. (#16476)

https://github.com/mono/mono/pull/16408 temporary fixed a tramp issue on
x86 (also exist on amd64). This commit fixes the underlying issue and re-enable
the use of noreturn outside of netcore.

The problem hit by the use of OP_NOT_REACHED on x86/amd64 is due to a specific
case when the address to patch happens to fall at the start of a different
managed method. Since the use of OP_NOT_REACHED can end a method
with the call instruction on x86/amd64 in combination with how patch location
(using the return address from stack) is resolved, the implementation in
mono_arch_patch_callsite didn't take this case into account, reading incorrect
patch data, triggering assert oh x86. So, based on timing we could end up with
the following code:

025715B3 call 02570D98
025715B8 push ebp

since the patch target is 025715B8, but also the start of a completely different
method, method_start == origin_code. The fix is to detect this case on x86/amd64
(done on each arch since the way origin_code is detected is arch specific)
and then use a method_start of NULL, that is already a supported scenario.
mono/mini/method-to-ir.c
mono/mini/tramp-amd64.c
mono/mini/tramp-x86.c