jit: Protect against write over-estimates.

This commit is contained in:
Unknown W. Brackets 2022-11-20 09:00:04 -08:00
parent 2e6a19fadc
commit 5294a64828

View file

@ -95,15 +95,37 @@ public:
// In case the last block made the current page exec/no-write, let's fix that.
if (PlatformIsWXExclusive()) {
writeStart_ = GetCodePtr();
if (writeStart_ + sizeEstimate - region > (ptrdiff_t)region_size)
sizeEstimate = region_size - (writeStart_ - region);
writeEstimated_ = sizeEstimate;
ProtectMemoryPages(writeStart_, sizeEstimate, MEM_PROT_READ | MEM_PROT_WRITE);
}
}
// In case you now know your original estimate is wrong.
void ContinueWrite(size_t sizeEstimate = 1) {
_dbg_assert_msg_(writeStart_, "Must have already called BeginWrite()");
if (PlatformIsWXExclusive()) {
const uint8_t *pos = GetCodePtr();
if (pos + sizeEstimate - region > (ptrdiff_t)region_size)
sizeEstimate = region_size - (pos - region);
writeEstimated_ = pos - writeStart_ + sizeEstimate;
ProtectMemoryPages(pos, sizeEstimate, MEM_PROT_READ | MEM_PROT_WRITE);
}
}
void EndWrite() {
// OK, we're done. Re-protect the memory we touched.
if (PlatformIsWXExclusive() && writeStart_ != nullptr) {
const uint8_t *end = GetCodePtr();
ProtectMemoryPages(writeStart_, end - writeStart_, MEM_PROT_READ | MEM_PROT_EXEC);
size_t sz = end - writeStart_;
if (sz > writeEstimated_)
WARN_LOG(JIT, "EndWrite(): Estimated %d bytes, wrote %d", (int)writeEstimated_, (int)sz);
// If we protected and wrote less, we may need to unprotect.
// Especially if we're linking blocks or similar.
if (sz < writeEstimated_)
sz = writeEstimated_;
ProtectMemoryPages(writeStart_, sz, MEM_PROT_READ | MEM_PROT_EXEC);
writeStart_ = nullptr;
}
}
@ -150,5 +172,6 @@ private:
// Note: this is a readable pointer.
const uint8_t *writeStart_ = nullptr;
uint8_t *writableRegion = nullptr;
size_t writeEstimated_ = 0;
};