diff --git a/src/coreclr/src/vm/gccover.cpp b/src/coreclr/src/vm/gccover.cpp index cbe3873f364f40..3ad4f9203d64a1 100644 --- a/src/coreclr/src/vm/gccover.cpp +++ b/src/coreclr/src/vm/gccover.cpp @@ -744,23 +744,37 @@ void replaceSafePointInstructionWithGcStressInstr(UINT32 safePointOffset, LPVOID //Determine if instruction before the safe point is call using immediate (BLX Imm) or call by register (BLX Rm) BOOL instructionIsACallThroughRegister = FALSE; BOOL instructionIsACallThroughImmediate = FALSE; + #if defined(TARGET_ARM) + // POSSIBLE BUG: Note that we are looking backwards by 2 or 4 bytes, looking for particular call instruction encodings. + // However, we don't know if the previous instruction is 2 bytes or 4 bytes. Looking back 2 bytes could be looking into + // the middle of a 4-byte instruction. The only safe way to do this is by walking forward from the first instruction of + // the function. + // call by register instruction is two bytes (BL Reg T1 encoding) WORD instr = *((WORD*)savedInstrPtr - 1); - instr = instr & 0xff87; - if((instr ^ 0x4780) == 0) + if ((instr ^ 0x4780) == 0) + { // It is call by register instructionIsACallThroughRegister = TRUE; + } + else + { + // call using immediate instructions are 4 bytes (BL