From 8263b95e5d8ae846666a64576c4cca89f6303d7e Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 20 Mar 2019 14:51:59 -0400 Subject: [PATCH] Report out of range memory reads instead of crashing. --- src/common/page_table.cpp | 5 ++++- src/common/page_table.h | 6 ++++++ src/core/memory.cpp | 7 ++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp index 8eba1c3f12..15966d5681 100644 --- a/src/common/page_table.cpp +++ b/src/common/page_table.cpp @@ -6,7 +6,9 @@ namespace Common { -PageTable::PageTable(std::size_t page_size_in_bits) : page_size_in_bits{page_size_in_bits} {} +PageTable::PageTable(std::size_t page_size_in_bits) : page_size_in_bits{page_size_in_bits} { + number_of_entries = 1ULL << page_size_in_bits; +} PageTable::~PageTable() = default; @@ -24,6 +26,7 @@ void PageTable::Resize(std::size_t address_space_width_in_bits) { pointers.shrink_to_fit(); attributes.shrink_to_fit(); + number_of_entries = num_page_table_entries; } } // namespace Common diff --git a/src/common/page_table.h b/src/common/page_table.h index 8339f2890c..6c5cc13bbc 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -75,6 +75,12 @@ struct PageTable { std::vector attributes; const std::size_t page_size_in_bits{}; + + /** + * Size variable that contains the number of entries to this page table's. Equivalent + * to page_table->pointers.size(). Used for micro-optimizations on reads. + */ + std::size_t number_of_entries; }; } // namespace Common diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 365ac82b4a..6fa942088d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -152,7 +152,12 @@ static u8* GetPointerFromVMA(VAddr vaddr) { template T Read(const VAddr vaddr) { - const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; + auto entry = vaddr >> PAGE_BITS; + if (entry > current_page_table->number_of_entries) { + LOG_ERROR(HW_Memory, "Out of range Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); + return 0; + } + const u8* page_pointer = current_page_table->pointers[entry]; if (page_pointer) { // NOTE: Avoid adding any extra logic to this fast-path block T value;