diff --git a/DevTools/UserspaceEmulator/CMakeLists.txt b/DevTools/UserspaceEmulator/CMakeLists.txt index afa694ae59f..dd2a2b37ad2 100644 --- a/DevTools/UserspaceEmulator/CMakeLists.txt +++ b/DevTools/UserspaceEmulator/CMakeLists.txt @@ -2,6 +2,7 @@ set(SOURCES Emulator.cpp MallocTracer.cpp MmapRegion.cpp + Region.cpp SharedBufferRegion.cpp SimpleRegion.cpp SoftCPU.cpp diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index c65e0f89ee6..427eed248ca 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -72,9 +72,10 @@ Emulator& Emulator::the() Emulator::Emulator(const Vector& arguments, const Vector& environment, NonnullRefPtr elf) : m_elf(move(elf)) + , m_mmu(*this) , m_cpu(*this) { - m_malloc_tracer = make(); + m_malloc_tracer = make(*this); ASSERT(!s_the); s_the = this; setup_stack(arguments, environment); diff --git a/DevTools/UserspaceEmulator/MallocTracer.cpp b/DevTools/UserspaceEmulator/MallocTracer.cpp index 13bce805ee4..e0c6803ba53 100644 --- a/DevTools/UserspaceEmulator/MallocTracer.cpp +++ b/DevTools/UserspaceEmulator/MallocTracer.cpp @@ -36,14 +36,15 @@ namespace UserspaceEmulator { -MallocTracer::MallocTracer() +MallocTracer::MallocTracer(Emulator& emulator) + : m_emulator(emulator) { } template inline void MallocTracer::for_each_mallocation(Callback callback) const { - Emulator::the().mmu().for_each_region([&](auto& region) { + m_emulator.mmu().for_each_region([&](auto& region) { if (region.is_mmap() && static_cast(region).is_malloc_block()) { auto* malloc_data = static_cast(region).malloc_metadata(); for (auto& mallocation : malloc_data->mallocations) { @@ -57,7 +58,7 @@ inline void MallocTracer::for_each_mallocation(Callback callback) const void MallocTracer::target_did_malloc(Badge, FlatPtr address, size_t size) { - auto* region = Emulator::the().mmu().find_region({ 0x20, address }); + auto* region = m_emulator.mmu().find_region({ 0x20, address }); ASSERT(region); ASSERT(region->is_mmap()); auto& mmap_region = static_cast(*region); @@ -72,7 +73,7 @@ void MallocTracer::target_did_malloc(Badge, FlatPtr address, size_t siz ASSERT(existing_mallocation->freed); existing_mallocation->size = size; existing_mallocation->freed = false; - existing_mallocation->malloc_backtrace = Emulator::the().raw_backtrace(); + existing_mallocation->malloc_backtrace = m_emulator.raw_backtrace(); existing_mallocation->free_backtrace.clear(); return; } @@ -92,7 +93,7 @@ void MallocTracer::target_did_malloc(Badge, FlatPtr address, size_t siz malloc_data->mallocations.resize(1); dbgln("Tracking malloc block @ {:p} with chunk_size={}, chunk_count={}", malloc_data->address, malloc_data->chunk_size, malloc_data->mallocations.size()); } - malloc_data->mallocation_for_address(address) = { address, size, true, false, Emulator::the().raw_backtrace(), Vector() }; + malloc_data->mallocation_for_address(address) = { address, size, true, false, m_emulator.raw_backtrace(), Vector() }; } ALWAYS_INLINE Mallocation& MallocRegionMetadata::mallocation_for_address(FlatPtr address) const @@ -120,22 +121,22 @@ void MallocTracer::target_did_free(Badge, FlatPtr address) if (mallocation->freed) { reportln("\n=={}== \033[31;1mDouble free()\033[0m, {:p}", getpid(), address); reportln("=={}== Address {} has already been passed to free()", getpid(), address); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); } else { mallocation->freed = true; - mallocation->free_backtrace = Emulator::the().raw_backtrace(); + mallocation->free_backtrace = m_emulator.raw_backtrace(); } return; } reportln("\n=={}== \033[31;1mInvalid free()\033[0m, {:p}", getpid(), address); reportln("=={}== Address {} has never been returned by malloc()", getpid(), address); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); } void MallocTracer::target_did_realloc(Badge, FlatPtr address, size_t size) { - auto* region = Emulator::the().mmu().find_region({ 0x20, address }); + auto* region = m_emulator.mmu().find_region({ 0x20, address }); ASSERT(region); ASSERT(region->is_mmap()); auto& mmap_region = static_cast(*region); @@ -158,7 +159,7 @@ void MallocTracer::target_did_realloc(Badge, FlatPtr address, size_t si existing_mallocation->size = size; // FIXME: Should we track malloc/realloc backtrace separately perhaps? - existing_mallocation->malloc_backtrace = Emulator::the().raw_backtrace(); + existing_mallocation->malloc_backtrace = m_emulator.raw_backtrace(); } Mallocation* MallocTracer::find_mallocation(const Region& region, FlatPtr address) @@ -179,7 +180,7 @@ Mallocation* MallocTracer::find_mallocation(const Region& region, FlatPtr addres Mallocation* MallocTracer::find_mallocation(FlatPtr address) { - auto* region = Emulator::the().mmu().find_region({ 0x23, address }); + auto* region = m_emulator.mmu().find_region({ 0x23, address }); if (!region) return nullptr; return find_mallocation(*region, address); @@ -216,26 +217,26 @@ void MallocTracer::audit_read(const Region& region, FlatPtr address, size_t size if (!m_auditing_enabled) return; - if (Emulator::the().is_in_malloc_or_free()) + if (m_emulator.is_in_malloc_or_free()) return; auto* mallocation = find_mallocation(region, address); if (!mallocation) { reportln("\n=={}== \033[31;1mHeap buffer overflow\033[0m, invalid {}-byte read at address {:p}", getpid(), size, address); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); auto* mallocation_before = find_mallocation_before(address); auto* mallocation_after = find_mallocation_after(address); size_t distance_to_mallocation_before = mallocation_before ? (address - mallocation_before->address - mallocation_before->size) : 0; size_t distance_to_mallocation_after = mallocation_after ? (mallocation_after->address - address) : 0; if (mallocation_before && (!mallocation_after || distance_to_mallocation_before < distance_to_mallocation_after)) { reportln("=={}== Address is {} byte(s) after block of size {}, identity {:p}, allocated at:", getpid(), distance_to_mallocation_before, mallocation_before->size, mallocation_before->address); - Emulator::the().dump_backtrace(mallocation_before->malloc_backtrace); + m_emulator.dump_backtrace(mallocation_before->malloc_backtrace); return; } if (mallocation_after && (!mallocation_before || distance_to_mallocation_after < distance_to_mallocation_before)) { reportln("=={}== Address is {} byte(s) before block of size {}, identity {:p}, allocated at:", getpid(), distance_to_mallocation_after, mallocation_after->size, mallocation_after->address); - Emulator::the().dump_backtrace(mallocation_after->malloc_backtrace); + m_emulator.dump_backtrace(mallocation_after->malloc_backtrace); } return; } @@ -244,11 +245,11 @@ void MallocTracer::audit_read(const Region& region, FlatPtr address, size_t size if (mallocation->freed) { reportln("\n=={}== \033[31;1mUse-after-free\033[0m, invalid {}-byte read at address {:p}", getpid(), size, address); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); reportln("=={}== Address is {} byte(s) into block of size {}, allocated at:", getpid(), offset_into_mallocation, mallocation->size); - Emulator::the().dump_backtrace(mallocation->malloc_backtrace); + m_emulator.dump_backtrace(mallocation->malloc_backtrace); reportln("=={}== Later freed at:", getpid()); - Emulator::the().dump_backtrace(mallocation->free_backtrace); + m_emulator.dump_backtrace(mallocation->free_backtrace); return; } } @@ -258,25 +259,25 @@ void MallocTracer::audit_write(const Region& region, FlatPtr address, size_t siz if (!m_auditing_enabled) return; - if (Emulator::the().is_in_malloc_or_free()) + if (m_emulator.is_in_malloc_or_free()) return; auto* mallocation = find_mallocation(region, address); if (!mallocation) { reportln("\n=={}== \033[31;1mHeap buffer overflow\033[0m, invalid {}-byte write at address {:p}", getpid(), size, address); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); auto* mallocation_before = find_mallocation_before(address); auto* mallocation_after = find_mallocation_after(address); size_t distance_to_mallocation_before = mallocation_before ? (address - mallocation_before->address - mallocation_before->size) : 0; size_t distance_to_mallocation_after = mallocation_after ? (mallocation_after->address - address) : 0; if (mallocation_before && (!mallocation_after || distance_to_mallocation_before < distance_to_mallocation_after)) { reportln("=={}== Address is {} byte(s) after block of size {}, identity {:p}, allocated at:", getpid(), distance_to_mallocation_before, mallocation_before->size, mallocation_before->address); - Emulator::the().dump_backtrace(mallocation_before->malloc_backtrace); + m_emulator.dump_backtrace(mallocation_before->malloc_backtrace); return; } if (mallocation_after && (!mallocation_before || distance_to_mallocation_after < distance_to_mallocation_before)) { reportln("=={}== Address is {} byte(s) before block of size {}, identity {:p}, allocated at:", getpid(), distance_to_mallocation_after, mallocation_after->size, mallocation_after->address); - Emulator::the().dump_backtrace(mallocation_after->malloc_backtrace); + m_emulator.dump_backtrace(mallocation_after->malloc_backtrace); } return; } @@ -285,11 +286,11 @@ void MallocTracer::audit_write(const Region& region, FlatPtr address, size_t siz if (mallocation->freed) { reportln("\n=={}== \033[31;1mUse-after-free\033[0m, invalid {}-byte write at address {:p}", getpid(), size, address); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); reportln("=={}== Address is {} byte(s) into block of size {}, allocated at:", getpid(), offset_into_mallocation, mallocation->size); - Emulator::the().dump_backtrace(mallocation->malloc_backtrace); + m_emulator.dump_backtrace(mallocation->malloc_backtrace); reportln("=={}== Later freed at:", getpid()); - Emulator::the().dump_backtrace(mallocation->free_backtrace); + m_emulator.dump_backtrace(mallocation->free_backtrace); return; } } @@ -308,7 +309,7 @@ bool MallocTracer::is_reachable(const Mallocation& mallocation) const return IterationDecision::Continue; size_t pointers_in_mallocation = other_mallocation.size / sizeof(u32); for (size_t i = 0; i < pointers_in_mallocation; ++i) { - auto value = Emulator::the().mmu().read32({ 0x20, other_mallocation.address + i * sizeof(u32) }); + auto value = m_emulator.mmu().read32({ 0x20, other_mallocation.address + i * sizeof(u32) }); if (value.value() == mallocation.address && !value.is_uninitialized()) { #ifdef REACHABLE_DEBUG reportln("mallocation {:p} is reachable from other mallocation {:p}", mallocation.address, other_mallocation.address); @@ -324,7 +325,7 @@ bool MallocTracer::is_reachable(const Mallocation& mallocation) const return true; // 2. Search in other memory regions for pointers to this mallocation - Emulator::the().mmu().for_each_region([&](auto& region) { + m_emulator.mmu().for_each_region([&](auto& region) { // Skip the stack if (region.is_stack()) return IterationDecision::Continue; @@ -364,7 +365,7 @@ void MallocTracer::dump_leak_report() ++leaks_found; bytes_leaked += mallocation.size; reportln("\n=={}== \033[31;1mLeak\033[0m, {}-byte allocation at address {:p}", getpid(), mallocation.size, mallocation.address); - Emulator::the().dump_backtrace(mallocation.malloc_backtrace); + m_emulator.dump_backtrace(mallocation.malloc_backtrace); return IterationDecision::Continue; }); diff --git a/DevTools/UserspaceEmulator/MallocTracer.h b/DevTools/UserspaceEmulator/MallocTracer.h index c04ee43bf45..f9bcd5d1733 100644 --- a/DevTools/UserspaceEmulator/MallocTracer.h +++ b/DevTools/UserspaceEmulator/MallocTracer.h @@ -35,7 +35,7 @@ namespace UserspaceEmulator { -class MmapRegion; +class Emulator; class SoftCPU; struct Mallocation { @@ -66,7 +66,7 @@ public: class MallocTracer { public: - MallocTracer(); + explicit MallocTracer(Emulator&); void target_did_malloc(Badge, FlatPtr address, size_t); void target_did_free(Badge, FlatPtr address); @@ -87,6 +87,8 @@ private: Mallocation* find_mallocation_after(FlatPtr); bool is_reachable(const Mallocation&) const; + Emulator& m_emulator; + bool m_auditing_enabled { true }; }; diff --git a/DevTools/UserspaceEmulator/MmapRegion.cpp b/DevTools/UserspaceEmulator/MmapRegion.cpp index 19fbac94efd..40efc0f9a22 100644 --- a/DevTools/UserspaceEmulator/MmapRegion.cpp +++ b/DevTools/UserspaceEmulator/MmapRegion.cpp @@ -69,12 +69,12 @@ ValueWithShadow MmapRegion::read8(FlatPtr offset) { if (!is_readable()) { reportln("8-bit read from unreadable MmapRegion @ {:p}", base() + offset); - Emulator::the().dump_backtrace(); + emulator().dump_backtrace(); TODO(); } if (is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) + if (auto* tracer = emulator().malloc_tracer()) tracer->audit_read(*this, base() + offset, 1); } @@ -86,12 +86,12 @@ ValueWithShadow MmapRegion::read16(u32 offset) { if (!is_readable()) { reportln("16-bit read from unreadable MmapRegion @ {:p}", base() + offset); - Emulator::the().dump_backtrace(); + emulator().dump_backtrace(); TODO(); } if (is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) + if (auto* tracer = emulator().malloc_tracer()) tracer->audit_read(*this, base() + offset, 2); } @@ -103,12 +103,12 @@ ValueWithShadow MmapRegion::read32(u32 offset) { if (!is_readable()) { reportln("32-bit read from unreadable MmapRegion @ {:p}", base() + offset); - Emulator::the().dump_backtrace(); + emulator().dump_backtrace(); TODO(); } if (is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) + if (auto* tracer = emulator().malloc_tracer()) tracer->audit_read(*this, base() + offset, 4); } @@ -120,12 +120,12 @@ ValueWithShadow MmapRegion::read64(u32 offset) { if (!is_readable()) { reportln("64-bit read from unreadable MmapRegion @ {:p}", base() + offset); - Emulator::the().dump_backtrace(); + emulator().dump_backtrace(); TODO(); } if (is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) + if (auto* tracer = emulator().malloc_tracer()) tracer->audit_read(*this, base() + offset, 8); } @@ -137,12 +137,12 @@ void MmapRegion::write8(u32 offset, ValueWithShadow value) { if (!is_writable()) { reportln("8-bit write from unwritable MmapRegion @ {:p}", base() + offset); - Emulator::the().dump_backtrace(); + emulator().dump_backtrace(); TODO(); } if (is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) + if (auto* tracer = emulator().malloc_tracer()) tracer->audit_write(*this, base() + offset, 1); } @@ -155,12 +155,12 @@ void MmapRegion::write16(u32 offset, ValueWithShadow value) { if (!is_writable()) { reportln("16-bit write from unwritable MmapRegion @ {:p}", base() + offset); - Emulator::the().dump_backtrace(); + emulator().dump_backtrace(); TODO(); } if (is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) + if (auto* tracer = emulator().malloc_tracer()) tracer->audit_write(*this, base() + offset, 2); } @@ -173,12 +173,12 @@ void MmapRegion::write32(u32 offset, ValueWithShadow value) { if (!is_writable()) { reportln("32-bit write from unwritable MmapRegion @ {:p}", base() + offset); - Emulator::the().dump_backtrace(); + emulator().dump_backtrace(); TODO(); } if (is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) + if (auto* tracer = emulator().malloc_tracer()) tracer->audit_write(*this, base() + offset, 4); } @@ -192,12 +192,12 @@ void MmapRegion::write64(u32 offset, ValueWithShadow value) { if (!is_writable()) { reportln("64-bit write from unwritable MmapRegion @ {:p}", base() + offset); - Emulator::the().dump_backtrace(); + emulator().dump_backtrace(); TODO(); } if (is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) + if (auto* tracer = emulator().malloc_tracer()) tracer->audit_write(*this, base() + offset, 8); } diff --git a/DevTools/UserspaceEmulator/Region.cpp b/DevTools/UserspaceEmulator/Region.cpp new file mode 100644 index 00000000000..c5f989c802a --- /dev/null +++ b/DevTools/UserspaceEmulator/Region.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Region.h" +#include "Emulator.h" + +namespace UserspaceEmulator { + +Region::Region(u32 base, u32 size) + : m_emulator(Emulator::the()) + , m_base(base) + , m_size(size) +{ +} + +} diff --git a/DevTools/UserspaceEmulator/Region.h b/DevTools/UserspaceEmulator/Region.h index 0c37c5235ca..b75f37f5177 100644 --- a/DevTools/UserspaceEmulator/Region.h +++ b/DevTools/UserspaceEmulator/Region.h @@ -31,6 +31,8 @@ namespace UserspaceEmulator { +class Emulator; + class Region { public: virtual ~Region() { } @@ -72,14 +74,15 @@ public: virtual u8* data() = 0; virtual u8* shadow_data() = 0; + Emulator& emulator() { return m_emulator; } + const Emulator& emulator() const { return m_emulator; } + protected: - Region(u32 base, u32 size) - : m_base(base) - , m_size(size) - { - } + Region(u32 base, u32 size); private: + Emulator& m_emulator; + u32 m_base { 0 }; u32 m_size { 0 }; diff --git a/DevTools/UserspaceEmulator/SoftMMU.cpp b/DevTools/UserspaceEmulator/SoftMMU.cpp index b8c2f3b9413..313e06a6056 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.cpp +++ b/DevTools/UserspaceEmulator/SoftMMU.cpp @@ -34,6 +34,11 @@ namespace UserspaceEmulator { +SoftMMU::SoftMMU(Emulator& emulator) + : m_emulator(emulator) +{ +} + Region* SoftMMU::find_region(X86::LogicalAddress address) { if (address.selector() == 0x28) @@ -82,13 +87,13 @@ ValueWithShadow SoftMMU::read8(X86::LogicalAddress address) auto* region = find_region(address); if (!region) { reportln("SoftMMU::read8: No region for @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } if (!region->is_readable()) { reportln("SoftMMU::read8: Non-readable region @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } @@ -100,13 +105,13 @@ ValueWithShadow SoftMMU::read16(X86::LogicalAddress address) auto* region = find_region(address); if (!region) { reportln("SoftMMU::read16: No region for @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } if (!region->is_readable()) { reportln("SoftMMU::read16: Non-readable region @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } @@ -118,13 +123,13 @@ ValueWithShadow SoftMMU::read32(X86::LogicalAddress address) auto* region = find_region(address); if (!region) { reportln("SoftMMU::read32: No region for @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } if (!region->is_readable()) { reportln("SoftMMU::read32: Non-readable region @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } @@ -136,13 +141,13 @@ ValueWithShadow SoftMMU::read64(X86::LogicalAddress address) auto* region = find_region(address); if (!region) { reportln("SoftMMU::read64: No region for @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } if (!region->is_readable()) { reportln("SoftMMU::read64: Non-readable region @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } @@ -154,13 +159,13 @@ void SoftMMU::write8(X86::LogicalAddress address, ValueWithShadow value) auto* region = find_region(address); if (!region) { reportln("SoftMMU::write8: No region for @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } if (!region->is_writable()) { reportln("SoftMMU::write8: Non-writable region @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } region->write8(address.offset() - region->base(), value); @@ -171,13 +176,13 @@ void SoftMMU::write16(X86::LogicalAddress address, ValueWithShadow value) auto* region = find_region(address); if (!region) { reportln("SoftMMU::write16: No region for @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } if (!region->is_writable()) { reportln("SoftMMU::write16: Non-writable region @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } @@ -189,13 +194,13 @@ void SoftMMU::write32(X86::LogicalAddress address, ValueWithShadow value) auto* region = find_region(address); if (!region) { reportln("SoftMMU::write32: No region for @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } if (!region->is_writable()) { reportln("SoftMMU::write32: Non-writable region @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } @@ -207,13 +212,13 @@ void SoftMMU::write64(X86::LogicalAddress address, ValueWithShadow value) auto* region = find_region(address); if (!region) { reportln("SoftMMU::write64: No region for @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } if (!region->is_writable()) { reportln("SoftMMU::write64: Non-writable region @ {:p}", address.offset()); - Emulator::the().dump_backtrace(); + m_emulator.dump_backtrace(); TODO(); } @@ -257,7 +262,7 @@ bool SoftMMU::fast_fill_memory8(X86::LogicalAddress address, size_t size, ValueW return false; if (region->is_mmap() && static_cast(*region).is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) { + if (auto* tracer = m_emulator.malloc_tracer()) { // FIXME: Add a way to audit an entire range of memory instead of looping here! for (size_t i = 0; i < size; ++i) { tracer->audit_write(*region, address.offset() + (i * sizeof(u8)), sizeof(u8)); @@ -282,7 +287,7 @@ bool SoftMMU::fast_fill_memory32(X86::LogicalAddress address, size_t count, Valu return false; if (region->is_mmap() && static_cast(*region).is_malloc_block()) { - if (auto* tracer = Emulator::the().malloc_tracer()) { + if (auto* tracer = m_emulator.malloc_tracer()) { // FIXME: Add a way to audit an entire range of memory instead of looping here! for (size_t i = 0; i < count; ++i) { tracer->audit_write(*region, address.offset() + (i * sizeof(u32)), sizeof(u32)); diff --git a/DevTools/UserspaceEmulator/SoftMMU.h b/DevTools/UserspaceEmulator/SoftMMU.h index 398e09eeb93..f59ae955312 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.h +++ b/DevTools/UserspaceEmulator/SoftMMU.h @@ -36,10 +36,13 @@ namespace UserspaceEmulator { +class Emulator; class SharedBufferRegion; class SoftMMU { public: + explicit SoftMMU(Emulator&); + ValueWithShadow read8(X86::LogicalAddress); ValueWithShadow read16(X86::LogicalAddress); ValueWithShadow read32(X86::LogicalAddress); @@ -80,6 +83,8 @@ public: } private: + Emulator& m_emulator; + Region* m_page_to_region_map[786432]; OwnPtr m_tls_region;