diff options
author | Igor Kulaychuk <i.kulaychuk@samsung.com> | 2018-04-06 18:11:37 +0300 |
---|---|---|
committer | 이형주/Tizen Platform Lab(SR)/Staff Engineer/삼성전자 <leee.lee@samsung.com> | 2018-07-06 09:22:08 +0900 |
commit | 1ab482c03987358a574d7d09edc587db62fe465f (patch) | |
tree | 5f0b36e750a730d7e149eba88699f8b8b88e0b35 | |
parent | 7d4b30265d2f50fac759109045818839b5c94d22 (diff) | |
download | coreclr-1ab482c03987358a574d7d09edc587db62fe465f.tar.gz coreclr-1ab482c03987358a574d7d09edc587db62fe465f.tar.bz2 coreclr-1ab482c03987358a574d7d09edc587db62fe465f.zip |
Fix unwinding of funclet with no epilog on x86/Linux
-rw-r--r-- | src/vm/eetwain.cpp | 19 |
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; |