summaryrefslogtreecommitdiff
path: root/DevTools/UserspaceEmulator
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-11-08 10:10:41 +0100
committerAndreas Kling <kling@serenityos.org>2020-11-08 10:43:15 +0100
commitc4dd77a170a66fb50921dd8ce8f83ed3c42c10ac (patch)
treefa5f8f5204eaf46d8bbecceccc99109d16bc91f2 /DevTools/UserspaceEmulator
parenta0e25b2d31e5024ae839fe5f2931c343c8efef48 (diff)
downloadserenity-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.cpp28
-rw-r--r--DevTools/UserspaceEmulator/MallocTracer.h1
-rw-r--r--DevTools/UserspaceEmulator/SoftCPU.cpp3
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();
}