Core: Fix issues with #4273 (#4287)

* Assert on failed mappings, ignore segment prot

* Re-add segment prot conversion

* Disable backing for execute mappings

Macs don't allow this apparently.

* Add assert for file execute permissions
This commit is contained in:
Stephen Miller 2026-04-19 16:20:42 -05:00 committed by GitHub
parent 9af4aa2e25
commit 3400bdf4b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 20 additions and 7 deletions

View File

@ -716,6 +716,12 @@ struct AddressSpace::Impl {
void* Map(VAddr virtual_addr, PAddr phys_addr, u64 size, PosixPageProtection prot,
int fd = -1) {
m_free_regions.subtract({virtual_addr, virtual_addr + size});
#ifdef __APPLE__
if (prot & PROT_EXEC != 0) {
ASSERT_MSG(fd == -1, "Requested execute permissions for file mapping");
phys_addr = -1;
}
#endif
const int handle = phys_addr != -1 ? (fd == -1 ? backing_fd : fd) : -1;
const off_t host_offset = phys_addr != -1 ? phys_addr : 0;
const int flag = phys_addr != -1 ? MAP_SHARED : (MAP_ANONYMOUS | MAP_PRIVATE);

View File

@ -10,6 +10,7 @@
#include "common/string_util.h"
#include "core/aerolib/aerolib.h"
#include "core/cpu_patches.h"
#include "core/libraries/error_codes.h"
#include "core/loader/dwarf.h"
#include "core/memory.h"
#include "core/module.h"
@ -112,17 +113,20 @@ void Module::LoadModuleToMemory(u32& max_tls_index) {
// Reserve memory area for module
void** out_addr = reinterpret_cast<void**>(&base_virtual_addr);
memory->MapMemory(out_addr, ModuleLoadBase, aligned_base_size + TrampolineSize,
MemoryProt::NoAccess, MemoryMapFlags::NoFlags, VMAType::Reserved, name);
s32 result =
memory->MapMemory(out_addr, ModuleLoadBase, aligned_base_size + TrampolineSize,
MemoryProt::NoAccess, MemoryMapFlags::NoFlags, VMAType::Reserved, name);
ASSERT_MSG(result == ORBIS_OK, "Failed to reserve memory for module {}", name);
LOG_INFO(Core_Linker, "Loading module {} to {}", name, fmt::ptr(*out_addr));
#ifdef ARCH_X86_64
// Initialize trampoline generator.
VAddr trampoline_vaddr = base_virtual_addr + aligned_base_size;
void* trampoline_addr = std::bit_cast<void*>(trampoline_vaddr);
memory->MapMemory(&trampoline_addr, trampoline_vaddr, TrampolineSize,
MemoryProt::CpuReadWrite | MemoryProt::CpuExec, MemoryMapFlags::Fixed,
VMAType::Code, name);
result = memory->MapMemory(&trampoline_addr, trampoline_vaddr, TrampolineSize,
MemoryProt::CpuReadWrite | MemoryProt::CpuExec,
MemoryMapFlags::Fixed, VMAType::Code, name);
ASSERT_MSG(result == ORBIS_OK, "Failed to map trampoline area for module {}", name);
RegisterPatchModule(*out_addr, aligned_base_size, trampoline_addr, TrampolineSize);
#endif
@ -147,10 +151,13 @@ void Module::LoadModuleToMemory(u32& max_tls_index) {
if ((phdr.p_flags & PF_EXEC) != 0) {
segment_prot |= MemoryProt::CpuExec;
}
// Map module segments
const auto memory_type = IsSystemLib() ? VMAType::Code : VMAType::Flexible;
memory->MapMemory(&segment_addr, segment_vaddr, segment_size, segment_prot,
MemoryMapFlags::Fixed, memory_type, name);
s32 result = memory->MapMemory(&segment_addr, segment_vaddr, segment_size, segment_prot,
MemoryMapFlags::Fixed, memory_type, name);
ASSERT_MSG(result == ORBIS_OK, "Failed to map segment at {:#x} for module {}",
segment_vaddr, name);
elf.LoadSegment(segment_vaddr, phdr.p_offset, phdr.p_filesz);
}
if (info.num_segments < 4) {