202 lines
8.7 KiB
Diff
202 lines
8.7 KiB
Diff
|
From 35614462443c100b6753b335b58a134fed4b5c35 Mon Sep 17 00:00:00 2001
|
||
|
From: Ulf Hermann <ulf.hermann@qt.io>
|
||
|
Date: Wed, 16 Dec 2020 16:45:36 +0100
|
||
|
Subject: [PATCH 23/28] JIT: When making memory writable, include the exception
|
||
|
handler
|
||
|
|
||
|
makeWritable() rounds the memory down to the next page boundary. Usually
|
||
|
we include the exception handler this way, unless the offset from the
|
||
|
page boundary is less than the exception handler size. Make it explicit
|
||
|
that we do want the exception handler to be writable, too.
|
||
|
|
||
|
Fixes: QTBUG-89513
|
||
|
Change-Id: I2fb8fb0e1dcc3450b036924463dc1b40d2020c46
|
||
|
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
||
|
(cherry picked from commit 86a595b126bc6794380dc00af80ec4802f7d058c)
|
||
|
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
||
|
---
|
||
|
src/3rdparty/masm/assembler/AssemblerBuffer.h | 4 ++--
|
||
|
src/3rdparty/masm/assembler/LinkBuffer.h | 9 +++++----
|
||
|
.../masm/assembler/MacroAssemblerCodeRef.h | 6 +++---
|
||
|
src/3rdparty/masm/stubs/ExecutableAllocator.h | 11 ++++++++---
|
||
|
src/qml/jsruntime/qv4executableallocator.cpp | 14 ++++++++++++--
|
||
|
src/qml/jsruntime/qv4executableallocator_p.h | 10 ++++++++--
|
||
|
src/qml/jsruntime/qv4functiontable_win64.cpp | 4 ++--
|
||
|
7 files changed, 40 insertions(+), 18 deletions(-)
|
||
|
|
||
|
diff --git a/src/3rdparty/masm/assembler/AssemblerBuffer.h b/src/3rdparty/masm/assembler/AssemblerBuffer.h
|
||
|
index 45874235b6..2292a4c244 100644
|
||
|
--- a/src/3rdparty/masm/assembler/AssemblerBuffer.h
|
||
|
+++ b/src/3rdparty/masm/assembler/AssemblerBuffer.h
|
||
|
@@ -140,9 +140,9 @@ namespace JSC {
|
||
|
if (!result)
|
||
|
return 0;
|
||
|
|
||
|
- ExecutableAllocator::makeWritable(result->start(), result->sizeInBytes());
|
||
|
+ ExecutableAllocator::makeWritable(result->memoryStart(), result->memorySize());
|
||
|
|
||
|
- memcpy(result->start(), m_buffer, m_index);
|
||
|
+ memcpy(result->codeStart(), m_buffer, m_index);
|
||
|
|
||
|
return result.release();
|
||
|
}
|
||
|
diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
|
||
|
index ba57564a1d..fa669deaf9 100644
|
||
|
--- a/src/3rdparty/masm/assembler/LinkBuffer.h
|
||
|
+++ b/src/3rdparty/masm/assembler/LinkBuffer.h
|
||
|
@@ -333,7 +333,7 @@ inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::linkCode
|
||
|
m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort);
|
||
|
if (!m_executableMemory)
|
||
|
return;
|
||
|
- m_code = m_executableMemory->start();
|
||
|
+ m_code = m_executableMemory->codeStart();
|
||
|
m_size = m_assembler->m_assembler.codeSize();
|
||
|
ASSERT(m_code);
|
||
|
}
|
||
|
@@ -355,7 +355,8 @@ void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performFinaliza
|
||
|
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
|
||
|
inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable()
|
||
|
{
|
||
|
- ExecutableAllocator::makeExecutable(code(), static_cast<int>(m_size));
|
||
|
+ ExecutableAllocator::makeExecutable(m_executableMemory->memoryStart(),
|
||
|
+ m_executableMemory->memorySize());
|
||
|
}
|
||
|
|
||
|
template <typename MacroAssembler>
|
||
|
@@ -442,9 +443,9 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID,
|
||
|
m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);
|
||
|
if (!m_executableMemory)
|
||
|
return;
|
||
|
- m_code = (uint8_t*)m_executableMemory->start();
|
||
|
+ m_code = (uint8_t*)m_executableMemory->codeStart();
|
||
|
ASSERT(m_code);
|
||
|
- ExecutableAllocator::makeWritable(m_code, m_initialSize);
|
||
|
+ ExecutableAllocator::makeWritable(m_executableMemory->memoryStart(), m_executableMemory->memorySize());
|
||
|
uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode();
|
||
|
uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);
|
||
|
int readPtr = 0;
|
||
|
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
|
||
|
index a7e78ad78f..cde9751108 100644
|
||
|
--- a/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
|
||
|
+++ b/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
|
||
|
@@ -357,11 +357,11 @@ public:
|
||
|
}
|
||
|
|
||
|
MacroAssemblerCodeRef(PassRefPtr<ExecutableMemoryHandle> executableMemory)
|
||
|
- : m_codePtr(executableMemory->start())
|
||
|
+ : m_codePtr(executableMemory->codeStart())
|
||
|
, m_executableMemory(executableMemory)
|
||
|
{
|
||
|
ASSERT(m_executableMemory->isManaged());
|
||
|
- ASSERT(m_executableMemory->start());
|
||
|
+ ASSERT(m_executableMemory->codeStart());
|
||
|
ASSERT(m_codePtr);
|
||
|
}
|
||
|
|
||
|
@@ -395,7 +395,7 @@ public:
|
||
|
{
|
||
|
if (!m_executableMemory)
|
||
|
return 0;
|
||
|
- return m_executableMemory->sizeInBytes();
|
||
|
+ return m_executableMemory->codeSize();
|
||
|
}
|
||
|
|
||
|
bool tryToDisassemble(const char* prefix) const
|
||
|
diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
|
||
|
index a439c53827..f984704023 100644
|
||
|
--- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
|
||
|
+++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
|
||
|
@@ -82,9 +82,14 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> {
|
||
|
|
||
|
inline bool isManaged() const { return true; }
|
||
|
|
||
|
- void *exceptionHandler() { return m_allocation->exceptionHandler(); }
|
||
|
- void *start() { return m_allocation->start(); }
|
||
|
- size_t sizeInBytes() { return m_size; }
|
||
|
+ void *memoryStart() { return m_allocation->memoryStart(); }
|
||
|
+ size_t memorySize() { return m_allocation->memorySize(); }
|
||
|
+
|
||
|
+ void *exceptionHandlerStart() { return m_allocation->exceptionHandlerStart(); }
|
||
|
+ size_t exceptionHandlerSize() { return m_allocation->exceptionHandlerSize(); }
|
||
|
+
|
||
|
+ void *codeStart() { return m_allocation->codeStart(); }
|
||
|
+ size_t codeSize() { return m_size; }
|
||
|
|
||
|
QV4::ExecutableAllocator::ChunkOfPages *chunk() const
|
||
|
{ return m_allocator->chunkForAllocation(m_allocation); }
|
||
|
diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp
|
||
|
index 7ee6f39aa2..c06773d3c5 100644
|
||
|
--- a/src/qml/jsruntime/qv4executableallocator.cpp
|
||
|
+++ b/src/qml/jsruntime/qv4executableallocator.cpp
|
||
|
@@ -45,12 +45,22 @@
|
||
|
|
||
|
using namespace QV4;
|
||
|
|
||
|
-void *ExecutableAllocator::Allocation::exceptionHandler() const
|
||
|
+void *ExecutableAllocator::Allocation::exceptionHandlerStart() const
|
||
|
{
|
||
|
return reinterpret_cast<void*>(addr);
|
||
|
}
|
||
|
|
||
|
-void *ExecutableAllocator::Allocation::start() const
|
||
|
+size_t ExecutableAllocator::Allocation::exceptionHandlerSize() const
|
||
|
+{
|
||
|
+ return QV4::exceptionHandlerSize();
|
||
|
+}
|
||
|
+
|
||
|
+void *ExecutableAllocator::Allocation::memoryStart() const
|
||
|
+{
|
||
|
+ return reinterpret_cast<void*>(addr);
|
||
|
+}
|
||
|
+
|
||
|
+void *ExecutableAllocator::Allocation::codeStart() const
|
||
|
{
|
||
|
return reinterpret_cast<void*>(addr + exceptionHandlerSize());
|
||
|
}
|
||
|
diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h
|
||
|
index f98f2c7d33..4735fb151f 100644
|
||
|
--- a/src/qml/jsruntime/qv4executableallocator_p.h
|
||
|
+++ b/src/qml/jsruntime/qv4executableallocator_p.h
|
||
|
@@ -86,8 +86,14 @@ public:
|
||
|
, free(true)
|
||
|
{}
|
||
|
|
||
|
- void *exceptionHandler() const;
|
||
|
- void *start() const;
|
||
|
+ void *memoryStart() const;
|
||
|
+ size_t memorySize() const { return size; }
|
||
|
+
|
||
|
+ void *exceptionHandlerStart() const;
|
||
|
+ size_t exceptionHandlerSize() const;
|
||
|
+
|
||
|
+ void *codeStart() const;
|
||
|
+
|
||
|
void invalidate() { addr = 0; }
|
||
|
bool isValid() const { return addr != 0; }
|
||
|
void deallocate(ExecutableAllocator *allocator);
|
||
|
diff --git a/src/qml/jsruntime/qv4functiontable_win64.cpp b/src/qml/jsruntime/qv4functiontable_win64.cpp
|
||
|
index fc13dc2602..0cb98641cd 100644
|
||
|
--- a/src/qml/jsruntime/qv4functiontable_win64.cpp
|
||
|
+++ b/src/qml/jsruntime/qv4functiontable_win64.cpp
|
||
|
@@ -106,7 +106,7 @@ struct ExceptionHandlerRecord
|
||
|
void generateFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
|
||
|
{
|
||
|
ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>(
|
||
|
- codeRef->executableMemory()->exceptionHandler());
|
||
|
+ codeRef->executableMemory()->exceptionHandlerStart());
|
||
|
|
||
|
record->info.Version = 1;
|
||
|
record->info.Flags = 0;
|
||
|
@@ -136,7 +136,7 @@ void generateFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
|
||
|
void destroyFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
|
||
|
{
|
||
|
ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>(
|
||
|
- codeRef->executableMemory()->exceptionHandler());
|
||
|
+ codeRef->executableMemory()->exceptionHandlerStart());
|
||
|
if (!RtlDeleteFunctionTable(&record->handler)) {
|
||
|
const unsigned int errorCode = GetLastError();
|
||
|
qWarning() << "Failed to remove win64 unwind hook. Error code:" << errorCode;
|
||
|
--
|
||
|
2.31.1
|
||
|
|