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
