From b16a154901c1efbdf877b4fb28daa939ec04c5f5 Mon Sep 17 00:00:00 2001 From: "commit-queue@webkit.org" Date: Wed, 13 Nov 2013 17:39:43 +0000 Subject: [sh4] Protect repatchCompact from flushConstantPool. https://bugs.webkit.org/show_bug.cgi?id=124278 Patch by Julien Brianceau on 2013-11-13 Reviewed by Michael Saboff. Random crashes may occur with sh4 architecture, when a flushConstantPool occurs in movlMemRegCompact. As in this case a branch opcode and the constant pool are put before the movlMemRegCompact, the branch itself is patched when calling repatchCompact instead of the mov instruction, which is really bad. * assembler/SH4Assembler.h: (JSC::SH4Assembler::repatchCompact): Handle this specific case and add an ASSERT. Change-Id: I9c0e78cade4d20d0d83d683ffe6a499cee63bdbb git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159203 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Allan Sandfeld Jensen --- Source/JavaScriptCore/assembler/SH4Assembler.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'Source/JavaScriptCore/assembler') diff --git a/Source/JavaScriptCore/assembler/SH4Assembler.h b/Source/JavaScriptCore/assembler/SH4Assembler.h index 59d42d6e2..41afeaf3c 100644 --- a/Source/JavaScriptCore/assembler/SH4Assembler.h +++ b/Source/JavaScriptCore/assembler/SH4Assembler.h @@ -1453,10 +1453,17 @@ public: static void repatchCompact(void* where, int32_t value) { + uint16_t* instructionPtr = reinterpret_cast(where); ASSERT(value >= 0); ASSERT(value <= 60); - *reinterpret_cast(where) = ((*reinterpret_cast(where) & 0xfff0) | (value >> 2)); - cacheFlush(reinterpret_cast(where), sizeof(uint16_t)); + + // Handle the uncommon case where a flushConstantPool occurred in movlMemRegCompact. + if ((instructionPtr[0] & 0xf000) == BRA_OPCODE) + instructionPtr += (instructionPtr[0] & 0x0fff) + 2; + + ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFRM_OPCODE); + instructionPtr[0] = (instructionPtr[0] & 0xfff0) | (value >> 2); + cacheFlush(instructionPtr, sizeof(uint16_t)); } static void relinkCall(void* from, void* to) -- cgit v1.2.1