mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 19:45:12 +00:00
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.
This commit is contained in:
parent
a0e25b2d31
commit
c4dd77a170
Notes:
sideshowbarker
2024-07-19 01:30:53 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c4dd77a170a
4 changed files with 41 additions and 1 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -57,6 +57,11 @@ ALWAYS_INLINE static void ue_notify_free(const void* ptr)
|
|||
send_secret_data_to_userspace_emulator(2, (FlatPtr)ptr, 0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void ue_notify_realloc(const void* ptr, size_t size)
|
||||
{
|
||||
send_secret_data_to_userspace_emulator(3, size, (FlatPtr)ptr);
|
||||
}
|
||||
|
||||
static LibThread::Lock& malloc_lock()
|
||||
{
|
||||
static u32 lock_storage[sizeof(LibThread::Lock) / sizeof(u32)];
|
||||
|
@ -470,8 +475,11 @@ void* realloc(void* ptr, size_t size)
|
|||
|
||||
LOCKER(malloc_lock());
|
||||
auto existing_allocation_size = malloc_size(ptr);
|
||||
if (size <= existing_allocation_size)
|
||||
|
||||
if (size <= existing_allocation_size) {
|
||||
ue_notify_realloc(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
auto* new_ptr = malloc(size);
|
||||
if (new_ptr) {
|
||||
memcpy(new_ptr, ptr, min(existing_allocation_size, size));
|
||||
|
|
Loading…
Add table
Reference in a new issue