summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Kulaychuk <i.kulaychuk@samsung.com>2018-04-06 18:11:37 +0300
committerGleb Balykov <g.balykov@samsung.com>2018-09-18 15:49:14 +0300
commitb3acda1a58e28cf4d9ddcad02fc6f1240f27d5b1 (patch)
tree0d4b95afc73aeda1e4166e6cf6abfba25bab82a1
parentef843928dded8dc9353b980899ed697258618b06 (diff)
downloadcoreclr-b3acda1a58e28cf4d9ddcad02fc6f1240f27d5b1.tar.gz
coreclr-b3acda1a58e28cf4d9ddcad02fc6f1240f27d5b1.tar.bz2
coreclr-b3acda1a58e28cf4d9ddcad02fc6f1240f27d5b1.zip
Fix unwinding of funclet with no epilog on x86/Linux
-rw-r--r--src/vm/eetwain.cpp19
1 files changed, 5 insertions, 14 deletions
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
index 511a635509..593b44d2df 100644
--- a/src/vm/eetwain.cpp
+++ b/src/vm/eetwain.cpp
@@ -36,7 +36,8 @@
#define X86_INSTR_PUSH_EBP 0x55 // push ebp
#define X86_INSTR_W_MOV_EBP_ESP 0xEC8B // mov ebp, esp
#define X86_INSTR_POP_ECX 0x59 // pop ecx
-#define X86_INSTR_RET 0xC2 // ret
+#define X86_INSTR_RET 0xC2 // ret imm16
+#define X86_INSTR_RETN 0xC3 // ret
#define X86_INSTR_w_LEA_ESP_EBP_BYTE_OFFSET 0x658d // lea esp, [ebp-bOffset]
#define X86_INSTR_w_LEA_ESP_EBP_DWORD_OFFSET 0xa58d // lea esp, [ebp-dwOffset]
#define X86_INSTR_JMP_NEAR_REL32 0xE9 // near jmp rel32
@@ -3880,19 +3881,9 @@ bool UnwindEbpDoubleAlignFrame(
// epilog: add esp, 12
// ret
// SP alignment padding should be added for all instructions except the first one and the last one.
- TADDR funcletStart = pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo);
-
- const ULONG32 funcletLastInstSize = 1; // 0xc3, ret
- BOOL atFuncletLastInst = (pCodeInfo->GetRelOffset() + funcletLastInstSize) >= info->methodSize;
- if (!atFuncletLastInst)
- {
- EECodeInfo nextCodeInfo;
- nextCodeInfo.Init(pCodeInfo->GetCodeAddress() + funcletLastInstSize);
- atFuncletLastInst = !nextCodeInfo.IsValid() || !nextCodeInfo.IsFunclet() ||
- nextCodeInfo.GetJitManager()->GetFuncletStartAddress(&nextCodeInfo) != funcletStart;
- }
-
- if (!atFuncletLastInst && funcletStart != pCodeInfo->GetCodeAddress())
+ // Epilog may not exist (unreachable), so we need to check the instruction code.
+ const TADDR funcletStart = pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo);
+ if (funcletStart != pCodeInfo->GetCodeAddress() && methodStart[pCodeInfo->GetRelOffset()] != X86_INSTR_RETN)
baseSP += 12;
pContext->PCTAddr = baseSP;