Title: [236534] trunk/Source/_javascript_Core
Revision
236534
Author
[email protected]
Date
2018-09-26 17:14:16 -0700 (Wed, 26 Sep 2018)

Log Message

Assert that performJITMemcpy() is always called with instruction size aligned addresses on ARM64.
https://bugs.webkit.org/show_bug.cgi?id=190016
<rdar://problem/44802875>

Reviewed by Saam Barati.

Also assert in performJITMemcpy() that the entire buffer to be copied will fit in
JIT memory.

* assembler/ARM64Assembler.h:
(JSC::ARM64Assembler::fillNops):
(JSC::ARM64Assembler::replaceWithVMHalt):
(JSC::ARM64Assembler::replaceWithJump):
(JSC::ARM64Assembler::replaceWithLoad):
(JSC::ARM64Assembler::replaceWithAddressComputation):
(JSC::ARM64Assembler::setPointer):
(JSC::ARM64Assembler::repatchInt32):
(JSC::ARM64Assembler::repatchCompact):
(JSC::ARM64Assembler::linkJumpOrCall):
(JSC::ARM64Assembler::linkCompareAndBranch):
(JSC::ARM64Assembler::linkConditionalBranch):
(JSC::ARM64Assembler::linkTestAndBranch):
* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::copyCompactAndLinkCode):
(JSC::LinkBuffer::linkCode):
* jit/ExecutableAllocator.h:
(JSC::performJITMemcpy):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (236533 => 236534)


--- trunk/Source/_javascript_Core/ChangeLog	2018-09-26 23:35:14 UTC (rev 236533)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-09-27 00:14:16 UTC (rev 236534)
@@ -1,3 +1,33 @@
+2018-09-26  Mark Lam  <[email protected]>
+
+        Assert that performJITMemcpy() is always called with instruction size aligned addresses on ARM64.
+        https://bugs.webkit.org/show_bug.cgi?id=190016
+        <rdar://problem/44802875>
+
+        Reviewed by Saam Barati.
+
+        Also assert in performJITMemcpy() that the entire buffer to be copied will fit in
+        JIT memory.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::fillNops):
+        (JSC::ARM64Assembler::replaceWithVMHalt):
+        (JSC::ARM64Assembler::replaceWithJump):
+        (JSC::ARM64Assembler::replaceWithLoad):
+        (JSC::ARM64Assembler::replaceWithAddressComputation):
+        (JSC::ARM64Assembler::setPointer):
+        (JSC::ARM64Assembler::repatchInt32):
+        (JSC::ARM64Assembler::repatchCompact):
+        (JSC::ARM64Assembler::linkJumpOrCall):
+        (JSC::ARM64Assembler::linkCompareAndBranch):
+        (JSC::ARM64Assembler::linkConditionalBranch):
+        (JSC::ARM64Assembler::linkTestAndBranch):
+        * assembler/LinkBuffer.cpp:
+        (JSC::LinkBuffer::copyCompactAndLinkCode):
+        (JSC::LinkBuffer::linkCode):
+        * jit/ExecutableAllocator.h:
+        (JSC::performJITMemcpy):
+
 2018-09-25  Keith Miller  <[email protected]>
 
         Move Symbol API to SPI

Modified: trunk/Source/_javascript_Core/assembler/ARM64Assembler.h (236533 => 236534)


--- trunk/Source/_javascript_Core/assembler/ARM64Assembler.h	2018-09-26 23:35:14 UTC (rev 236533)
+++ trunk/Source/_javascript_Core/assembler/ARM64Assembler.h	2018-09-27 00:14:16 UTC (rev 236534)
@@ -266,6 +266,8 @@
 
 class ARM64Assembler {
 public:
+    static constexpr size_t instructionSize = sizeof(unsigned);
+
     typedef ARM64Registers::RegisterID RegisterID;
     typedef ARM64Registers::SPRegisterID SPRegisterID;
     typedef ARM64Registers::FPRegisterID FPRegisterID;
@@ -1562,9 +1564,10 @@
         size_t n = size / sizeof(int32_t);
         for (int32_t* ptr = static_cast<int32_t*>(base); n--;) {
             int insn = nopPseudo();
-            if (isCopyingToExecutableMemory)
+            if (isCopyingToExecutableMemory) {
+                RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(ptr) == ptr);
                 performJITMemcpy(ptr++, &insn, sizeof(int));
-            else
+            } else
                 memcpy(ptr++, &insn, sizeof(int));
         }
     }
@@ -2636,6 +2639,7 @@
     {
         // This should try to write to null which should always Segfault.
         int insn = dataCacheZeroVirtualAddress(ARM64Registers::zr);
+        RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(where) == where);
         performJITMemcpy(where, &insn, sizeof(int));
         cacheFlush(where, sizeof(int));
     }
@@ -2645,6 +2649,7 @@
         intptr_t offset = (reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(where)) >> 2;
         ASSERT(static_cast<int>(offset) == offset);
         int insn = unconditionalBranchImmediate(false, static_cast<int>(offset));
+        RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(where) == where);
         performJITMemcpy(where, &insn, sizeof(int));
         cacheFlush(where, sizeof(int));
     }
@@ -2675,6 +2680,7 @@
             ASSERT(!shift);
             ASSERT(!(imm12 & ~0xff8));
             int insn = loadStoreRegisterUnsignedImmediate(MemOpSize_64, false, MemOp_LOAD, encodePositiveImmediate<64>(imm12), rn, rd);
+            RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(where) == where);
             performJITMemcpy(where, &insn, sizeof(int));
             cacheFlush(where, sizeof(int));
         }
@@ -2709,6 +2715,7 @@
             ASSERT(opc == MemOp_LOAD);
             ASSERT(!(imm12 & ~0x1ff));
             int insn = addSubtractImmediate(Datasize_64, AddOp_ADD, DontSetFlags, 0, imm12 * sizeof(void*), rn, rt);
+            RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(where) == where);
             performJITMemcpy(where, &insn, sizeof(int));
             cacheFlush(where, sizeof(int));
         }
@@ -2743,6 +2750,7 @@
         buffer[0] = moveWideImediate(Datasize_64, MoveWideOp_Z, 0, getHalfword(value, 0), rd);
         buffer[1] = moveWideImediate(Datasize_64, MoveWideOp_K, 1, getHalfword(value, 1), rd);
         buffer[2] = moveWideImediate(Datasize_64, MoveWideOp_K, 2, getHalfword(value, 2), rd);
+        RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(address) == address);
         performJITMemcpy(address, buffer, sizeof(int) * 3);
 
         if (flush)
@@ -2770,6 +2778,7 @@
             buffer[0] = moveWideImediate(Datasize_32, MoveWideOp_N, 0, ~getHalfword(value, 0), rd);
             buffer[1] = moveWideImediate(Datasize_32, MoveWideOp_K, 1, getHalfword(value, 1), rd);
         }
+        RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(where) == where);
         performJITMemcpy(where, &buffer, sizeof(int) * 2);
 
         cacheFlush(where, sizeof(int) * 2);
@@ -2845,6 +2854,7 @@
         else
             imm12 = encodePositiveImmediate<64>(value);
         int insn = loadStoreRegisterUnsignedImmediate(size, V, opc, imm12, rn, rt);
+        RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(where) == where);
         performJITMemcpy(where, &insn, sizeof(int));
 
         cacheFlush(where, sizeof(int));
@@ -3048,6 +3058,7 @@
         ASSERT(static_cast<int>(offset) == offset);
 
         int insn = unconditionalBranchImmediate(isCall, static_cast<int>(offset));
+        RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
         performJITMemcpy(from, &insn, sizeof(int));
     }
 
@@ -3064,13 +3075,16 @@
 
         if (useDirect || isDirect) {
             int insn = compareAndBranchImmediate(is64Bit ? Datasize_64 : Datasize_32, condition == ConditionNE, static_cast<int>(offset), rt);
+            RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             performJITMemcpy(from, &insn, sizeof(int));
             if (!isDirect) {
                 insn = nopPseudo();
+                RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
                 performJITMemcpy(from + 1, &insn, sizeof(int));
             }
         } else {
             int insn = compareAndBranchImmediate(is64Bit ? Datasize_64 : Datasize_32, invert(condition) == ConditionNE, 2, rt);
+            RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             performJITMemcpy(from, &insn, sizeof(int));
             linkJumpOrCall<false>(from + 1, fromInstruction + 1, to);
         }
@@ -3089,13 +3103,16 @@
 
         if (useDirect || isDirect) {
             int insn = conditionalBranchImmediate(static_cast<int>(offset), condition);
+            RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             performJITMemcpy(from, &insn, sizeof(int));
             if (!isDirect) {
                 insn = nopPseudo();
+                RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
                 performJITMemcpy(from + 1, &insn, sizeof(int));
             }
         } else {
             int insn = conditionalBranchImmediate(2, invert(condition));
+            RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             performJITMemcpy(from, &insn, sizeof(int));
             linkJumpOrCall<false>(from + 1, fromInstruction + 1, to);
         }
@@ -3115,13 +3132,16 @@
 
         if (useDirect || isDirect) {
             int insn = testAndBranchImmediate(condition == ConditionNE, static_cast<int>(bitNumber), static_cast<int>(offset), rt);
+            RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             performJITMemcpy(from, &insn, sizeof(int));
             if (!isDirect) {
                 insn = nopPseudo();
+                RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
                 performJITMemcpy(from + 1, &insn, sizeof(int));
             }
         } else {
             int insn = testAndBranchImmediate(invert(condition) == ConditionNE, static_cast<int>(bitNumber), 2, rt);
+            RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             performJITMemcpy(from, &insn, sizeof(int));
             linkJumpOrCall<false>(from + 1, fromInstruction + 1, to);
         }

Modified: trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp (236533 => 236534)


--- trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp	2018-09-26 23:35:14 UTC (rev 236533)
+++ trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp	2018-09-27 00:14:16 UTC (rev 236534)
@@ -113,6 +113,10 @@
 
     uint8_t* outData = reinterpret_cast<uint8_t*>(outBuffer.buffer());
     uint8_t* codeOutData = m_code.dataLocation<uint8_t*>();
+#if CPU(ARM64)
+    RELEASE_ASSERT(roundUpToMultipleOf<sizeof(unsigned)>(outData) == outData);
+    RELEASE_ASSERT(roundUpToMultipleOf<sizeof(unsigned)>(codeOutData) == codeOutData);
+#endif
 
     int readPtr = 0;
     int writePtr = 0;
@@ -213,6 +217,8 @@
     void* code = m_code.dataLocation();
 #if CPU(ARM_TRADITIONAL)
     macroAssembler.m_assembler.prepareExecutableCopy(code);
+#elif CPU(ARM64)
+    RELEASE_ASSERT(roundUpToMultipleOf<Assembler::instructionSize>(code) == code);
 #endif
     performJITMemcpy(code, buffer.data(), buffer.codeSize());
 #if CPU(MIPS)
@@ -335,5 +341,3 @@
 } // namespace JSC
 
 #endif // ENABLE(ASSEMBLER)
-
-

Modified: trunk/Source/_javascript_Core/jit/ExecutableAllocator.h (236533 => 236534)


--- trunk/Source/_javascript_Core/jit/ExecutableAllocator.h	2018-09-26 23:35:14 UTC (rev 236533)
+++ trunk/Source/_javascript_Core/jit/ExecutableAllocator.h	2018-09-27 00:14:16 UTC (rev 236534)
@@ -88,7 +88,13 @@
 
 static inline void* performJITMemcpy(void *dst, const void *src, size_t n)
 {
+#if CPU(ARM64)
+    static constexpr size_t instructionSize = sizeof(unsigned);
+    RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(dst) == dst);
+    RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(src) == src);
+#endif
     if (dst >= startOfFixedExecutableMemoryPool() && dst < endOfFixedExecutableMemoryPool()) {
+        RELEASE_ASSERT(reinterpret_cast<uint8_t*>(dst) + n <= endOfFixedExecutableMemoryPool());
 #if ENABLE(FAST_JIT_PERMISSIONS)
         if (useFastPermisionsJITCopy) {
             os_thread_self_restrict_rwx_to_rw();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to