summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>2013-11-13 17:39:43 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-20 15:02:27 +0100
commitb16a154901c1efbdf877b4fb28daa939ec04c5f5 (patch)
treef8a444bed5046d0fb753db1134e2c264ddca91e0
parentd7af109d619e3a6d88631598aaab7275a084da7f (diff)
[sh4] Protect repatchCompact from flushConstantPool.
https://bugs.webkit.org/show_bug.cgi?id=124278 Patch by Julien Brianceau <jbriance@cisco.com> 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 <allan.jensen@digia.com>
-rw-r--r--Source/JavaScriptCore/assembler/SH4Assembler.h11
1 files changed, 9 insertions, 2 deletions
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<uint16_t*>(where);
ASSERT(value >= 0);
ASSERT(value <= 60);
- *reinterpret_cast<uint16_t*>(where) = ((*reinterpret_cast<uint16_t*>(where) & 0xfff0) | (value >> 2));
- cacheFlush(reinterpret_cast<uint16_t*>(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)