diff options
4 files changed, 20 insertions, 3 deletions
diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.cpp b/Userland/DevTools/UserspaceEmulator/Emulator.cpp index 829dca0a26..b02bf7c692 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator.cpp @@ -34,6 +34,8 @@ namespace UserspaceEmulator { static constexpr u32 stack_location = 0x10000000; static constexpr size_t stack_size = 1 * MiB; +static constexpr u32 signal_trampoline_location = 0xb0000000; + static Emulator* s_the; Emulator& Emulator::the() @@ -95,6 +97,7 @@ Vector<ELF::AuxiliaryValue> Emulator::generate_auxiliary_vector(FlatPtr load_bas void Emulator::setup_stack(Vector<ELF::AuxiliaryValue> aux_vector) { + m_range_allocator.reserve_user_range(VirtualAddress(stack_location), stack_size); auto stack_region = make<SimpleRegion>(stack_location, stack_size); stack_region->set_stack(true); m_mmu.add_region(move(stack_region)); @@ -183,7 +186,9 @@ bool Emulator::load_elf() VERIFY(program_header.type() != PT_TLS); if (program_header.type() == PT_LOAD) { - auto region = make<SimpleRegion>(program_header.vaddr().offset(interpreter_load_offset).get(), program_header.size_in_memory()); + auto start_address = program_header.vaddr().offset(interpreter_load_offset); + m_range_allocator.reserve_user_range(start_address, program_header.size_in_memory()); + auto region = make<SimpleRegion>(start_address.get(), program_header.size_in_memory()); if (program_header.is_executable() && !program_header.is_writable()) region->set_text(true); memcpy(region->data(), program_header.raw_data(), program_header.size_in_image()); @@ -666,7 +671,8 @@ extern "C" void asm_signal_trampoline_end(void); void Emulator::setup_signal_trampoline() { - auto trampoline_region = make<SimpleRegion>(0xb0000000, 4096); + m_range_allocator.reserve_user_range(VirtualAddress(signal_trampoline_location), 4096); + auto trampoline_region = make<SimpleRegion>(signal_trampoline_location, 4096); u8* trampoline = (u8*)asm_signal_trampoline; u8* trampoline_end = (u8*)asm_signal_trampoline_end; diff --git a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp index 704127175a..6672409ef4 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp @@ -1533,7 +1533,9 @@ u32 Emulator::virt$allocate_tls(FlatPtr initial_data, size_t size) // TODO: This matches what Thread::make_thread_specific_region does. The kernel // ends up allocating one more page. Figure out if this is intentional. auto region_size = align_up_to(size, PAGE_SIZE) + PAGE_SIZE; - auto tcb_region = make<SimpleRegion>(0x20000000, region_size); + constexpr auto tls_location = VirtualAddress(0x20000000); + m_range_allocator.reserve_user_range(tls_location, region_size); + auto tcb_region = make<SimpleRegion>(tls_location.get(), region_size); size_t offset = 0; while (size - offset > 0) { diff --git a/Userland/DevTools/UserspaceEmulator/RangeAllocator.cpp b/Userland/DevTools/UserspaceEmulator/RangeAllocator.cpp index e22980b397..8ed75c51cd 100644 --- a/Userland/DevTools/UserspaceEmulator/RangeAllocator.cpp +++ b/Userland/DevTools/UserspaceEmulator/RangeAllocator.cpp @@ -181,4 +181,11 @@ void RangeAllocator::deallocate(const Range& range) } } +void RangeAllocator::reserve_user_range(VirtualAddress begin, size_t size) +{ + auto end = round_up_to_power_of_two(begin.offset(size).get(), PAGE_SIZE); + auto allocated_range = allocate_specific(begin.page_base(), end - begin.page_base().get()); + VERIFY(allocated_range.has_value()); +} + } diff --git a/Userland/DevTools/UserspaceEmulator/RangeAllocator.h b/Userland/DevTools/UserspaceEmulator/RangeAllocator.h index c8264bd190..c0957d8021 100644 --- a/Userland/DevTools/UserspaceEmulator/RangeAllocator.h +++ b/Userland/DevTools/UserspaceEmulator/RangeAllocator.h @@ -22,6 +22,8 @@ public: Optional<Range> allocate_randomized(size_t, size_t alignment); void deallocate(const Range&); + void reserve_user_range(VirtualAddress, size_t); + void dump() const; bool contains(const Range& range) const { return m_total_range.contains(range); } |