diff options
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 47 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.h | 24 | 
3 files changed, 66 insertions, 30 deletions
| diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index c5d399bab..223d717e2 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -47,23 +47,6 @@ constexpr bool IsValidAddressRange(VAddr address, u64 size) {      return address + size > address;  } -// Checks if a given address range lies within a larger address range. -constexpr bool IsInsideAddressRange(VAddr address, u64 size, VAddr address_range_begin, -                                    VAddr address_range_end) { -    const VAddr end_address = address + size - 1; -    return address_range_begin <= address && end_address <= address_range_end - 1; -} - -bool IsInsideAddressSpace(const VMManager& vm, VAddr address, u64 size) { -    return IsInsideAddressRange(address, size, vm.GetAddressSpaceBaseAddress(), -                                vm.GetAddressSpaceEndAddress()); -} - -bool IsInsideNewMapRegion(const VMManager& vm, VAddr address, u64 size) { -    return IsInsideAddressRange(address, size, vm.GetNewMapRegionBaseAddress(), -                                vm.GetNewMapRegionEndAddress()); -} -  // 8 GiB  constexpr u64 MAIN_MEMORY_SIZE = 0x200000000; @@ -105,14 +88,14 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add          return ERR_INVALID_ADDRESS_STATE;      } -    if (!IsInsideAddressSpace(vm_manager, src_addr, size)) { +    if (!vm_manager.IsWithinAddressSpace(src_addr, size)) {          LOG_ERROR(Kernel_SVC,                    "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}",                    src_addr, size);          return ERR_INVALID_ADDRESS_STATE;      } -    if (!IsInsideNewMapRegion(vm_manager, dst_addr, size)) { +    if (!vm_manager.IsWithinNewMapRegion(dst_addr, size)) {          LOG_ERROR(Kernel_SVC,                    "Destination is not within the new map region, addr=0x{:016X}, size=0x{:016X}",                    dst_addr, size); @@ -238,7 +221,7 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) {      auto* const current_process = Core::CurrentProcess();      auto& vm_manager = current_process->VMManager(); -    if (!IsInsideAddressSpace(vm_manager, addr, size)) { +    if (!vm_manager.IsWithinAddressSpace(addr, size)) {          LOG_ERROR(Kernel_SVC,                    "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr,                    size); @@ -299,7 +282,7 @@ static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attr      }      auto& vm_manager = Core::CurrentProcess()->VMManager(); -    if (!IsInsideAddressSpace(vm_manager, address, size)) { +    if (!vm_manager.IsWithinAddressSpace(address, size)) {          LOG_ERROR(Kernel_SVC,                    "Given address (0x{:016X}) is outside the bounds of the address space.", address);          return ERR_INVALID_ADDRESS_STATE; diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 10ad94aa6..05c59af34 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -17,8 +17,8 @@  #include "core/memory_setup.h"  namespace Kernel { - -static const char* GetMemoryStateName(MemoryState state) { +namespace { +const char* GetMemoryStateName(MemoryState state) {      static constexpr const char* names[] = {          "Unmapped",         "Io",          "Normal",           "CodeStatic", @@ -35,6 +35,14 @@ static const char* GetMemoryStateName(MemoryState state) {      return names[ToSvcMemoryState(state)];  } +// Checks if a given address range lies within a larger address range. +constexpr bool IsInsideAddressRange(VAddr address, u64 size, VAddr address_range_begin, +                                    VAddr address_range_end) { +    const VAddr end_address = address + size - 1; +    return address_range_begin <= address && end_address <= address_range_end - 1; +} +} // Anonymous namespace +  bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {      ASSERT(base + size == next.base);      if (permissions != next.permissions || state != next.state || attribute != next.attribute || @@ -249,8 +257,7 @@ ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_p  }  ResultVal<VAddr> VMManager::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { -    if (target < GetHeapRegionBaseAddress() || target + size > GetHeapRegionEndAddress() || -        target + size < target) { +    if (!IsWithinHeapRegion(target, size)) {          return ERR_INVALID_ADDRESS;      } @@ -285,8 +292,7 @@ ResultVal<VAddr> VMManager::HeapAllocate(VAddr target, u64 size, VMAPermission p  }  ResultCode VMManager::HeapFree(VAddr target, u64 size) { -    if (target < GetHeapRegionBaseAddress() || target + size > GetHeapRegionEndAddress() || -        target + size < target) { +    if (!IsWithinHeapRegion(target, size)) {          return ERR_INVALID_ADDRESS;      } @@ -706,6 +712,11 @@ u64 VMManager::GetAddressSpaceWidth() const {      return address_space_width;  } +bool VMManager::IsWithinAddressSpace(VAddr address, u64 size) const { +    return IsInsideAddressRange(address, size, GetAddressSpaceBaseAddress(), +                                GetAddressSpaceEndAddress()); +} +  VAddr VMManager::GetASLRRegionBaseAddress() const {      return aslr_region_base;  } @@ -750,6 +761,11 @@ u64 VMManager::GetCodeRegionSize() const {      return code_region_end - code_region_base;  } +bool VMManager::IsWithinCodeRegion(VAddr address, u64 size) const { +    return IsInsideAddressRange(address, size, GetCodeRegionBaseAddress(), +                                GetCodeRegionEndAddress()); +} +  VAddr VMManager::GetHeapRegionBaseAddress() const {      return heap_region_base;  } @@ -762,6 +778,11 @@ u64 VMManager::GetHeapRegionSize() const {      return heap_region_end - heap_region_base;  } +bool VMManager::IsWithinHeapRegion(VAddr address, u64 size) const { +    return IsInsideAddressRange(address, size, GetHeapRegionBaseAddress(), +                                GetHeapRegionEndAddress()); +} +  VAddr VMManager::GetMapRegionBaseAddress() const {      return map_region_base;  } @@ -774,6 +795,10 @@ u64 VMManager::GetMapRegionSize() const {      return map_region_end - map_region_base;  } +bool VMManager::IsWithinMapRegion(VAddr address, u64 size) const { +    return IsInsideAddressRange(address, size, GetMapRegionBaseAddress(), GetMapRegionEndAddress()); +} +  VAddr VMManager::GetNewMapRegionBaseAddress() const {      return new_map_region_base;  } @@ -786,6 +811,11 @@ u64 VMManager::GetNewMapRegionSize() const {      return new_map_region_end - new_map_region_base;  } +bool VMManager::IsWithinNewMapRegion(VAddr address, u64 size) const { +    return IsInsideAddressRange(address, size, GetNewMapRegionBaseAddress(), +                                GetNewMapRegionEndAddress()); +} +  VAddr VMManager::GetTLSIORegionBaseAddress() const {      return tls_io_region_base;  } @@ -798,4 +828,9 @@ u64 VMManager::GetTLSIORegionSize() const {      return tls_io_region_end - tls_io_region_base;  } +bool VMManager::IsWithinTLSIORegion(VAddr address, u64 size) const { +    return IsInsideAddressRange(address, size, GetTLSIORegionBaseAddress(), +                                GetTLSIORegionEndAddress()); +} +  } // namespace Kernel diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 6091533bc..88e0b3c02 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -432,18 +432,21 @@ public:      /// Gets the address space width in bits.      u64 GetAddressSpaceWidth() const; +    /// Determines whether or not the given address range lies within the address space. +    bool IsWithinAddressSpace(VAddr address, u64 size) const; +      /// Gets the base address of the ASLR region.      VAddr GetASLRRegionBaseAddress() const;      /// Gets the end address of the ASLR region.      VAddr GetASLRRegionEndAddress() const; -    /// Determines whether or not the specified address range is within the ASLR region. -    bool IsWithinASLRRegion(VAddr address, u64 size) const; -      /// Gets the size of the ASLR region      u64 GetASLRRegionSize() const; +    /// Determines whether or not the specified address range is within the ASLR region. +    bool IsWithinASLRRegion(VAddr address, u64 size) const; +      /// Gets the base address of the code region.      VAddr GetCodeRegionBaseAddress() const; @@ -453,6 +456,9 @@ public:      /// Gets the total size of the code region in bytes.      u64 GetCodeRegionSize() const; +    /// Determines whether or not the specified range is within the code region. +    bool IsWithinCodeRegion(VAddr address, u64 size) const; +      /// Gets the base address of the heap region.      VAddr GetHeapRegionBaseAddress() const; @@ -462,6 +468,9 @@ public:      /// Gets the total size of the heap region in bytes.      u64 GetHeapRegionSize() const; +    /// Determines whether or not the specified range is within the heap region. +    bool IsWithinHeapRegion(VAddr address, u64 size) const; +      /// Gets the base address of the map region.      VAddr GetMapRegionBaseAddress() const; @@ -471,6 +480,9 @@ public:      /// Gets the total size of the map region in bytes.      u64 GetMapRegionSize() const; +    /// Determines whether or not the specified range is within the map region. +    bool IsWithinMapRegion(VAddr address, u64 size) const; +      /// Gets the base address of the new map region.      VAddr GetNewMapRegionBaseAddress() const; @@ -480,6 +492,9 @@ public:      /// Gets the total size of the new map region in bytes.      u64 GetNewMapRegionSize() const; +    /// Determines whether or not the given address range is within the new map region +    bool IsWithinNewMapRegion(VAddr address, u64 size) const; +      /// Gets the base address of the TLS IO region.      VAddr GetTLSIORegionBaseAddress() const; @@ -489,6 +504,9 @@ public:      /// Gets the total size of the TLS IO region in bytes.      u64 GetTLSIORegionSize() const; +    /// Determines if the given address range is within the TLS IO region. +    bool IsWithinTLSIORegion(VAddr address, u64 size) const; +      /// Each VMManager has its own page table, which is set as the main one when the owning process      /// is scheduled.      Memory::PageTable page_table; | 
