diff options
author | commit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc> | 2013-11-13 17:39:43 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-20 15:02:27 +0100 |
commit | b16a154901c1efbdf877b4fb28daa939ec04c5f5 (patch) | |
tree | f8a444bed5046d0fb753db1134e2c264ddca91e0 /Source/JavaScriptCore/assembler/SH4Assembler.h | |
parent | d7af109d619e3a6d88631598aaab7275a084da7f (diff) | |
download | qtwebkit-b16a154901c1efbdf877b4fb28daa939ec04c5f5.tar.gz |
[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>
Diffstat (limited to 'Source/JavaScriptCore/assembler/SH4Assembler.h')
-rw-r--r-- | Source/JavaScriptCore/assembler/SH4Assembler.h | 11 |
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) |