summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/app/src/main/jni/native.cpp2
-rw-r--r--src/android/app/src/main/res/values-de/strings.xml20
-rw-r--r--src/android/app/src/main/res/values-es/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-fr/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-it/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-ja/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-ko/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-nb/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-pl/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-pt-rBR/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-pt-rPT/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-ru/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-uk/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-zh-rCN/strings.xml18
-rw-r--r--src/android/app/src/main/res/values-zh-rTW/strings.xml18
-rw-r--r--src/android/app/src/main/res/values/strings.xml36
-rw-r--r--src/audio_core/common/audio_renderer_parameter.h6
-rw-r--r--src/common/page_table.h12
-rw-r--r--src/common/settings.cpp3
-rw-r--r--src/common/time_zone.cpp47
-rw-r--r--src/common/wall_clock.cpp4
-rw-r--r--src/core/arm/arm_interface.cpp4
-rw-r--r--src/core/arm/arm_interface.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h6
-rw-r--r--src/core/arm/dynarmic/dynarmic_exclusive_monitor.h5
-rw-r--r--src/core/core.cpp8
-rw-r--r--src/core/core.h3
-rw-r--r--src/core/debugger/gdbstub.cpp13
-rw-r--r--src/core/hle/kernel/k_auto_object.cpp4
-rw-r--r--src/core/hle/kernel/k_auto_object.h5
-rw-r--r--src/core/hle/kernel/k_code_memory.cpp17
-rw-r--r--src/core/hle/kernel/k_page_table.h41
-rw-r--r--src/core/hle/kernel/k_process.cpp2
-rw-r--r--src/core/hle/kernel/k_process.h10
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp3
-rw-r--r--src/core/hle/kernel/k_shared_memory.cpp6
-rw-r--r--src/core/hle/kernel/k_thread.cpp2
-rw-r--r--src/core/hle/kernel/k_thread_local_page.cpp10
-rw-r--r--src/core/hle/kernel/physical_core.cpp8
-rw-r--r--src/core/hle/kernel/svc/svc_cache.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_code_memory.cpp14
-rw-r--r--src/core/hle/kernel/svc/svc_device_address_space.cpp6
-rw-r--r--src/core/hle/kernel/svc/svc_info.cpp16
-rw-r--r--src/core/hle/kernel/svc/svc_ipc.cpp11
-rw-r--r--src/core/hle/kernel/svc/svc_memory.cpp33
-rw-r--r--src/core/hle/kernel/svc/svc_physical_memory.cpp14
-rw-r--r--src/core/hle/kernel/svc/svc_process.cpp4
-rw-r--r--src/core/hle/kernel/svc/svc_process_memory.cpp34
-rw-r--r--src/core/hle/kernel/svc/svc_query_memory.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_shared_memory.cpp4
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp11
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_transfer_memory.cpp2
-rw-r--r--src/core/hle/service/acc/acc.cpp3
-rw-r--r--src/core/hle/service/audio/audren_u.cpp5
-rw-r--r--src/core/hle/service/glue/ectx.cpp43
-rw-r--r--src/core/hle/service/glue/ectx.h3
-rw-r--r--src/core/hle/service/ldr/ldr.cpp20
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp4
-rw-r--r--src/core/hle/service/sockets/bsd.cpp2
-rw-r--r--src/core/hle/service/sockets/nsd.cpp27
-rw-r--r--src/core/hle/service/sockets/nsd.h2
-rw-r--r--src/core/hle/service/sockets/sfdnsres.cpp16
-rw-r--r--src/core/hle/service/sockets/sfdnsres.h1
-rw-r--r--src/core/hle/service/sockets/sockets_translate.cpp38
-rw-r--r--src/core/hle/service/sockets/sockets_translate.h3
-rw-r--r--src/core/hle/service/time/time_zone_content_manager.cpp17
-rw-r--r--src/core/hle/service/time/time_zone_content_manager.h2
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp2
-rw-r--r--src/core/loader/kip.cpp2
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/memory.cpp172
-rw-r--r--src/core/memory.h13
-rw-r--r--src/core/memory/cheat_engine.cpp2
-rw-r--r--src/core/reporter.cpp4
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp11
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h10
-rw-r--r--src/video_core/buffer_cache/buffer_cache_base.h2
-rw-r--r--src/video_core/query_cache.h4
-rw-r--r--src/video_core/rasterizer_accelerated.cpp5
-rw-r--r--src/video_core/rasterizer_accelerated.h3
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_descriptor_pool.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_fsr.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_turbo_mode.cpp2
-rw-r--r--src/video_core/vulkan_common/vma.cpp4
-rw-r--r--src/video_core/vulkan_common/vma.h11
-rw-r--r--src/video_core/vulkan_common/vulkan.h13
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp18
-rw-r--r--src/video_core/vulkan_common/vulkan_memory_allocator.cpp3
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.h11
-rw-r--r--src/yuzu/discord_impl.cpp82
-rw-r--r--src/yuzu/discord_impl.h7
-rw-r--r--src/yuzu/game_list_worker.cpp8
100 files changed, 573 insertions, 706 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 8bc6a4a04..c23b2f19e 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -449,7 +449,7 @@ private:
449 loader->ReadTitle(entry.title); 449 loader->ReadTitle(entry.title);
450 loader->ReadIcon(entry.icon); 450 loader->ReadIcon(entry.icon);
451 if (loader->GetFileType() == Loader::FileType::NRO) { 451 if (loader->GetFileType() == Loader::FileType::NRO) {
452 jauto loader_nro = dynamic_cast<Loader::AppLoader_NRO*>(loader.get()); 452 jauto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get());
453 entry.isHomebrew = loader_nro->IsHomebrew(); 453 entry.isHomebrew = loader_nro->IsHomebrew();
454 } else { 454 } else {
455 entry.isHomebrew = false; 455 entry.isHomebrew = false;
diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml
index 969223ef8..0c1d91264 100644
--- a/src/android/app/src/main/res/values-de/strings.xml
+++ b/src/android/app/src/main/res/values-de/strings.xml
@@ -235,26 +235,6 @@
235 <string name="region_korea">Korea</string> 235 <string name="region_korea">Korea</string>
236 <string name="region_taiwan">Taiwan</string> 236 <string name="region_taiwan">Taiwan</string>
237 237
238 <!-- Language Names -->
239 <string name="language_japanese">Japanisch (日本語)</string>
240 <string name="language_english">Englisch</string>
241 <string name="language_french">Französisch (Français)</string>
242 <string name="langauge_german">Deutsch (German)</string>
243 <string name="language_italian">Italienisch (Italiano)</string>
244 <string name="language_spanish">Spanisch (Español)</string>
245 <string name="language_chinese">Chinesisch (简体中文)</string>
246 <string name="language_korean">Koreanisch (한국어)</string>
247 <string name="language_dutch">Niederländisch (Nederlands)</string>
248 <string name="language_portuguese">Portugiesisch (Português)</string>
249 <string name="language_russian">Russisch (Русский)</string>
250 <string name="language_taiwanese">Taiwanesisch (台湾)</string>
251 <string name="language_british_english">Britisches Englisch</string>
252 <string name="language_canadian_french">Kanadisches Französisch (Français canadien)</string>
253 <string name="language_latin_american_spanish">Lateinamerikanisches Spanisch (Español latinoamericano)</string>
254 <string name="language_simplified_chinese">Vereinfachtes Chinesisch (简体中文)</string>
255 <string name="language_traditional_chinese">Traditionelles Chinesisch (正體中文)</string>
256 <string name="language_brazilian_portuguese">Brasilianisches Portugiesisch (Português do Brasil)</string>
257
258 <!-- Renderer APIs --> 238 <!-- Renderer APIs -->
259 <string name="renderer_vulkan">Vulkan</string> 239 <string name="renderer_vulkan">Vulkan</string>
260 <string name="renderer_none">Keiner</string> 240 <string name="renderer_none">Keiner</string>
diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml
index 986e80e50..357f956d1 100644
--- a/src/android/app/src/main/res/values-es/strings.xml
+++ b/src/android/app/src/main/res/values-es/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Taiwán</string> 241 <string name="region_taiwan">Taiwán</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Japonés (日本語)</string>
245 <string name="language_english">Inglés (English)</string>
246 <string name="language_french">Francés (Français)</string>
247 <string name="langauge_german">Alemán (deutsch)</string>
248 <string name="language_italian">Italiano (Italiano)</string>
249 <string name="language_spanish">Español (Español)</string>
250 <string name="language_chinese">Chino (简体中文)</string>
251 <string name="language_korean">Coreano (한국어)</string>
252 <string name="language_dutch">Holandés (nederlands)</string>
253 <string name="language_portuguese">Portugués (Português)</string>
254 <string name="language_russian">Ruso (Русский)</string>
255 <string name="language_taiwanese">Taiwanés (台湾)</string>
256 <string name="language_british_english">Inglés británico</string>
257 <string name="language_canadian_french">Francés Canadiense (Français canadien)</string>
258 <string name="language_latin_american_spanish">Español Latinoamericano (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">Chino Simplificado (简体中文)</string>
260 <string name="language_traditional_chinese">Chino tradicional (正體中文)</string>
261 <string name="language_brazilian_portuguese">Portugués Brasileño (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml
index 14a9b2d5c..dfca1c830 100644
--- a/src/android/app/src/main/res/values-fr/strings.xml
+++ b/src/android/app/src/main/res/values-fr/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Taïwan</string> 241 <string name="region_taiwan">Taïwan</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Japonais (日本語)</string>
245 <string name="language_english">Anglais</string>
246 <string name="language_french">Français (Français)</string>
247 <string name="langauge_german">Allemand (Deutsch)</string>
248 <string name="language_italian">Italien (Italiano)</string>
249 <string name="language_spanish">Espagnol (Español)</string>
250 <string name="language_chinese">Chinois (简体中文)</string>
251 <string name="language_korean">Coréen (한국어)</string>
252 <string name="language_dutch">Néerlandais (Nederlands)</string>
253 <string name="language_portuguese">Portugais (Português)</string>
254 <string name="language_russian">Russe (Русский)</string>
255 <string name="language_taiwanese">Taïwanais (台湾)</string>
256 <string name="language_british_english">Anglais Britannique</string>
257 <string name="language_canadian_french">Français canadien (Français canadien)</string>
258 <string name="language_latin_american_spanish">Espagnol latino-américain (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">Chinois simplifié (简体中文)</string>
260 <string name="language_traditional_chinese">Chinois Traditionnel (正體中文)</string>
261 <string name="language_brazilian_portuguese">Portugais brésilien (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml
index 47a4cfa31..089d93ed6 100644
--- a/src/android/app/src/main/res/values-it/strings.xml
+++ b/src/android/app/src/main/res/values-it/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Taiwan</string> 241 <string name="region_taiwan">Taiwan</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Giapponese (日本語)</string>
245 <string name="language_english">Inglese (English)</string>
246 <string name="language_french">Francese (Français)</string>
247 <string name="langauge_german">Tedesco (Deutsch)</string>
248 <string name="language_italian">Italiano (Italiano)</string>
249 <string name="language_spanish">Spagnolo (Español)</string>
250 <string name="language_chinese">Cinese (简体中文)</string>
251 <string name="language_korean">Coreano (한국어)</string>
252 <string name="language_dutch">Olandese (Nederlands)</string>
253 <string name="language_portuguese">Portoghese (Português)</string>
254 <string name="language_russian">Russo (Русский)</string>
255 <string name="language_taiwanese">Taiwanese (台湾)</string>
256 <string name="language_british_english">Inglese britannico</string>
257 <string name="language_canadian_french">Francese Canadese (Français canadien)</string>
258 <string name="language_latin_american_spanish">Spagnolo Latino Americano (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">Cinese Semplificato (简体中文)</string>
260 <string name="language_traditional_chinese">Cinese tradizionale (正體中文)</string>
261 <string name="language_brazilian_portuguese">Portoghese (Português)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml
index 46eda9ef7..39b590bee 100644
--- a/src/android/app/src/main/res/values-ja/strings.xml
+++ b/src/android/app/src/main/res/values-ja/strings.xml
@@ -239,24 +239,6 @@
239 <string name="region_taiwan">台湾</string> 239 <string name="region_taiwan">台湾</string>
240 240
241 <!-- Language Names --> 241 <!-- Language Names -->
242 <string name="language_japanese">日本語</string>
243 <string name="language_english">英語</string>
244 <string name="language_french">フランス語 (Français)</string>
245 <string name="langauge_german">ドイツ語 (Deutsch)</string>
246 <string name="language_italian">イタリア語 (Italiano)</string>
247 <string name="language_spanish">スペイン語 (Español)</string>
248 <string name="language_chinese">中国語 (简体中文)</string>
249 <string name="language_korean">韓国語 (한국어)</string>
250 <string name="language_dutch">オランダ語 (Nederlands)</string>
251 <string name="language_portuguese">ポルトガル語 (Português)</string>
252 <string name="language_russian">ロシア語 (Русский)</string>
253 <string name="language_taiwanese">台湾語 (台湾)</string>
254 <string name="language_british_english">イギリス英語</string>
255 <string name="language_canadian_french">フランス語(カナダ) (Français canadien)</string>
256 <string name="language_latin_american_spanish">スペイン語(ラテンアメリカ) (Español latinoamericano)</string>
257 <string name="language_simplified_chinese">中国語 (简体中文)</string>
258 <string name="language_traditional_chinese">繁体字中国語 (正體中文)</string>
259 <string name="language_brazilian_portuguese">ポルトガル語(ブラジル) (Português do Brasil)</string>
260 242
261 <!-- Renderer APIs --> 243 <!-- Renderer APIs -->
262 <string name="renderer_vulkan">Vulkan</string> 244 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml
index 5da80ab4b..cbcb2873f 100644
--- a/src/android/app/src/main/res/values-ko/strings.xml
+++ b/src/android/app/src/main/res/values-ko/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">타이완</string> 241 <string name="region_taiwan">타이완</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">일본어 (日本語)</string>
245 <string name="language_english">영어 (English)</string>
246 <string name="language_french">프랑스어 (Français)</string>
247 <string name="langauge_german">독일어(Deutsch)</string>
248 <string name="language_italian">이탈리아어 (Italiano)</string>
249 <string name="language_spanish">스페인어 (Español)</string>
250 <string name="language_chinese">중국어 (简体中文)</string>
251 <string name="language_korean">한국어 (Korean)</string>
252 <string name="language_dutch">네덜란드어 (Nederlands)</string>
253 <string name="language_portuguese">포르투갈어 (Português)</string>
254 <string name="language_russian">러시아어 (Русский)</string>
255 <string name="language_taiwanese">대만어 (台湾)</string>
256 <string name="language_british_english">영어 (British English)</string>
257 <string name="language_canadian_french">캐나다 프랑스어 (Français canadien)</string>
258 <string name="language_latin_american_spanish">라틴 아메리카 스페인어 (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">중국어 간체 (简体中文)</string>
260 <string name="language_traditional_chinese">중국어 번체 (正體中文)</string>
261 <string name="language_brazilian_portuguese">브라질 포르투갈어 (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">불칸</string> 246 <string name="renderer_vulkan">불칸</string>
diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml
index 3e1f9bce5..e48a4be38 100644
--- a/src/android/app/src/main/res/values-nb/strings.xml
+++ b/src/android/app/src/main/res/values-nb/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Taiwan</string> 241 <string name="region_taiwan">Taiwan</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Japansk (日本語)</string>
245 <string name="language_english">Engelsk</string>
246 <string name="language_french">Fransk (Français)</string>
247 <string name="langauge_german">Tysk (Deutsch)</string>
248 <string name="language_italian">Italiensk (Italiano)</string>
249 <string name="language_spanish">Spansk (Español)</string>
250 <string name="language_chinese">Kinesisk (简体中文)</string>
251 <string name="language_korean">Koreansk (한국어)</string>
252 <string name="language_dutch">Nederlandsk (Nederlands)</string>
253 <string name="language_portuguese">Portugisisk (Português)</string>
254 <string name="language_russian">Russisk (Русский)</string>
255 <string name="language_taiwanese">Taiwansk (台湾)</string>
256 <string name="language_british_english">Britisk Engelsk</string>
257 <string name="language_canadian_french">Kanadisk fransk (Français canadien)</string>
258 <string name="language_latin_american_spanish">Latinamerikansk spansk (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">Forenklet kinesisk (简体中文)</string>
260 <string name="language_traditional_chinese">Tradisjonell Kinesisk (正體中文)</string>
261 <string name="language_brazilian_portuguese">Brasiliansk portugisisk (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml
index 1cd1a8f87..bc9c0f7f4 100644
--- a/src/android/app/src/main/res/values-pl/strings.xml
+++ b/src/android/app/src/main/res/values-pl/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Tajwan</string> 241 <string name="region_taiwan">Tajwan</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Japoński (日本語)</string>
245 <string name="language_english">Angielski</string>
246 <string name="language_french">Francuski (Francja)</string>
247 <string name="langauge_german">Niemiecki (Niemcy)</string>
248 <string name="language_italian">Włoski (Włochy)</string>
249 <string name="language_spanish">Hiszpański (Hiszpania)</string>
250 <string name="language_chinese">Chiński (简体中文)</string>
251 <string name="language_korean">Koreański (한국어)</string>
252 <string name="language_dutch">Duński (Holandia)</string>
253 <string name="language_portuguese">Portugalski (Portugalia)</string>
254 <string name="language_russian">Rosyjski (Русский)</string>
255 <string name="language_taiwanese">Tajwański (台湾)</string>
256 <string name="language_british_english">Angielski Brytyjski</string>
257 <string name="language_canadian_french">Francuski (Kanada)</string>
258 <string name="language_latin_american_spanish">Hiszpański (Ameryka Latynoska)</string>
259 <string name="language_simplified_chinese">Chiński uproszczony (简体中文)</string>
260 <string name="language_traditional_chinese">Chiński tradycyjny (正體中文)</string>
261 <string name="language_brazilian_portuguese">Portugalski (Brazylia)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml
index 35197c280..75fe0edbf 100644
--- a/src/android/app/src/main/res/values-pt-rBR/strings.xml
+++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Taiwan</string> 241 <string name="region_taiwan">Taiwan</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Japônes (日本語)</string>
245 <string name="language_english">Português do Brasil</string>
246 <string name="language_french">Francês (Français)</string>
247 <string name="langauge_german">Alemão (Deutsch)</string>
248 <string name="language_italian">Italiano (Italiano)</string>
249 <string name="language_spanish">Espanhol (Español)</string>
250 <string name="language_chinese">Mandarim (简体中文)</string>
251 <string name="language_korean">Coreano (한국어)</string>
252 <string name="language_dutch">Holandês (Nederlands)</string>
253 <string name="language_portuguese">Português (Português)</string>
254 <string name="language_russian">Russo (Русский)</string>
255 <string name="language_taiwanese">Taiwanês (台湾)</string>
256 <string name="language_british_english">Inglês britânico (British English)</string>
257 <string name="language_canadian_french">Fracês Canadiano (Français canadien)</string>
258 <string name="language_latin_american_spanish">Espanhol da América Latina (Español latino-americano)</string>
259 <string name="language_simplified_chinese">Chinês Simplificado (简体中文)</string>
260 <string name="language_traditional_chinese">Chinês tradicional (正體中文)</string>
261 <string name="language_brazilian_portuguese">Português do Brasil (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulcano</string> 246 <string name="renderer_vulkan">Vulcano</string>
diff --git a/src/android/app/src/main/res/values-pt-rPT/strings.xml b/src/android/app/src/main/res/values-pt-rPT/strings.xml
index 8761e2374..96b040c66 100644
--- a/src/android/app/src/main/res/values-pt-rPT/strings.xml
+++ b/src/android/app/src/main/res/values-pt-rPT/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Taiwan</string> 241 <string name="region_taiwan">Taiwan</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Japonês (日本語)</string>
245 <string name="language_english">Inglês</string>
246 <string name="language_french">Francês (Français)</string>
247 <string name="langauge_german">Alemão (Deutsch)</string>
248 <string name="language_italian">Italiano (Italiano)</string>
249 <string name="language_spanish">Espanhol (Español)</string>
250 <string name="language_chinese">Chinês simplificado (简体中文)</string>
251 <string name="language_korean">Coreano (한국어)</string>
252 <string name="language_dutch">Holandês (Nederlands)</string>
253 <string name="language_portuguese">Português (Português)</string>
254 <string name="language_russian">Russo (Русский)</string>
255 <string name="language_taiwanese">Taiwanês (台湾)</string>
256 <string name="language_british_english">Inglês Britânico</string>
257 <string name="language_canadian_french">Fracês Canadiano (Français canadien)</string>
258 <string name="language_latin_american_spanish">Espanhol da América Latina (Español latino-americano)</string>
259 <string name="language_simplified_chinese">Chinês Simplificado (简体中文)</string>
260 <string name="language_traditional_chinese">Chinês Tradicional (正 體 中文)</string>
261 <string name="language_brazilian_portuguese">Português do Brasil (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulcano</string> 246 <string name="renderer_vulkan">Vulcano</string>
diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml
index 0fb4908f7..8d954f59e 100644
--- a/src/android/app/src/main/res/values-ru/strings.xml
+++ b/src/android/app/src/main/res/values-ru/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Тайвань</string> 241 <string name="region_taiwan">Тайвань</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Японский (日本語)</string>
245 <string name="language_english">Английский (English)</string>
246 <string name="language_french">Французский (Français)</string>
247 <string name="langauge_german">Немецкий (Deutsch)</string>
248 <string name="language_italian">Итальянский (Italiano)</string>
249 <string name="language_spanish">Испанский (Español)</string>
250 <string name="language_chinese">Китайский (简体中文)</string>
251 <string name="language_korean">Корейский (한국어)</string>
252 <string name="language_dutch">Голландский (Nederlands)</string>
253 <string name="language_portuguese">Португальский (Português)</string>
254 <string name="language_russian">Русский</string>
255 <string name="language_taiwanese">Тайваньский (台湾)</string>
256 <string name="language_british_english">Британский английский</string>
257 <string name="language_canadian_french">Канадский французский (Français canadien)</string>
258 <string name="language_latin_american_spanish">Латиноамериканский испанский (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">Упрощенный китайский (简体中文)</string>
260 <string name="language_traditional_chinese">Традиционный китайский (正體中文)</string>
261 <string name="language_brazilian_portuguese">Бразильский португальский (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml
index 0d11eb2d2..6c028535b 100644
--- a/src/android/app/src/main/res/values-uk/strings.xml
+++ b/src/android/app/src/main/res/values-uk/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">Тайвань</string> 241 <string name="region_taiwan">Тайвань</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">Японська (日本語)</string>
245 <string name="language_english">Англійська (English)</string>
246 <string name="language_french">Французька (Français)</string>
247 <string name="langauge_german">Німецька (Deutsch)</string>
248 <string name="language_italian">Італійська (Italiano)</string>
249 <string name="language_spanish">Іспанська (Español)</string>
250 <string name="language_chinese">Китайскька (简体中文)</string>
251 <string name="language_korean">Корейська (한국어)</string>
252 <string name="language_dutch">Голландська (Nederlands)</string>
253 <string name="language_portuguese">Португальська (Português)</string>
254 <string name="language_russian">Російська (Русский)</string>
255 <string name="language_taiwanese">Тайванська (台湾)</string>
256 <string name="language_british_english">Британська англійська</string>
257 <string name="language_canadian_french">Канадська французька (Français canadien)</string>
258 <string name="language_latin_american_spanish">Латиноамериканська іспанська (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">Спрощена китайська (简体中文)</string>
260 <string name="language_traditional_chinese">Традиційна китайська (正體中文)</string>
261 <string name="language_brazilian_portuguese">Бразильська португальська (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml
index e00bbaa2e..e4ad2ed07 100644
--- a/src/android/app/src/main/res/values-zh-rCN/strings.xml
+++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">中国台湾</string> 241 <string name="region_taiwan">中国台湾</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">日语 (日本語)</string>
245 <string name="language_english">英语 (English)</string>
246 <string name="language_french">法语 (Français)</string>
247 <string name="langauge_german">德语 (Deutsch)</string>
248 <string name="language_italian">意大利语 (Italiano)</string>
249 <string name="language_spanish">西班牙语 (Español)</string>
250 <string name="language_chinese">中文 (简体中文)</string>
251 <string name="language_korean">韩语 (한국어)</string>
252 <string name="language_dutch">荷兰语 (Nederlands)</string>
253 <string name="language_portuguese">葡萄牙语 (Português)</string>
254 <string name="language_russian">俄语 (Русский)</string>
255 <string name="language_taiwanese">台湾中文 (台灣)</string>
256 <string name="language_british_english">英式英语</string>
257 <string name="language_canadian_french">加拿大法语 (Français canadien)</string>
258 <string name="language_latin_american_spanish">拉丁美洲西班牙语 (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">简体中文 (简体中文)</string>
260 <string name="language_traditional_chinese">繁体中文 (正體中文)</string>
261 <string name="language_brazilian_portuguese">巴西葡萄牙语 (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml
index a54d04248..0d32f23df 100644
--- a/src/android/app/src/main/res/values-zh-rTW/strings.xml
+++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml
@@ -241,24 +241,6 @@
241 <string name="region_taiwan">台灣</string> 241 <string name="region_taiwan">台灣</string>
242 242
243 <!-- Language Names --> 243 <!-- Language Names -->
244 <string name="language_japanese">日文 (日本語)</string>
245 <string name="language_english">英文</string>
246 <string name="language_french">法文 (Français)</string>
247 <string name="langauge_german">德文 (Deutsch)</string>
248 <string name="language_italian">義大利文 (Italiano)</string>
249 <string name="language_spanish">西班牙文 (Español)</string>
250 <string name="language_chinese">中文 (简体中文)</string>
251 <string name="language_korean">韓文 (한국어)</string>
252 <string name="language_dutch">荷蘭文 (Nederlands)</string>
253 <string name="language_portuguese">葡萄牙文 (Português)</string>
254 <string name="language_russian">俄文 (Русский)</string>
255 <string name="language_taiwanese">台文 (台灣)</string>
256 <string name="language_british_english">英式英文</string>
257 <string name="language_canadian_french">加拿大法文 (Français canadien)</string>
258 <string name="language_latin_american_spanish">拉丁美洲西班牙文 (Español latinoamericano)</string>
259 <string name="language_simplified_chinese">簡體中文 (简体中文)</string>
260 <string name="language_traditional_chinese">正體中文 (正體中文)</string>
261 <string name="language_brazilian_portuguese">巴西葡萄牙文 (Português do Brasil)</string>
262 244
263 <!-- Renderer APIs --> 245 <!-- Renderer APIs -->
264 <string name="renderer_vulkan">Vulkan</string> 246 <string name="renderer_vulkan">Vulkan</string>
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index bfdebd35b..02e25504d 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -287,24 +287,24 @@
287 <string name="region_taiwan">Taiwan</string> 287 <string name="region_taiwan">Taiwan</string>
288 288
289 <!-- Language Names --> 289 <!-- Language Names -->
290 <string name="language_japanese">Japanese (日本語)</string> 290 <string name="language_japanese" translatable="false">日本語</string>
291 <string name="language_english">English</string> 291 <string name="language_english" translatable="false">English</string>
292 <string name="language_french">French (Français)</string> 292 <string name="language_french" translatable="false">Français</string>
293 <string name="langauge_german">German (Deutsch)</string> 293 <string name="langauge_german" translatable="false">Deutsch</string>
294 <string name="language_italian">Italian (Italiano)</string> 294 <string name="language_italian" translatable="false">Italiano</string>
295 <string name="language_spanish">Spanish (Español)</string> 295 <string name="language_spanish" translatable="false">Español</string>
296 <string name="language_chinese">Chinese (简体中文)</string> 296 <string name="language_chinese" translatable="false">简体中文</string>
297 <string name="language_korean">Korean (한국어)</string> 297 <string name="language_korean" translatable="false">한국어</string>
298 <string name="language_dutch">Dutch (Nederlands)</string> 298 <string name="language_dutch" translatable="false">Nederlands</string>
299 <string name="language_portuguese">Portuguese (Português)</string> 299 <string name="language_portuguese" translatable="false">Português</string>
300 <string name="language_russian">Russian (Русский)</string> 300 <string name="language_russian" translatable="false">Русский</string>
301 <string name="language_taiwanese">Taiwanese (台湾)</string> 301 <string name="language_taiwanese" translatable="false">台湾</string>
302 <string name="language_british_english">British English</string> 302 <string name="language_british_english" translatable="false">British English</string>
303 <string name="language_canadian_french">Canadian French (Français canadien)</string> 303 <string name="language_canadian_french" translatable="false">Français canadien</string>
304 <string name="language_latin_american_spanish">Latin American Spanish (Español latinoamericano)</string> 304 <string name="language_latin_american_spanish" translatable="false">Español latinoamericano</string>
305 <string name="language_simplified_chinese">Simplified Chinese (简体中文)</string> 305 <string name="language_simplified_chinese" translatable="false">简体中文</string>
306 <string name="language_traditional_chinese">Traditional Chinese (正體中文)</string> 306 <string name="language_traditional_chinese" translatable="false">正體中文</string>
307 <string name="language_brazilian_portuguese">Brazilian Portuguese (Português do Brasil)</string> 307 <string name="language_brazilian_portuguese" translatable="false">Português do Brasil</string>
308 308
309 <!-- Memory Sizes --> 309 <!-- Memory Sizes -->
310 <string name="memory_byte">Byte</string> 310 <string name="memory_byte">Byte</string>
diff --git a/src/audio_core/common/audio_renderer_parameter.h b/src/audio_core/common/audio_renderer_parameter.h
index 2f62c383b..8c7892bcf 100644
--- a/src/audio_core/common/audio_renderer_parameter.h
+++ b/src/audio_core/common/audio_renderer_parameter.h
@@ -32,16 +32,16 @@ struct AudioRendererParameterInternal {
32 /* 0x14 */ u32 sinks; 32 /* 0x14 */ u32 sinks;
33 /* 0x18 */ u32 effects; 33 /* 0x18 */ u32 effects;
34 /* 0x1C */ u32 perf_frames; 34 /* 0x1C */ u32 perf_frames;
35 /* 0x20 */ u16 voice_drop_enabled; 35 /* 0x20 */ u8 voice_drop_enabled;
36 /* 0x21 */ u8 unk_21;
36 /* 0x22 */ u8 rendering_device; 37 /* 0x22 */ u8 rendering_device;
37 /* 0x23 */ ExecutionMode execution_mode; 38 /* 0x23 */ ExecutionMode execution_mode;
38 /* 0x24 */ u32 splitter_infos; 39 /* 0x24 */ u32 splitter_infos;
39 /* 0x28 */ s32 splitter_destinations; 40 /* 0x28 */ s32 splitter_destinations;
40 /* 0x2C */ u32 external_context_size; 41 /* 0x2C */ u32 external_context_size;
41 /* 0x30 */ u32 revision; 42 /* 0x30 */ u32 revision;
42 /* 0x34 */ char unk34[0x4];
43}; 43};
44static_assert(sizeof(AudioRendererParameterInternal) == 0x38, 44static_assert(sizeof(AudioRendererParameterInternal) == 0x34,
45 "AudioRendererParameterInternal has the wrong size!"); 45 "AudioRendererParameterInternal has the wrong size!");
46 46
47/** 47/**
diff --git a/src/common/page_table.h b/src/common/page_table.h
index fec8378f3..e653d52ad 100644
--- a/src/common/page_table.h
+++ b/src/common/page_table.h
@@ -51,7 +51,7 @@ struct PageTable {
51 class PageInfo { 51 class PageInfo {
52 public: 52 public:
53 /// Returns the page pointer 53 /// Returns the page pointer
54 [[nodiscard]] u8* Pointer() const noexcept { 54 [[nodiscard]] uintptr_t Pointer() const noexcept {
55 return ExtractPointer(raw.load(std::memory_order_relaxed)); 55 return ExtractPointer(raw.load(std::memory_order_relaxed));
56 } 56 }
57 57
@@ -61,7 +61,7 @@ struct PageTable {
61 } 61 }
62 62
63 /// Returns the page pointer and attribute pair, extracted from the same atomic read 63 /// Returns the page pointer and attribute pair, extracted from the same atomic read
64 [[nodiscard]] std::pair<u8*, PageType> PointerType() const noexcept { 64 [[nodiscard]] std::pair<uintptr_t, PageType> PointerType() const noexcept {
65 const uintptr_t non_atomic_raw = raw.load(std::memory_order_relaxed); 65 const uintptr_t non_atomic_raw = raw.load(std::memory_order_relaxed);
66 return {ExtractPointer(non_atomic_raw), ExtractType(non_atomic_raw)}; 66 return {ExtractPointer(non_atomic_raw), ExtractType(non_atomic_raw)};
67 } 67 }
@@ -73,13 +73,13 @@ struct PageTable {
73 } 73 }
74 74
75 /// Write a page pointer and type pair atomically 75 /// Write a page pointer and type pair atomically
76 void Store(u8* pointer, PageType type) noexcept { 76 void Store(uintptr_t pointer, PageType type) noexcept {
77 raw.store(reinterpret_cast<uintptr_t>(pointer) | static_cast<uintptr_t>(type)); 77 raw.store(pointer | static_cast<uintptr_t>(type));
78 } 78 }
79 79
80 /// Unpack a pointer from a page info raw representation 80 /// Unpack a pointer from a page info raw representation
81 [[nodiscard]] static u8* ExtractPointer(uintptr_t raw) noexcept { 81 [[nodiscard]] static uintptr_t ExtractPointer(uintptr_t raw) noexcept {
82 return reinterpret_cast<u8*>(raw & (~uintptr_t{0} << ATTRIBUTE_BITS)); 82 return raw & (~uintptr_t{0} << ATTRIBUTE_BITS);
83 } 83 }
84 84
85 /// Unpack a page type from a page info raw representation 85 /// Unpack a page type from a page info raw representation
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 491adc30e..15fd2e222 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -72,7 +72,8 @@ std::string GetTimeZoneString(TimeZone time_zone) {
72 72
73 std::string location_name; 73 std::string location_name;
74 if (time_zone_index == 0) { // Auto 74 if (time_zone_index == 0) { // Auto
75#if __cpp_lib_chrono >= 201907L 75#if __cpp_lib_chrono >= 201907L && !defined(MINGW)
76 // Disabled for MinGW -- tzdb always returns Etc/UTC
76 try { 77 try {
77 const struct std::chrono::tzdb& time_zone_data = std::chrono::get_tzdb(); 78 const struct std::chrono::tzdb& time_zone_data = std::chrono::get_tzdb();
78 const std::chrono::time_zone* current_zone = time_zone_data.current_zone(); 79 const std::chrono::time_zone* current_zone = time_zone_data.current_zone();
diff --git a/src/common/time_zone.cpp b/src/common/time_zone.cpp
index d8d7896c6..69e728a9d 100644
--- a/src/common/time_zone.cpp
+++ b/src/common/time_zone.cpp
@@ -4,13 +4,13 @@
4#include <chrono> 4#include <chrono>
5#include <exception> 5#include <exception>
6#include <iomanip> 6#include <iomanip>
7#include <map>
7#include <sstream> 8#include <sstream>
8#include <stdexcept> 9#include <stdexcept>
9#include <fmt/chrono.h> 10#include <fmt/chrono.h>
10#include <fmt/core.h> 11#include <fmt/core.h>
11 12
12#include "common/logging/log.h" 13#include "common/logging/log.h"
13#include "common/settings.h"
14#include "common/time_zone.h" 14#include "common/time_zone.h"
15 15
16namespace Common::TimeZone { 16namespace Common::TimeZone {
@@ -33,32 +33,29 @@ std::string GetDefaultTimeZone() {
33 return "GMT"; 33 return "GMT";
34} 34}
35 35
36static std::string GetOsTimeZoneOffset() { 36// Results are not comparable to seconds since Epoch
37 const std::time_t t{std::time(nullptr)}; 37static std::time_t TmSpecToSeconds(const struct std::tm& spec) {
38 const std::tm tm{*std::localtime(&t)}; 38 const int year = spec.tm_year - 1; // Years up to now
39 39 const int leap_years = year / 4 - year / 100;
40 return fmt::format("{:%z}", tm); 40 std::time_t cumulative = spec.tm_year;
41} 41 cumulative = cumulative * 365 + leap_years + spec.tm_yday; // Years to days
42 42 cumulative = cumulative * 24 + spec.tm_hour; // Days to hours
43static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) { 43 cumulative = cumulative * 60 + spec.tm_min; // Hours to minutes
44 try { 44 cumulative = cumulative * 60 + spec.tm_sec; // Minutes to seconds
45 return std::stoi(timezone); 45 return cumulative;
46 } catch (const std::invalid_argument&) {
47 LOG_CRITICAL(Common, "invalid_argument with {}!", timezone);
48 return 0;
49 } catch (const std::out_of_range&) {
50 LOG_CRITICAL(Common, "out_of_range with {}!", timezone);
51 return 0;
52 }
53} 46}
54 47
55std::chrono::seconds GetCurrentOffsetSeconds() { 48std::chrono::seconds GetCurrentOffsetSeconds() {
56 const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())}; 49 const std::time_t t{std::time(nullptr)};
50 const std::tm local{*std::localtime(&t)};
51 const std::tm gmt{*std::gmtime(&t)};
57 52
58 int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds 53 // gmt_seconds is a different offset than time(nullptr)
59 seconds += (offset % 100) * 60; // Convert minute component to seconds 54 const auto gmt_seconds = TmSpecToSeconds(gmt);
55 const auto local_seconds = TmSpecToSeconds(local);
56 const auto seconds_offset = local_seconds - gmt_seconds;
60 57
61 return std::chrono::seconds{seconds}; 58 return std::chrono::seconds{seconds_offset};
62} 59}
63 60
64// Key is [Hours * 100 + Minutes], multiplied by 100 if DST 61// Key is [Hours * 100 + Minutes], multiplied by 100 if DST
@@ -71,11 +68,6 @@ const static std::map<s64, const char*> off_timezones = {
71}; 68};
72 69
73std::string FindSystemTimeZone() { 70std::string FindSystemTimeZone() {
74#if defined(MINGW)
75 // MinGW has broken strftime -- https://sourceforge.net/p/mingw-w64/bugs/793/
76 // e.g. fmt::format("{:%z}") -- returns "Eastern Daylight Time" when it should be "-0400"
77 return timezones[0];
78#else
79 const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count()); 71 const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count());
80 72
81 const s64 minutes = seconds / 60; 73 const s64 minutes = seconds / 60;
@@ -97,7 +89,6 @@ std::string FindSystemTimeZone() {
97 } 89 }
98 } 90 }
99 return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours)); 91 return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours));
100#endif
101} 92}
102 93
103} // namespace Common::TimeZone 94} // namespace Common::TimeZone
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp
index dc0dcbd68..71e15ab4c 100644
--- a/src/common/wall_clock.cpp
+++ b/src/common/wall_clock.cpp
@@ -56,12 +56,12 @@ std::unique_ptr<WallClock> CreateOptimalClock() {
56#ifdef ARCHITECTURE_x86_64 56#ifdef ARCHITECTURE_x86_64
57 const auto& caps = GetCPUCaps(); 57 const auto& caps = GetCPUCaps();
58 58
59 if (caps.invariant_tsc && caps.tsc_frequency >= WallClock::GPUTickFreq) { 59 if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) {
60 return std::make_unique<X64::NativeClock>(caps.tsc_frequency); 60 return std::make_unique<X64::NativeClock>(caps.tsc_frequency);
61 } else { 61 } else {
62 // Fallback to StandardWallClock if the hardware TSC 62 // Fallback to StandardWallClock if the hardware TSC
63 // - Is not invariant 63 // - Is not invariant
64 // - Is not more precise than GPUTickFreq 64 // - Is not more precise than 1 GHz (1ns resolution)
65 return std::make_unique<StandardWallClock>(); 65 return std::make_unique<StandardWallClock>();
66 } 66 }
67#else 67#else
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index aa0eb9791..0c012f094 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -217,8 +217,8 @@ void ARM_Interface::Run() {
217 } 217 }
218} 218}
219 219
220void ARM_Interface::LoadWatchpointArray(const WatchpointArray& wp) { 220void ARM_Interface::LoadWatchpointArray(const WatchpointArray* wp) {
221 watchpoints = &wp; 221 watchpoints = wp;
222} 222}
223 223
224const Kernel::DebugWatchpoint* ARM_Interface::MatchingWatchpoint( 224const Kernel::DebugWatchpoint* ARM_Interface::MatchingWatchpoint(
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index d5f2fa09a..3d866ff6f 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -186,7 +186,7 @@ public:
186 virtual void SaveContext(ThreadContext64& ctx) const = 0; 186 virtual void SaveContext(ThreadContext64& ctx) const = 0;
187 virtual void LoadContext(const ThreadContext32& ctx) = 0; 187 virtual void LoadContext(const ThreadContext32& ctx) = 0;
188 virtual void LoadContext(const ThreadContext64& ctx) = 0; 188 virtual void LoadContext(const ThreadContext64& ctx) = 0;
189 void LoadWatchpointArray(const WatchpointArray& wp); 189 void LoadWatchpointArray(const WatchpointArray* wp);
190 190
191 /// Clears the exclusive monitor's state. 191 /// Clears the exclusive monitor's state.
192 virtual void ClearExclusiveState() = 0; 192 virtual void ClearExclusiveState() = 0;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index dc7cfd239..44a297cdc 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -346,11 +346,11 @@ void ARM_Dynarmic_32::RewindBreakpointInstruction() {
346} 346}
347 347
348ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, 348ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_,
349 ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) 349 DynarmicExclusiveMonitor& exclusive_monitor_,
350 std::size_t core_index_)
350 : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)), 351 : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)),
351 cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_}, 352 cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_},
352 exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, 353 exclusive_monitor{exclusive_monitor_}, null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {}
353 null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {}
354 354
355ARM_Dynarmic_32::~ARM_Dynarmic_32() = default; 355ARM_Dynarmic_32::~ARM_Dynarmic_32() = default;
356 356
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index a990845cb..92fb3f836 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -12,7 +12,7 @@
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/hash.h" 13#include "common/hash.h"
14#include "core/arm/arm_interface.h" 14#include "core/arm/arm_interface.h"
15#include "core/arm/exclusive_monitor.h" 15#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h"
16 16
17namespace Core::Memory { 17namespace Core::Memory {
18class Memory; 18class Memory;
@@ -28,8 +28,8 @@ class System;
28 28
29class ARM_Dynarmic_32 final : public ARM_Interface { 29class ARM_Dynarmic_32 final : public ARM_Interface {
30public: 30public:
31 ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, 31 ARM_Dynarmic_32(System& system_, bool uses_wall_clock_,
32 std::size_t core_index_); 32 DynarmicExclusiveMonitor& exclusive_monitor_, std::size_t core_index_);
33 ~ARM_Dynarmic_32() override; 33 ~ARM_Dynarmic_32() override;
34 34
35 void SetPC(u64 pc) override; 35 void SetPC(u64 pc) override;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index a4cc74ebf..2e3674b6d 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -405,11 +405,11 @@ void ARM_Dynarmic_64::RewindBreakpointInstruction() {
405} 405}
406 406
407ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, 407ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_,
408 ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) 408 DynarmicExclusiveMonitor& exclusive_monitor_,
409 std::size_t core_index_)
409 : ARM_Interface{system_, uses_wall_clock_}, 410 : ARM_Interface{system_, uses_wall_clock_},
410 cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_}, 411 cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_},
411 exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, 412 exclusive_monitor{exclusive_monitor_}, null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {}
412 null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {}
413 413
414ARM_Dynarmic_64::~ARM_Dynarmic_64() = default; 414ARM_Dynarmic_64::~ARM_Dynarmic_64() = default;
415 415
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index af2aa1f1c..2b88a08e2 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -11,7 +11,7 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/hash.h" 12#include "common/hash.h"
13#include "core/arm/arm_interface.h" 13#include "core/arm/arm_interface.h"
14#include "core/arm/exclusive_monitor.h" 14#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h"
15 15
16namespace Core::Memory { 16namespace Core::Memory {
17class Memory; 17class Memory;
@@ -25,8 +25,8 @@ class System;
25 25
26class ARM_Dynarmic_64 final : public ARM_Interface { 26class ARM_Dynarmic_64 final : public ARM_Interface {
27public: 27public:
28 ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, 28 ARM_Dynarmic_64(System& system_, bool uses_wall_clock_,
29 std::size_t core_index_); 29 DynarmicExclusiveMonitor& exclusive_monitor_, std::size_t core_index_);
30 ~ARM_Dynarmic_64() override; 30 ~ARM_Dynarmic_64() override;
31 31
32 void SetPC(u64 pc) override; 32 void SetPC(u64 pc) override;
diff --git a/src/core/arm/dynarmic/dynarmic_exclusive_monitor.h b/src/core/arm/dynarmic/dynarmic_exclusive_monitor.h
index 57e6dd0d0..fbfcd8d95 100644
--- a/src/core/arm/dynarmic/dynarmic_exclusive_monitor.h
+++ b/src/core/arm/dynarmic/dynarmic_exclusive_monitor.h
@@ -6,8 +6,6 @@
6#include <dynarmic/interface/exclusive_monitor.h> 6#include <dynarmic/interface/exclusive_monitor.h>
7 7
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/arm/dynarmic/arm_dynarmic_32.h"
10#include "core/arm/dynarmic/arm_dynarmic_64.h"
11#include "core/arm/exclusive_monitor.h" 9#include "core/arm/exclusive_monitor.h"
12 10
13namespace Core::Memory { 11namespace Core::Memory {
@@ -16,6 +14,9 @@ class Memory;
16 14
17namespace Core { 15namespace Core {
18 16
17class ARM_Dynarmic_32;
18class ARM_Dynarmic_64;
19
19class DynarmicExclusiveMonitor final : public ExclusiveMonitor { 20class DynarmicExclusiveMonitor final : public ExclusiveMonitor {
20public: 21public:
21 explicit DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count_); 22 explicit DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count_);
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 951942083..2f67e60a9 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -890,6 +890,14 @@ const FileSys::ContentProvider& System::GetContentProvider() const {
890 return *impl->content_provider; 890 return *impl->content_provider;
891} 891}
892 892
893FileSys::ContentProviderUnion& System::GetContentProviderUnion() {
894 return *impl->content_provider;
895}
896
897const FileSys::ContentProviderUnion& System::GetContentProviderUnion() const {
898 return *impl->content_provider;
899}
900
893Service::FileSystem::FileSystemController& System::GetFileSystemController() { 901Service::FileSystem::FileSystemController& System::GetFileSystemController() {
894 return impl->fs_controller; 902 return impl->fs_controller;
895} 903}
diff --git a/src/core/core.h b/src/core/core.h
index 14b2f7785..c70ea1965 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -381,6 +381,9 @@ public:
381 [[nodiscard]] FileSys::ContentProvider& GetContentProvider(); 381 [[nodiscard]] FileSys::ContentProvider& GetContentProvider();
382 [[nodiscard]] const FileSys::ContentProvider& GetContentProvider() const; 382 [[nodiscard]] const FileSys::ContentProvider& GetContentProvider() const;
383 383
384 [[nodiscard]] FileSys::ContentProviderUnion& GetContentProviderUnion();
385 [[nodiscard]] const FileSys::ContentProviderUnion& GetContentProviderUnion() const;
386
384 [[nodiscard]] Service::FileSystem::FileSystemController& GetFileSystemController(); 387 [[nodiscard]] Service::FileSystem::FileSystemController& GetFileSystemController();
385 [[nodiscard]] const Service::FileSystem::FileSystemController& GetFileSystemController() const; 388 [[nodiscard]] const Service::FileSystem::FileSystemController& GetFileSystemController() const;
386 389
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index e2a13bbd2..0f839d5b4 100644
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -261,10 +261,8 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
261 const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; 261 const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))};
262 const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))}; 262 const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))};
263 263
264 if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { 264 std::vector<u8> mem(size);
265 std::vector<u8> mem(size); 265 if (system.ApplicationMemory().ReadBlock(addr, mem.data(), size)) {
266 system.ApplicationMemory().ReadBlock(addr, mem.data(), size);
267
268 SendReply(Common::HexToString(mem)); 266 SendReply(Common::HexToString(mem));
269 } else { 267 } else {
270 SendReply(GDB_STUB_REPLY_ERR); 268 SendReply(GDB_STUB_REPLY_ERR);
@@ -281,8 +279,7 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction
281 const auto mem_substr{std::string_view(command).substr(mem_sep)}; 279 const auto mem_substr{std::string_view(command).substr(mem_sep)};
282 const auto mem{Common::HexStringToVector(mem_substr, false)}; 280 const auto mem{Common::HexStringToVector(mem_substr, false)};
283 281
284 if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { 282 if (system.ApplicationMemory().WriteBlock(addr, mem.data(), size)) {
285 system.ApplicationMemory().WriteBlock(addr, mem.data(), size);
286 system.InvalidateCpuInstructionCacheRange(addr, size); 283 system.InvalidateCpuInstructionCacheRange(addr, size);
287 SendReply(GDB_STUB_REPLY_OK); 284 SendReply(GDB_STUB_REPLY_OK);
288 } else { 285 } else {
@@ -556,7 +553,7 @@ void GDBStub::HandleQuery(std::string_view command) {
556 } else { 553 } else {
557 SendReply(fmt::format( 554 SendReply(fmt::format(
558 "TextSeg={:x}", 555 "TextSeg={:x}",
559 GetInteger(system.ApplicationProcess()->PageTable().GetCodeRegionStart()))); 556 GetInteger(system.ApplicationProcess()->GetPageTable().GetCodeRegionStart())));
560 } 557 }
561 } else if (command.starts_with("Xfer:libraries:read::")) { 558 } else if (command.starts_with("Xfer:libraries:read::")) {
562 Loader::AppLoader::Modules modules; 559 Loader::AppLoader::Modules modules;
@@ -731,7 +728,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
731 std::string reply; 728 std::string reply;
732 729
733 auto* process = system.ApplicationProcess(); 730 auto* process = system.ApplicationProcess();
734 auto& page_table = process->PageTable(); 731 auto& page_table = process->GetPageTable();
735 732
736 const char* commands = "Commands:\n" 733 const char* commands = "Commands:\n"
737 " get fastmem\n" 734 " get fastmem\n"
diff --git a/src/core/hle/kernel/k_auto_object.cpp b/src/core/hle/kernel/k_auto_object.cpp
index 0ae42c95c..9cd7a9fd5 100644
--- a/src/core/hle/kernel/k_auto_object.cpp
+++ b/src/core/hle/kernel/k_auto_object.cpp
@@ -15,8 +15,8 @@ void KAutoObject::RegisterWithKernel() {
15 m_kernel.RegisterKernelObject(this); 15 m_kernel.RegisterKernelObject(this);
16} 16}
17 17
18void KAutoObject::UnregisterWithKernel() { 18void KAutoObject::UnregisterWithKernel(KernelCore& kernel, KAutoObject* self) {
19 m_kernel.UnregisterKernelObject(this); 19 kernel.UnregisterKernelObject(self);
20} 20}
21 21
22} // namespace Kernel 22} // namespace Kernel
diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h
index f384b1568..8d4e0df44 100644
--- a/src/core/hle/kernel/k_auto_object.h
+++ b/src/core/hle/kernel/k_auto_object.h
@@ -159,14 +159,15 @@ public:
159 159
160 // If ref count hits zero, destroy the object. 160 // If ref count hits zero, destroy the object.
161 if (cur_ref_count - 1 == 0) { 161 if (cur_ref_count - 1 == 0) {
162 KernelCore& kernel = m_kernel;
162 this->Destroy(); 163 this->Destroy();
163 this->UnregisterWithKernel(); 164 KAutoObject::UnregisterWithKernel(kernel, this);
164 } 165 }
165 } 166 }
166 167
167private: 168private:
168 void RegisterWithKernel(); 169 void RegisterWithKernel();
169 void UnregisterWithKernel(); 170 static void UnregisterWithKernel(KernelCore& kernel, KAutoObject* self);
170 171
171protected: 172protected:
172 KernelCore& m_kernel; 173 KernelCore& m_kernel;
diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp
index 3583bee44..7454be55c 100644
--- a/src/core/hle/kernel/k_code_memory.cpp
+++ b/src/core/hle/kernel/k_code_memory.cpp
@@ -25,7 +25,7 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, KProcessAddres
25 m_owner = GetCurrentProcessPointer(m_kernel); 25 m_owner = GetCurrentProcessPointer(m_kernel);
26 26
27 // Get the owner page table. 27 // Get the owner page table.
28 auto& page_table = m_owner->PageTable(); 28 auto& page_table = m_owner->GetPageTable();
29 29
30 // Construct the page group. 30 // Construct the page group.
31 m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager()); 31 m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager());
@@ -53,7 +53,7 @@ void KCodeMemory::Finalize() {
53 // Unlock. 53 // Unlock.
54 if (!m_is_mapped && !m_is_owner_mapped) { 54 if (!m_is_mapped && !m_is_owner_mapped) {
55 const size_t size = m_page_group->GetNumPages() * PageSize; 55 const size_t size = m_page_group->GetNumPages() * PageSize;
56 m_owner->PageTable().UnlockForCodeMemory(m_address, size, *m_page_group); 56 m_owner->GetPageTable().UnlockForCodeMemory(m_address, size, *m_page_group);
57 } 57 }
58 58
59 // Close the page group. 59 // Close the page group.
@@ -75,7 +75,7 @@ Result KCodeMemory::Map(KProcessAddress address, size_t size) {
75 R_UNLESS(!m_is_mapped, ResultInvalidState); 75 R_UNLESS(!m_is_mapped, ResultInvalidState);
76 76
77 // Map the memory. 77 // Map the memory.
78 R_TRY(GetCurrentProcess(m_kernel).PageTable().MapPageGroup( 78 R_TRY(GetCurrentProcess(m_kernel).GetPageTable().MapPageGroup(
79 address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite)); 79 address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite));
80 80
81 // Mark ourselves as mapped. 81 // Mark ourselves as mapped.
@@ -92,8 +92,8 @@ Result KCodeMemory::Unmap(KProcessAddress address, size_t size) {
92 KScopedLightLock lk(m_lock); 92 KScopedLightLock lk(m_lock);
93 93
94 // Unmap the memory. 94 // Unmap the memory.
95 R_TRY(GetCurrentProcess(m_kernel).PageTable().UnmapPageGroup(address, *m_page_group, 95 R_TRY(GetCurrentProcess(m_kernel).GetPageTable().UnmapPageGroup(address, *m_page_group,
96 KMemoryState::CodeOut)); 96 KMemoryState::CodeOut));
97 97
98 // Mark ourselves as unmapped. 98 // Mark ourselves as unmapped.
99 m_is_mapped = false; 99 m_is_mapped = false;
@@ -126,8 +126,8 @@ Result KCodeMemory::MapToOwner(KProcessAddress address, size_t size, Svc::Memory
126 } 126 }
127 127
128 // Map the memory. 128 // Map the memory.
129 R_TRY(m_owner->PageTable().MapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode, 129 R_TRY(m_owner->GetPageTable().MapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode,
130 k_perm)); 130 k_perm));
131 131
132 // Mark ourselves as mapped. 132 // Mark ourselves as mapped.
133 m_is_owner_mapped = true; 133 m_is_owner_mapped = true;
@@ -143,7 +143,8 @@ Result KCodeMemory::UnmapFromOwner(KProcessAddress address, size_t size) {
143 KScopedLightLock lk(m_lock); 143 KScopedLightLock lk(m_lock);
144 144
145 // Unmap the memory. 145 // Unmap the memory.
146 R_TRY(m_owner->PageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode)); 146 R_TRY(m_owner->GetPageTable().UnmapPageGroup(address, *m_page_group,
147 KMemoryState::GeneratedCode));
147 148
148 // Mark ourselves as unmapped. 149 // Mark ourselves as unmapped.
149 m_is_owner_mapped = false; 150 m_is_owner_mapped = false;
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index 022d15f35..b9e8c6042 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -388,39 +388,6 @@ public:
388 constexpr size_t GetHeapSize() const { 388 constexpr size_t GetHeapSize() const {
389 return m_current_heap_end - m_heap_region_start; 389 return m_current_heap_end - m_heap_region_start;
390 } 390 }
391 constexpr bool IsInsideAddressSpace(KProcessAddress address, size_t size) const {
392 return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1;
393 }
394 constexpr bool IsOutsideAliasRegion(KProcessAddress address, size_t size) const {
395 return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1;
396 }
397 constexpr bool IsOutsideStackRegion(KProcessAddress address, size_t size) const {
398 return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1;
399 }
400 constexpr bool IsInvalidRegion(KProcessAddress address, size_t size) const {
401 return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1;
402 }
403 constexpr bool IsInsideHeapRegion(KProcessAddress address, size_t size) const {
404 return address + size > m_heap_region_start && m_heap_region_end > address;
405 }
406 constexpr bool IsInsideAliasRegion(KProcessAddress address, size_t size) const {
407 return address + size > m_alias_region_start && m_alias_region_end > address;
408 }
409 constexpr bool IsOutsideASLRRegion(KProcessAddress address, size_t size) const {
410 if (IsInvalidRegion(address, size)) {
411 return true;
412 }
413 if (IsInsideHeapRegion(address, size)) {
414 return true;
415 }
416 if (IsInsideAliasRegion(address, size)) {
417 return true;
418 }
419 return {};
420 }
421 constexpr bool IsInsideASLRRegion(KProcessAddress address, size_t size) const {
422 return !IsOutsideASLRRegion(address, size);
423 }
424 constexpr size_t GetNumGuardPages() const { 391 constexpr size_t GetNumGuardPages() const {
425 return IsKernel() ? 1 : 4; 392 return IsKernel() ? 1 : 4;
426 } 393 }
@@ -436,6 +403,14 @@ public:
436 return m_address_space_start <= addr && addr < addr + size && 403 return m_address_space_start <= addr && addr < addr + size &&
437 addr + size - 1 <= m_address_space_end - 1; 404 addr + size - 1 <= m_address_space_end - 1;
438 } 405 }
406 constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const {
407 return this->Contains(addr, size) && m_alias_region_start <= addr &&
408 addr + size - 1 <= m_alias_region_end - 1;
409 }
410 constexpr bool IsInHeapRegion(KProcessAddress addr, size_t size) const {
411 return this->Contains(addr, size) && m_heap_region_start <= addr &&
412 addr + size - 1 <= m_heap_region_end - 1;
413 }
439 414
440public: 415public:
441 static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout, 416 static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout,
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index ae064ee04..e573e2a57 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -38,7 +38,7 @@ namespace {
38 */ 38 */
39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, 39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
40 KProcessAddress stack_top) { 40 KProcessAddress stack_top) {
41 const KProcessAddress entry_point = owner_process.PageTable().GetCodeRegionStart(); 41 const KProcessAddress entry_point = owner_process.GetPageTable().GetCodeRegionStart();
42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1)); 42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
43 43
44 KThread* thread = KThread::Create(system.Kernel()); 44 KThread* thread = KThread::Create(system.Kernel());
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 925981d06..c9b37e138 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -110,16 +110,6 @@ public:
110 ProcessType type, KResourceLimit* res_limit); 110 ProcessType type, KResourceLimit* res_limit);
111 111
112 /// Gets a reference to the process' page table. 112 /// Gets a reference to the process' page table.
113 KPageTable& PageTable() {
114 return m_page_table;
115 }
116
117 /// Gets const a reference to the process' page table.
118 const KPageTable& PageTable() const {
119 return m_page_table;
120 }
121
122 /// Gets a reference to the process' page table.
123 KPageTable& GetPageTable() { 113 KPageTable& GetPageTable() {
124 return m_page_table; 114 return m_page_table;
125 } 115 }
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index 75ce5a23c..d8143c650 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -510,11 +510,12 @@ void KScheduler::Unload(KThread* thread) {
510 510
511void KScheduler::Reload(KThread* thread) { 511void KScheduler::Reload(KThread* thread) {
512 auto& cpu_core = m_kernel.System().ArmInterface(m_core_id); 512 auto& cpu_core = m_kernel.System().ArmInterface(m_core_id);
513 auto* process = thread->GetOwnerProcess();
513 cpu_core.LoadContext(thread->GetContext32()); 514 cpu_core.LoadContext(thread->GetContext32());
514 cpu_core.LoadContext(thread->GetContext64()); 515 cpu_core.LoadContext(thread->GetContext64());
515 cpu_core.SetTlsAddress(GetInteger(thread->GetTlsAddress())); 516 cpu_core.SetTlsAddress(GetInteger(thread->GetTlsAddress()));
516 cpu_core.SetTPIDR_EL0(thread->GetTpidrEl0()); 517 cpu_core.SetTPIDR_EL0(thread->GetTpidrEl0());
517 cpu_core.LoadWatchpointArray(thread->GetOwnerProcess()->GetWatchpoints()); 518 cpu_core.LoadWatchpointArray(process ? &process->GetWatchpoints() : nullptr);
518 cpu_core.ClearExclusiveState(); 519 cpu_core.ClearExclusiveState();
519} 520}
520 521
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp
index efb5699de..f713968f6 100644
--- a/src/core/hle/kernel/k_shared_memory.cpp
+++ b/src/core/hle/kernel/k_shared_memory.cpp
@@ -90,8 +90,8 @@ Result KSharedMemory::Map(KProcess& target_process, KProcessAddress address, std
90 R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission); 90 R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission);
91 } 91 }
92 92
93 R_RETURN(target_process.PageTable().MapPageGroup(address, *m_page_group, KMemoryState::Shared, 93 R_RETURN(target_process.GetPageTable().MapPageGroup(
94 ConvertToKMemoryPermission(map_perm))); 94 address, *m_page_group, KMemoryState::Shared, ConvertToKMemoryPermission(map_perm)));
95} 95}
96 96
97Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address, 97Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address,
@@ -100,7 +100,7 @@ Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address,
100 R_UNLESS(m_size == unmap_size, ResultInvalidSize); 100 R_UNLESS(m_size == unmap_size, ResultInvalidSize);
101 101
102 R_RETURN( 102 R_RETURN(
103 target_process.PageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::Shared)); 103 target_process.GetPageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::Shared));
104} 104}
105 105
106} // namespace Kernel 106} // namespace Kernel
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index d88909889..7df8fd7f7 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -129,7 +129,7 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress
129 case ThreadType::User: 129 case ThreadType::User:
130 ASSERT(((owner == nullptr) || 130 ASSERT(((owner == nullptr) ||
131 (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask())); 131 (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask()));
132 ASSERT(((owner == nullptr) || 132 ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) ||
133 (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask())); 133 (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask()));
134 break; 134 break;
135 case ThreadType::Kernel: 135 case ThreadType::Kernel:
diff --git a/src/core/hle/kernel/k_thread_local_page.cpp b/src/core/hle/kernel/k_thread_local_page.cpp
index b4a1e3cdb..2c45b4232 100644
--- a/src/core/hle/kernel/k_thread_local_page.cpp
+++ b/src/core/hle/kernel/k_thread_local_page.cpp
@@ -25,9 +25,9 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
25 25
26 // Map the address in. 26 // Map the address in.
27 const auto phys_addr = kernel.System().DeviceMemory().GetPhysicalAddr(page_buf); 27 const auto phys_addr = kernel.System().DeviceMemory().GetPhysicalAddr(page_buf);
28 R_TRY(m_owner->PageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, phys_addr, 28 R_TRY(m_owner->GetPageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, phys_addr,
29 KMemoryState::ThreadLocal, 29 KMemoryState::ThreadLocal,
30 KMemoryPermission::UserReadWrite)); 30 KMemoryPermission::UserReadWrite));
31 31
32 // We succeeded. 32 // We succeeded.
33 page_buf_guard.Cancel(); 33 page_buf_guard.Cancel();
@@ -37,11 +37,11 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
37 37
38Result KThreadLocalPage::Finalize() { 38Result KThreadLocalPage::Finalize() {
39 // Get the physical address of the page. 39 // Get the physical address of the page.
40 const KPhysicalAddress phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr); 40 const KPhysicalAddress phys_addr = m_owner->GetPageTable().GetPhysicalAddr(m_virt_addr);
41 ASSERT(phys_addr); 41 ASSERT(phys_addr);
42 42
43 // Unmap the page. 43 // Unmap the page.
44 R_TRY(m_owner->PageTable().UnmapPages(this->GetAddress(), 1, KMemoryState::ThreadLocal)); 44 R_TRY(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState::ThreadLocal));
45 45
46 // Free the page. 46 // Free the page.
47 KPageBuffer::Free(*m_kernel, KPageBuffer::FromPhysicalAddress(m_kernel->System(), phys_addr)); 47 KPageBuffer::Free(*m_kernel, KPageBuffer::FromPhysicalAddress(m_kernel->System(), phys_addr));
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index 2e0c36129..5ee869fa2 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -17,7 +17,9 @@ PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system, KSchedu
17 // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. 17 // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager.
18 auto& kernel = system.Kernel(); 18 auto& kernel = system.Kernel();
19 m_arm_interface = std::make_unique<Core::ARM_Dynarmic_64>( 19 m_arm_interface = std::make_unique<Core::ARM_Dynarmic_64>(
20 system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), m_core_index); 20 system, kernel.IsMulticore(),
21 reinterpret_cast<Core::DynarmicExclusiveMonitor&>(kernel.GetExclusiveMonitor()),
22 m_core_index);
21#else 23#else
22#error Platform not supported yet. 24#error Platform not supported yet.
23#endif 25#endif
@@ -31,7 +33,9 @@ void PhysicalCore::Initialize(bool is_64_bit) {
31 if (!is_64_bit) { 33 if (!is_64_bit) {
32 // We already initialized a 64-bit core, replace with a 32-bit one. 34 // We already initialized a 64-bit core, replace with a 32-bit one.
33 m_arm_interface = std::make_unique<Core::ARM_Dynarmic_32>( 35 m_arm_interface = std::make_unique<Core::ARM_Dynarmic_32>(
34 m_system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), m_core_index); 36 m_system, kernel.IsMulticore(),
37 reinterpret_cast<Core::DynarmicExclusiveMonitor&>(kernel.GetExclusiveMonitor()),
38 m_core_index);
35 } 39 }
36#else 40#else
37#error Platform not supported yet. 41#error Platform not supported yet.
diff --git a/src/core/hle/kernel/svc/svc_cache.cpp b/src/core/hle/kernel/svc/svc_cache.cpp
index 082942dab..c2c8be10f 100644
--- a/src/core/hle/kernel/svc/svc_cache.cpp
+++ b/src/core/hle/kernel/svc/svc_cache.cpp
@@ -42,7 +42,7 @@ Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 ad
42 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); 42 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
43 43
44 // Verify the region is within range. 44 // Verify the region is within range.
45 auto& page_table = process->PageTable(); 45 auto& page_table = process->GetPageTable();
46 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); 46 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
47 47
48 // Perform the operation. 48 // Perform the operation.
diff --git a/src/core/hle/kernel/svc/svc_code_memory.cpp b/src/core/hle/kernel/svc/svc_code_memory.cpp
index 687baff82..bae4cb0cd 100644
--- a/src/core/hle/kernel/svc/svc_code_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_code_memory.cpp
@@ -48,7 +48,7 @@ Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t
48 SCOPE_EXIT({ code_mem->Close(); }); 48 SCOPE_EXIT({ code_mem->Close(); });
49 49
50 // Verify that the region is in range. 50 // Verify that the region is in range.
51 R_UNLESS(GetCurrentProcess(system.Kernel()).PageTable().Contains(address, size), 51 R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size),
52 ResultInvalidCurrentMemory); 52 ResultInvalidCurrentMemory);
53 53
54 // Initialize the code memory. 54 // Initialize the code memory.
@@ -92,7 +92,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
92 case CodeMemoryOperation::Map: { 92 case CodeMemoryOperation::Map: {
93 // Check that the region is in range. 93 // Check that the region is in range.
94 R_UNLESS(GetCurrentProcess(system.Kernel()) 94 R_UNLESS(GetCurrentProcess(system.Kernel())
95 .PageTable() 95 .GetPageTable()
96 .CanContain(address, size, KMemoryState::CodeOut), 96 .CanContain(address, size, KMemoryState::CodeOut),
97 ResultInvalidMemoryRegion); 97 ResultInvalidMemoryRegion);
98 98
@@ -105,7 +105,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
105 case CodeMemoryOperation::Unmap: { 105 case CodeMemoryOperation::Unmap: {
106 // Check that the region is in range. 106 // Check that the region is in range.
107 R_UNLESS(GetCurrentProcess(system.Kernel()) 107 R_UNLESS(GetCurrentProcess(system.Kernel())
108 .PageTable() 108 .GetPageTable()
109 .CanContain(address, size, KMemoryState::CodeOut), 109 .CanContain(address, size, KMemoryState::CodeOut),
110 ResultInvalidMemoryRegion); 110 ResultInvalidMemoryRegion);
111 111
@@ -117,8 +117,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
117 } break; 117 } break;
118 case CodeMemoryOperation::MapToOwner: { 118 case CodeMemoryOperation::MapToOwner: {
119 // Check that the region is in range. 119 // Check that the region is in range.
120 R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size, 120 R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size,
121 KMemoryState::GeneratedCode), 121 KMemoryState::GeneratedCode),
122 ResultInvalidMemoryRegion); 122 ResultInvalidMemoryRegion);
123 123
124 // Check the memory permission. 124 // Check the memory permission.
@@ -129,8 +129,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
129 } break; 129 } break;
130 case CodeMemoryOperation::UnmapFromOwner: { 130 case CodeMemoryOperation::UnmapFromOwner: {
131 // Check that the region is in range. 131 // Check that the region is in range.
132 R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size, 132 R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size,
133 KMemoryState::GeneratedCode), 133 KMemoryState::GeneratedCode),
134 ResultInvalidMemoryRegion); 134 ResultInvalidMemoryRegion);
135 135
136 // Check the memory permission. 136 // Check the memory permission.
diff --git a/src/core/hle/kernel/svc/svc_device_address_space.cpp b/src/core/hle/kernel/svc/svc_device_address_space.cpp
index ec3143e67..42add9473 100644
--- a/src/core/hle/kernel/svc/svc_device_address_space.cpp
+++ b/src/core/hle/kernel/svc/svc_device_address_space.cpp
@@ -107,7 +107,7 @@ Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Han
107 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); 107 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
108 108
109 // Validate that the process address is within range. 109 // Validate that the process address is within range.
110 auto& page_table = process->PageTable(); 110 auto& page_table = process->GetPageTable();
111 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); 111 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
112 112
113 // Map. 113 // Map.
@@ -148,7 +148,7 @@ Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Han
148 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); 148 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
149 149
150 // Validate that the process address is within range. 150 // Validate that the process address is within range.
151 auto& page_table = process->PageTable(); 151 auto& page_table = process->GetPageTable();
152 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); 152 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
153 153
154 // Map. 154 // Map.
@@ -180,7 +180,7 @@ Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle p
180 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); 180 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
181 181
182 // Validate that the process address is within range. 182 // Validate that the process address is within range.
183 auto& page_table = process->PageTable(); 183 auto& page_table = process->GetPageTable();
184 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); 184 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
185 185
186 R_RETURN(das->Unmap(std::addressof(page_table), process_address, size, device_address)); 186 R_RETURN(das->Unmap(std::addressof(page_table), process_address, size, device_address));
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp
index 445cdd87b..f99964028 100644
--- a/src/core/hle/kernel/svc/svc_info.cpp
+++ b/src/core/hle/kernel/svc/svc_info.cpp
@@ -54,35 +54,35 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
54 R_SUCCEED(); 54 R_SUCCEED();
55 55
56 case InfoType::AliasRegionAddress: 56 case InfoType::AliasRegionAddress:
57 *result = GetInteger(process->PageTable().GetAliasRegionStart()); 57 *result = GetInteger(process->GetPageTable().GetAliasRegionStart());
58 R_SUCCEED(); 58 R_SUCCEED();
59 59
60 case InfoType::AliasRegionSize: 60 case InfoType::AliasRegionSize:
61 *result = process->PageTable().GetAliasRegionSize(); 61 *result = process->GetPageTable().GetAliasRegionSize();
62 R_SUCCEED(); 62 R_SUCCEED();
63 63
64 case InfoType::HeapRegionAddress: 64 case InfoType::HeapRegionAddress:
65 *result = GetInteger(process->PageTable().GetHeapRegionStart()); 65 *result = GetInteger(process->GetPageTable().GetHeapRegionStart());
66 R_SUCCEED(); 66 R_SUCCEED();
67 67
68 case InfoType::HeapRegionSize: 68 case InfoType::HeapRegionSize:
69 *result = process->PageTable().GetHeapRegionSize(); 69 *result = process->GetPageTable().GetHeapRegionSize();
70 R_SUCCEED(); 70 R_SUCCEED();
71 71
72 case InfoType::AslrRegionAddress: 72 case InfoType::AslrRegionAddress:
73 *result = GetInteger(process->PageTable().GetAliasCodeRegionStart()); 73 *result = GetInteger(process->GetPageTable().GetAliasCodeRegionStart());
74 R_SUCCEED(); 74 R_SUCCEED();
75 75
76 case InfoType::AslrRegionSize: 76 case InfoType::AslrRegionSize:
77 *result = process->PageTable().GetAliasCodeRegionSize(); 77 *result = process->GetPageTable().GetAliasCodeRegionSize();
78 R_SUCCEED(); 78 R_SUCCEED();
79 79
80 case InfoType::StackRegionAddress: 80 case InfoType::StackRegionAddress:
81 *result = GetInteger(process->PageTable().GetStackRegionStart()); 81 *result = GetInteger(process->GetPageTable().GetStackRegionStart());
82 R_SUCCEED(); 82 R_SUCCEED();
83 83
84 case InfoType::StackRegionSize: 84 case InfoType::StackRegionSize:
85 *result = process->PageTable().GetStackRegionSize(); 85 *result = process->GetPageTable().GetStackRegionSize();
86 R_SUCCEED(); 86 R_SUCCEED();
87 87
88 case InfoType::TotalMemorySize: 88 case InfoType::TotalMemorySize:
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp
index bb94f6934..373ae7c8d 100644
--- a/src/core/hle/kernel/svc/svc_ipc.cpp
+++ b/src/core/hle/kernel/svc/svc_ipc.cpp
@@ -8,6 +8,7 @@
8#include "core/hle/kernel/k_process.h" 8#include "core/hle/kernel/k_process.h"
9#include "core/hle/kernel/k_server_session.h" 9#include "core/hle/kernel/k_server_session.h"
10#include "core/hle/kernel/svc.h" 10#include "core/hle/kernel/svc.h"
11#include "core/hle/kernel/svc_results.h"
11 12
12namespace Kernel::Svc { 13namespace Kernel::Svc {
13 14
@@ -49,14 +50,10 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
49 50
50 // Copy user handles. 51 // Copy user handles.
51 if (num_handles > 0) { 52 if (num_handles > 0) {
52 // Ensure we can try to get the handles.
53 R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
54 handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
55 ResultInvalidPointer);
56
57 // Get the handles. 53 // Get the handles.
58 GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), 54 R_UNLESS(GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(),
59 sizeof(Handle) * num_handles); 55 sizeof(Handle) * num_handles),
56 ResultInvalidPointer);
60 57
61 // Convert the handles to objects. 58 // Convert the handles to objects.
62 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>( 59 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp
index 5dcb7f045..2cab74127 100644
--- a/src/core/hle/kernel/svc/svc_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_memory.cpp
@@ -63,36 +63,13 @@ Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 s
63 R_THROW(ResultInvalidCurrentMemory); 63 R_THROW(ResultInvalidCurrentMemory);
64 } 64 }
65 65
66 if (!manager.IsInsideAddressSpace(src_addr, size)) { 66 if (!manager.Contains(src_addr, size)) {
67 LOG_ERROR(Kernel_SVC, 67 LOG_ERROR(Kernel_SVC,
68 "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", 68 "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}",
69 src_addr, size); 69 src_addr, size);
70 R_THROW(ResultInvalidCurrentMemory); 70 R_THROW(ResultInvalidCurrentMemory);
71 } 71 }
72 72
73 if (manager.IsOutsideStackRegion(dst_addr, size)) {
74 LOG_ERROR(Kernel_SVC,
75 "Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}",
76 dst_addr, size);
77 R_THROW(ResultInvalidMemoryRegion);
78 }
79
80 if (manager.IsInsideHeapRegion(dst_addr, size)) {
81 LOG_ERROR(Kernel_SVC,
82 "Destination does not fit within the heap region, addr=0x{:016X}, "
83 "size=0x{:016X}",
84 dst_addr, size);
85 R_THROW(ResultInvalidMemoryRegion);
86 }
87
88 if (manager.IsInsideAliasRegion(dst_addr, size)) {
89 LOG_ERROR(Kernel_SVC,
90 "Destination does not fit within the map region, addr=0x{:016X}, "
91 "size=0x{:016X}",
92 dst_addr, size);
93 R_THROW(ResultInvalidMemoryRegion);
94 }
95
96 R_SUCCEED(); 73 R_SUCCEED();
97} 74}
98 75
@@ -112,7 +89,7 @@ Result SetMemoryPermission(Core::System& system, u64 address, u64 size, MemoryPe
112 R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission); 89 R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission);
113 90
114 // Validate that the region is in range for the current process. 91 // Validate that the region is in range for the current process.
115 auto& page_table = GetCurrentProcess(system.Kernel()).PageTable(); 92 auto& page_table = GetCurrentProcess(system.Kernel()).GetPageTable();
116 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); 93 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
117 94
118 // Set the memory attribute. 95 // Set the memory attribute.
@@ -136,7 +113,7 @@ Result SetMemoryAttribute(Core::System& system, u64 address, u64 size, u32 mask,
136 R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination); 113 R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination);
137 114
138 // Validate that the region is in range for the current process. 115 // Validate that the region is in range for the current process.
139 auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()}; 116 auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()};
140 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); 117 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
141 118
142 // Set the memory attribute. 119 // Set the memory attribute.
@@ -148,7 +125,7 @@ Result MapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) {
148 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 125 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
149 src_addr, size); 126 src_addr, size);
150 127
151 auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()}; 128 auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()};
152 129
153 if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; 130 if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)};
154 result.IsError()) { 131 result.IsError()) {
@@ -163,7 +140,7 @@ Result UnmapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) {
163 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 140 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
164 src_addr, size); 141 src_addr, size);
165 142
166 auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()}; 143 auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()};
167 144
168 if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; 145 if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)};
169 result.IsError()) { 146 result.IsError()) {
diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp
index c2fbfb59a..d3545f232 100644
--- a/src/core/hle/kernel/svc/svc_physical_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp
@@ -16,7 +16,7 @@ Result SetHeapSize(Core::System& system, u64* out_address, u64 size) {
16 R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize); 16 R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize);
17 17
18 // Set the heap size. 18 // Set the heap size.
19 R_RETURN(GetCurrentProcess(system.Kernel()).PageTable().SetHeapSize(out_address, size)); 19 R_RETURN(GetCurrentProcess(system.Kernel()).GetPageTable().SetHeapSize(out_address, size));
20} 20}
21 21
22/// Maps memory at a desired address 22/// Maps memory at a desired address
@@ -44,21 +44,21 @@ Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
44 } 44 }
45 45
46 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())}; 46 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
47 auto& page_table{current_process->PageTable()}; 47 auto& page_table{current_process->GetPageTable()};
48 48
49 if (current_process->GetSystemResourceSize() == 0) { 49 if (current_process->GetSystemResourceSize() == 0) {
50 LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); 50 LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
51 R_THROW(ResultInvalidState); 51 R_THROW(ResultInvalidState);
52 } 52 }
53 53
54 if (!page_table.IsInsideAddressSpace(addr, size)) { 54 if (!page_table.Contains(addr, size)) {
55 LOG_ERROR(Kernel_SVC, 55 LOG_ERROR(Kernel_SVC,
56 "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, 56 "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr,
57 size); 57 size);
58 R_THROW(ResultInvalidMemoryRegion); 58 R_THROW(ResultInvalidMemoryRegion);
59 } 59 }
60 60
61 if (page_table.IsOutsideAliasRegion(addr, size)) { 61 if (!page_table.IsInAliasRegion(addr, size)) {
62 LOG_ERROR(Kernel_SVC, 62 LOG_ERROR(Kernel_SVC,
63 "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, 63 "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr,
64 size); 64 size);
@@ -93,21 +93,21 @@ Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) {
93 } 93 }
94 94
95 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())}; 95 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
96 auto& page_table{current_process->PageTable()}; 96 auto& page_table{current_process->GetPageTable()};
97 97
98 if (current_process->GetSystemResourceSize() == 0) { 98 if (current_process->GetSystemResourceSize() == 0) {
99 LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); 99 LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
100 R_THROW(ResultInvalidState); 100 R_THROW(ResultInvalidState);
101 } 101 }
102 102
103 if (!page_table.IsInsideAddressSpace(addr, size)) { 103 if (!page_table.Contains(addr, size)) {
104 LOG_ERROR(Kernel_SVC, 104 LOG_ERROR(Kernel_SVC,
105 "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, 105 "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr,
106 size); 106 size);
107 R_THROW(ResultInvalidMemoryRegion); 107 R_THROW(ResultInvalidMemoryRegion);
108 } 108 }
109 109
110 if (page_table.IsOutsideAliasRegion(addr, size)) { 110 if (!page_table.IsInAliasRegion(addr, size)) {
111 LOG_ERROR(Kernel_SVC, 111 LOG_ERROR(Kernel_SVC,
112 "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, 112 "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr,
113 size); 113 size);
diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp
index 619ed16a3..caa8bee9a 100644
--- a/src/core/hle/kernel/svc/svc_process.cpp
+++ b/src/core/hle/kernel/svc/svc_process.cpp
@@ -66,8 +66,8 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, u64 out_proc
66 auto& kernel = system.Kernel(); 66 auto& kernel = system.Kernel();
67 const auto total_copy_size = out_process_ids_size * sizeof(u64); 67 const auto total_copy_size = out_process_ids_size * sizeof(u64);
68 68
69 if (out_process_ids_size > 0 && !GetCurrentProcess(kernel).PageTable().IsInsideAddressSpace( 69 if (out_process_ids_size > 0 &&
70 out_process_ids, total_copy_size)) { 70 !GetCurrentProcess(kernel).GetPageTable().Contains(out_process_ids, total_copy_size)) {
71 LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", 71 LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
72 out_process_ids, out_process_ids + total_copy_size); 72 out_process_ids, out_process_ids + total_copy_size);
73 R_THROW(ResultInvalidCurrentMemory); 73 R_THROW(ResultInvalidCurrentMemory);
diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp
index aee0f2f36..07cd48175 100644
--- a/src/core/hle/kernel/svc/svc_process_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_process_memory.cpp
@@ -49,7 +49,7 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, u
49 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); 49 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
50 50
51 // Validate that the address is in range. 51 // Validate that the address is in range.
52 auto& page_table = process->PageTable(); 52 auto& page_table = process->GetPageTable();
53 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); 53 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
54 54
55 // Set the memory permission. 55 // Set the memory permission.
@@ -77,8 +77,8 @@ Result MapProcessMemory(Core::System& system, u64 dst_address, Handle process_ha
77 R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); 77 R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
78 78
79 // Get the page tables. 79 // Get the page tables.
80 auto& dst_pt = dst_process->PageTable(); 80 auto& dst_pt = dst_process->GetPageTable();
81 auto& src_pt = src_process->PageTable(); 81 auto& src_pt = src_process->GetPageTable();
82 82
83 // Validate that the mapping is in range. 83 // Validate that the mapping is in range.
84 R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory); 84 R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory);
@@ -118,8 +118,8 @@ Result UnmapProcessMemory(Core::System& system, u64 dst_address, Handle process_
118 R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); 118 R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
119 119
120 // Get the page tables. 120 // Get the page tables.
121 auto& dst_pt = dst_process->PageTable(); 121 auto& dst_pt = dst_process->GetPageTable();
122 auto& src_pt = src_process->PageTable(); 122 auto& src_pt = src_process->GetPageTable();
123 123
124 // Validate that the mapping is in range. 124 // Validate that the mapping is in range.
125 R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory); 125 R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory);
@@ -178,8 +178,8 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
178 R_THROW(ResultInvalidHandle); 178 R_THROW(ResultInvalidHandle);
179 } 179 }
180 180
181 auto& page_table = process->PageTable(); 181 auto& page_table = process->GetPageTable();
182 if (!page_table.IsInsideAddressSpace(src_address, size)) { 182 if (!page_table.Contains(src_address, size)) {
183 LOG_ERROR(Kernel_SVC, 183 LOG_ERROR(Kernel_SVC,
184 "Source address range is not within the address space (src_address=0x{:016X}, " 184 "Source address range is not within the address space (src_address=0x{:016X}, "
185 "size=0x{:016X}).", 185 "size=0x{:016X}).",
@@ -187,14 +187,6 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
187 R_THROW(ResultInvalidCurrentMemory); 187 R_THROW(ResultInvalidCurrentMemory);
188 } 188 }
189 189
190 if (!page_table.IsInsideASLRRegion(dst_address, size)) {
191 LOG_ERROR(Kernel_SVC,
192 "Destination address range is not within the ASLR region (dst_address=0x{:016X}, "
193 "size=0x{:016X}).",
194 dst_address, size);
195 R_THROW(ResultInvalidMemoryRegion);
196 }
197
198 R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size)); 190 R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size));
199} 191}
200 192
@@ -246,8 +238,8 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
246 R_THROW(ResultInvalidHandle); 238 R_THROW(ResultInvalidHandle);
247 } 239 }
248 240
249 auto& page_table = process->PageTable(); 241 auto& page_table = process->GetPageTable();
250 if (!page_table.IsInsideAddressSpace(src_address, size)) { 242 if (!page_table.Contains(src_address, size)) {
251 LOG_ERROR(Kernel_SVC, 243 LOG_ERROR(Kernel_SVC,
252 "Source address range is not within the address space (src_address=0x{:016X}, " 244 "Source address range is not within the address space (src_address=0x{:016X}, "
253 "size=0x{:016X}).", 245 "size=0x{:016X}).",
@@ -255,14 +247,6 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
255 R_THROW(ResultInvalidCurrentMemory); 247 R_THROW(ResultInvalidCurrentMemory);
256 } 248 }
257 249
258 if (!page_table.IsInsideASLRRegion(dst_address, size)) {
259 LOG_ERROR(Kernel_SVC,
260 "Destination address range is not within the ASLR region (dst_address=0x{:016X}, "
261 "size=0x{:016X}).",
262 dst_address, size);
263 R_THROW(ResultInvalidMemoryRegion);
264 }
265
266 R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size, 250 R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size,
267 KPageTable::ICacheInvalidationStrategy::InvalidateAll)); 251 KPageTable::ICacheInvalidationStrategy::InvalidateAll));
268} 252}
diff --git a/src/core/hle/kernel/svc/svc_query_memory.cpp b/src/core/hle/kernel/svc/svc_query_memory.cpp
index 4d9fcd25f..51af06e97 100644
--- a/src/core/hle/kernel/svc/svc_query_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_query_memory.cpp
@@ -31,7 +31,7 @@ Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageIn
31 } 31 }
32 32
33 auto& current_memory{GetCurrentMemory(system.Kernel())}; 33 auto& current_memory{GetCurrentMemory(system.Kernel())};
34 const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; 34 const auto memory_info{process->GetPageTable().QueryInfo(address).GetSvcMemoryInfo()};
35 35
36 current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info)); 36 current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info));
37 37
diff --git a/src/core/hle/kernel/svc/svc_shared_memory.cpp b/src/core/hle/kernel/svc/svc_shared_memory.cpp
index a698596aa..012b1ae2b 100644
--- a/src/core/hle/kernel/svc/svc_shared_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_shared_memory.cpp
@@ -43,7 +43,7 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u
43 43
44 // Get the current process. 44 // Get the current process.
45 auto& process = GetCurrentProcess(system.Kernel()); 45 auto& process = GetCurrentProcess(system.Kernel());
46 auto& page_table = process.PageTable(); 46 auto& page_table = process.GetPageTable();
47 47
48 // Get the shared memory. 48 // Get the shared memory.
49 KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle); 49 KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
@@ -73,7 +73,7 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address,
73 73
74 // Get the current process. 74 // Get the current process.
75 auto& process = GetCurrentProcess(system.Kernel()); 75 auto& process = GetCurrentProcess(system.Kernel());
76 auto& page_table = process.PageTable(); 76 auto& page_table = process.GetPageTable();
77 77
78 // Get the shared memory. 78 // Get the shared memory.
79 KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle); 79 KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp
index f02d03f30..366e8ed4a 100644
--- a/src/core/hle/kernel/svc/svc_synchronization.cpp
+++ b/src/core/hle/kernel/svc/svc_synchronization.cpp
@@ -7,6 +7,7 @@
7#include "core/hle/kernel/k_process.h" 7#include "core/hle/kernel/k_process.h"
8#include "core/hle/kernel/k_readable_event.h" 8#include "core/hle/kernel/k_readable_event.h"
9#include "core/hle/kernel/svc.h" 9#include "core/hle/kernel/svc.h"
10#include "core/hle/kernel/svc_results.h"
10 11
11namespace Kernel::Svc { 12namespace Kernel::Svc {
12 13
@@ -64,14 +65,10 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
64 65
65 // Copy user handles. 66 // Copy user handles.
66 if (num_handles > 0) { 67 if (num_handles > 0) {
67 // Ensure we can try to get the handles.
68 R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
69 user_handles, static_cast<u64>(sizeof(Handle) * num_handles)),
70 ResultInvalidPointer);
71
72 // Get the handles. 68 // Get the handles.
73 GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(), 69 R_UNLESS(GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(),
74 sizeof(Handle) * num_handles); 70 sizeof(Handle) * num_handles),
71 ResultInvalidPointer);
75 72
76 // Convert the handles to objects. 73 // Convert the handles to objects.
77 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>( 74 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index 36b94e6bf..92bcea72b 100644
--- a/src/core/hle/kernel/svc/svc_thread.cpp
+++ b/src/core/hle/kernel/svc/svc_thread.cpp
@@ -236,7 +236,7 @@ Result GetThreadList(Core::System& system, s32* out_num_threads, u64 out_thread_
236 const auto total_copy_size = out_thread_ids_size * sizeof(u64); 236 const auto total_copy_size = out_thread_ids_size * sizeof(u64);
237 237
238 if (out_thread_ids_size > 0 && 238 if (out_thread_ids_size > 0 &&
239 !current_process->PageTable().IsInsideAddressSpace(out_thread_ids, total_copy_size)) { 239 !current_process->GetPageTable().Contains(out_thread_ids, total_copy_size)) {
240 LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", 240 LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
241 out_thread_ids, out_thread_ids + total_copy_size); 241 out_thread_ids, out_thread_ids + total_copy_size);
242 R_THROW(ResultInvalidCurrentMemory); 242 R_THROW(ResultInvalidCurrentMemory);
diff --git a/src/core/hle/kernel/svc/svc_transfer_memory.cpp b/src/core/hle/kernel/svc/svc_transfer_memory.cpp
index 82d469a37..7d94e7f09 100644
--- a/src/core/hle/kernel/svc/svc_transfer_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_transfer_memory.cpp
@@ -55,7 +55,7 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64
55 SCOPE_EXIT({ trmem->Close(); }); 55 SCOPE_EXIT({ trmem->Close(); });
56 56
57 // Ensure that the region is in range. 57 // Ensure that the region is in range.
58 R_UNLESS(process.PageTable().Contains(address, size), ResultInvalidCurrentMemory); 58 R_UNLESS(process.GetPageTable().Contains(address, size), ResultInvalidCurrentMemory);
59 59
60 // Initialize the transfer memory. 60 // Initialize the transfer memory.
61 R_TRY(trmem->Initialize(address, size, map_perm)); 61 R_TRY(trmem->Initialize(address, size, map_perm));
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 6c29cb613..2632cd3ef 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -496,8 +496,9 @@ public:
496 void LoadIdTokenCache(HLERequestContext& ctx) { 496 void LoadIdTokenCache(HLERequestContext& ctx) {
497 LOG_WARNING(Service_ACC, "(STUBBED) called"); 497 LOG_WARNING(Service_ACC, "(STUBBED) called");
498 498
499 IPC::ResponseBuilder rb{ctx, 2}; 499 IPC::ResponseBuilder rb{ctx, 3};
500 rb.Push(ResultSuccess); 500 rb.Push(ResultSuccess);
501 rb.Push(0);
501 } 502 }
502 503
503protected: 504protected:
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 003870176..b723b65c8 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -441,10 +441,11 @@ void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) {
441 441
442 AudioCore::AudioRendererParameterInternal params; 442 AudioCore::AudioRendererParameterInternal params;
443 rp.PopRaw<AudioCore::AudioRendererParameterInternal>(params); 443 rp.PopRaw<AudioCore::AudioRendererParameterInternal>(params);
444 auto transfer_memory_handle = ctx.GetCopyHandle(0); 444 rp.Skip(1, false);
445 auto process_handle = ctx.GetCopyHandle(1);
446 auto transfer_memory_size = rp.Pop<u64>(); 445 auto transfer_memory_size = rp.Pop<u64>();
447 auto applet_resource_user_id = rp.Pop<u64>(); 446 auto applet_resource_user_id = rp.Pop<u64>();
447 auto transfer_memory_handle = ctx.GetCopyHandle(0);
448 auto process_handle = ctx.GetCopyHandle(1);
448 449
449 if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) { 450 if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) {
450 LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!"); 451 LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!");
diff --git a/src/core/hle/service/glue/ectx.cpp b/src/core/hle/service/glue/ectx.cpp
index 1bd9314ae..6f71b62f3 100644
--- a/src/core/hle/service/glue/ectx.cpp
+++ b/src/core/hle/service/glue/ectx.cpp
@@ -2,13 +2,48 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/glue/ectx.h" 4#include "core/hle/service/glue/ectx.h"
5#include "core/hle/service/ipc_helpers.h"
5 6
6namespace Service::Glue { 7namespace Service::Glue {
7 8
9// This is nn::err::context::IContextRegistrar
10class IContextRegistrar : public ServiceFramework<IContextRegistrar> {
11public:
12 IContextRegistrar(Core::System& system_) : ServiceFramework{system_, "IContextRegistrar"} {
13 // clang-format off
14 static const FunctionInfo functions[] = {
15 {0, &IContextRegistrar::Complete, "Complete"},
16 };
17 // clang-format on
18
19 RegisterHandlers(functions);
20 }
21
22 ~IContextRegistrar() override = default;
23
24private:
25 void Complete(HLERequestContext& ctx) {
26 struct InputParameters {
27 u32 unk;
28 };
29 struct OutputParameters {
30 u32 unk;
31 };
32
33 IPC::RequestParser rp{ctx};
34 [[maybe_unused]] auto input = rp.PopRaw<InputParameters>();
35 [[maybe_unused]] auto value = ctx.ReadBuffer();
36
37 IPC::ResponseBuilder rb{ctx, 3};
38 rb.Push(ResultSuccess);
39 rb.Push(0);
40 }
41};
42
8ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} { 43ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
9 // clang-format off 44 // clang-format off
10 static const FunctionInfo functions[] = { 45 static const FunctionInfo functions[] = {
11 {0, nullptr, "CreateContextRegistrar"}, 46 {0, &ECTX_AW::CreateContextRegistrar, "CreateContextRegistrar"},
12 {1, nullptr, "CommitContext"}, 47 {1, nullptr, "CommitContext"},
13 }; 48 };
14 // clang-format on 49 // clang-format on
@@ -18,4 +53,10 @@ ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
18 53
19ECTX_AW::~ECTX_AW() = default; 54ECTX_AW::~ECTX_AW() = default;
20 55
56void ECTX_AW::CreateContextRegistrar(HLERequestContext& ctx) {
57 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
58 rb.Push(ResultSuccess);
59 rb.PushIpcInterface<IContextRegistrar>(std::make_shared<IContextRegistrar>(system));
60}
61
21} // namespace Service::Glue 62} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/ectx.h b/src/core/hle/service/glue/ectx.h
index a608de053..ffa74d8d3 100644
--- a/src/core/hle/service/glue/ectx.h
+++ b/src/core/hle/service/glue/ectx.h
@@ -15,6 +15,9 @@ class ECTX_AW final : public ServiceFramework<ECTX_AW> {
15public: 15public:
16 explicit ECTX_AW(Core::System& system_); 16 explicit ECTX_AW(Core::System& system_);
17 ~ECTX_AW() override; 17 ~ECTX_AW() override;
18
19private:
20 void CreateContextRegistrar(HLERequestContext& ctx);
18}; 21};
19 22
20} // namespace Service::Glue 23} // namespace Service::Glue
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index c42489ff9..055c0a2db 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -318,15 +318,15 @@ public:
318 return false; 318 return false;
319 } 319 }
320 320
321 if (!page_table.IsInsideAddressSpace(out_addr, size)) { 321 if (!page_table.Contains(out_addr, size)) {
322 return false; 322 return false;
323 } 323 }
324 324
325 if (page_table.IsInsideHeapRegion(out_addr, size)) { 325 if (page_table.IsInHeapRegion(out_addr, size)) {
326 return false; 326 return false;
327 } 327 }
328 328
329 if (page_table.IsInsideAliasRegion(out_addr, size)) { 329 if (page_table.IsInAliasRegion(out_addr, size)) {
330 return false; 330 return false;
331 } 331 }
332 332
@@ -358,7 +358,7 @@ public:
358 } 358 }
359 359
360 ResultVal<VAddr> MapProcessCodeMemory(Kernel::KProcess* process, VAddr base_addr, u64 size) { 360 ResultVal<VAddr> MapProcessCodeMemory(Kernel::KProcess* process, VAddr base_addr, u64 size) {
361 auto& page_table{process->PageTable()}; 361 auto& page_table{process->GetPageTable()};
362 VAddr addr{}; 362 VAddr addr{};
363 363
364 for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { 364 for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) {
@@ -382,7 +382,7 @@ public:
382 ResultVal<VAddr> MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size, 382 ResultVal<VAddr> MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size,
383 VAddr bss_addr, std::size_t bss_size, std::size_t size) { 383 VAddr bss_addr, std::size_t bss_size, std::size_t size) {
384 for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { 384 for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) {
385 auto& page_table{process->PageTable()}; 385 auto& page_table{process->GetPageTable()};
386 VAddr addr{}; 386 VAddr addr{};
387 387
388 CASCADE_RESULT(addr, MapProcessCodeMemory(process, nro_addr, nro_size)); 388 CASCADE_RESULT(addr, MapProcessCodeMemory(process, nro_addr, nro_size));
@@ -437,12 +437,12 @@ public:
437 CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start, 437 CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start,
438 nro_header.segment_headers[DATA_INDEX].memory_size); 438 nro_header.segment_headers[DATA_INDEX].memory_size);
439 439
440 CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( 440 CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission(
441 text_start, ro_start - text_start, Kernel::Svc::MemoryPermission::ReadExecute)); 441 text_start, ro_start - text_start, Kernel::Svc::MemoryPermission::ReadExecute));
442 CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( 442 CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission(
443 ro_start, data_start - ro_start, Kernel::Svc::MemoryPermission::Read)); 443 ro_start, data_start - ro_start, Kernel::Svc::MemoryPermission::Read));
444 444
445 return process->PageTable().SetProcessMemoryPermission( 445 return process->GetPageTable().SetProcessMemoryPermission(
446 data_start, bss_end_addr - data_start, Kernel::Svc::MemoryPermission::ReadWrite); 446 data_start, bss_end_addr - data_start, Kernel::Svc::MemoryPermission::ReadWrite);
447 } 447 }
448 448
@@ -571,7 +571,7 @@ public:
571 571
572 Result UnmapNro(const NROInfo& info) { 572 Result UnmapNro(const NROInfo& info) {
573 // Each region must be unmapped separately to validate memory state 573 // Each region must be unmapped separately to validate memory state
574 auto& page_table{system.ApplicationProcess()->PageTable()}; 574 auto& page_table{system.ApplicationProcess()->GetPageTable()};
575 575
576 if (info.bss_size != 0) { 576 if (info.bss_size != 0) {
577 CASCADE_CODE(page_table.UnmapCodeMemory( 577 CASCADE_CODE(page_table.UnmapCodeMemory(
@@ -643,7 +643,7 @@ public:
643 643
644 initialized = true; 644 initialized = true;
645 current_map_addr = 645 current_map_addr =
646 GetInteger(system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart()); 646 GetInteger(system.ApplicationProcess()->GetPageTable().GetAliasCodeRegionStart());
647 647
648 IPC::ResponseBuilder rb{ctx, 2}; 648 IPC::ResponseBuilder rb{ctx, 2};
649 rb.Push(ResultSuccess); 649 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index e7f7e273b..968eaa175 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -128,7 +128,7 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) {
128 } 128 }
129 bool is_out_io{}; 129 bool is_out_io{};
130 ASSERT(system.ApplicationProcess() 130 ASSERT(system.ApplicationProcess()
131 ->PageTable() 131 ->GetPageTable()
132 .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address, 132 .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address,
133 handle_description->size, 133 handle_description->size,
134 Kernel::KMemoryPermission::None, true, false) 134 Kernel::KMemoryPermission::None, true, false)
@@ -255,7 +255,7 @@ NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) {
255 if (auto freeInfo{file.FreeHandle(params.handle, false)}) { 255 if (auto freeInfo{file.FreeHandle(params.handle, false)}) {
256 if (freeInfo->can_unlock) { 256 if (freeInfo->can_unlock) {
257 ASSERT(system.ApplicationProcess() 257 ASSERT(system.ApplicationProcess()
258 ->PageTable() 258 ->GetPageTable()
259 .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) 259 .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size)
260 .IsSuccess()); 260 .IsSuccess());
261 } 261 }
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index e63b0a357..11f8efbac 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -559,7 +559,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con
559 559
560 const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd]; 560 const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd];
561 if (!descriptor) { 561 if (!descriptor) {
562 LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd); 562 LOG_TRACE(Service, "File descriptor handle={} is not allocated", pollfd.fd);
563 pollfd.revents = PollEvents::Nval; 563 pollfd.revents = PollEvents::Nval;
564 return {0, Errno::SUCCESS}; 564 return {0, Errno::SUCCESS};
565 } 565 }
diff --git a/src/core/hle/service/sockets/nsd.cpp b/src/core/hle/service/sockets/nsd.cpp
index 0dfb0f166..5dfcaabb1 100644
--- a/src/core/hle/service/sockets/nsd.cpp
+++ b/src/core/hle/service/sockets/nsd.cpp
@@ -10,12 +10,21 @@ namespace Service::Sockets {
10 10
11constexpr Result ResultOverflow{ErrorModule::NSD, 6}; 11constexpr Result ResultOverflow{ErrorModule::NSD, 6};
12 12
13// This is nn::oe::ServerEnvironmentType
14enum class ServerEnvironmentType : u8 {
15 Dd,
16 Lp,
17 Sd,
18 Sp,
19 Dp,
20};
21
13NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} { 22NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
14 // clang-format off 23 // clang-format off
15 static const FunctionInfo functions[] = { 24 static const FunctionInfo functions[] = {
16 {5, nullptr, "GetSettingUrl"}, 25 {5, nullptr, "GetSettingUrl"},
17 {10, nullptr, "GetSettingName"}, 26 {10, nullptr, "GetSettingName"},
18 {11, nullptr, "GetEnvironmentIdentifier"}, 27 {11, &NSD::GetEnvironmentIdentifier, "GetEnvironmentIdentifier"},
19 {12, nullptr, "GetDeviceId"}, 28 {12, nullptr, "GetDeviceId"},
20 {13, nullptr, "DeleteSettings"}, 29 {13, nullptr, "DeleteSettings"},
21 {14, nullptr, "ImportSettings"}, 30 {14, nullptr, "ImportSettings"},
@@ -36,7 +45,7 @@ NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
36 {62, nullptr, "DeleteSaveDataOfFsForTest"}, 45 {62, nullptr, "DeleteSaveDataOfFsForTest"},
37 {63, nullptr, "IsChangeEnvironmentIdentifierDisabled"}, 46 {63, nullptr, "IsChangeEnvironmentIdentifierDisabled"},
38 {64, nullptr, "SetWithoutDomainExchangeFqdns"}, 47 {64, nullptr, "SetWithoutDomainExchangeFqdns"},
39 {100, nullptr, "GetApplicationServerEnvironmentType"}, 48 {100, &NSD::GetApplicationServerEnvironmentType, "GetApplicationServerEnvironmentType"},
40 {101, nullptr, "SetApplicationServerEnvironmentType"}, 49 {101, nullptr, "SetApplicationServerEnvironmentType"},
41 {102, nullptr, "DeleteApplicationServerEnvironmentType"}, 50 {102, nullptr, "DeleteApplicationServerEnvironmentType"},
42 }; 51 };
@@ -94,6 +103,20 @@ void NSD::ResolveEx(HLERequestContext& ctx) {
94 rb.Push(ResultSuccess); 103 rb.Push(ResultSuccess);
95} 104}
96 105
106void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) {
107 const std::string environment_identifier = "lp1";
108 ctx.WriteBuffer(environment_identifier);
109
110 IPC::ResponseBuilder rb{ctx, 2};
111 rb.Push(ResultSuccess);
112}
113
114void NSD::GetApplicationServerEnvironmentType(HLERequestContext& ctx) {
115 IPC::ResponseBuilder rb{ctx, 3};
116 rb.Push(ResultSuccess);
117 rb.Push(static_cast<u32>(ServerEnvironmentType::Lp));
118}
119
97NSD::~NSD() = default; 120NSD::~NSD() = default;
98 121
99} // namespace Service::Sockets 122} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/nsd.h b/src/core/hle/service/sockets/nsd.h
index a7379a8a9..b0cfec507 100644
--- a/src/core/hle/service/sockets/nsd.h
+++ b/src/core/hle/service/sockets/nsd.h
@@ -19,6 +19,8 @@ public:
19private: 19private:
20 void Resolve(HLERequestContext& ctx); 20 void Resolve(HLERequestContext& ctx);
21 void ResolveEx(HLERequestContext& ctx); 21 void ResolveEx(HLERequestContext& ctx);
22 void GetEnvironmentIdentifier(HLERequestContext& ctx);
23 void GetApplicationServerEnvironmentType(HLERequestContext& ctx);
22}; 24};
23 25
24} // namespace Service::Sockets 26} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp
index 84cc79de8..22e4a6f49 100644
--- a/src/core/hle/service/sockets/sfdnsres.cpp
+++ b/src/core/hle/service/sockets/sfdnsres.cpp
@@ -24,7 +24,7 @@ SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"
24 {2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"}, 24 {2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"},
25 {3, nullptr, "GetHostByAddrRequest"}, 25 {3, nullptr, "GetHostByAddrRequest"},
26 {4, nullptr, "GetHostStringErrorRequest"}, 26 {4, nullptr, "GetHostStringErrorRequest"},
27 {5, nullptr, "GetGaiStringErrorRequest"}, 27 {5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"},
28 {6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"}, 28 {6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"},
29 {7, nullptr, "GetNameInfoRequest"}, 29 {7, nullptr, "GetNameInfoRequest"},
30 {8, nullptr, "RequestCancelHandleRequest"}, 30 {8, nullptr, "RequestCancelHandleRequest"},
@@ -300,6 +300,20 @@ void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) {
300 }); 300 });
301} 301}
302 302
303void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) {
304 struct InputParameters {
305 GetAddrInfoError gai_errno;
306 };
307 IPC::RequestParser rp{ctx};
308 auto input = rp.PopRaw<InputParameters>();
309
310 const std::string result = Translate(input.gai_errno);
311 ctx.WriteBuffer(result);
312
313 IPC::ResponseBuilder rb{ctx, 2};
314 rb.Push(ResultSuccess);
315}
316
303void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) { 317void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) {
304 // Additional options are ignored 318 // Additional options are ignored
305 auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx); 319 auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx);
diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h
index d99a9d560..282ef9071 100644
--- a/src/core/hle/service/sockets/sfdnsres.h
+++ b/src/core/hle/service/sockets/sfdnsres.h
@@ -18,6 +18,7 @@ public:
18 18
19private: 19private:
20 void GetHostByNameRequest(HLERequestContext& ctx); 20 void GetHostByNameRequest(HLERequestContext& ctx);
21 void GetGaiStringErrorRequest(HLERequestContext& ctx);
21 void GetHostByNameRequestWithOptions(HLERequestContext& ctx); 22 void GetHostByNameRequestWithOptions(HLERequestContext& ctx);
22 void GetAddrInfoRequest(HLERequestContext& ctx); 23 void GetAddrInfoRequest(HLERequestContext& ctx);
23 void GetAddrInfoRequestWithOptions(HLERequestContext& ctx); 24 void GetAddrInfoRequestWithOptions(HLERequestContext& ctx);
diff --git a/src/core/hle/service/sockets/sockets_translate.cpp b/src/core/hle/service/sockets/sockets_translate.cpp
index 2f9a0e39c..c1187209f 100644
--- a/src/core/hle/service/sockets/sockets_translate.cpp
+++ b/src/core/hle/service/sockets/sockets_translate.cpp
@@ -81,6 +81,44 @@ GetAddrInfoError Translate(Network::GetAddrInfoError error) {
81 } 81 }
82} 82}
83 83
84const char* Translate(GetAddrInfoError error) {
85 // https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254
86 switch (error) {
87 case GetAddrInfoError::SUCCESS:
88 return "Success";
89 case GetAddrInfoError::ADDRFAMILY:
90 return "Address family for hostname not supported";
91 case GetAddrInfoError::AGAIN:
92 return "Temporary failure in name resolution";
93 case GetAddrInfoError::BADFLAGS:
94 return "Invalid value for ai_flags";
95 case GetAddrInfoError::FAIL:
96 return "Non-recoverable failure in name resolution";
97 case GetAddrInfoError::FAMILY:
98 return "ai_family not supported";
99 case GetAddrInfoError::MEMORY:
100 return "Memory allocation failure";
101 case GetAddrInfoError::NODATA:
102 return "No address associated with hostname";
103 case GetAddrInfoError::NONAME:
104 return "hostname nor servname provided, or not known";
105 case GetAddrInfoError::SERVICE:
106 return "servname not supported for ai_socktype";
107 case GetAddrInfoError::SOCKTYPE:
108 return "ai_socktype not supported";
109 case GetAddrInfoError::SYSTEM:
110 return "System error returned in errno";
111 case GetAddrInfoError::BADHINTS:
112 return "Invalid value for hints";
113 case GetAddrInfoError::PROTOCOL:
114 return "Resolved protocol is unknown";
115 case GetAddrInfoError::OVERFLOW_:
116 return "Argument buffer overflow";
117 default:
118 return "Unknown error";
119 }
120}
121
84Network::Domain Translate(Domain domain) { 122Network::Domain Translate(Domain domain) {
85 switch (domain) { 123 switch (domain) {
86 case Domain::Unspecified: 124 case Domain::Unspecified:
diff --git a/src/core/hle/service/sockets/sockets_translate.h b/src/core/hle/service/sockets/sockets_translate.h
index 694868b37..bd6721fd3 100644
--- a/src/core/hle/service/sockets/sockets_translate.h
+++ b/src/core/hle/service/sockets/sockets_translate.h
@@ -20,6 +20,9 @@ std::pair<s32, Errno> Translate(std::pair<s32, Network::Errno> value);
20/// Translate abstract getaddrinfo error to guest getaddrinfo error 20/// Translate abstract getaddrinfo error to guest getaddrinfo error
21GetAddrInfoError Translate(Network::GetAddrInfoError value); 21GetAddrInfoError Translate(Network::GetAddrInfoError value);
22 22
23/// Translate guest error to string
24const char* Translate(GetAddrInfoError value);
25
23/// Translate guest domain to abstract domain 26/// Translate guest domain to abstract domain
24Network::Domain Translate(Domain domain); 27Network::Domain Translate(Domain domain);
25 28
diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp
index 565f6b39b..1b96de37a 100644
--- a/src/core/hle/service/time/time_zone_content_manager.cpp
+++ b/src/core/hle/service/time/time_zone_content_manager.cpp
@@ -3,6 +3,7 @@
3 3
4#include <chrono> 4#include <chrono>
5#include <sstream> 5#include <sstream>
6#include <utility>
6 7
7#include "common/logging/log.h" 8#include "common/logging/log.h"
8#include "common/settings.h" 9#include "common/settings.h"
@@ -46,14 +47,14 @@ static FileSys::VirtualDir GetTimeZoneBinary(Core::System& system) {
46 return FileSys::ExtractRomFS(romfs); 47 return FileSys::ExtractRomFS(romfs);
47} 48}
48 49
49static std::vector<std::string> BuildLocationNameCache(Core::System& system) { 50static std::vector<std::string> BuildLocationNameCache(
50 const FileSys::VirtualDir extracted_romfs{GetTimeZoneBinary(system)}; 51 const FileSys::VirtualDir& time_zone_binary) {
51 if (!extracted_romfs) { 52 if (!time_zone_binary) {
52 LOG_ERROR(Service_Time, "Failed to extract RomFS for {:016X}!", time_zone_binary_titleid); 53 LOG_ERROR(Service_Time, "Failed to extract RomFS for {:016X}!", time_zone_binary_titleid);
53 return {}; 54 return {};
54 } 55 }
55 56
56 const FileSys::VirtualFile binary_list{extracted_romfs->GetFile("binaryList.txt")}; 57 const FileSys::VirtualFile binary_list{time_zone_binary->GetFile("binaryList.txt")};
57 if (!binary_list) { 58 if (!binary_list) {
58 LOG_ERROR(Service_Time, "{:016X} has no file binaryList.txt!", time_zone_binary_titleid); 59 LOG_ERROR(Service_Time, "{:016X} has no file binaryList.txt!", time_zone_binary_titleid);
59 return {}; 60 return {};
@@ -73,7 +74,8 @@ static std::vector<std::string> BuildLocationNameCache(Core::System& system) {
73} 74}
74 75
75TimeZoneContentManager::TimeZoneContentManager(Core::System& system_) 76TimeZoneContentManager::TimeZoneContentManager(Core::System& system_)
76 : system{system_}, location_name_cache{BuildLocationNameCache(system)} {} 77 : system{system_}, time_zone_binary{GetTimeZoneBinary(system)},
78 location_name_cache{BuildLocationNameCache(time_zone_binary)} {}
77 79
78void TimeZoneContentManager::Initialize(TimeManager& time_manager) { 80void TimeZoneContentManager::Initialize(TimeManager& time_manager) {
79 const auto timezone_setting = 81 const auto timezone_setting =
@@ -112,13 +114,12 @@ Result TimeZoneContentManager::GetTimeZoneInfoFile(const std::string& location_n
112 return ERROR_TIME_NOT_FOUND; 114 return ERROR_TIME_NOT_FOUND;
113 } 115 }
114 116
115 const FileSys::VirtualDir extracted_romfs{GetTimeZoneBinary(system)}; 117 if (!time_zone_binary) {
116 if (!extracted_romfs) {
117 LOG_ERROR(Service_Time, "Failed to extract RomFS for {:016X}!", time_zone_binary_titleid); 118 LOG_ERROR(Service_Time, "Failed to extract RomFS for {:016X}!", time_zone_binary_titleid);
118 return ERROR_TIME_NOT_FOUND; 119 return ERROR_TIME_NOT_FOUND;
119 } 120 }
120 121
121 const FileSys::VirtualDir zoneinfo_dir{extracted_romfs->GetSubdirectory("zoneinfo")}; 122 const FileSys::VirtualDir zoneinfo_dir{time_zone_binary->GetSubdirectory("zoneinfo")};
122 if (!zoneinfo_dir) { 123 if (!zoneinfo_dir) {
123 LOG_ERROR(Service_Time, "{:016X} has no directory zoneinfo!", time_zone_binary_titleid); 124 LOG_ERROR(Service_Time, "{:016X} has no directory zoneinfo!", time_zone_binary_titleid);
124 return ERROR_TIME_NOT_FOUND; 125 return ERROR_TIME_NOT_FOUND;
diff --git a/src/core/hle/service/time/time_zone_content_manager.h b/src/core/hle/service/time/time_zone_content_manager.h
index 3d94b6428..a6f9698bc 100644
--- a/src/core/hle/service/time/time_zone_content_manager.h
+++ b/src/core/hle/service/time/time_zone_content_manager.h
@@ -6,6 +6,7 @@
6#include <string> 6#include <string>
7#include <vector> 7#include <vector>
8 8
9#include "core/file_sys/vfs_types.h"
9#include "core/hle/service/time/time_zone_manager.h" 10#include "core/hle/service/time/time_zone_manager.h"
10 11
11namespace Core { 12namespace Core {
@@ -41,6 +42,7 @@ private:
41 42
42 Core::System& system; 43 Core::System& system;
43 TimeZoneManager time_zone_manager; 44 TimeZoneManager time_zone_manager;
45 const FileSys::VirtualDir time_zone_binary;
44 const std::vector<std::string> location_name_cache; 46 const std::vector<std::string> location_name_cache;
45}; 47};
46 48
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 3be9b71cf..e04ad19db 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -153,7 +153,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
153 153
154 // Load NSO modules 154 // Load NSO modules
155 modules.clear(); 155 modules.clear();
156 const VAddr base_address{GetInteger(process.PageTable().GetCodeRegionStart())}; 156 const VAddr base_address{GetInteger(process.GetPageTable().GetCodeRegionStart())};
157 VAddr next_load_addr{base_address}; 157 VAddr next_load_addr{base_address};
158 const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), 158 const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
159 system.GetContentProvider()}; 159 system.GetContentProvider()};
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index 709e2564f..ffe976b94 100644
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
96 } 96 }
97 97
98 codeset.memory = std::move(program_image); 98 codeset.memory = std::move(program_image);
99 const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart()); 99 const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart());
100 process.LoadModule(std::move(codeset), base_address); 100 process.LoadModule(std::move(codeset), base_address);
101 101
102 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); 102 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address);
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 7be6cf5f3..506808b5d 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -203,7 +203,7 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector<u8>& data)
203 203
204 // Load codeset for current process 204 // Load codeset for current process
205 codeset.memory = std::move(program_image); 205 codeset.memory = std::move(program_image);
206 process.LoadModule(std::move(codeset), process.PageTable().GetCodeRegionStart()); 206 process.LoadModule(std::move(codeset), process.GetPageTable().GetCodeRegionStart());
207 207
208 return true; 208 return true;
209} 209}
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 79639f5e4..74cc9579f 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
167 modules.clear(); 167 modules.clear();
168 168
169 // Load module 169 // Load module
170 const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart()); 170 const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart());
171 if (!LoadModule(process, system, *file, base_address, true, true)) { 171 if (!LoadModule(process, system, *file, base_address, true, true)) {
172 return {ResultStatus::ErrorLoadingNSO, {}}; 172 return {ResultStatus::ErrorLoadingNSO, {}};
173 } 173 }
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 805963178..fa5273402 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -24,6 +24,16 @@
24 24
25namespace Core::Memory { 25namespace Core::Memory {
26 26
27namespace {
28
29bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessAddress addr,
30 const std::size_t size) {
31 const Common::ProcessAddress max_addr = 1ULL << table.GetAddressSpaceBits();
32 return addr + size >= addr && addr + size <= max_addr;
33}
34
35} // namespace
36
27// Implementation class used to keep the specifics of the memory subsystem hidden 37// Implementation class used to keep the specifics of the memory subsystem hidden
28// from outside classes. This also allows modification to the internals of the memory 38// from outside classes. This also allows modification to the internals of the memory
29// subsystem without needing to rebuild all files that make use of the memory interface. 39// subsystem without needing to rebuild all files that make use of the memory interface.
@@ -31,10 +41,10 @@ struct Memory::Impl {
31 explicit Impl(Core::System& system_) : system{system_} {} 41 explicit Impl(Core::System& system_) : system{system_} {}
32 42
33 void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { 43 void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
34 current_page_table = &process.PageTable().PageTableImpl(); 44 current_page_table = &process.GetPageTable().PageTableImpl();
35 current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer(); 45 current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
36 46
37 const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth(); 47 const std::size_t address_space_width = process.GetPageTable().GetAddressSpaceWidth();
38 48
39 system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width); 49 system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width);
40 } 50 }
@@ -73,7 +83,7 @@ struct Memory::Impl {
73 return {}; 83 return {};
74 } 84 }
75 85
76 return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr; 86 return system.DeviceMemory().GetPointer<u8>(paddr + vaddr);
77 } 87 }
78 88
79 [[nodiscard]] u8* GetPointerFromDebugMemory(u64 vaddr) const { 89 [[nodiscard]] u8* GetPointerFromDebugMemory(u64 vaddr) const {
@@ -84,7 +94,7 @@ struct Memory::Impl {
84 return {}; 94 return {};
85 } 95 }
86 96
87 return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr; 97 return system.DeviceMemory().GetPointer<u8>(paddr + vaddr);
88 } 98 }
89 99
90 u8 Read8(const Common::ProcessAddress addr) { 100 u8 Read8(const Common::ProcessAddress addr) {
@@ -183,13 +193,18 @@ struct Memory::Impl {
183 return string; 193 return string;
184 } 194 }
185 195
186 void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr, 196 bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
187 const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer, 197 auto on_memory, auto on_rasterizer, auto increment) {
188 auto increment) { 198 const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl();
189 const auto& page_table = process.PageTable().PageTableImpl();
190 std::size_t remaining_size = size; 199 std::size_t remaining_size = size;
191 std::size_t page_index = addr >> YUZU_PAGEBITS; 200 std::size_t page_index = addr >> YUZU_PAGEBITS;
192 std::size_t page_offset = addr & YUZU_PAGEMASK; 201 std::size_t page_offset = addr & YUZU_PAGEMASK;
202 bool user_accessible = true;
203
204 if (!AddressSpaceContains(page_table, addr, size)) [[unlikely]] {
205 on_unmapped(size, addr);
206 return false;
207 }
193 208
194 while (remaining_size) { 209 while (remaining_size) {
195 const std::size_t copy_amount = 210 const std::size_t copy_amount =
@@ -200,11 +215,13 @@ struct Memory::Impl {
200 const auto [pointer, type] = page_table.pointers[page_index].PointerType(); 215 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
201 switch (type) { 216 switch (type) {
202 case Common::PageType::Unmapped: { 217 case Common::PageType::Unmapped: {
218 user_accessible = false;
203 on_unmapped(copy_amount, current_vaddr); 219 on_unmapped(copy_amount, current_vaddr);
204 break; 220 break;
205 } 221 }
206 case Common::PageType::Memory: { 222 case Common::PageType::Memory: {
207 u8* mem_ptr = pointer + page_offset + (page_index << YUZU_PAGEBITS); 223 u8* mem_ptr =
224 reinterpret_cast<u8*>(pointer + page_offset + (page_index << YUZU_PAGEBITS));
208 on_memory(copy_amount, mem_ptr); 225 on_memory(copy_amount, mem_ptr);
209 break; 226 break;
210 } 227 }
@@ -227,13 +244,15 @@ struct Memory::Impl {
227 increment(copy_amount); 244 increment(copy_amount);
228 remaining_size -= copy_amount; 245 remaining_size -= copy_amount;
229 } 246 }
247
248 return user_accessible;
230 } 249 }
231 250
232 template <bool UNSAFE> 251 template <bool UNSAFE>
233 void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr, 252 bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer,
234 void* dest_buffer, const std::size_t size) { 253 const std::size_t size) {
235 WalkBlock( 254 return WalkBlock(
236 process, src_addr, size, 255 src_addr, size,
237 [src_addr, size, &dest_buffer](const std::size_t copy_amount, 256 [src_addr, size, &dest_buffer](const std::size_t copy_amount,
238 const Common::ProcessAddress current_vaddr) { 257 const Common::ProcessAddress current_vaddr) {
239 LOG_ERROR(HW_Memory, 258 LOG_ERROR(HW_Memory,
@@ -256,14 +275,14 @@ struct Memory::Impl {
256 }); 275 });
257 } 276 }
258 277
259 void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, 278 bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
260 const std::size_t size) { 279 const std::size_t size) {
261 ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size); 280 return ReadBlockImpl<false>(src_addr, dest_buffer, size);
262 } 281 }
263 282
264 void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, 283 bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
265 const std::size_t size) { 284 const std::size_t size) {
266 ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size); 285 return ReadBlockImpl<true>(src_addr, dest_buffer, size);
267 } 286 }
268 287
269 const u8* GetSpan(const VAddr src_addr, const std::size_t size) const { 288 const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
@@ -283,10 +302,10 @@ struct Memory::Impl {
283 } 302 }
284 303
285 template <bool UNSAFE> 304 template <bool UNSAFE>
286 void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, 305 bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer,
287 const void* src_buffer, const std::size_t size) { 306 const std::size_t size) {
288 WalkBlock( 307 return WalkBlock(
289 process, dest_addr, size, 308 dest_addr, size,
290 [dest_addr, size](const std::size_t copy_amount, 309 [dest_addr, size](const std::size_t copy_amount,
291 const Common::ProcessAddress current_vaddr) { 310 const Common::ProcessAddress current_vaddr) {
292 LOG_ERROR(HW_Memory, 311 LOG_ERROR(HW_Memory,
@@ -308,20 +327,19 @@ struct Memory::Impl {
308 }); 327 });
309 } 328 }
310 329
311 void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, 330 bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
312 const std::size_t size) { 331 const std::size_t size) {
313 WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size); 332 return WriteBlockImpl<false>(dest_addr, src_buffer, size);
314 } 333 }
315 334
316 void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, 335 bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
317 const std::size_t size) { 336 const std::size_t size) {
318 WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size); 337 return WriteBlockImpl<true>(dest_addr, src_buffer, size);
319 } 338 }
320 339
321 void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, 340 bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) {
322 const std::size_t size) { 341 return WalkBlock(
323 WalkBlock( 342 dest_addr, size,
324 process, dest_addr, size,
325 [dest_addr, size](const std::size_t copy_amount, 343 [dest_addr, size](const std::size_t copy_amount,
326 const Common::ProcessAddress current_vaddr) { 344 const Common::ProcessAddress current_vaddr) {
327 LOG_ERROR(HW_Memory, 345 LOG_ERROR(HW_Memory,
@@ -339,23 +357,23 @@ struct Memory::Impl {
339 [](const std::size_t copy_amount) {}); 357 [](const std::size_t copy_amount) {});
340 } 358 }
341 359
342 void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 360 bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
343 Common::ProcessAddress src_addr, const std::size_t size) { 361 const std::size_t size) {
344 WalkBlock( 362 return WalkBlock(
345 process, dest_addr, size, 363 dest_addr, size,
346 [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { 364 [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
347 LOG_ERROR(HW_Memory, 365 LOG_ERROR(HW_Memory,
348 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 366 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
349 GetInteger(current_vaddr), GetInteger(src_addr), size); 367 GetInteger(current_vaddr), GetInteger(src_addr), size);
350 ZeroBlock(process, dest_addr, copy_amount); 368 ZeroBlock(dest_addr, copy_amount);
351 }, 369 },
352 [&](const std::size_t copy_amount, const u8* const src_ptr) { 370 [&](const std::size_t copy_amount, const u8* const src_ptr) {
353 WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount); 371 WriteBlockImpl<false>(dest_addr, src_ptr, copy_amount);
354 }, 372 },
355 [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, 373 [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
356 u8* const host_ptr) { 374 u8* const host_ptr) {
357 HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount); 375 HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
358 WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount); 376 WriteBlockImpl<false>(dest_addr, host_ptr, copy_amount);
359 }, 377 },
360 [&](const std::size_t copy_amount) { 378 [&](const std::size_t copy_amount) {
361 dest_addr += copy_amount; 379 dest_addr += copy_amount;
@@ -364,13 +382,13 @@ struct Memory::Impl {
364 } 382 }
365 383
366 template <typename Callback> 384 template <typename Callback>
367 Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 385 Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size,
368 std::size_t size, Callback&& cb) { 386 Callback&& cb) {
369 class InvalidMemoryException : public std::exception {}; 387 class InvalidMemoryException : public std::exception {};
370 388
371 try { 389 try {
372 WalkBlock( 390 WalkBlock(
373 process, dest_addr, size, 391 dest_addr, size,
374 [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) { 392 [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
375 LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", 393 LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
376 GetInteger(current_vaddr)); 394 GetInteger(current_vaddr));
@@ -387,41 +405,38 @@ struct Memory::Impl {
387 return ResultSuccess; 405 return ResultSuccess;
388 } 406 }
389 407
390 Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 408 Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
391 std::size_t size) {
392 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, 409 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
393 const std::size_t block_size) { 410 const std::size_t block_size) {
394 // dc ivac: Invalidate to point of coherency 411 // dc ivac: Invalidate to point of coherency
395 // GPU flush -> CPU invalidate 412 // GPU flush -> CPU invalidate
396 HandleRasterizerDownload(GetInteger(current_vaddr), block_size); 413 HandleRasterizerDownload(GetInteger(current_vaddr), block_size);
397 }; 414 };
398 return PerformCacheOperation(process, dest_addr, size, on_rasterizer); 415 return PerformCacheOperation(dest_addr, size, on_rasterizer);
399 } 416 }
400 417
401 Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 418 Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
402 std::size_t size) {
403 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, 419 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
404 const std::size_t block_size) { 420 const std::size_t block_size) {
405 // dc cvac: Store to point of coherency 421 // dc cvac: Store to point of coherency
406 // CPU flush -> GPU invalidate 422 // CPU flush -> GPU invalidate
407 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); 423 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
408 }; 424 };
409 return PerformCacheOperation(process, dest_addr, size, on_rasterizer); 425 return PerformCacheOperation(dest_addr, size, on_rasterizer);
410 } 426 }
411 427
412 Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 428 Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
413 std::size_t size) {
414 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, 429 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
415 const std::size_t block_size) { 430 const std::size_t block_size) {
416 // dc civac: Store to point of coherency, and invalidate from cache 431 // dc civac: Store to point of coherency, and invalidate from cache
417 // CPU flush -> GPU invalidate 432 // CPU flush -> GPU invalidate
418 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); 433 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
419 }; 434 };
420 return PerformCacheOperation(process, dest_addr, size, on_rasterizer); 435 return PerformCacheOperation(dest_addr, size, on_rasterizer);
421 } 436 }
422 437
423 void MarkRegionDebug(u64 vaddr, u64 size, bool debug) { 438 void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
424 if (vaddr == 0) { 439 if (vaddr == 0 || !AddressSpaceContains(*current_page_table, vaddr, size)) {
425 return; 440 return;
426 } 441 }
427 442
@@ -448,7 +463,7 @@ struct Memory::Impl {
448 break; 463 break;
449 case Common::PageType::Memory: 464 case Common::PageType::Memory:
450 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( 465 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
451 nullptr, Common::PageType::DebugMemory); 466 0, Common::PageType::DebugMemory);
452 break; 467 break;
453 default: 468 default:
454 UNREACHABLE(); 469 UNREACHABLE();
@@ -466,7 +481,8 @@ struct Memory::Impl {
466 case Common::PageType::DebugMemory: { 481 case Common::PageType::DebugMemory: {
467 u8* const pointer{GetPointerFromDebugMemory(vaddr & ~YUZU_PAGEMASK)}; 482 u8* const pointer{GetPointerFromDebugMemory(vaddr & ~YUZU_PAGEMASK)};
468 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( 483 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
469 pointer - (vaddr & ~YUZU_PAGEMASK), Common::PageType::Memory); 484 reinterpret_cast<uintptr_t>(pointer) - (vaddr & ~YUZU_PAGEMASK),
485 Common::PageType::Memory);
470 break; 486 break;
471 } 487 }
472 default: 488 default:
@@ -477,7 +493,7 @@ struct Memory::Impl {
477 } 493 }
478 494
479 void RasterizerMarkRegionCached(u64 vaddr, u64 size, bool cached) { 495 void RasterizerMarkRegionCached(u64 vaddr, u64 size, bool cached) {
480 if (vaddr == 0) { 496 if (vaddr == 0 || !AddressSpaceContains(*current_page_table, vaddr, size)) {
481 return; 497 return;
482 } 498 }
483 499
@@ -506,7 +522,7 @@ struct Memory::Impl {
506 case Common::PageType::DebugMemory: 522 case Common::PageType::DebugMemory:
507 case Common::PageType::Memory: 523 case Common::PageType::Memory:
508 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( 524 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
509 nullptr, Common::PageType::RasterizerCachedMemory); 525 0, Common::PageType::RasterizerCachedMemory);
510 break; 526 break;
511 case Common::PageType::RasterizerCachedMemory: 527 case Common::PageType::RasterizerCachedMemory:
512 // There can be more than one GPU region mapped per CPU region, so it's common 528 // There can be more than one GPU region mapped per CPU region, so it's common
@@ -534,10 +550,11 @@ struct Memory::Impl {
534 // pagetable after unmapping a VMA. In that case the underlying VMA will no 550 // pagetable after unmapping a VMA. In that case the underlying VMA will no
535 // longer exist, and we should just leave the pagetable entry blank. 551 // longer exist, and we should just leave the pagetable entry blank.
536 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( 552 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
537 nullptr, Common::PageType::Unmapped); 553 0, Common::PageType::Unmapped);
538 } else { 554 } else {
539 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( 555 current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store(
540 pointer - (vaddr & ~YUZU_PAGEMASK), Common::PageType::Memory); 556 reinterpret_cast<uintptr_t>(pointer) - (vaddr & ~YUZU_PAGEMASK),
557 Common::PageType::Memory);
541 } 558 }
542 break; 559 break;
543 } 560 }
@@ -584,7 +601,7 @@ struct Memory::Impl {
584 "Mapping memory page without a pointer @ {:016x}", base * YUZU_PAGESIZE); 601 "Mapping memory page without a pointer @ {:016x}", base * YUZU_PAGESIZE);
585 602
586 while (base != end) { 603 while (base != end) {
587 page_table.pointers[base].Store(nullptr, type); 604 page_table.pointers[base].Store(0, type);
588 page_table.backing_addr[base] = 0; 605 page_table.backing_addr[base] = 0;
589 page_table.blocks[base] = 0; 606 page_table.blocks[base] = 0;
590 base += 1; 607 base += 1;
@@ -593,7 +610,8 @@ struct Memory::Impl {
593 auto orig_base = base; 610 auto orig_base = base;
594 while (base != end) { 611 while (base != end) {
595 auto host_ptr = 612 auto host_ptr =
596 system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS); 613 reinterpret_cast<uintptr_t>(system.DeviceMemory().GetPointer<u8>(target)) -
614 (base << YUZU_PAGEBITS);
597 auto backing = GetInteger(target) - (base << YUZU_PAGEBITS); 615 auto backing = GetInteger(target) - (base << YUZU_PAGEBITS);
598 page_table.pointers[base].Store(host_ptr, type); 616 page_table.pointers[base].Store(host_ptr, type);
599 page_table.backing_addr[base] = backing; 617 page_table.backing_addr[base] = backing;
@@ -612,15 +630,15 @@ struct Memory::Impl {
612 // AARCH64 masks the upper 16 bit of all memory accesses 630 // AARCH64 masks the upper 16 bit of all memory accesses
613 vaddr = vaddr & 0xffffffffffffULL; 631 vaddr = vaddr & 0xffffffffffffULL;
614 632
615 if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { 633 if (!AddressSpaceContains(*current_page_table, vaddr, 1)) [[unlikely]] {
616 on_unmapped(); 634 on_unmapped();
617 return nullptr; 635 return nullptr;
618 } 636 }
619 637
620 // Avoid adding any extra logic to this fast-path block 638 // Avoid adding any extra logic to this fast-path block
621 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw(); 639 const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw();
622 if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { 640 if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
623 return &pointer[vaddr]; 641 return reinterpret_cast<u8*>(pointer + vaddr);
624 } 642 }
625 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) { 643 switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
626 case Common::PageType::Unmapped: 644 case Common::PageType::Unmapped:
@@ -808,13 +826,13 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b
808 826
809bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { 827bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
810 const Kernel::KProcess& process = *system.ApplicationProcess(); 828 const Kernel::KProcess& process = *system.ApplicationProcess();
811 const auto& page_table = process.PageTable().PageTableImpl(); 829 const auto& page_table = process.GetPageTable().PageTableImpl();
812 const size_t page = vaddr >> YUZU_PAGEBITS; 830 const size_t page = vaddr >> YUZU_PAGEBITS;
813 if (page >= page_table.pointers.size()) { 831 if (page >= page_table.pointers.size()) {
814 return false; 832 return false;
815 } 833 }
816 const auto [pointer, type] = page_table.pointers[page].PointerType(); 834 const auto [pointer, type] = page_table.pointers[page].PointerType();
817 return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory || 835 return pointer != 0 || type == Common::PageType::RasterizerCachedMemory ||
818 type == Common::PageType::DebugMemory; 836 type == Common::PageType::DebugMemory;
819} 837}
820 838
@@ -899,14 +917,14 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le
899 return impl->ReadCString(vaddr, max_length); 917 return impl->ReadCString(vaddr, max_length);
900} 918}
901 919
902void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, 920bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
903 const std::size_t size) { 921 const std::size_t size) {
904 impl->ReadBlock(src_addr, dest_buffer, size); 922 return impl->ReadBlock(src_addr, dest_buffer, size);
905} 923}
906 924
907void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, 925bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
908 const std::size_t size) { 926 const std::size_t size) {
909 impl->ReadBlockUnsafe(src_addr, dest_buffer, size); 927 return impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
910} 928}
911 929
912const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const { 930const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
@@ -917,23 +935,23 @@ u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) {
917 return impl->GetSpan(src_addr, size); 935 return impl->GetSpan(src_addr, size);
918} 936}
919 937
920void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, 938bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
921 const std::size_t size) { 939 const std::size_t size) {
922 impl->WriteBlock(dest_addr, src_buffer, size); 940 return impl->WriteBlock(dest_addr, src_buffer, size);
923} 941}
924 942
925void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, 943bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
926 const std::size_t size) { 944 const std::size_t size) {
927 impl->WriteBlockUnsafe(dest_addr, src_buffer, size); 945 return impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
928} 946}
929 947
930void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, 948bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
931 const std::size_t size) { 949 const std::size_t size) {
932 impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size); 950 return impl->CopyBlock(dest_addr, src_addr, size);
933} 951}
934 952
935void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) { 953bool Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
936 impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size); 954 return impl->ZeroBlock(dest_addr, size);
937} 955}
938 956
939void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) { 957void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) {
@@ -941,15 +959,15 @@ void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers
941} 959}
942 960
943Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { 961Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
944 return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size); 962 return impl->InvalidateDataCache(dest_addr, size);
945} 963}
946 964
947Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { 965Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
948 return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size); 966 return impl->StoreDataCache(dest_addr, size);
949} 967}
950 968
951Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { 969Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
952 return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size); 970 return impl->FlushDataCache(dest_addr, size);
953} 971}
954 972
955void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) { 973void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {
diff --git a/src/core/memory.h b/src/core/memory.h
index ea33c769c..2eb61ffd3 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -24,7 +24,6 @@ class GPUDirtyMemoryManager;
24} // namespace Core 24} // namespace Core
25 25
26namespace Kernel { 26namespace Kernel {
27class PhysicalMemory;
28class KProcess; 27class KProcess;
29} // namespace Kernel 28} // namespace Kernel
30 29
@@ -330,7 +329,7 @@ public:
330 * @post The range [dest_buffer, size) contains the read bytes from the 329 * @post The range [dest_buffer, size) contains the read bytes from the
331 * current process' address space. 330 * current process' address space.
332 */ 331 */
333 void ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); 332 bool ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
334 333
335 /** 334 /**
336 * Reads a contiguous block of bytes from the current process' address space. 335 * Reads a contiguous block of bytes from the current process' address space.
@@ -349,7 +348,7 @@ public:
349 * @post The range [dest_buffer, size) contains the read bytes from the 348 * @post The range [dest_buffer, size) contains the read bytes from the
350 * current process' address space. 349 * current process' address space.
351 */ 350 */
352 void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); 351 bool ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size);
353 352
354 const u8* GetSpan(const VAddr src_addr, const std::size_t size) const; 353 const u8* GetSpan(const VAddr src_addr, const std::size_t size) const;
355 u8* GetSpan(const VAddr src_addr, const std::size_t size); 354 u8* GetSpan(const VAddr src_addr, const std::size_t size);
@@ -373,7 +372,7 @@ public:
373 * and will mark that region as invalidated to caches that the active 372 * and will mark that region as invalidated to caches that the active
374 * graphics backend may be maintaining over the course of execution. 373 * graphics backend may be maintaining over the course of execution.
375 */ 374 */
376 void WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size); 375 bool WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size);
377 376
378 /** 377 /**
379 * Writes a range of bytes into the current process' address space at the specified 378 * Writes a range of bytes into the current process' address space at the specified
@@ -391,7 +390,7 @@ public:
391 * will be ignored and an error will be logged. 390 * will be ignored and an error will be logged.
392 * 391 *
393 */ 392 */
394 void WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer, 393 bool WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer,
395 std::size_t size); 394 std::size_t size);
396 395
397 /** 396 /**
@@ -405,7 +404,7 @@ public:
405 * @post The range [dest_addr, size) within the process' address space contains the 404 * @post The range [dest_addr, size) within the process' address space contains the
406 * same data within the range [src_addr, size). 405 * same data within the range [src_addr, size).
407 */ 406 */
408 void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, 407 bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
409 std::size_t size); 408 std::size_t size);
410 409
411 /** 410 /**
@@ -418,7 +417,7 @@ public:
418 * @post The range [dest_addr, size) within the process' address space contains the 417 * @post The range [dest_addr, size) within the process' address space contains the
419 * value 0. 418 * value 0.
420 */ 419 */
421 void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size); 420 bool ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size);
422 421
423 /** 422 /**
424 * Invalidates a range of bytes within the current process' address space at the specified 423 * Invalidates a range of bytes within the current process' address space at the specified
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 8742dd164..7b52f61a7 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -199,7 +199,7 @@ void CheatEngine::Initialize() {
199 metadata.process_id = system.ApplicationProcess()->GetProcessId(); 199 metadata.process_id = system.ApplicationProcess()->GetProcessId();
200 metadata.title_id = system.GetApplicationProcessProgramID(); 200 metadata.title_id = system.GetApplicationProcessProgramID();
201 201
202 const auto& page_table = system.ApplicationProcess()->PageTable(); 202 const auto& page_table = system.ApplicationProcess()->GetPageTable();
203 metadata.heap_extents = { 203 metadata.heap_extents = {
204 .base = GetInteger(page_table.GetHeapRegionStart()), 204 .base = GetInteger(page_table.GetHeapRegionStart()),
205 .size = page_table.GetHeapRegionSize(), 205 .size = page_table.GetHeapRegionSize(),
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index 6c3dc7369..b5b3e7eda 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -117,8 +117,8 @@ json GetProcessorStateDataAuto(Core::System& system) {
117 arm.SaveContext(context); 117 arm.SaveContext(context);
118 118
119 return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32", 119 return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32",
120 GetInteger(process->PageTable().GetCodeRegionStart()), context.sp, 120 GetInteger(process->GetPageTable().GetCodeRegionStart()),
121 context.pc, context.pstate, context.cpu_registers); 121 context.sp, context.pc, context.pstate, context.cpu_registers);
122} 122}
123 123
124json GetBacktraceData(Core::System& system) { 124json GetBacktraceData(Core::System& system) {
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
index d0b145860..07cabca43 100644
--- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
+++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
@@ -14,12 +14,12 @@
14// 14//
15 15
16#include <deque> 16#include <deque>
17#include <map>
17#include <span> 18#include <span>
19#include <unordered_map>
18#include <variant> 20#include <variant>
19#include <vector> 21#include <vector>
20 22
21#include <boost/container/flat_map.hpp>
22
23#include "shader_recompiler/frontend/ir/basic_block.h" 23#include "shader_recompiler/frontend/ir/basic_block.h"
24#include "shader_recompiler/frontend/ir/opcodes.h" 24#include "shader_recompiler/frontend/ir/opcodes.h"
25#include "shader_recompiler/frontend/ir/pred.h" 25#include "shader_recompiler/frontend/ir/pred.h"
@@ -52,7 +52,7 @@ struct IndirectBranchVariable {
52 52
53using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, 53using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
54 OverflowFlagTag, GotoVariable, IndirectBranchVariable>; 54 OverflowFlagTag, GotoVariable, IndirectBranchVariable>;
55using ValueMap = boost::container::flat_map<IR::Block*, IR::Value>; 55using ValueMap = std::unordered_map<IR::Block*, IR::Value>;
56 56
57struct DefTable { 57struct DefTable {
58 const IR::Value& Def(IR::Block* block, IR::Reg variable) { 58 const IR::Value& Def(IR::Block* block, IR::Reg variable) {
@@ -112,7 +112,7 @@ struct DefTable {
112 } 112 }
113 113
114 std::array<ValueMap, IR::NUM_USER_PREDS> preds; 114 std::array<ValueMap, IR::NUM_USER_PREDS> preds;
115 boost::container::flat_map<u32, ValueMap> goto_vars; 115 std::unordered_map<u32, ValueMap> goto_vars;
116 ValueMap indirect_branch_var; 116 ValueMap indirect_branch_var;
117 ValueMap zero_flag; 117 ValueMap zero_flag;
118 ValueMap sign_flag; 118 ValueMap sign_flag;
@@ -295,8 +295,7 @@ private:
295 return same; 295 return same;
296 } 296 }
297 297
298 boost::container::flat_map<IR::Block*, boost::container::flat_map<Variant, IR::Inst*>> 298 std::unordered_map<IR::Block*, std::map<Variant, IR::Inst*>> incomplete_phis;
299 incomplete_phis;
300 DefTable current_def; 299 DefTable current_def;
301}; 300};
302 301
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 7f79111e0..9b13ccbab 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -275,6 +275,8 @@ add_library(video_core STATIC
275 vulkan_common/nsight_aftermath_tracker.cpp 275 vulkan_common/nsight_aftermath_tracker.cpp
276 vulkan_common/nsight_aftermath_tracker.h 276 vulkan_common/nsight_aftermath_tracker.h
277 vulkan_common/vma.cpp 277 vulkan_common/vma.cpp
278 vulkan_common/vma.h
279 vulkan_common/vulkan.h
278) 280)
279 281
280create_target_directory_groups(video_core) 282create_target_directory_groups(video_core)
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 6ed4b78f2..f0f450edb 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -442,6 +442,11 @@ void BufferCache<P>::UnbindComputeStorageBuffers() {
442template <class P> 442template <class P>
443void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, u32 cbuf_offset, 443void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, u32 cbuf_offset,
444 bool is_written) { 444 bool is_written) {
445 if (ssbo_index >= channel_state->compute_storage_buffers.size()) [[unlikely]] {
446 LOG_ERROR(HW_GPU, "Storage buffer index {} exceeds maximum storage buffer count",
447 ssbo_index);
448 return;
449 }
445 channel_state->enabled_compute_storage_buffers |= 1U << ssbo_index; 450 channel_state->enabled_compute_storage_buffers |= 1U << ssbo_index;
446 channel_state->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index; 451 channel_state->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index;
447 452
@@ -464,6 +469,11 @@ void BufferCache<P>::UnbindComputeTextureBuffers() {
464template <class P> 469template <class P>
465void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, 470void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size,
466 PixelFormat format, bool is_written, bool is_image) { 471 PixelFormat format, bool is_written, bool is_image) {
472 if (tbo_index >= channel_state->compute_texture_buffers.size()) [[unlikely]] {
473 LOG_ERROR(HW_GPU, "Texture buffer index {} exceeds maximum texture buffer count",
474 tbo_index);
475 return;
476 }
467 channel_state->enabled_compute_texture_buffers |= 1U << tbo_index; 477 channel_state->enabled_compute_texture_buffers |= 1U << tbo_index;
468 channel_state->written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index; 478 channel_state->written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index;
469 if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { 479 if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) {
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h
index 460fc7551..0b7135d49 100644
--- a/src/video_core/buffer_cache/buffer_cache_base.h
+++ b/src/video_core/buffer_cache/buffer_cache_base.h
@@ -67,7 +67,7 @@ constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4;
67constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18; 67constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18;
68constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8; 68constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8;
69constexpr u32 NUM_STORAGE_BUFFERS = 16; 69constexpr u32 NUM_STORAGE_BUFFERS = 16;
70constexpr u32 NUM_TEXTURE_BUFFERS = 16; 70constexpr u32 NUM_TEXTURE_BUFFERS = 32;
71constexpr u32 NUM_STAGES = 5; 71constexpr u32 NUM_STAGES = 5;
72 72
73using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>; 73using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>;
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h
index 1528cc1dd..7047e2e63 100644
--- a/src/video_core/query_cache.h
+++ b/src/video_core/query_cache.h
@@ -103,7 +103,9 @@ public:
103 explicit QueryCacheBase(VideoCore::RasterizerInterface& rasterizer_, 103 explicit QueryCacheBase(VideoCore::RasterizerInterface& rasterizer_,
104 Core::Memory::Memory& cpu_memory_) 104 Core::Memory::Memory& cpu_memory_)
105 : rasterizer{rasterizer_}, 105 : rasterizer{rasterizer_},
106 cpu_memory{cpu_memory_}, streams{{CounterStream{static_cast<QueryCache&>(*this), 106 // Use reinterpret_cast instead of static_cast as workaround for
107 // UBSan bug (https://github.com/llvm/llvm-project/issues/59060)
108 cpu_memory{cpu_memory_}, streams{{CounterStream{reinterpret_cast<QueryCache&>(*this),
107 VideoCore::QueryType::SamplesPassed}}} { 109 VideoCore::QueryType::SamplesPassed}}} {
108 (void)slot_async_jobs.insert(); // Null value 110 (void)slot_async_jobs.insert(); // Null value
109 } 111 }
diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp
index 4a197d65d..f200a650f 100644
--- a/src/video_core/rasterizer_accelerated.cpp
+++ b/src/video_core/rasterizer_accelerated.cpp
@@ -13,7 +13,8 @@ namespace VideoCore {
13 13
14using namespace Core::Memory; 14using namespace Core::Memory;
15 15
16RasterizerAccelerated::RasterizerAccelerated(Memory& cpu_memory_) : cpu_memory{cpu_memory_} {} 16RasterizerAccelerated::RasterizerAccelerated(Memory& cpu_memory_)
17 : cached_pages(std::make_unique<CachedPages>()), cpu_memory{cpu_memory_} {}
17 18
18RasterizerAccelerated::~RasterizerAccelerated() = default; 19RasterizerAccelerated::~RasterizerAccelerated() = default;
19 20
@@ -26,7 +27,7 @@ void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int del
26 std::atomic_thread_fence(std::memory_order_acquire); 27 std::atomic_thread_fence(std::memory_order_acquire);
27 const u64 page_end = Common::DivCeil(addr + size, YUZU_PAGESIZE); 28 const u64 page_end = Common::DivCeil(addr + size, YUZU_PAGESIZE);
28 for (u64 page = addr >> YUZU_PAGEBITS; page != page_end; ++page) { 29 for (u64 page = addr >> YUZU_PAGEBITS; page != page_end; ++page) {
29 std::atomic_uint16_t& count = cached_pages.at(page >> 2).Count(page); 30 std::atomic_uint16_t& count = cached_pages->at(page >> 2).Count(page);
30 31
31 if (delta > 0) { 32 if (delta > 0) {
32 ASSERT_MSG(count.load(std::memory_order::relaxed) < UINT16_MAX, "Count may overflow!"); 33 ASSERT_MSG(count.load(std::memory_order::relaxed) < UINT16_MAX, "Count may overflow!");
diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h
index 7118b8aff..e6c0ea87a 100644
--- a/src/video_core/rasterizer_accelerated.h
+++ b/src/video_core/rasterizer_accelerated.h
@@ -41,7 +41,8 @@ private:
41 }; 41 };
42 static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!"); 42 static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!");
43 43
44 std::array<CacheEntry, 0x2000000> cached_pages; 44 using CachedPages = std::array<CacheEntry, 0x2000000>;
45 std::unique_ptr<CachedPages> cached_pages;
45 Core::Memory::Memory& cpu_memory; 46 Core::Memory::Memory& cpu_memory;
46}; 47};
47 48
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index ad3b29f0e..31928bb94 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -566,7 +566,7 @@ void BlitScreen::CreateDescriptorPool() {
566 const VkDescriptorPoolCreateInfo ci{ 566 const VkDescriptorPoolCreateInfo ci{
567 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 567 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
568 .pNext = nullptr, 568 .pNext = nullptr,
569 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 569 .flags = 0,
570 .maxSets = static_cast<u32>(image_count), 570 .maxSets = static_cast<u32>(image_count),
571 .poolSizeCount = static_cast<u32>(pool_sizes.size()), 571 .poolSizeCount = static_cast<u32>(pool_sizes.size()),
572 .pPoolSizes = pool_sizes.data(), 572 .pPoolSizes = pool_sizes.data(),
@@ -576,7 +576,7 @@ void BlitScreen::CreateDescriptorPool() {
576 const VkDescriptorPoolCreateInfo ci_aa{ 576 const VkDescriptorPoolCreateInfo ci_aa{
577 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 577 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
578 .pNext = nullptr, 578 .pNext = nullptr,
579 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 579 .flags = 0,
580 .maxSets = static_cast<u32>(image_count), 580 .maxSets = static_cast<u32>(image_count),
581 .poolSizeCount = static_cast<u32>(pool_sizes_aa.size()), 581 .poolSizeCount = static_cast<u32>(pool_sizes_aa.size()),
582 .pPoolSizes = pool_sizes_aa.data(), 582 .pPoolSizes = pool_sizes_aa.data(),
diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
index b5ae6443c..6048a301f 100644
--- a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
@@ -77,7 +77,7 @@ static void AllocatePool(const Device& device, DescriptorBank& bank) {
77 bank.pools.push_back(device.GetLogical().CreateDescriptorPool({ 77 bank.pools.push_back(device.GetLogical().CreateDescriptorPool({
78 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 78 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
79 .pNext = nullptr, 79 .pNext = nullptr,
80 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 80 .flags = 0,
81 .maxSets = sets_per_pool, 81 .maxSets = sets_per_pool,
82 .poolSizeCount = static_cast<u32>(pool_cursor), 82 .poolSizeCount = static_cast<u32>(pool_cursor),
83 .pPoolSizes = std::data(pool_sizes), 83 .pPoolSizes = std::data(pool_sizes),
diff --git a/src/video_core/renderer_vulkan/vk_fsr.cpp b/src/video_core/renderer_vulkan/vk_fsr.cpp
index 9bcdca2fb..ce8f3f3c2 100644
--- a/src/video_core/renderer_vulkan/vk_fsr.cpp
+++ b/src/video_core/renderer_vulkan/vk_fsr.cpp
@@ -150,7 +150,7 @@ void FSR::CreateDescriptorPool() {
150 const VkDescriptorPoolCreateInfo ci{ 150 const VkDescriptorPoolCreateInfo ci{
151 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 151 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
152 .pNext = nullptr, 152 .pNext = nullptr,
153 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 153 .flags = 0,
154 .maxSets = static_cast<u32>(image_count * 2), 154 .maxSets = static_cast<u32>(image_count * 2),
155 .poolSizeCount = static_cast<u32>(pool_sizes.size()), 155 .poolSizeCount = static_cast<u32>(pool_sizes.size()),
156 .pPoolSizes = pool_sizes.data(), 156 .pPoolSizes = pool_sizes.data(),
diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp
index 460d8d59d..04a51f2d1 100644
--- a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp
+++ b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp
@@ -62,7 +62,7 @@ void TurboMode::Run(std::stop_token stop_token) {
62 auto descriptor_pool = dld.CreateDescriptorPool(VkDescriptorPoolCreateInfo{ 62 auto descriptor_pool = dld.CreateDescriptorPool(VkDescriptorPoolCreateInfo{
63 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 63 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
64 .pNext = nullptr, 64 .pNext = nullptr,
65 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 65 .flags = 0,
66 .maxSets = 1, 66 .maxSets = 1,
67 .poolSizeCount = 1, 67 .poolSizeCount = 1,
68 .pPoolSizes = &pool_size, 68 .pPoolSizes = &pool_size,
diff --git a/src/video_core/vulkan_common/vma.cpp b/src/video_core/vulkan_common/vma.cpp
index 1fe2cf52b..addf10762 100644
--- a/src/video_core/vulkan_common/vma.cpp
+++ b/src/video_core/vulkan_common/vma.cpp
@@ -2,7 +2,5 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#define VMA_IMPLEMENTATION 4#define VMA_IMPLEMENTATION
5#define VMA_STATIC_VULKAN_FUNCTIONS 0
6#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
7 5
8#include <vk_mem_alloc.h> \ No newline at end of file 6#include "video_core/vulkan_common/vma.h"
diff --git a/src/video_core/vulkan_common/vma.h b/src/video_core/vulkan_common/vma.h
new file mode 100644
index 000000000..6e25aa1bd
--- /dev/null
+++ b/src/video_core/vulkan_common/vma.h
@@ -0,0 +1,11 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "video_core/vulkan_common/vulkan.h"
7
8#define VMA_STATIC_VULKAN_FUNCTIONS 0
9#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
10
11#include <vk_mem_alloc.h>
diff --git a/src/video_core/vulkan_common/vulkan.h b/src/video_core/vulkan_common/vulkan.h
new file mode 100644
index 000000000..3fa963647
--- /dev/null
+++ b/src/video_core/vulkan_common/vulkan.h
@@ -0,0 +1,13 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#define VK_NO_PROTOTYPES
7#ifdef _WIN32
8#define VK_USE_PLATFORM_WIN32_KHR
9#elif defined(__APPLE__)
10#define VK_USE_PLATFORM_METAL_EXT
11#endif
12
13#include <vulkan/vulkan.h>
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index e04852e01..bd67e27ed 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -15,6 +15,7 @@
15#include "common/polyfill_ranges.h" 15#include "common/polyfill_ranges.h"
16#include "common/settings.h" 16#include "common/settings.h"
17#include "video_core/vulkan_common/nsight_aftermath_tracker.h" 17#include "video_core/vulkan_common/nsight_aftermath_tracker.h"
18#include "video_core/vulkan_common/vma.h"
18#include "video_core/vulkan_common/vulkan_device.h" 19#include "video_core/vulkan_common/vulkan_device.h"
19#include "video_core/vulkan_common/vulkan_wrapper.h" 20#include "video_core/vulkan_common/vulkan_wrapper.h"
20 21
@@ -22,8 +23,6 @@
22#include <adrenotools/bcenabler.h> 23#include <adrenotools/bcenabler.h>
23#endif 24#endif
24 25
25#include <vk_mem_alloc.h>
26
27namespace Vulkan { 26namespace Vulkan {
28using namespace Common::Literals; 27using namespace Common::Literals;
29namespace { 28namespace {
@@ -526,6 +525,13 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
526 dynamic_state3_enables = false; 525 dynamic_state3_enables = false;
527 } 526 }
528 } 527 }
528 if (extensions.extended_dynamic_state3 && is_amd_driver) {
529 LOG_WARNING(Render_Vulkan,
530 "AMD drivers have broken extendedDynamicState3ColorBlendEquation");
531 features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
532 features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
533 dynamic_state3_blending = false;
534 }
529 if (extensions.vertex_input_dynamic_state && is_radv) { 535 if (extensions.vertex_input_dynamic_state && is_radv) {
530 // TODO(ameerj): Blacklist only offending driver versions 536 // TODO(ameerj): Blacklist only offending driver versions
531 // TODO(ameerj): Confirm if RDNA1 is affected 537 // TODO(ameerj): Confirm if RDNA1 is affected
@@ -554,14 +560,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
554 } 560 }
555 561
556 sets_per_pool = 64; 562 sets_per_pool = 64;
557 if (extensions.extended_dynamic_state3 && is_amd_driver &&
558 properties.properties.driverVersion >= VK_MAKE_API_VERSION(0, 2, 0, 270)) {
559 LOG_WARNING(Render_Vulkan,
560 "AMD drivers after 23.5.2 have broken extendedDynamicState3ColorBlendEquation");
561 features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
562 features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
563 dynamic_state3_blending = false;
564 }
565 if (is_amd_driver) { 563 if (is_amd_driver) {
566 // AMD drivers need a higher amount of Sets per Pool in certain circumstances like in XC2. 564 // AMD drivers need a higher amount of Sets per Pool in certain circumstances like in XC2.
567 sets_per_pool = 96; 565 sets_per_pool = 96;
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
index 42f3ee0b4..3ef381a38 100644
--- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
+++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
@@ -11,12 +11,11 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "common/polyfill_ranges.h" 13#include "common/polyfill_ranges.h"
14#include "video_core/vulkan_common/vma.h"
14#include "video_core/vulkan_common/vulkan_device.h" 15#include "video_core/vulkan_common/vulkan_device.h"
15#include "video_core/vulkan_common/vulkan_memory_allocator.h" 16#include "video_core/vulkan_common/vulkan_memory_allocator.h"
16#include "video_core/vulkan_common/vulkan_wrapper.h" 17#include "video_core/vulkan_common/vulkan_wrapper.h"
17 18
18#include <vk_mem_alloc.h>
19
20namespace Vulkan { 19namespace Vulkan {
21namespace { 20namespace {
22struct Range { 21struct Range {
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp
index 2fa29793a..78e5a248f 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.cpp
+++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp
@@ -9,11 +9,9 @@
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12 12#include "video_core/vulkan_common/vma.h"
13#include "video_core/vulkan_common/vulkan_wrapper.h" 13#include "video_core/vulkan_common/vulkan_wrapper.h"
14 14
15#include <vk_mem_alloc.h>
16
17namespace Vulkan::vk { 15namespace Vulkan::vk {
18 16
19namespace { 17namespace {
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h
index 32bd75ad8..3089c3d41 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.h
+++ b/src/video_core/vulkan_common/vulkan_wrapper.h
@@ -12,13 +12,8 @@
12#include <utility> 12#include <utility>
13#include <vector> 13#include <vector>
14 14
15#define VK_NO_PROTOTYPES 15#include "common/common_types.h"
16#ifdef _WIN32 16#include "video_core/vulkan_common/vulkan.h"
17#define VK_USE_PLATFORM_WIN32_KHR
18#elif defined(__APPLE__)
19#define VK_USE_PLATFORM_METAL_EXT
20#endif
21#include <vulkan/vulkan.h>
22 17
23// Sanitize macros 18// Sanitize macros
24#ifdef CreateEvent 19#ifdef CreateEvent
@@ -28,8 +23,6 @@
28#undef CreateSemaphore 23#undef CreateSemaphore
29#endif 24#endif
30 25
31#include "common/common_types.h"
32
33#ifdef _MSC_VER 26#ifdef _MSC_VER
34#pragma warning(disable : 26812) // Disable prefer enum class over enum 27#pragma warning(disable : 26812) // Disable prefer enum class over enum
35#endif 28#endif
diff --git a/src/yuzu/discord_impl.cpp b/src/yuzu/discord_impl.cpp
index ac2fc1bcb..57b50abd0 100644
--- a/src/yuzu/discord_impl.cpp
+++ b/src/yuzu/discord_impl.cpp
@@ -3,9 +3,14 @@
3 3
4#include <chrono> 4#include <chrono>
5#include <string> 5#include <string>
6
7#include <QEventLoop>
8#include <QNetworkAccessManager>
9#include <QNetworkReply>
10
6#include <discord_rpc.h> 11#include <discord_rpc.h>
7#include <fmt/format.h> 12#include <fmt/format.h>
8#include <httplib.h> 13
9#include "common/common_types.h" 14#include "common/common_types.h"
10#include "common/string_util.h" 15#include "common/string_util.h"
11#include "core/core.h" 16#include "core/core.h"
@@ -31,7 +36,7 @@ void DiscordImpl::Pause() {
31 Discord_ClearPresence(); 36 Discord_ClearPresence();
32} 37}
33 38
34static std::string GetGameString(const std::string& title) { 39std::string DiscordImpl::GetGameString(const std::string& title) {
35 // Convert to lowercase 40 // Convert to lowercase
36 std::string icon_name = Common::ToLower(title); 41 std::string icon_name = Common::ToLower(title);
37 42
@@ -56,51 +61,56 @@ static std::string GetGameString(const std::string& title) {
56 return icon_name; 61 return icon_name;
57} 62}
58 63
59void DiscordImpl::Update() { 64void DiscordImpl::UpdateGameStatus(bool use_default) {
65 const std::string default_text = "yuzu is an emulator for the Nintendo Switch";
66 const std::string default_image = "yuzu_logo";
67 const std::string url = use_default ? default_image : game_url;
60 s64 start_time = std::chrono::duration_cast<std::chrono::seconds>( 68 s64 start_time = std::chrono::duration_cast<std::chrono::seconds>(
61 std::chrono::system_clock::now().time_since_epoch()) 69 std::chrono::system_clock::now().time_since_epoch())
62 .count(); 70 .count();
71 DiscordRichPresence presence{};
72
73 presence.largeImageKey = url.c_str();
74 presence.largeImageText = game_title.c_str();
75 presence.smallImageKey = default_image.c_str();
76 presence.smallImageText = default_text.c_str();
77 presence.state = game_title.c_str();
78 presence.details = "Currently in game";
79 presence.startTimestamp = start_time;
80 Discord_UpdatePresence(&presence);
81}
82
83void DiscordImpl::Update() {
63 const std::string default_text = "yuzu is an emulator for the Nintendo Switch"; 84 const std::string default_text = "yuzu is an emulator for the Nintendo Switch";
64 const std::string default_image = "yuzu_logo"; 85 const std::string default_image = "yuzu_logo";
65 std::string game_cover_url = "https://yuzu-emu.org";
66 std::string title;
67
68 DiscordRichPresence presence{};
69 86
70 if (system.IsPoweredOn()) { 87 if (system.IsPoweredOn()) {
71 system.GetAppLoader().ReadTitle(title); 88 system.GetAppLoader().ReadTitle(game_title);
72 89
73 // Used to format Icon URL for yuzu website game compatibility page 90 // Used to format Icon URL for yuzu website game compatibility page
74 std::string icon_name = GetGameString(title); 91 std::string icon_name = GetGameString(game_title);
75 92 game_url = fmt::format("https://yuzu-emu.org/images/game/boxart/{}.png", icon_name);
76 // New Check for game cover 93
77 httplib::Client cli(game_cover_url); 94 QNetworkAccessManager manager;
78 cli.set_connection_timeout(std::chrono::seconds(3)); 95 QNetworkRequest request;
79 cli.set_read_timeout(std::chrono::seconds(3)); 96 request.setUrl(QUrl(QString::fromStdString(game_url)));
80 97 request.setTransferTimeout(3000);
81 if (auto res = cli.Head(fmt::format("/images/game/boxart/{}.png", icon_name))) { 98 QNetworkReply* reply = manager.head(request);
82 if (res->status == 200) { 99 QEventLoop request_event_loop;
83 game_cover_url += fmt::format("/images/game/boxart/{}.png", icon_name); 100 QObject::connect(reply, &QNetworkReply::finished, &request_event_loop, &QEventLoop::quit);
84 } else { 101 request_event_loop.exec();
85 game_cover_url = "yuzu_logo"; 102 UpdateGameStatus(reply->error());
86 } 103 return;
87 } else {
88 game_cover_url = "yuzu_logo";
89 }
90
91 presence.largeImageKey = game_cover_url.c_str();
92 presence.largeImageText = title.c_str();
93
94 presence.smallImageKey = default_image.c_str();
95 presence.smallImageText = default_text.c_str();
96 presence.state = title.c_str();
97 presence.details = "Currently in game";
98 } else {
99 presence.largeImageKey = default_image.c_str();
100 presence.largeImageText = default_text.c_str();
101 presence.details = "Currently not in game";
102 } 104 }
103 105
106 s64 start_time = std::chrono::duration_cast<std::chrono::seconds>(
107 std::chrono::system_clock::now().time_since_epoch())
108 .count();
109
110 DiscordRichPresence presence{};
111 presence.largeImageKey = default_image.c_str();
112 presence.largeImageText = default_text.c_str();
113 presence.details = "Currently not in game";
104 presence.startTimestamp = start_time; 114 presence.startTimestamp = start_time;
105 Discord_UpdatePresence(&presence); 115 Discord_UpdatePresence(&presence);
106} 116}
diff --git a/src/yuzu/discord_impl.h b/src/yuzu/discord_impl.h
index 84710b9c6..eb6cf9ae0 100644
--- a/src/yuzu/discord_impl.h
+++ b/src/yuzu/discord_impl.h
@@ -19,6 +19,13 @@ public:
19 void Pause() override; 19 void Pause() override;
20 void Update() override; 20 void Update() override;
21 21
22private:
23 std::string GetGameString(const std::string& title);
24 void UpdateGameStatus(bool use_default);
25
26 std::string game_url{};
27 std::string game_title{};
28
22 Core::System& system; 29 Core::System& system;
23}; 30};
24 31
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index 63326968b..9404365b4 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -235,7 +235,7 @@ GameListWorker::~GameListWorker() = default;
235void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { 235void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
236 using namespace FileSys; 236 using namespace FileSys;
237 237
238 const auto& cache = dynamic_cast<ContentProviderUnion&>(system.GetContentProvider()); 238 const auto& cache = system.GetContentProviderUnion();
239 239
240 auto installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application, 240 auto installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application,
241 ContentRecordType::Program); 241 ContentRecordType::Program);
@@ -265,7 +265,11 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
265 std::vector<u8> icon; 265 std::vector<u8> icon;
266 std::string name; 266 std::string name;
267 u64 program_id = 0; 267 u64 program_id = 0;
268 loader->ReadProgramId(program_id); 268 const auto result = loader->ReadProgramId(program_id);
269
270 if (result != Loader::ResultStatus::Success) {
271 continue;
272 }
269 273
270 const PatchManager patch{program_id, system.GetFileSystemController(), 274 const PatchManager patch{program_id, system.GetFileSystemController(),
271 system.GetContentProvider()}; 275 system.GetContentProvider()};