diff options
author | Andreas Kling <kling@serenityos.org> | 2020-11-08 10:10:41 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-11-08 10:43:15 +0100 |
commit | c4dd77a170a66fb50921dd8ce8f83ed3c42c10ac (patch) | |
tree | fa5f8f5204eaf46d8bbecceccc99109d16bc91f2 /DevTools/UserspaceEmulator | |
parent | a0e25b2d31e5024ae839fe5f2931c343c8efef48 (diff) | |
download | serenity-c4dd77a170a66fb50921dd8ce8f83ed3c42c10ac.zip |
UserspaceEmulator+LibC: Have UE notice realloc() and update accounting
When a mallocation is shrunk/grown without moving, UE needs to update
its precise metadata about the mallocation, since it tracks *exactly*
how many bytes were allocated, not just the malloc chunk size.
Diffstat (limited to 'DevTools/UserspaceEmulator')
-rw-r--r-- | DevTools/UserspaceEmulator/MallocTracer.cpp | 28 | ||||
-rw-r--r-- | DevTools/UserspaceEmulator/MallocTracer.h | 1 | ||||
-rw-r--r-- | DevTools/UserspaceEmulator/SoftCPU.cpp | 3 |
3 files changed, 32 insertions, 0 deletions
diff --git a/DevTools/UserspaceEmulator/MallocTracer.cpp b/DevTools/UserspaceEmulator/MallocTracer.cpp index 48cff29c37..6f88d9a446 100644 --- a/DevTools/UserspaceEmulator/MallocTracer.cpp +++ b/DevTools/UserspaceEmulator/MallocTracer.cpp @@ -87,6 +87,34 @@ void MallocTracer::target_did_free(Badge<SoftCPU>, FlatPtr address) Emulator::the().dump_backtrace(); } +void MallocTracer::target_did_realloc(Badge<SoftCPU>, FlatPtr address, size_t size) +{ + auto* region = Emulator::the().mmu().find_region({ 0x20, address }); + ASSERT(region); + ASSERT(region->is_mmap()); + auto& mmap_region = static_cast<MmapRegion&>(*region); + + ASSERT(mmap_region.is_malloc_block()); + + auto* existing_mallocation = find_mallocation(address); + ASSERT(existing_mallocation); + ASSERT(!existing_mallocation->freed); + + size_t old_size = existing_mallocation->size; + + auto* shadow_bits = mmap_region.shadow_data() + address - mmap_region.base(); + + if (size > old_size) { + memset(shadow_bits + old_size, 1, size - old_size); + } else { + memset(shadow_bits + size, 1, old_size - size); + } + + existing_mallocation->size = size; + // FIXME: Should we track malloc/realloc backtrace separately perhaps? + existing_mallocation->malloc_backtrace = Emulator::the().raw_backtrace(); +} + MallocTracer::Mallocation* MallocTracer::find_mallocation(FlatPtr address) { for (auto& mallocation : m_mallocations) { diff --git a/DevTools/UserspaceEmulator/MallocTracer.h b/DevTools/UserspaceEmulator/MallocTracer.h index a38f93823f..fb7f99a307 100644 --- a/DevTools/UserspaceEmulator/MallocTracer.h +++ b/DevTools/UserspaceEmulator/MallocTracer.h @@ -40,6 +40,7 @@ public: void target_did_malloc(Badge<SoftCPU>, FlatPtr address, size_t); void target_did_free(Badge<SoftCPU>, FlatPtr address); + void target_did_realloc(Badge<SoftCPU>, FlatPtr address, size_t); void audit_read(FlatPtr address, size_t); void audit_write(FlatPtr address, size_t); diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index 2c5bb3fdce..7ffbebee88 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -111,6 +111,9 @@ void SoftCPU::did_receive_secret_data() } else if (m_secret_data[0] == 2) { if (auto* tracer = m_emulator.malloc_tracer()) tracer->target_did_free({}, m_secret_data[1]); + } else if (m_secret_data[0] == 3) { + if (auto* tracer = m_emulator.malloc_tracer()) + tracer->target_did_realloc({}, m_secret_data[2], m_secret_data[1]); } else { ASSERT_NOT_REACHED(); } |