Modified: trunk/Source/_javascript_Core/ChangeLog (107446 => 107447)
--- trunk/Source/_javascript_Core/ChangeLog 2012-02-10 23:01:40 UTC (rev 107446)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-02-10 23:01:54 UTC (rev 107447)
@@ -1,3 +1,22 @@
+2012-02-10 Yong Li <[email protected]>
+
+ ENABLE(ASSEMBLER_WX_EXCLUSIVE): LinkBuffer can leave pages not marked as executable.
+ https://bugs.webkit.org/show_bug.cgi?id=76724
+
+ Reviewed by Rob Buis.
+
+ This issue only exists when both ENABLE(ASSEMBLER_WX_EXCLUSIVE) and ENABLE(BRANCH_COMPACTION) are on.
+ The size used to call makeExecutable can be smaller than the one that was used for makeWritable.
+ So it can leave pages behind that are not set back to default flags. When an assembly on one of those
+ pages is executed or JIT returns to those pages in the case it was already executing from there, the
+ software will crash.
+
+ * assembler/LinkBuffer.h: Add m_initialSize and use it in performFinalization().
+ (JSC::LinkBuffer::LinkBuffer):
+ (JSC::LinkBuffer::linkCode):
+ (JSC::LinkBuffer::performFinalization):
+ (LinkBuffer):
+
2012-02-10 Mark Hahnenberg <[email protected]>
Split MarkedSpace into destructor and destructor-free subspaces
Modified: trunk/Source/_javascript_Core/assembler/LinkBuffer.h (107446 => 107447)
--- trunk/Source/_javascript_Core/assembler/LinkBuffer.h 2012-02-10 23:01:40 UTC (rev 107446)
+++ trunk/Source/_javascript_Core/assembler/LinkBuffer.h 2012-02-10 23:01:54 UTC (rev 107447)
@@ -74,6 +74,9 @@
public:
LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID)
: m_size(0)
+#if ENABLE(BRANCH_COMPACTION)
+ , m_initialSize(0)
+#endif
, m_code(0)
, m_assembler(masm)
, m_globalData(&globalData)
@@ -225,13 +228,13 @@
m_size = m_assembler->m_assembler.codeSize();
ASSERT(m_code);
#else
- size_t initialSize = m_assembler->m_assembler.codeSize();
- m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, initialSize, ownerUID);
+ m_initialSize = m_assembler->m_assembler.codeSize();
+ m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID);
if (!m_executableMemory)
return;
m_code = (uint8_t*)m_executableMemory->start();
ASSERT(m_code);
- ExecutableAllocator::makeWritable(m_code, initialSize);
+ ExecutableAllocator::makeWritable(m_code, m_initialSize);
uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode();
uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);
int readPtr = 0;
@@ -277,8 +280,8 @@
jumpsToLink[i].setFrom(writePtr);
}
// Copy everything after the last jump
- memcpy(outData + writePtr, inData + readPtr, initialSize - readPtr);
- m_assembler->recordLinkOffsets(readPtr, initialSize, readPtr - writePtr);
+ memcpy(outData + writePtr, inData + readPtr, m_initialSize - readPtr);
+ m_assembler->recordLinkOffsets(readPtr, m_initialSize, readPtr - writePtr);
for (unsigned i = 0; i < jumpCount; ++i) {
uint8_t* location = outData + jumpsToLink[i].from();
@@ -287,11 +290,11 @@
}
jumpsToLink.clear();
- m_size = writePtr + initialSize - readPtr;
+ m_size = writePtr + m_initialSize - readPtr;
m_executableMemory->shrink(m_size);
#if DUMP_LINK_STATISTICS
- dumpLinkStatistics(m_code, initialSize, m_size);
+ dumpLinkStatistics(m_code, m_initialSize, m_size);
#endif
#if DUMP_CODE
dumpCode(m_code, m_size);
@@ -306,7 +309,11 @@
m_completed = true;
#endif
+#if ENABLE(BRANCH_COMPACTION)
+ ExecutableAllocator::makeExecutable(code(), m_initialSize);
+#else
ExecutableAllocator::makeExecutable(code(), m_size);
+#endif
ExecutableAllocator::cacheFlush(code(), m_size);
}
@@ -359,6 +366,9 @@
RefPtr<ExecutableMemoryHandle> m_executableMemory;
size_t m_size;
+#if ENABLE(BRANCH_COMPACTION)
+ size_t m_initialSize;
+#endif
void* m_code;
MacroAssembler* m_assembler;
JSGlobalData* m_globalData;