summaryrefslogtreecommitdiff
path: root/src/common/host_memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/host_memory.cpp')
-rw-r--r--src/common/host_memory.cpp45
1 files changed, 33 insertions, 12 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index a66fc49e2..3e4b34de6 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -144,7 +144,7 @@ public:
144 Release(); 144 Release();
145 } 145 }
146 146
147 void Map(size_t virtual_offset, size_t host_offset, size_t length) { 147 void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perms) {
148 std::unique_lock lock{placeholder_mutex}; 148 std::unique_lock lock{placeholder_mutex};
149 if (!IsNiechePlaceholder(virtual_offset, length)) { 149 if (!IsNiechePlaceholder(virtual_offset, length)) {
150 Split(virtual_offset, length); 150 Split(virtual_offset, length);
@@ -163,7 +163,7 @@ public:
163 } 163 }
164 } 164 }
165 165
166 void Protect(size_t virtual_offset, size_t length, bool read, bool write) { 166 void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {
167 DWORD new_flags{}; 167 DWORD new_flags{};
168 if (read && write) { 168 if (read && write) {
169 new_flags = PAGE_READWRITE; 169 new_flags = PAGE_READWRITE;
@@ -494,15 +494,29 @@ public:
494 Release(); 494 Release();
495 } 495 }
496 496
497 void Map(size_t virtual_offset, size_t host_offset, size_t length) { 497 void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perms) {
498 // Intersect the range with our address space. 498 // Intersect the range with our address space.
499 AdjustMap(&virtual_offset, &length); 499 AdjustMap(&virtual_offset, &length);
500 500
501 // We are removing a placeholder. 501 // We are removing a placeholder.
502 free_manager.AllocateBlock(virtual_base + virtual_offset, length); 502 free_manager.AllocateBlock(virtual_base + virtual_offset, length);
503 503
504 void* ret = mmap(virtual_base + virtual_offset, length, PROT_READ | PROT_WRITE, 504 // Deduce mapping protection flags.
505 MAP_SHARED | MAP_FIXED, fd, host_offset); 505 int flags = PROT_NONE;
506 if (True(perms & MemoryPermission::Read)) {
507 flags |= PROT_READ;
508 }
509 if (True(perms & MemoryPermission::Write)) {
510 flags |= PROT_WRITE;
511 }
512#ifdef ARCHITECTURE_arm64
513 if (True(perms & MemoryPermission::Execute)) {
514 flags |= PROT_EXEC;
515 }
516#endif
517
518 void* ret = mmap(virtual_base + virtual_offset, length, flags, MAP_SHARED | MAP_FIXED, fd,
519 host_offset);
506 ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); 520 ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
507 } 521 }
508 522
@@ -522,7 +536,7 @@ public:
522 ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); 536 ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
523 } 537 }
524 538
525 void Protect(size_t virtual_offset, size_t length, bool read, bool write) { 539 void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {
526 // Intersect the range with our address space. 540 // Intersect the range with our address space.
527 AdjustMap(&virtual_offset, &length); 541 AdjustMap(&virtual_offset, &length);
528 542
@@ -533,6 +547,11 @@ public:
533 if (write) { 547 if (write) {
534 flags |= PROT_WRITE; 548 flags |= PROT_WRITE;
535 } 549 }
550#ifdef ARCHITECTURE_arm64
551 if (execute) {
552 flags |= PROT_EXEC;
553 }
554#endif
536 int ret = mprotect(virtual_base + virtual_offset, length, flags); 555 int ret = mprotect(virtual_base + virtual_offset, length, flags);
537 ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno)); 556 ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno));
538 } 557 }
@@ -602,11 +621,11 @@ public:
602 throw std::bad_alloc{}; 621 throw std::bad_alloc{};
603 } 622 }
604 623
605 void Map(size_t virtual_offset, size_t host_offset, size_t length) {} 624 void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perm) {}
606 625
607 void Unmap(size_t virtual_offset, size_t length) {} 626 void Unmap(size_t virtual_offset, size_t length) {}
608 627
609 void Protect(size_t virtual_offset, size_t length, bool read, bool write) {} 628 void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {}
610 629
611 u8* backing_base{nullptr}; 630 u8* backing_base{nullptr};
612 u8* virtual_base{nullptr}; 631 u8* virtual_base{nullptr};
@@ -647,7 +666,8 @@ HostMemory::HostMemory(HostMemory&&) noexcept = default;
647 666
648HostMemory& HostMemory::operator=(HostMemory&&) noexcept = default; 667HostMemory& HostMemory::operator=(HostMemory&&) noexcept = default;
649 668
650void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length) { 669void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
670 MemoryPermission perms) {
651 ASSERT(virtual_offset % PageAlignment == 0); 671 ASSERT(virtual_offset % PageAlignment == 0);
652 ASSERT(host_offset % PageAlignment == 0); 672 ASSERT(host_offset % PageAlignment == 0);
653 ASSERT(length % PageAlignment == 0); 673 ASSERT(length % PageAlignment == 0);
@@ -656,7 +676,7 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length) {
656 if (length == 0 || !virtual_base || !impl) { 676 if (length == 0 || !virtual_base || !impl) {
657 return; 677 return;
658 } 678 }
659 impl->Map(virtual_offset + virtual_base_offset, host_offset, length); 679 impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
660} 680}
661 681
662void HostMemory::Unmap(size_t virtual_offset, size_t length) { 682void HostMemory::Unmap(size_t virtual_offset, size_t length) {
@@ -669,14 +689,15 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length) {
669 impl->Unmap(virtual_offset + virtual_base_offset, length); 689 impl->Unmap(virtual_offset + virtual_base_offset, length);
670} 690}
671 691
672void HostMemory::Protect(size_t virtual_offset, size_t length, bool read, bool write) { 692void HostMemory::Protect(size_t virtual_offset, size_t length, bool read, bool write,
693 bool execute) {
673 ASSERT(virtual_offset % PageAlignment == 0); 694 ASSERT(virtual_offset % PageAlignment == 0);
674 ASSERT(length % PageAlignment == 0); 695 ASSERT(length % PageAlignment == 0);
675 ASSERT(virtual_offset + length <= virtual_size); 696 ASSERT(virtual_offset + length <= virtual_size);
676 if (length == 0 || !virtual_base || !impl) { 697 if (length == 0 || !virtual_base || !impl) {
677 return; 698 return;
678 } 699 }
679 impl->Protect(virtual_offset + virtual_base_offset, length, read, write); 700 impl->Protect(virtual_offset + virtual_base_offset, length, read, write, execute);
680} 701}
681 702
682void HostMemory::EnableDirectMappedAddress() { 703void HostMemory::EnableDirectMappedAddress() {