Explorar o código

Merge pull request #2328 from lioncash/transfer

service/am: Correct behavior of CreateTransferMemoryStorage()
bunnei %!s(int64=7) %!d(string=hai) anos
pai
achega
acde8d3f68

+ 15 - 7
src/core/hle/kernel/transfer_memory.cpp

@@ -14,8 +14,8 @@ namespace Kernel {
 TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {}
 TransferMemory::~TransferMemory() = default;
 
-SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address,
-                                                 size_t size, MemoryPermission permissions) {
+SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, u64 size,
+                                                 MemoryPermission permissions) {
     SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)};
 
     transfer_memory->base_address = base_address;
@@ -26,7 +26,15 @@ SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_
     return transfer_memory;
 }
 
-ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermission permissions) {
+const u8* TransferMemory::GetPointer() const {
+    return backing_block.get()->data();
+}
+
+u64 TransferMemory::GetSize() const {
+    return memory_size;
+}
+
+ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission permissions) {
     if (memory_size != size) {
         return ERR_INVALID_SIZE;
     }
@@ -39,13 +47,13 @@ ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermissio
         return ERR_INVALID_STATE;
     }
 
+    backing_block = std::make_shared<std::vector<u8>>(size);
+
     const auto map_state = owner_permissions == MemoryPermission::None
                                ? MemoryState::TransferMemoryIsolated
                                : MemoryState::TransferMemory;
     auto& vm_manager = owner_process->VMManager();
-    const auto map_result = vm_manager.MapMemoryBlock(
-        address, std::make_shared<std::vector<u8>>(size), 0, size, map_state);
-
+    const auto map_result = vm_manager.MapMemoryBlock(address, backing_block, 0, size, map_state);
     if (map_result.Failed()) {
         return map_result.Code();
     }
@@ -54,7 +62,7 @@ ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermissio
     return RESULT_SUCCESS;
 }
 
-ResultCode TransferMemory::UnmapMemory(VAddr address, size_t size) {
+ResultCode TransferMemory::UnmapMemory(VAddr address, u64 size) {
     if (memory_size != size) {
         return ERR_INVALID_SIZE;
     }

+ 16 - 4
src/core/hle/kernel/transfer_memory.h

@@ -4,6 +4,9 @@
 
 #pragma once
 
+#include <memory>
+#include <vector>
+
 #include "core/hle/kernel/object.h"
 
 union ResultCode;
@@ -25,7 +28,7 @@ class TransferMemory final : public Object {
 public:
     static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory;
 
-    static SharedPtr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, size_t size,
+    static SharedPtr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, u64 size,
                                             MemoryPermission permissions);
 
     TransferMemory(const TransferMemory&) = delete;
@@ -46,6 +49,12 @@ public:
         return HANDLE_TYPE;
     }
 
+    /// Gets a pointer to the backing block of this instance.
+    const u8* GetPointer() const;
+
+    /// Gets the size of the memory backing this instance in bytes.
+    u64 GetSize() const;
+
     /// Attempts to map transfer memory with the given range and memory permissions.
     ///
     /// @param address     The base address to being mapping memory at.
@@ -56,7 +65,7 @@ public:
     ///      the same values that were given when creating the transfer memory
     ///      instance.
     ///
-    ResultCode MapMemory(VAddr address, size_t size, MemoryPermission permissions);
+    ResultCode MapMemory(VAddr address, u64 size, MemoryPermission permissions);
 
     /// Unmaps the transfer memory with the given range
     ///
@@ -66,17 +75,20 @@ public:
     /// @pre The given address and size must be the same as the ones used
     ///      to create the transfer memory instance.
     ///
-    ResultCode UnmapMemory(VAddr address, size_t size);
+    ResultCode UnmapMemory(VAddr address, u64 size);
 
 private:
     explicit TransferMemory(KernelCore& kernel);
     ~TransferMemory() override;
 
+    /// Memory block backing this instance.
+    std::shared_ptr<std::vector<u8>> backing_block;
+
     /// The base address for the memory managed by this instance.
     VAddr base_address = 0;
 
     /// Size of the memory, in bytes, that this instance manages.
-    size_t memory_size = 0;
+    u64 memory_size = 0;
 
     /// The memory permissions that are applied to this instance.
     MemoryPermission owner_permissions{};

+ 6 - 6
src/core/hle/service/am/am.cpp

@@ -13,7 +13,7 @@
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/process.h"
 #include "core/hle/kernel/readable_event.h"
-#include "core/hle/kernel/shared_memory.h"
+#include "core/hle/kernel/transfer_memory.h"
 #include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/hle/service/am/am.h"
@@ -931,19 +931,19 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
     rp.SetCurrentOffset(3);
     const auto handle{rp.Pop<Kernel::Handle>()};
 
-    const auto shared_mem =
-        Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get<Kernel::SharedMemory>(
+    const auto transfer_mem =
+        Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(
             handle);
 
-    if (shared_mem == nullptr) {
+    if (transfer_mem == nullptr) {
         LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle);
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(ResultCode(-1));
         return;
     }
 
-    const u8* mem_begin = shared_mem->GetPointer();
-    const u8* mem_end = mem_begin + shared_mem->GetSize();
+    const u8* const mem_begin = transfer_mem->GetPointer();
+    const u8* const mem_end = mem_begin + transfer_mem->GetSize();
     std::vector<u8> memory{mem_begin, mem_end};
 
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};