Fix DECR mode allocations (sys_memory)

This commit is contained in:
eladash 2019-01-04 18:42:31 +02:00 committed by Ivan
parent 400718dfd9
commit d4a24433e8
3 changed files with 37 additions and 20 deletions

View file

@ -45,16 +45,24 @@ error_code sys_memory_allocate(u32 size, u64 flags, vm::ptr<u32> alloc_addr)
return CELL_ENOMEM; return CELL_ENOMEM;
} }
if (!alloc_addr) if (const auto area = vm::get(align == 0x10000 ? vm::user64k : vm::user1m, 0, ::align(size, 0x10000000)))
{ {
dct->used -= size; if (u32 addr = area->alloc(size, align))
return CELL_EFAULT; {
if (alloc_addr)
{
*alloc_addr = addr;
return CELL_OK;
}
// Dealloc using the syscall
sys_memory_free(addr);
return CELL_EFAULT;
}
} }
// Allocate memory, write back the start address of the allocated area dct->used -= size;
*alloc_addr = verify(HERE, vm::alloc(size, align == 0x10000 ? vm::user64k : vm::user1m, align)); return CELL_ENOMEM;
return CELL_OK;
} }
error_code sys_memory_allocate_from_container(u32 size, u32 cid, u64 flags, vm::ptr<u32> alloc_addr) error_code sys_memory_allocate_from_container(u32 size, u32 cid, u64 flags, vm::ptr<u32> alloc_addr)
@ -98,19 +106,28 @@ error_code sys_memory_allocate_from_container(u32 size, u32 cid, u64 flags, vm::
return ct.ret; return ct.ret;
} }
if (!alloc_addr)
{
ct->used -= size;
return CELL_EFAULT;
}
// Create phantom memory object // Create phantom memory object
const auto mem = idm::make_ptr<lv2_memory_alloca>(size, align, flags, ct.ptr); const auto mem = idm::make_ptr<lv2_memory_alloca>(size, align, flags, ct.ptr);
// Allocate memory if (const auto area = vm::get(align == 0x10000 ? vm::user64k : vm::user1m, 0, ::align(size, 0x10000000)))
*alloc_addr = verify(HERE, vm::get(align == 0x10000 ? vm::user64k : vm::user1m)->alloc(size, mem->align, &mem->shm)); {
if (u32 addr = area->alloc(size, mem->align, &mem->shm))
{
if (alloc_addr)
{
*alloc_addr = addr;
return CELL_OK;
}
return CELL_OK; // Dealloc using the syscall
sys_memory_free(addr);
return CELL_EFAULT;
}
}
idm::remove<lv2_memory_alloca>(idm::last_id());
ct->used -= size;
return CELL_ENOMEM;
} }
error_code sys_memory_free(u32 addr) error_code sys_memory_free(u32 addr)

View file

@ -978,7 +978,7 @@ namespace vm
return nullptr; return nullptr;
} }
std::shared_ptr<block_t> get(memory_location_t location, u32 addr) std::shared_ptr<block_t> get(memory_location_t location, u32 addr, u32 area_size)
{ {
vm::reader_lock lock; vm::reader_lock lock;
@ -989,7 +989,7 @@ namespace vm
{ {
auto& loc = g_locations[location]; auto& loc = g_locations[location];
if (!loc) if (!loc && area_size)
{ {
if (location == vm::user64k || location == vm::user1m) if (location == vm::user64k || location == vm::user1m)
{ {
@ -998,7 +998,7 @@ namespace vm
if (!loc) if (!loc)
{ {
// Deferred allocation // Deferred allocation
loc = _find_map(0x10000000, 0x10000000, location == vm::user64k ? 0x201 : 0x401); loc = _find_map(area_size, 0x10000000, location == vm::user64k ? 0x201 : 0x401);
} }
} }
} }

View file

@ -189,7 +189,7 @@ namespace vm
std::shared_ptr<block_t> unmap(u32 addr, bool must_be_empty = false); std::shared_ptr<block_t> unmap(u32 addr, bool must_be_empty = false);
// Get memory block associated with optionally specified memory location or optionally specified address // Get memory block associated with optionally specified memory location or optionally specified address
std::shared_ptr<block_t> get(memory_location_t location, u32 addr = 0); std::shared_ptr<block_t> get(memory_location_t location, u32 addr = 0, u32 area_size = 0);
// Get PS3/PSV virtual memory address from the provided pointer (nullptr always converted to 0) // Get PS3/PSV virtual memory address from the provided pointer (nullptr always converted to 0)
inline vm::addr_t get_addr(const void* real_ptr) inline vm::addr_t get_addr(const void* real_ptr)