diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index 138a4bd2cb..be96bfc5bf 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -920,9 +920,17 @@ u32 Emulator::virt$unveil(u32) return 0; } -u32 Emulator::virt$mprotect(FlatPtr, size_t, int) +u32 Emulator::virt$mprotect(FlatPtr base, size_t size, int prot) { - return 0; + if (auto* region = mmu().find_region({ m_cpu.ds(), base })) { + if (!region->is_mmap()) + return -EINVAL; + ASSERT(region->size() == size); + auto& mmap_region = *(MmapRegion*)region; + mmap_region.set_prot(prot); + return 0; + } + return -EINVAL; } u32 Emulator::virt$madvise(FlatPtr, size_t, int) diff --git a/DevTools/UserspaceEmulator/MmapRegion.h b/DevTools/UserspaceEmulator/MmapRegion.h index 882763cbde..cfe5694c92 100644 --- a/DevTools/UserspaceEmulator/MmapRegion.h +++ b/DevTools/UserspaceEmulator/MmapRegion.h @@ -50,13 +50,15 @@ public: u8* data() { return m_data; } u8* shadow_data() { return m_shadow_data; } - bool is_readable() const { return m_prot & PROT_READ; } - bool is_writable() const { return m_prot & PROT_WRITE; } - bool is_executable() const { return m_prot & PROT_EXEC; } + virtual bool is_readable() const override { return m_prot & PROT_READ; } + virtual bool is_writable() const override { return m_prot & PROT_WRITE; } + virtual bool is_executable() const override { return m_prot & PROT_EXEC; } bool is_malloc_block() const { return m_malloc; } void set_malloc(bool b) { m_malloc = b; } + void set_prot(int prot) { m_prot = prot; } + private: MmapRegion(u32 base, u32 size, int prot); virtual bool is_mmap() const override { return true; } diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index f75e6f191c..94de431e56 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -134,6 +134,12 @@ void SoftCPU::update_code_cache() auto* region = m_emulator.mmu().find_region({ cs(), eip() }); ASSERT(region); + if (!region->is_executable()) { + reportln("SoftCPU::update_code_cache: Non-readable region @ {:p}", eip()); + Emulator::the().dump_backtrace(); + TODO(); + } + m_cached_code_ptr = region->cacheable_ptr(eip() - region->base()); m_cached_code_end = region->cacheable_ptr(region->size()); } diff --git a/DevTools/UserspaceEmulator/SoftMMU.cpp b/DevTools/UserspaceEmulator/SoftMMU.cpp index 328a36c90c..9d330f2305 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.cpp +++ b/DevTools/UserspaceEmulator/SoftMMU.cpp @@ -75,6 +75,12 @@ ValueWithShadow SoftMMU::read8(X86::LogicalAddress address) TODO(); } + if (!region->is_readable()) { + reportln("SoftMMU::read8: Non-readable region @ {:p}", address.offset()); + Emulator::the().dump_backtrace(); + TODO(); + } + return region->read8(address.offset() - region->base()); } @@ -87,6 +93,12 @@ ValueWithShadow SoftMMU::read16(X86::LogicalAddress address) TODO(); } + if (!region->is_readable()) { + reportln("SoftMMU::read16: Non-readable region @ {:p}", address.offset()); + Emulator::the().dump_backtrace(); + TODO(); + } + return region->read16(address.offset() - region->base()); } @@ -99,6 +111,12 @@ ValueWithShadow SoftMMU::read32(X86::LogicalAddress address) TODO(); } + if (!region->is_readable()) { + reportln("SoftMMU::read32: Non-readable region @ {:p}", address.offset()); + Emulator::the().dump_backtrace(); + TODO(); + } + return region->read32(address.offset() - region->base()); } @@ -111,6 +129,12 @@ ValueWithShadow SoftMMU::read64(X86::LogicalAddress address) TODO(); } + if (!region->is_readable()) { + reportln("SoftMMU::read64: Non-readable region @ {:p}", address.offset()); + Emulator::the().dump_backtrace(); + TODO(); + } + return region->read64(address.offset() - region->base()); } @@ -123,6 +147,11 @@ void SoftMMU::write8(X86::LogicalAddress address, ValueWithShadow value) TODO(); } + if (!region->is_writable()) { + reportln("SoftMMU::write8: Non-writable region @ {:p}", address.offset()); + Emulator::the().dump_backtrace(); + TODO(); + } region->write8(address.offset() - region->base(), value); } @@ -135,6 +164,12 @@ void SoftMMU::write16(X86::LogicalAddress address, ValueWithShadow value) TODO(); } + if (!region->is_writable()) { + reportln("SoftMMU::write16: Non-writable region @ {:p}", address.offset()); + Emulator::the().dump_backtrace(); + TODO(); + } + region->write16(address.offset() - region->base(), value); } @@ -147,6 +182,12 @@ void SoftMMU::write32(X86::LogicalAddress address, ValueWithShadow value) TODO(); } + if (!region->is_writable()) { + reportln("SoftMMU::write32: Non-writable region @ {:p}", address.offset()); + Emulator::the().dump_backtrace(); + TODO(); + } + region->write32(address.offset() - region->base(), value); } @@ -159,6 +200,12 @@ void SoftMMU::write64(X86::LogicalAddress address, ValueWithShadow value) TODO(); } + if (!region->is_writable()) { + reportln("SoftMMU::write64: Non-writable region @ {:p}", address.offset()); + Emulator::the().dump_backtrace(); + TODO(); + } + region->write64(address.offset() - region->base(), value); } diff --git a/DevTools/UserspaceEmulator/SoftMMU.h b/DevTools/UserspaceEmulator/SoftMMU.h index 5318bf6b5d..52e9b2a249 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.h +++ b/DevTools/UserspaceEmulator/SoftMMU.h @@ -69,6 +69,10 @@ public: bool is_text() const { return m_text; } void set_text(bool b) { m_text = b; } + virtual bool is_readable() const { return true; } + virtual bool is_writable() const { return true; } + virtual bool is_executable() const { return true; } + protected: Region(u32 base, u32 size) : m_base(base)