diff options
Diffstat (limited to 'src')
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: loader->ReadTitle(entry.title); loader->ReadIcon(entry.icon); if (loader->GetFileType() == Loader::FileType::NRO) { - jauto loader_nro = dynamic_cast<Loader::AppLoader_NRO*>(loader.get()); + jauto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get()); entry.isHomebrew = loader_nro->IsHomebrew(); } else { 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 @@ <string name="region_korea">Korea</string> <string name="region_taiwan">Taiwan</string> - <!-- Language Names --> - <string name="language_japanese">Japanisch (日本語)</string> - <string name="language_english">Englisch</string> - <string name="language_french">Französisch (Français)</string> - <string name="langauge_german">Deutsch (German)</string> - <string name="language_italian">Italienisch (Italiano)</string> - <string name="language_spanish">Spanisch (Español)</string> - <string name="language_chinese">Chinesisch (简体中文)</string> - <string name="language_korean">Koreanisch (한국어)</string> - <string name="language_dutch">Niederländisch (Nederlands)</string> - <string name="language_portuguese">Portugiesisch (Português)</string> - <string name="language_russian">Russisch (Русский)</string> - <string name="language_taiwanese">Taiwanesisch (台湾)</string> - <string name="language_british_english">Britisches Englisch</string> - <string name="language_canadian_french">Kanadisches Französisch (Français canadien)</string> - <string name="language_latin_american_spanish">Lateinamerikanisches Spanisch (Español latinoamericano)</string> - <string name="language_simplified_chinese">Vereinfachtes Chinesisch (简体中文)</string> - <string name="language_traditional_chinese">Traditionelles Chinesisch (正體中文)</string> - <string name="language_brazilian_portuguese">Brasilianisches Portugiesisch (Português do Brasil)</string> - <!-- Renderer APIs --> <string name="renderer_vulkan">Vulkan</string> <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 @@ <string name="region_taiwan">Taiwán</string> <!-- Language Names --> - <string name="language_japanese">Japonés (日本語)</string> - <string name="language_english">Inglés (English)</string> - <string name="language_french">Francés (Français)</string> - <string name="langauge_german">Alemán (deutsch)</string> - <string name="language_italian">Italiano (Italiano)</string> - <string name="language_spanish">Español (Español)</string> - <string name="language_chinese">Chino (简体中文)</string> - <string name="language_korean">Coreano (한국어)</string> - <string name="language_dutch">Holandés (nederlands)</string> - <string name="language_portuguese">Portugués (Português)</string> - <string name="language_russian">Ruso (Русский)</string> - <string name="language_taiwanese">Taiwanés (台湾)</string> - <string name="language_british_english">Inglés británico</string> - <string name="language_canadian_french">Francés Canadiense (Français canadien)</string> - <string name="language_latin_american_spanish">Español Latinoamericano (Español latinoamericano)</string> - <string name="language_simplified_chinese">Chino Simplificado (简体中文)</string> - <string name="language_traditional_chinese">Chino tradicional (正體中文)</string> - <string name="language_brazilian_portuguese">Portugués Brasileño (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Taïwan</string> <!-- Language Names --> - <string name="language_japanese">Japonais (日本語)</string> - <string name="language_english">Anglais</string> - <string name="language_french">Français (Français)</string> - <string name="langauge_german">Allemand (Deutsch)</string> - <string name="language_italian">Italien (Italiano)</string> - <string name="language_spanish">Espagnol (Español)</string> - <string name="language_chinese">Chinois (简体中文)</string> - <string name="language_korean">Coréen (한국어)</string> - <string name="language_dutch">Néerlandais (Nederlands)</string> - <string name="language_portuguese">Portugais (Português)</string> - <string name="language_russian">Russe (Русский)</string> - <string name="language_taiwanese">Taïwanais (台湾)</string> - <string name="language_british_english">Anglais Britannique</string> - <string name="language_canadian_french">Français canadien (Français canadien)</string> - <string name="language_latin_american_spanish">Espagnol latino-américain (Español latinoamericano)</string> - <string name="language_simplified_chinese">Chinois simplifié (简体中文)</string> - <string name="language_traditional_chinese">Chinois Traditionnel (正體中文)</string> - <string name="language_brazilian_portuguese">Portugais brésilien (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Taiwan</string> <!-- Language Names --> - <string name="language_japanese">Giapponese (日本語)</string> - <string name="language_english">Inglese (English)</string> - <string name="language_french">Francese (Français)</string> - <string name="langauge_german">Tedesco (Deutsch)</string> - <string name="language_italian">Italiano (Italiano)</string> - <string name="language_spanish">Spagnolo (Español)</string> - <string name="language_chinese">Cinese (简体中文)</string> - <string name="language_korean">Coreano (한국어)</string> - <string name="language_dutch">Olandese (Nederlands)</string> - <string name="language_portuguese">Portoghese (Português)</string> - <string name="language_russian">Russo (Русский)</string> - <string name="language_taiwanese">Taiwanese (台湾)</string> - <string name="language_british_english">Inglese britannico</string> - <string name="language_canadian_french">Francese Canadese (Français canadien)</string> - <string name="language_latin_american_spanish">Spagnolo Latino Americano (Español latinoamericano)</string> - <string name="language_simplified_chinese">Cinese Semplificato (简体中文)</string> - <string name="language_traditional_chinese">Cinese tradizionale (正體中文)</string> - <string name="language_brazilian_portuguese">Portoghese (Português)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">台湾</string> <!-- Language Names --> - <string name="language_japanese">日本語</string> - <string name="language_english">英語</string> - <string name="language_french">フランス語 (Français)</string> - <string name="langauge_german">ドイツ語 (Deutsch)</string> - <string name="language_italian">イタリア語 (Italiano)</string> - <string name="language_spanish">スペイン語 (Español)</string> - <string name="language_chinese">中国語 (简体中文)</string> - <string name="language_korean">韓国語 (한국어)</string> - <string name="language_dutch">オランダ語 (Nederlands)</string> - <string name="language_portuguese">ポルトガル語 (Português)</string> - <string name="language_russian">ロシア語 (Русский)</string> - <string name="language_taiwanese">台湾語 (台湾)</string> - <string name="language_british_english">イギリス英語</string> - <string name="language_canadian_french">フランス語(カナダ) (Français canadien)</string> - <string name="language_latin_american_spanish">スペイン語(ラテンアメリカ) (Español latinoamericano)</string> - <string name="language_simplified_chinese">中国語 (简体中文)</string> - <string name="language_traditional_chinese">繁体字中国語 (正體中文)</string> - <string name="language_brazilian_portuguese">ポルトガル語(ブラジル) (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">타이완</string> <!-- Language Names --> - <string name="language_japanese">일본어 (日本語)</string> - <string name="language_english">영어 (English)</string> - <string name="language_french">프랑스어 (Français)</string> - <string name="langauge_german">독일어(Deutsch)</string> - <string name="language_italian">이탈리아어 (Italiano)</string> - <string name="language_spanish">스페인어 (Español)</string> - <string name="language_chinese">중국어 (简体中文)</string> - <string name="language_korean">한국어 (Korean)</string> - <string name="language_dutch">네덜란드어 (Nederlands)</string> - <string name="language_portuguese">포르투갈어 (Português)</string> - <string name="language_russian">러시아어 (Русский)</string> - <string name="language_taiwanese">대만어 (台湾)</string> - <string name="language_british_english">영어 (British English)</string> - <string name="language_canadian_french">캐나다 프랑스어 (Français canadien)</string> - <string name="language_latin_american_spanish">라틴 아메리카 스페인어 (Español latinoamericano)</string> - <string name="language_simplified_chinese">중국어 간체 (简体中文)</string> - <string name="language_traditional_chinese">중국어 번체 (正體中文)</string> - <string name="language_brazilian_portuguese">브라질 포르투갈어 (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Taiwan</string> <!-- Language Names --> - <string name="language_japanese">Japansk (日本語)</string> - <string name="language_english">Engelsk</string> - <string name="language_french">Fransk (Français)</string> - <string name="langauge_german">Tysk (Deutsch)</string> - <string name="language_italian">Italiensk (Italiano)</string> - <string name="language_spanish">Spansk (Español)</string> - <string name="language_chinese">Kinesisk (简体中文)</string> - <string name="language_korean">Koreansk (한국어)</string> - <string name="language_dutch">Nederlandsk (Nederlands)</string> - <string name="language_portuguese">Portugisisk (Português)</string> - <string name="language_russian">Russisk (Русский)</string> - <string name="language_taiwanese">Taiwansk (台湾)</string> - <string name="language_british_english">Britisk Engelsk</string> - <string name="language_canadian_french">Kanadisk fransk (Français canadien)</string> - <string name="language_latin_american_spanish">Latinamerikansk spansk (Español latinoamericano)</string> - <string name="language_simplified_chinese">Forenklet kinesisk (简体中文)</string> - <string name="language_traditional_chinese">Tradisjonell Kinesisk (正體中文)</string> - <string name="language_brazilian_portuguese">Brasiliansk portugisisk (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Tajwan</string> <!-- Language Names --> - <string name="language_japanese">Japoński (日本語)</string> - <string name="language_english">Angielski</string> - <string name="language_french">Francuski (Francja)</string> - <string name="langauge_german">Niemiecki (Niemcy)</string> - <string name="language_italian">Włoski (Włochy)</string> - <string name="language_spanish">Hiszpański (Hiszpania)</string> - <string name="language_chinese">Chiński (简体中文)</string> - <string name="language_korean">Koreański (한국어)</string> - <string name="language_dutch">Duński (Holandia)</string> - <string name="language_portuguese">Portugalski (Portugalia)</string> - <string name="language_russian">Rosyjski (Русский)</string> - <string name="language_taiwanese">Tajwański (台湾)</string> - <string name="language_british_english">Angielski Brytyjski</string> - <string name="language_canadian_french">Francuski (Kanada)</string> - <string name="language_latin_american_spanish">Hiszpański (Ameryka Latynoska)</string> - <string name="language_simplified_chinese">Chiński uproszczony (简体中文)</string> - <string name="language_traditional_chinese">Chiński tradycyjny (正體中文)</string> - <string name="language_brazilian_portuguese">Portugalski (Brazylia)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Taiwan</string> <!-- Language Names --> - <string name="language_japanese">Japônes (日本語)</string> - <string name="language_english">Português do Brasil</string> - <string name="language_french">Francês (Français)</string> - <string name="langauge_german">Alemão (Deutsch)</string> - <string name="language_italian">Italiano (Italiano)</string> - <string name="language_spanish">Espanhol (Español)</string> - <string name="language_chinese">Mandarim (简体中文)</string> - <string name="language_korean">Coreano (한국어)</string> - <string name="language_dutch">Holandês (Nederlands)</string> - <string name="language_portuguese">Português (Português)</string> - <string name="language_russian">Russo (Русский)</string> - <string name="language_taiwanese">Taiwanês (台湾)</string> - <string name="language_british_english">Inglês britânico (British English)</string> - <string name="language_canadian_french">Fracês Canadiano (Français canadien)</string> - <string name="language_latin_american_spanish">Espanhol da América Latina (Español latino-americano)</string> - <string name="language_simplified_chinese">Chinês Simplificado (简体中文)</string> - <string name="language_traditional_chinese">Chinês tradicional (正體中文)</string> - <string name="language_brazilian_portuguese">Português do Brasil (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Taiwan</string> <!-- Language Names --> - <string name="language_japanese">Japonês (日本語)</string> - <string name="language_english">Inglês</string> - <string name="language_french">Francês (Français)</string> - <string name="langauge_german">Alemão (Deutsch)</string> - <string name="language_italian">Italiano (Italiano)</string> - <string name="language_spanish">Espanhol (Español)</string> - <string name="language_chinese">Chinês simplificado (简体中文)</string> - <string name="language_korean">Coreano (한국어)</string> - <string name="language_dutch">Holandês (Nederlands)</string> - <string name="language_portuguese">Português (Português)</string> - <string name="language_russian">Russo (Русский)</string> - <string name="language_taiwanese">Taiwanês (台湾)</string> - <string name="language_british_english">Inglês Britânico</string> - <string name="language_canadian_french">Fracês Canadiano (Français canadien)</string> - <string name="language_latin_american_spanish">Espanhol da América Latina (Español latino-americano)</string> - <string name="language_simplified_chinese">Chinês Simplificado (简体中文)</string> - <string name="language_traditional_chinese">Chinês Tradicional (正 體 中文)</string> - <string name="language_brazilian_portuguese">Português do Brasil (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Тайвань</string> <!-- Language Names --> - <string name="language_japanese">Японский (日本語)</string> - <string name="language_english">Английский (English)</string> - <string name="language_french">Французский (Français)</string> - <string name="langauge_german">Немецкий (Deutsch)</string> - <string name="language_italian">Итальянский (Italiano)</string> - <string name="language_spanish">Испанский (Español)</string> - <string name="language_chinese">Китайский (简体中文)</string> - <string name="language_korean">Корейский (한국어)</string> - <string name="language_dutch">Голландский (Nederlands)</string> - <string name="language_portuguese">Португальский (Português)</string> - <string name="language_russian">Русский</string> - <string name="language_taiwanese">Тайваньский (台湾)</string> - <string name="language_british_english">Британский английский</string> - <string name="language_canadian_french">Канадский французский (Français canadien)</string> - <string name="language_latin_american_spanish">Латиноамериканский испанский (Español latinoamericano)</string> - <string name="language_simplified_chinese">Упрощенный китайский (简体中文)</string> - <string name="language_traditional_chinese">Традиционный китайский (正體中文)</string> - <string name="language_brazilian_portuguese">Бразильский португальский (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Тайвань</string> <!-- Language Names --> - <string name="language_japanese">Японська (日本語)</string> - <string name="language_english">Англійська (English)</string> - <string name="language_french">Французька (Français)</string> - <string name="langauge_german">Німецька (Deutsch)</string> - <string name="language_italian">Італійська (Italiano)</string> - <string name="language_spanish">Іспанська (Español)</string> - <string name="language_chinese">Китайскька (简体中文)</string> - <string name="language_korean">Корейська (한국어)</string> - <string name="language_dutch">Голландська (Nederlands)</string> - <string name="language_portuguese">Португальська (Português)</string> - <string name="language_russian">Російська (Русский)</string> - <string name="language_taiwanese">Тайванська (台湾)</string> - <string name="language_british_english">Британська англійська</string> - <string name="language_canadian_french">Канадська французька (Français canadien)</string> - <string name="language_latin_american_spanish">Латиноамериканська іспанська (Español latinoamericano)</string> - <string name="language_simplified_chinese">Спрощена китайська (简体中文)</string> - <string name="language_traditional_chinese">Традиційна китайська (正體中文)</string> - <string name="language_brazilian_portuguese">Бразильська португальська (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">中国台湾</string> <!-- Language Names --> - <string name="language_japanese">日语 (日本語)</string> - <string name="language_english">英语 (English)</string> - <string name="language_french">法语 (Français)</string> - <string name="langauge_german">德语 (Deutsch)</string> - <string name="language_italian">意大利语 (Italiano)</string> - <string name="language_spanish">西班牙语 (Español)</string> - <string name="language_chinese">中文 (简体中文)</string> - <string name="language_korean">韩语 (한국어)</string> - <string name="language_dutch">荷兰语 (Nederlands)</string> - <string name="language_portuguese">葡萄牙语 (Português)</string> - <string name="language_russian">俄语 (Русский)</string> - <string name="language_taiwanese">台湾中文 (台灣)</string> - <string name="language_british_english">英式英语</string> - <string name="language_canadian_french">加拿大法语 (Français canadien)</string> - <string name="language_latin_american_spanish">拉丁美洲西班牙语 (Español latinoamericano)</string> - <string name="language_simplified_chinese">简体中文 (简体中文)</string> - <string name="language_traditional_chinese">繁体中文 (正體中文)</string> - <string name="language_brazilian_portuguese">巴西葡萄牙语 (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">台灣</string> <!-- Language Names --> - <string name="language_japanese">日文 (日本語)</string> - <string name="language_english">英文</string> - <string name="language_french">法文 (Français)</string> - <string name="langauge_german">德文 (Deutsch)</string> - <string name="language_italian">義大利文 (Italiano)</string> - <string name="language_spanish">西班牙文 (Español)</string> - <string name="language_chinese">中文 (简体中文)</string> - <string name="language_korean">韓文 (한국어)</string> - <string name="language_dutch">荷蘭文 (Nederlands)</string> - <string name="language_portuguese">葡萄牙文 (Português)</string> - <string name="language_russian">俄文 (Русский)</string> - <string name="language_taiwanese">台文 (台灣)</string> - <string name="language_british_english">英式英文</string> - <string name="language_canadian_french">加拿大法文 (Français canadien)</string> - <string name="language_latin_american_spanish">拉丁美洲西班牙文 (Español latinoamericano)</string> - <string name="language_simplified_chinese">簡體中文 (简体中文)</string> - <string name="language_traditional_chinese">正體中文 (正體中文)</string> - <string name="language_brazilian_portuguese">巴西葡萄牙文 (Português do Brasil)</string> <!-- Renderer APIs --> <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 @@ <string name="region_taiwan">Taiwan</string> <!-- Language Names --> - <string name="language_japanese">Japanese (日本語)</string> - <string name="language_english">English</string> - <string name="language_french">French (Français)</string> - <string name="langauge_german">German (Deutsch)</string> - <string name="language_italian">Italian (Italiano)</string> - <string name="language_spanish">Spanish (Español)</string> - <string name="language_chinese">Chinese (简体中文)</string> - <string name="language_korean">Korean (한국어)</string> - <string name="language_dutch">Dutch (Nederlands)</string> - <string name="language_portuguese">Portuguese (Português)</string> - <string name="language_russian">Russian (Русский)</string> - <string name="language_taiwanese">Taiwanese (台湾)</string> - <string name="language_british_english">British English</string> - <string name="language_canadian_french">Canadian French (Français canadien)</string> - <string name="language_latin_american_spanish">Latin American Spanish (Español latinoamericano)</string> - <string name="language_simplified_chinese">Simplified Chinese (简体中文)</string> - <string name="language_traditional_chinese">Traditional Chinese (正體中文)</string> - <string name="language_brazilian_portuguese">Brazilian Portuguese (Português do Brasil)</string> + <string name="language_japanese" translatable="false">日本語</string> + <string name="language_english" translatable="false">English</string> + <string name="language_french" translatable="false">Français</string> + <string name="langauge_german" translatable="false">Deutsch</string> + <string name="language_italian" translatable="false">Italiano</string> + <string name="language_spanish" translatable="false">Español</string> + <string name="language_chinese" translatable="false">简体中文</string> + <string name="language_korean" translatable="false">한국어</string> + <string name="language_dutch" translatable="false">Nederlands</string> + <string name="language_portuguese" translatable="false">Português</string> + <string name="language_russian" translatable="false">Русский</string> + <string name="language_taiwanese" translatable="false">台湾</string> + <string name="language_british_english" translatable="false">British English</string> + <string name="language_canadian_french" translatable="false">Français canadien</string> + <string name="language_latin_american_spanish" translatable="false">Español latinoamericano</string> + <string name="language_simplified_chinese" translatable="false">简体中文</string> + <string name="language_traditional_chinese" translatable="false">正體中文</string> + <string name="language_brazilian_portuguese" translatable="false">Português do Brasil</string> <!-- Memory Sizes --> <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 { /* 0x14 */ u32 sinks; /* 0x18 */ u32 effects; /* 0x1C */ u32 perf_frames; - /* 0x20 */ u16 voice_drop_enabled; + /* 0x20 */ u8 voice_drop_enabled; + /* 0x21 */ u8 unk_21; /* 0x22 */ u8 rendering_device; /* 0x23 */ ExecutionMode execution_mode; /* 0x24 */ u32 splitter_infos; /* 0x28 */ s32 splitter_destinations; /* 0x2C */ u32 external_context_size; /* 0x30 */ u32 revision; - /* 0x34 */ char unk34[0x4]; }; -static_assert(sizeof(AudioRendererParameterInternal) == 0x38, +static_assert(sizeof(AudioRendererParameterInternal) == 0x34, "AudioRendererParameterInternal has the wrong size!"); /** 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 { class PageInfo { public: /// Returns the page pointer - [[nodiscard]] u8* Pointer() const noexcept { + [[nodiscard]] uintptr_t Pointer() const noexcept { return ExtractPointer(raw.load(std::memory_order_relaxed)); } @@ -61,7 +61,7 @@ struct PageTable { } /// Returns the page pointer and attribute pair, extracted from the same atomic read - [[nodiscard]] std::pair<u8*, PageType> PointerType() const noexcept { + [[nodiscard]] std::pair<uintptr_t, PageType> PointerType() const noexcept { const uintptr_t non_atomic_raw = raw.load(std::memory_order_relaxed); return {ExtractPointer(non_atomic_raw), ExtractType(non_atomic_raw)}; } @@ -73,13 +73,13 @@ struct PageTable { } /// Write a page pointer and type pair atomically - void Store(u8* pointer, PageType type) noexcept { - raw.store(reinterpret_cast<uintptr_t>(pointer) | static_cast<uintptr_t>(type)); + void Store(uintptr_t pointer, PageType type) noexcept { + raw.store(pointer | static_cast<uintptr_t>(type)); } /// Unpack a pointer from a page info raw representation - [[nodiscard]] static u8* ExtractPointer(uintptr_t raw) noexcept { - return reinterpret_cast<u8*>(raw & (~uintptr_t{0} << ATTRIBUTE_BITS)); + [[nodiscard]] static uintptr_t ExtractPointer(uintptr_t raw) noexcept { + return raw & (~uintptr_t{0} << ATTRIBUTE_BITS); } /// 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) { std::string location_name; if (time_zone_index == 0) { // Auto -#if __cpp_lib_chrono >= 201907L +#if __cpp_lib_chrono >= 201907L && !defined(MINGW) + // Disabled for MinGW -- tzdb always returns Etc/UTC try { const struct std::chrono::tzdb& time_zone_data = std::chrono::get_tzdb(); 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 @@ #include <chrono> #include <exception> #include <iomanip> +#include <map> #include <sstream> #include <stdexcept> #include <fmt/chrono.h> #include <fmt/core.h> #include "common/logging/log.h" -#include "common/settings.h" #include "common/time_zone.h" namespace Common::TimeZone { @@ -33,32 +33,29 @@ std::string GetDefaultTimeZone() { return "GMT"; } -static std::string GetOsTimeZoneOffset() { - const std::time_t t{std::time(nullptr)}; - const std::tm tm{*std::localtime(&t)}; - - return fmt::format("{:%z}", tm); -} - -static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) { - try { - return std::stoi(timezone); - } catch (const std::invalid_argument&) { - LOG_CRITICAL(Common, "invalid_argument with {}!", timezone); - return 0; - } catch (const std::out_of_range&) { - LOG_CRITICAL(Common, "out_of_range with {}!", timezone); - return 0; - } +// Results are not comparable to seconds since Epoch +static std::time_t TmSpecToSeconds(const struct std::tm& spec) { + const int year = spec.tm_year - 1; // Years up to now + const int leap_years = year / 4 - year / 100; + std::time_t cumulative = spec.tm_year; + cumulative = cumulative * 365 + leap_years + spec.tm_yday; // Years to days + cumulative = cumulative * 24 + spec.tm_hour; // Days to hours + cumulative = cumulative * 60 + spec.tm_min; // Hours to minutes + cumulative = cumulative * 60 + spec.tm_sec; // Minutes to seconds + return cumulative; } std::chrono::seconds GetCurrentOffsetSeconds() { - const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())}; + const std::time_t t{std::time(nullptr)}; + const std::tm local{*std::localtime(&t)}; + const std::tm gmt{*std::gmtime(&t)}; - int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds - seconds += (offset % 100) * 60; // Convert minute component to seconds + // gmt_seconds is a different offset than time(nullptr) + const auto gmt_seconds = TmSpecToSeconds(gmt); + const auto local_seconds = TmSpecToSeconds(local); + const auto seconds_offset = local_seconds - gmt_seconds; - return std::chrono::seconds{seconds}; + return std::chrono::seconds{seconds_offset}; } // Key is [Hours * 100 + Minutes], multiplied by 100 if DST @@ -71,11 +68,6 @@ const static std::map<s64, const char*> off_timezones = { }; std::string FindSystemTimeZone() { -#if defined(MINGW) - // MinGW has broken strftime -- https://sourceforge.net/p/mingw-w64/bugs/793/ - // e.g. fmt::format("{:%z}") -- returns "Eastern Daylight Time" when it should be "-0400" - return timezones[0]; -#else const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count()); const s64 minutes = seconds / 60; @@ -97,7 +89,6 @@ std::string FindSystemTimeZone() { } } return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours)); -#endif } } // 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() { #ifdef ARCHITECTURE_x86_64 const auto& caps = GetCPUCaps(); - if (caps.invariant_tsc && caps.tsc_frequency >= WallClock::GPUTickFreq) { + if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) { return std::make_unique<X64::NativeClock>(caps.tsc_frequency); } else { // Fallback to StandardWallClock if the hardware TSC // - Is not invariant - // - Is not more precise than GPUTickFreq + // - Is not more precise than 1 GHz (1ns resolution) return std::make_unique<StandardWallClock>(); } #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() { } } -void ARM_Interface::LoadWatchpointArray(const WatchpointArray& wp) { - watchpoints = ℘ +void ARM_Interface::LoadWatchpointArray(const WatchpointArray* wp) { + watchpoints = wp; } const 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: virtual void SaveContext(ThreadContext64& ctx) const = 0; virtual void LoadContext(const ThreadContext32& ctx) = 0; virtual void LoadContext(const ThreadContext64& ctx) = 0; - void LoadWatchpointArray(const WatchpointArray& wp); + void LoadWatchpointArray(const WatchpointArray* wp); /// Clears the exclusive monitor's state. 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() { } ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, - ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) + DynarmicExclusiveMonitor& exclusive_monitor_, + std::size_t core_index_) : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)), cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_}, - exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, - null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {} + exclusive_monitor{exclusive_monitor_}, null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {} ARM_Dynarmic_32::~ARM_Dynarmic_32() = default; 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 @@ #include "common/common_types.h" #include "common/hash.h" #include "core/arm/arm_interface.h" -#include "core/arm/exclusive_monitor.h" +#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h" namespace Core::Memory { class Memory; @@ -28,8 +28,8 @@ class System; class ARM_Dynarmic_32 final : public ARM_Interface { public: - ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, - std::size_t core_index_); + ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, + DynarmicExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); ~ARM_Dynarmic_32() override; 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() { } ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, - ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) + DynarmicExclusiveMonitor& exclusive_monitor_, + std::size_t core_index_) : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_}, - exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, - null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {} + exclusive_monitor{exclusive_monitor_}, null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {} ARM_Dynarmic_64::~ARM_Dynarmic_64() = default; 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 @@ #include "common/common_types.h" #include "common/hash.h" #include "core/arm/arm_interface.h" -#include "core/arm/exclusive_monitor.h" +#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h" namespace Core::Memory { class Memory; @@ -25,8 +25,8 @@ class System; class ARM_Dynarmic_64 final : public ARM_Interface { public: - ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, - std::size_t core_index_); + ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, + DynarmicExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); ~ARM_Dynarmic_64() override; 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 @@ #include <dynarmic/interface/exclusive_monitor.h> #include "common/common_types.h" -#include "core/arm/dynarmic/arm_dynarmic_32.h" -#include "core/arm/dynarmic/arm_dynarmic_64.h" #include "core/arm/exclusive_monitor.h" namespace Core::Memory { @@ -16,6 +14,9 @@ class Memory; namespace Core { +class ARM_Dynarmic_32; +class ARM_Dynarmic_64; + class DynarmicExclusiveMonitor final : public ExclusiveMonitor { public: 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 { return *impl->content_provider; } +FileSys::ContentProviderUnion& System::GetContentProviderUnion() { + return *impl->content_provider; +} + +const FileSys::ContentProviderUnion& System::GetContentProviderUnion() const { + return *impl->content_provider; +} + Service::FileSystem::FileSystemController& System::GetFileSystemController() { return impl->fs_controller; } 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: [[nodiscard]] FileSys::ContentProvider& GetContentProvider(); [[nodiscard]] const FileSys::ContentProvider& GetContentProvider() const; + [[nodiscard]] FileSys::ContentProviderUnion& GetContentProviderUnion(); + [[nodiscard]] const FileSys::ContentProviderUnion& GetContentProviderUnion() const; + [[nodiscard]] Service::FileSystem::FileSystemController& GetFileSystemController(); [[nodiscard]] const Service::FileSystem::FileSystemController& GetFileSystemController() const; 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 const size_t addr{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; const size_t size{static_cast<size_t>(strtoll(command.data() + sep, nullptr, 16))}; - if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { - std::vector<u8> mem(size); - system.ApplicationMemory().ReadBlock(addr, mem.data(), size); - + std::vector<u8> mem(size); + if (system.ApplicationMemory().ReadBlock(addr, mem.data(), size)) { SendReply(Common::HexToString(mem)); } else { SendReply(GDB_STUB_REPLY_ERR); @@ -281,8 +279,7 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction const auto mem_substr{std::string_view(command).substr(mem_sep)}; const auto mem{Common::HexStringToVector(mem_substr, false)}; - if (system.ApplicationMemory().IsValidVirtualAddressRange(addr, size)) { - system.ApplicationMemory().WriteBlock(addr, mem.data(), size); + if (system.ApplicationMemory().WriteBlock(addr, mem.data(), size)) { system.InvalidateCpuInstructionCacheRange(addr, size); SendReply(GDB_STUB_REPLY_OK); } else { @@ -556,7 +553,7 @@ void GDBStub::HandleQuery(std::string_view command) { } else { SendReply(fmt::format( "TextSeg={:x}", - GetInteger(system.ApplicationProcess()->PageTable().GetCodeRegionStart()))); + GetInteger(system.ApplicationProcess()->GetPageTable().GetCodeRegionStart()))); } } else if (command.starts_with("Xfer:libraries:read::")) { Loader::AppLoader::Modules modules; @@ -731,7 +728,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) { std::string reply; auto* process = system.ApplicationProcess(); - auto& page_table = process->PageTable(); + auto& page_table = process->GetPageTable(); const char* commands = "Commands:\n" " 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() { m_kernel.RegisterKernelObject(this); } -void KAutoObject::UnregisterWithKernel() { - m_kernel.UnregisterKernelObject(this); +void KAutoObject::UnregisterWithKernel(KernelCore& kernel, KAutoObject* self) { + kernel.UnregisterKernelObject(self); } } // 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: // If ref count hits zero, destroy the object. if (cur_ref_count - 1 == 0) { + KernelCore& kernel = m_kernel; this->Destroy(); - this->UnregisterWithKernel(); + KAutoObject::UnregisterWithKernel(kernel, this); } } private: void RegisterWithKernel(); - void UnregisterWithKernel(); + static void UnregisterWithKernel(KernelCore& kernel, KAutoObject* self); protected: 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 m_owner = GetCurrentProcessPointer(m_kernel); // Get the owner page table. - auto& page_table = m_owner->PageTable(); + auto& page_table = m_owner->GetPageTable(); // Construct the page group. m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager()); @@ -53,7 +53,7 @@ void KCodeMemory::Finalize() { // Unlock. if (!m_is_mapped && !m_is_owner_mapped) { const size_t size = m_page_group->GetNumPages() * PageSize; - m_owner->PageTable().UnlockForCodeMemory(m_address, size, *m_page_group); + m_owner->GetPageTable().UnlockForCodeMemory(m_address, size, *m_page_group); } // Close the page group. @@ -75,7 +75,7 @@ Result KCodeMemory::Map(KProcessAddress address, size_t size) { R_UNLESS(!m_is_mapped, ResultInvalidState); // Map the memory. - R_TRY(GetCurrentProcess(m_kernel).PageTable().MapPageGroup( + R_TRY(GetCurrentProcess(m_kernel).GetPageTable().MapPageGroup( address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite)); // Mark ourselves as mapped. @@ -92,8 +92,8 @@ Result KCodeMemory::Unmap(KProcessAddress address, size_t size) { KScopedLightLock lk(m_lock); // Unmap the memory. - R_TRY(GetCurrentProcess(m_kernel).PageTable().UnmapPageGroup(address, *m_page_group, - KMemoryState::CodeOut)); + R_TRY(GetCurrentProcess(m_kernel).GetPageTable().UnmapPageGroup(address, *m_page_group, + KMemoryState::CodeOut)); // Mark ourselves as unmapped. m_is_mapped = false; @@ -126,8 +126,8 @@ Result KCodeMemory::MapToOwner(KProcessAddress address, size_t size, Svc::Memory } // Map the memory. - R_TRY(m_owner->PageTable().MapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode, - k_perm)); + R_TRY(m_owner->GetPageTable().MapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode, + k_perm)); // Mark ourselves as mapped. m_is_owner_mapped = true; @@ -143,7 +143,8 @@ Result KCodeMemory::UnmapFromOwner(KProcessAddress address, size_t size) { KScopedLightLock lk(m_lock); // Unmap the memory. - R_TRY(m_owner->PageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::GeneratedCode)); + R_TRY(m_owner->GetPageTable().UnmapPageGroup(address, *m_page_group, + KMemoryState::GeneratedCode)); // Mark ourselves as unmapped. 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: constexpr size_t GetHeapSize() const { return m_current_heap_end - m_heap_region_start; } - constexpr bool IsInsideAddressSpace(KProcessAddress address, size_t size) const { - return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1; - } - constexpr bool IsOutsideAliasRegion(KProcessAddress address, size_t size) const { - return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1; - } - constexpr bool IsOutsideStackRegion(KProcessAddress address, size_t size) const { - return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1; - } - constexpr bool IsInvalidRegion(KProcessAddress address, size_t size) const { - return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1; - } - constexpr bool IsInsideHeapRegion(KProcessAddress address, size_t size) const { - return address + size > m_heap_region_start && m_heap_region_end > address; - } - constexpr bool IsInsideAliasRegion(KProcessAddress address, size_t size) const { - return address + size > m_alias_region_start && m_alias_region_end > address; - } - constexpr bool IsOutsideASLRRegion(KProcessAddress address, size_t size) const { - if (IsInvalidRegion(address, size)) { - return true; - } - if (IsInsideHeapRegion(address, size)) { - return true; - } - if (IsInsideAliasRegion(address, size)) { - return true; - } - return {}; - } - constexpr bool IsInsideASLRRegion(KProcessAddress address, size_t size) const { - return !IsOutsideASLRRegion(address, size); - } constexpr size_t GetNumGuardPages() const { return IsKernel() ? 1 : 4; } @@ -436,6 +403,14 @@ public: return m_address_space_start <= addr && addr < addr + size && addr + size - 1 <= m_address_space_end - 1; } + constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const { + return this->Contains(addr, size) && m_alias_region_start <= addr && + addr + size - 1 <= m_alias_region_end - 1; + } + constexpr bool IsInHeapRegion(KProcessAddress addr, size_t size) const { + return this->Contains(addr, size) && m_heap_region_start <= addr && + addr + size - 1 <= m_heap_region_end - 1; + } public: 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 { */ void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, KProcessAddress stack_top) { - const KProcessAddress entry_point = owner_process.PageTable().GetCodeRegionStart(); + const KProcessAddress entry_point = owner_process.GetPageTable().GetCodeRegionStart(); ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1)); 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: ProcessType type, KResourceLimit* res_limit); /// Gets a reference to the process' page table. - KPageTable& PageTable() { - return m_page_table; - } - - /// Gets const a reference to the process' page table. - const KPageTable& PageTable() const { - return m_page_table; - } - - /// Gets a reference to the process' page table. KPageTable& GetPageTable() { return m_page_table; } 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) { void KScheduler::Reload(KThread* thread) { auto& cpu_core = m_kernel.System().ArmInterface(m_core_id); + auto* process = thread->GetOwnerProcess(); cpu_core.LoadContext(thread->GetContext32()); cpu_core.LoadContext(thread->GetContext64()); cpu_core.SetTlsAddress(GetInteger(thread->GetTlsAddress())); cpu_core.SetTPIDR_EL0(thread->GetTpidrEl0()); - cpu_core.LoadWatchpointArray(thread->GetOwnerProcess()->GetWatchpoints()); + cpu_core.LoadWatchpointArray(process ? &process->GetWatchpoints() : nullptr); cpu_core.ClearExclusiveState(); } 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 R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission); } - R_RETURN(target_process.PageTable().MapPageGroup(address, *m_page_group, KMemoryState::Shared, - ConvertToKMemoryPermission(map_perm))); + R_RETURN(target_process.GetPageTable().MapPageGroup( + address, *m_page_group, KMemoryState::Shared, ConvertToKMemoryPermission(map_perm))); } Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address, @@ -100,7 +100,7 @@ Result KSharedMemory::Unmap(KProcess& target_process, KProcessAddress address, R_UNLESS(m_size == unmap_size, ResultInvalidSize); R_RETURN( - target_process.PageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::Shared)); + target_process.GetPageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::Shared)); } } // 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 case ThreadType::User: ASSERT(((owner == nullptr) || (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask())); - ASSERT(((owner == nullptr) || + ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) || (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask())); break; 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) { // Map the address in. const auto phys_addr = kernel.System().DeviceMemory().GetPhysicalAddr(page_buf); - R_TRY(m_owner->PageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, phys_addr, - KMemoryState::ThreadLocal, - KMemoryPermission::UserReadWrite)); + R_TRY(m_owner->GetPageTable().MapPages(std::addressof(m_virt_addr), 1, PageSize, phys_addr, + KMemoryState::ThreadLocal, + KMemoryPermission::UserReadWrite)); // We succeeded. page_buf_guard.Cancel(); @@ -37,11 +37,11 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) { Result KThreadLocalPage::Finalize() { // Get the physical address of the page. - const KPhysicalAddress phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr); + const KPhysicalAddress phys_addr = m_owner->GetPageTable().GetPhysicalAddr(m_virt_addr); ASSERT(phys_addr); // Unmap the page. - R_TRY(m_owner->PageTable().UnmapPages(this->GetAddress(), 1, KMemoryState::ThreadLocal)); + R_TRY(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState::ThreadLocal)); // Free the page. 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 // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. auto& kernel = system.Kernel(); m_arm_interface = std::make_unique<Core::ARM_Dynarmic_64>( - system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), m_core_index); + system, kernel.IsMulticore(), + reinterpret_cast<Core::DynarmicExclusiveMonitor&>(kernel.GetExclusiveMonitor()), + m_core_index); #else #error Platform not supported yet. #endif @@ -31,7 +33,9 @@ void PhysicalCore::Initialize(bool is_64_bit) { if (!is_64_bit) { // We already initialized a 64-bit core, replace with a 32-bit one. m_arm_interface = std::make_unique<Core::ARM_Dynarmic_32>( - m_system, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), m_core_index); + m_system, kernel.IsMulticore(), + reinterpret_cast<Core::DynarmicExclusiveMonitor&>(kernel.GetExclusiveMonitor()), + m_core_index); } #else #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 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); // Verify the region is within range. - auto& page_table = process->PageTable(); + auto& page_table = process->GetPageTable(); R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); // 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 SCOPE_EXIT({ code_mem->Close(); }); // Verify that the region is in range. - R_UNLESS(GetCurrentProcess(system.Kernel()).PageTable().Contains(address, size), + R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size), ResultInvalidCurrentMemory); // Initialize the code memory. @@ -92,7 +92,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, case CodeMemoryOperation::Map: { // Check that the region is in range. R_UNLESS(GetCurrentProcess(system.Kernel()) - .PageTable() + .GetPageTable() .CanContain(address, size, KMemoryState::CodeOut), ResultInvalidMemoryRegion); @@ -105,7 +105,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, case CodeMemoryOperation::Unmap: { // Check that the region is in range. R_UNLESS(GetCurrentProcess(system.Kernel()) - .PageTable() + .GetPageTable() .CanContain(address, size, KMemoryState::CodeOut), ResultInvalidMemoryRegion); @@ -117,8 +117,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, } break; case CodeMemoryOperation::MapToOwner: { // Check that the region is in range. - R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size, - KMemoryState::GeneratedCode), + R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size, + KMemoryState::GeneratedCode), ResultInvalidMemoryRegion); // Check the memory permission. @@ -129,8 +129,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, } break; case CodeMemoryOperation::UnmapFromOwner: { // Check that the region is in range. - R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size, - KMemoryState::GeneratedCode), + R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size, + KMemoryState::GeneratedCode), ResultInvalidMemoryRegion); // 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 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); // Validate that the process address is within range. - auto& page_table = process->PageTable(); + auto& page_table = process->GetPageTable(); R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); // Map. @@ -148,7 +148,7 @@ Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Han R_UNLESS(process.IsNotNull(), ResultInvalidHandle); // Validate that the process address is within range. - auto& page_table = process->PageTable(); + auto& page_table = process->GetPageTable(); R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); // Map. @@ -180,7 +180,7 @@ Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle p R_UNLESS(process.IsNotNull(), ResultInvalidHandle); // Validate that the process address is within range. - auto& page_table = process->PageTable(); + auto& page_table = process->GetPageTable(); R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory); 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 R_SUCCEED(); case InfoType::AliasRegionAddress: - *result = GetInteger(process->PageTable().GetAliasRegionStart()); + *result = GetInteger(process->GetPageTable().GetAliasRegionStart()); R_SUCCEED(); case InfoType::AliasRegionSize: - *result = process->PageTable().GetAliasRegionSize(); + *result = process->GetPageTable().GetAliasRegionSize(); R_SUCCEED(); case InfoType::HeapRegionAddress: - *result = GetInteger(process->PageTable().GetHeapRegionStart()); + *result = GetInteger(process->GetPageTable().GetHeapRegionStart()); R_SUCCEED(); case InfoType::HeapRegionSize: - *result = process->PageTable().GetHeapRegionSize(); + *result = process->GetPageTable().GetHeapRegionSize(); R_SUCCEED(); case InfoType::AslrRegionAddress: - *result = GetInteger(process->PageTable().GetAliasCodeRegionStart()); + *result = GetInteger(process->GetPageTable().GetAliasCodeRegionStart()); R_SUCCEED(); case InfoType::AslrRegionSize: - *result = process->PageTable().GetAliasCodeRegionSize(); + *result = process->GetPageTable().GetAliasCodeRegionSize(); R_SUCCEED(); case InfoType::StackRegionAddress: - *result = GetInteger(process->PageTable().GetStackRegionStart()); + *result = GetInteger(process->GetPageTable().GetStackRegionStart()); R_SUCCEED(); case InfoType::StackRegionSize: - *result = process->PageTable().GetStackRegionSize(); + *result = process->GetPageTable().GetStackRegionSize(); R_SUCCEED(); 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 @@ #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" namespace Kernel::Svc { @@ -49,14 +50,10 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad // Copy user handles. if (num_handles > 0) { - // Ensure we can try to get the handles. - R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( - handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), - ResultInvalidPointer); - // Get the handles. - GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), - sizeof(Handle) * num_handles); + R_UNLESS(GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), + sizeof(Handle) * num_handles), + ResultInvalidPointer); // Convert the handles to objects. 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 R_THROW(ResultInvalidCurrentMemory); } - if (!manager.IsInsideAddressSpace(src_addr, size)) { + if (!manager.Contains(src_addr, size)) { LOG_ERROR(Kernel_SVC, "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", src_addr, size); R_THROW(ResultInvalidCurrentMemory); } - if (manager.IsOutsideStackRegion(dst_addr, size)) { - LOG_ERROR(Kernel_SVC, - "Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}", - dst_addr, size); - R_THROW(ResultInvalidMemoryRegion); - } - - if (manager.IsInsideHeapRegion(dst_addr, size)) { - LOG_ERROR(Kernel_SVC, - "Destination does not fit within the heap region, addr=0x{:016X}, " - "size=0x{:016X}", - dst_addr, size); - R_THROW(ResultInvalidMemoryRegion); - } - - if (manager.IsInsideAliasRegion(dst_addr, size)) { - LOG_ERROR(Kernel_SVC, - "Destination does not fit within the map region, addr=0x{:016X}, " - "size=0x{:016X}", - dst_addr, size); - R_THROW(ResultInvalidMemoryRegion); - } - R_SUCCEED(); } @@ -112,7 +89,7 @@ Result SetMemoryPermission(Core::System& system, u64 address, u64 size, MemoryPe R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission); // Validate that the region is in range for the current process. - auto& page_table = GetCurrentProcess(system.Kernel()).PageTable(); + auto& page_table = GetCurrentProcess(system.Kernel()).GetPageTable(); R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); // Set the memory attribute. @@ -136,7 +113,7 @@ Result SetMemoryAttribute(Core::System& system, u64 address, u64 size, u32 mask, R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination); // Validate that the region is in range for the current process. - auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()}; + auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()}; R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); // Set the memory attribute. @@ -148,7 +125,7 @@ Result MapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, src_addr, size); - auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()}; + auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()}; if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; result.IsError()) { @@ -163,7 +140,7 @@ Result UnmapMemory(Core::System& system, u64 dst_addr, u64 src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, src_addr, size); - auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()}; + auto& page_table{GetCurrentProcess(system.Kernel()).GetPageTable()}; if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; 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) { R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize); // Set the heap size. - R_RETURN(GetCurrentProcess(system.Kernel()).PageTable().SetHeapSize(out_address, size)); + R_RETURN(GetCurrentProcess(system.Kernel()).GetPageTable().SetHeapSize(out_address, size)); } /// Maps memory at a desired address @@ -44,21 +44,21 @@ Result MapPhysicalMemory(Core::System& system, u64 addr, u64 size) { } KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())}; - auto& page_table{current_process->PageTable()}; + auto& page_table{current_process->GetPageTable()}; if (current_process->GetSystemResourceSize() == 0) { LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); R_THROW(ResultInvalidState); } - if (!page_table.IsInsideAddressSpace(addr, size)) { + if (!page_table.Contains(addr, size)) { LOG_ERROR(Kernel_SVC, "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, size); R_THROW(ResultInvalidMemoryRegion); } - if (page_table.IsOutsideAliasRegion(addr, size)) { + if (!page_table.IsInAliasRegion(addr, size)) { LOG_ERROR(Kernel_SVC, "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, size); @@ -93,21 +93,21 @@ Result UnmapPhysicalMemory(Core::System& system, u64 addr, u64 size) { } KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())}; - auto& page_table{current_process->PageTable()}; + auto& page_table{current_process->GetPageTable()}; if (current_process->GetSystemResourceSize() == 0) { LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); R_THROW(ResultInvalidState); } - if (!page_table.IsInsideAddressSpace(addr, size)) { + if (!page_table.Contains(addr, size)) { LOG_ERROR(Kernel_SVC, "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, size); R_THROW(ResultInvalidMemoryRegion); } - if (page_table.IsOutsideAliasRegion(addr, size)) { + if (!page_table.IsInAliasRegion(addr, size)) { LOG_ERROR(Kernel_SVC, "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, 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 auto& kernel = system.Kernel(); const auto total_copy_size = out_process_ids_size * sizeof(u64); - if (out_process_ids_size > 0 && !GetCurrentProcess(kernel).PageTable().IsInsideAddressSpace( - out_process_ids, total_copy_size)) { + if (out_process_ids_size > 0 && + !GetCurrentProcess(kernel).GetPageTable().Contains(out_process_ids, total_copy_size)) { LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", out_process_ids, out_process_ids + total_copy_size); 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 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); // Validate that the address is in range. - auto& page_table = process->PageTable(); + auto& page_table = process->GetPageTable(); R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); // Set the memory permission. @@ -77,8 +77,8 @@ Result MapProcessMemory(Core::System& system, u64 dst_address, Handle process_ha R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); // Get the page tables. - auto& dst_pt = dst_process->PageTable(); - auto& src_pt = src_process->PageTable(); + auto& dst_pt = dst_process->GetPageTable(); + auto& src_pt = src_process->GetPageTable(); // Validate that the mapping is in range. R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory); @@ -118,8 +118,8 @@ Result UnmapProcessMemory(Core::System& system, u64 dst_address, Handle process_ R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); // Get the page tables. - auto& dst_pt = dst_process->PageTable(); - auto& src_pt = src_process->PageTable(); + auto& dst_pt = dst_process->GetPageTable(); + auto& src_pt = src_process->GetPageTable(); // Validate that the mapping is in range. R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory); @@ -178,8 +178,8 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst R_THROW(ResultInvalidHandle); } - auto& page_table = process->PageTable(); - if (!page_table.IsInsideAddressSpace(src_address, size)) { + auto& page_table = process->GetPageTable(); + if (!page_table.Contains(src_address, size)) { LOG_ERROR(Kernel_SVC, "Source address range is not within the address space (src_address=0x{:016X}, " "size=0x{:016X}).", @@ -187,14 +187,6 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst R_THROW(ResultInvalidCurrentMemory); } - if (!page_table.IsInsideASLRRegion(dst_address, size)) { - LOG_ERROR(Kernel_SVC, - "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " - "size=0x{:016X}).", - dst_address, size); - R_THROW(ResultInvalidMemoryRegion); - } - R_RETURN(page_table.MapCodeMemory(dst_address, src_address, size)); } @@ -246,8 +238,8 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d R_THROW(ResultInvalidHandle); } - auto& page_table = process->PageTable(); - if (!page_table.IsInsideAddressSpace(src_address, size)) { + auto& page_table = process->GetPageTable(); + if (!page_table.Contains(src_address, size)) { LOG_ERROR(Kernel_SVC, "Source address range is not within the address space (src_address=0x{:016X}, " "size=0x{:016X}).", @@ -255,14 +247,6 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d R_THROW(ResultInvalidCurrentMemory); } - if (!page_table.IsInsideASLRRegion(dst_address, size)) { - LOG_ERROR(Kernel_SVC, - "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " - "size=0x{:016X}).", - dst_address, size); - R_THROW(ResultInvalidMemoryRegion); - } - R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size, KPageTable::ICacheInvalidationStrategy::InvalidateAll)); } 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 } auto& current_memory{GetCurrentMemory(system.Kernel())}; - const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; + const auto memory_info{process->GetPageTable().QueryInfo(address).GetSvcMemoryInfo()}; current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info)); 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 // Get the current process. auto& process = GetCurrentProcess(system.Kernel()); - auto& page_table = process.PageTable(); + auto& page_table = process.GetPageTable(); // Get the shared memory. KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle); @@ -73,7 +73,7 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, // Get the current process. auto& process = GetCurrentProcess(system.Kernel()); - auto& page_table = process.PageTable(); + auto& page_table = process.GetPageTable(); // Get the shared memory. 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 @@ #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_results.h" namespace Kernel::Svc { @@ -64,14 +65,10 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha // Copy user handles. if (num_handles > 0) { - // Ensure we can try to get the handles. - R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( - user_handles, static_cast<u64>(sizeof(Handle) * num_handles)), - ResultInvalidPointer); - // Get the handles. - GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(), - sizeof(Handle) * num_handles); + R_UNLESS(GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(), + sizeof(Handle) * num_handles), + ResultInvalidPointer); // Convert the handles to objects. 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_ const auto total_copy_size = out_thread_ids_size * sizeof(u64); if (out_thread_ids_size > 0 && - !current_process->PageTable().IsInsideAddressSpace(out_thread_ids, total_copy_size)) { + !current_process->GetPageTable().Contains(out_thread_ids, total_copy_size)) { LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", out_thread_ids, out_thread_ids + total_copy_size); 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 SCOPE_EXIT({ trmem->Close(); }); // Ensure that the region is in range. - R_UNLESS(process.PageTable().Contains(address, size), ResultInvalidCurrentMemory); + R_UNLESS(process.GetPageTable().Contains(address, size), ResultInvalidCurrentMemory); // Initialize the transfer memory. 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: void LoadIdTokenCache(HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); + rb.Push(0); } protected: 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) { AudioCore::AudioRendererParameterInternal params; rp.PopRaw<AudioCore::AudioRendererParameterInternal>(params); - auto transfer_memory_handle = ctx.GetCopyHandle(0); - auto process_handle = ctx.GetCopyHandle(1); + rp.Skip(1, false); auto transfer_memory_size = rp.Pop<u64>(); auto applet_resource_user_id = rp.Pop<u64>(); + auto transfer_memory_handle = ctx.GetCopyHandle(0); + auto process_handle = ctx.GetCopyHandle(1); if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) { 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 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/glue/ectx.h" +#include "core/hle/service/ipc_helpers.h" namespace Service::Glue { +// This is nn::err::context::IContextRegistrar +class IContextRegistrar : public ServiceFramework<IContextRegistrar> { +public: + IContextRegistrar(Core::System& system_) : ServiceFramework{system_, "IContextRegistrar"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &IContextRegistrar::Complete, "Complete"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + + ~IContextRegistrar() override = default; + +private: + void Complete(HLERequestContext& ctx) { + struct InputParameters { + u32 unk; + }; + struct OutputParameters { + u32 unk; + }; + + IPC::RequestParser rp{ctx}; + [[maybe_unused]] auto input = rp.PopRaw<InputParameters>(); + [[maybe_unused]] auto value = ctx.ReadBuffer(); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); + } +}; + ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "CreateContextRegistrar"}, + {0, &ECTX_AW::CreateContextRegistrar, "CreateContextRegistrar"}, {1, nullptr, "CommitContext"}, }; // clang-format on @@ -18,4 +53,10 @@ ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} { ECTX_AW::~ECTX_AW() = default; +void ECTX_AW::CreateContextRegistrar(HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<IContextRegistrar>(std::make_shared<IContextRegistrar>(system)); +} + } // 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> { public: explicit ECTX_AW(Core::System& system_); ~ECTX_AW() override; + +private: + void CreateContextRegistrar(HLERequestContext& ctx); }; } // 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: return false; } - if (!page_table.IsInsideAddressSpace(out_addr, size)) { + if (!page_table.Contains(out_addr, size)) { return false; } - if (page_table.IsInsideHeapRegion(out_addr, size)) { + if (page_table.IsInHeapRegion(out_addr, size)) { return false; } - if (page_table.IsInsideAliasRegion(out_addr, size)) { + if (page_table.IsInAliasRegion(out_addr, size)) { return false; } @@ -358,7 +358,7 @@ public: } ResultVal<VAddr> MapProcessCodeMemory(Kernel::KProcess* process, VAddr base_addr, u64 size) { - auto& page_table{process->PageTable()}; + auto& page_table{process->GetPageTable()}; VAddr addr{}; for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { @@ -382,7 +382,7 @@ public: ResultVal<VAddr> MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size, VAddr bss_addr, std::size_t bss_size, std::size_t size) { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { - auto& page_table{process->PageTable()}; + auto& page_table{process->GetPageTable()}; VAddr addr{}; CASCADE_RESULT(addr, MapProcessCodeMemory(process, nro_addr, nro_size)); @@ -437,12 +437,12 @@ public: CopyCode(nro_addr + nro_header.segment_headers[DATA_INDEX].memory_offset, data_start, nro_header.segment_headers[DATA_INDEX].memory_size); - CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( + CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission( text_start, ro_start - text_start, Kernel::Svc::MemoryPermission::ReadExecute)); - CASCADE_CODE(process->PageTable().SetProcessMemoryPermission( + CASCADE_CODE(process->GetPageTable().SetProcessMemoryPermission( ro_start, data_start - ro_start, Kernel::Svc::MemoryPermission::Read)); - return process->PageTable().SetProcessMemoryPermission( + return process->GetPageTable().SetProcessMemoryPermission( data_start, bss_end_addr - data_start, Kernel::Svc::MemoryPermission::ReadWrite); } @@ -571,7 +571,7 @@ public: Result UnmapNro(const NROInfo& info) { // Each region must be unmapped separately to validate memory state - auto& page_table{system.ApplicationProcess()->PageTable()}; + auto& page_table{system.ApplicationProcess()->GetPageTable()}; if (info.bss_size != 0) { CASCADE_CODE(page_table.UnmapCodeMemory( @@ -643,7 +643,7 @@ public: initialized = true; current_map_addr = - GetInteger(system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart()); + GetInteger(system.ApplicationProcess()->GetPageTable().GetAliasCodeRegionStart()); IPC::ResponseBuilder rb{ctx, 2}; 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) { } bool is_out_io{}; ASSERT(system.ApplicationProcess() - ->PageTable() + ->GetPageTable() .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address, handle_description->size, Kernel::KMemoryPermission::None, true, false) @@ -255,7 +255,7 @@ NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) { if (auto freeInfo{file.FreeHandle(params.handle, false)}) { if (freeInfo->can_unlock) { ASSERT(system.ApplicationProcess() - ->PageTable() + ->GetPageTable() .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) .IsSuccess()); } 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 const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd]; if (!descriptor) { - LOG_ERROR(Service, "File descriptor handle={} is not allocated", pollfd.fd); + LOG_TRACE(Service, "File descriptor handle={} is not allocated", pollfd.fd); pollfd.revents = PollEvents::Nval; return {0, Errno::SUCCESS}; } 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 { constexpr Result ResultOverflow{ErrorModule::NSD, 6}; +// This is nn::oe::ServerEnvironmentType +enum class ServerEnvironmentType : u8 { + Dd, + Lp, + Sd, + Sp, + Dp, +}; + NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} { // clang-format off static const FunctionInfo functions[] = { {5, nullptr, "GetSettingUrl"}, {10, nullptr, "GetSettingName"}, - {11, nullptr, "GetEnvironmentIdentifier"}, + {11, &NSD::GetEnvironmentIdentifier, "GetEnvironmentIdentifier"}, {12, nullptr, "GetDeviceId"}, {13, nullptr, "DeleteSettings"}, {14, nullptr, "ImportSettings"}, @@ -36,7 +45,7 @@ NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, na {62, nullptr, "DeleteSaveDataOfFsForTest"}, {63, nullptr, "IsChangeEnvironmentIdentifierDisabled"}, {64, nullptr, "SetWithoutDomainExchangeFqdns"}, - {100, nullptr, "GetApplicationServerEnvironmentType"}, + {100, &NSD::GetApplicationServerEnvironmentType, "GetApplicationServerEnvironmentType"}, {101, nullptr, "SetApplicationServerEnvironmentType"}, {102, nullptr, "DeleteApplicationServerEnvironmentType"}, }; @@ -94,6 +103,20 @@ void NSD::ResolveEx(HLERequestContext& ctx) { rb.Push(ResultSuccess); } +void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) { + const std::string environment_identifier = "lp1"; + ctx.WriteBuffer(environment_identifier); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void NSD::GetApplicationServerEnvironmentType(HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(static_cast<u32>(ServerEnvironmentType::Lp)); +} + NSD::~NSD() = default; } // 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: private: void Resolve(HLERequestContext& ctx); void ResolveEx(HLERequestContext& ctx); + void GetEnvironmentIdentifier(HLERequestContext& ctx); + void GetApplicationServerEnvironmentType(HLERequestContext& ctx); }; } // 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" {2, &SFDNSRES::GetHostByNameRequest, "GetHostByNameRequest"}, {3, nullptr, "GetHostByAddrRequest"}, {4, nullptr, "GetHostStringErrorRequest"}, - {5, nullptr, "GetGaiStringErrorRequest"}, + {5, &SFDNSRES::GetGaiStringErrorRequest, "GetGaiStringErrorRequest"}, {6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"}, {7, nullptr, "GetNameInfoRequest"}, {8, nullptr, "RequestCancelHandleRequest"}, @@ -300,6 +300,20 @@ void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) { }); } +void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) { + struct InputParameters { + GetAddrInfoError gai_errno; + }; + IPC::RequestParser rp{ctx}; + auto input = rp.PopRaw<InputParameters>(); + + const std::string result = Translate(input.gai_errno); + ctx.WriteBuffer(result); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) { // Additional options are ignored 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: private: void GetHostByNameRequest(HLERequestContext& ctx); + void GetGaiStringErrorRequest(HLERequestContext& ctx); void GetHostByNameRequestWithOptions(HLERequestContext& ctx); void GetAddrInfoRequest(HLERequestContext& ctx); 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) { } } +const char* Translate(GetAddrInfoError error) { + // https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254 + switch (error) { + case GetAddrInfoError::SUCCESS: + return "Success"; + case GetAddrInfoError::ADDRFAMILY: + return "Address family for hostname not supported"; + case GetAddrInfoError::AGAIN: + return "Temporary failure in name resolution"; + case GetAddrInfoError::BADFLAGS: + return "Invalid value for ai_flags"; + case GetAddrInfoError::FAIL: + return "Non-recoverable failure in name resolution"; + case GetAddrInfoError::FAMILY: + return "ai_family not supported"; + case GetAddrInfoError::MEMORY: + return "Memory allocation failure"; + case GetAddrInfoError::NODATA: + return "No address associated with hostname"; + case GetAddrInfoError::NONAME: + return "hostname nor servname provided, or not known"; + case GetAddrInfoError::SERVICE: + return "servname not supported for ai_socktype"; + case GetAddrInfoError::SOCKTYPE: + return "ai_socktype not supported"; + case GetAddrInfoError::SYSTEM: + return "System error returned in errno"; + case GetAddrInfoError::BADHINTS: + return "Invalid value for hints"; + case GetAddrInfoError::PROTOCOL: + return "Resolved protocol is unknown"; + case GetAddrInfoError::OVERFLOW_: + return "Argument buffer overflow"; + default: + return "Unknown error"; + } +} + Network::Domain Translate(Domain domain) { switch (domain) { 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); /// Translate abstract getaddrinfo error to guest getaddrinfo error GetAddrInfoError Translate(Network::GetAddrInfoError value); +/// Translate guest error to string +const char* Translate(GetAddrInfoError value); + /// Translate guest domain to abstract domain Network::Domain Translate(Domain domain); 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 @@ #include <chrono> #include <sstream> +#include <utility> #include "common/logging/log.h" #include "common/settings.h" @@ -46,14 +47,14 @@ static FileSys::VirtualDir GetTimeZoneBinary(Core::System& system) { return FileSys::ExtractRomFS(romfs); } -static std::vector<std::string> BuildLocationNameCache(Core::System& system) { - const FileSys::VirtualDir extracted_romfs{GetTimeZoneBinary(system)}; - if (!extracted_romfs) { +static std::vector<std::string> BuildLocationNameCache( + const FileSys::VirtualDir& time_zone_binary) { + if (!time_zone_binary) { LOG_ERROR(Service_Time, "Failed to extract RomFS for {:016X}!", time_zone_binary_titleid); return {}; } - const FileSys::VirtualFile binary_list{extracted_romfs->GetFile("binaryList.txt")}; + const FileSys::VirtualFile binary_list{time_zone_binary->GetFile("binaryList.txt")}; if (!binary_list) { LOG_ERROR(Service_Time, "{:016X} has no file binaryList.txt!", time_zone_binary_titleid); return {}; @@ -73,7 +74,8 @@ static std::vector<std::string> BuildLocationNameCache(Core::System& system) { } TimeZoneContentManager::TimeZoneContentManager(Core::System& system_) - : system{system_}, location_name_cache{BuildLocationNameCache(system)} {} + : system{system_}, time_zone_binary{GetTimeZoneBinary(system)}, + location_name_cache{BuildLocationNameCache(time_zone_binary)} {} void TimeZoneContentManager::Initialize(TimeManager& time_manager) { const auto timezone_setting = @@ -112,13 +114,12 @@ Result TimeZoneContentManager::GetTimeZoneInfoFile(const std::string& location_n return ERROR_TIME_NOT_FOUND; } - const FileSys::VirtualDir extracted_romfs{GetTimeZoneBinary(system)}; - if (!extracted_romfs) { + if (!time_zone_binary) { LOG_ERROR(Service_Time, "Failed to extract RomFS for {:016X}!", time_zone_binary_titleid); return ERROR_TIME_NOT_FOUND; } - const FileSys::VirtualDir zoneinfo_dir{extracted_romfs->GetSubdirectory("zoneinfo")}; + const FileSys::VirtualDir zoneinfo_dir{time_zone_binary->GetSubdirectory("zoneinfo")}; if (!zoneinfo_dir) { LOG_ERROR(Service_Time, "{:016X} has no directory zoneinfo!", time_zone_binary_titleid); 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 @@ #include <string> #include <vector> +#include "core/file_sys/vfs_types.h" #include "core/hle/service/time/time_zone_manager.h" namespace Core { @@ -41,6 +42,7 @@ private: Core::System& system; TimeZoneManager time_zone_manager; + const FileSys::VirtualDir time_zone_binary; const std::vector<std::string> location_name_cache; }; 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 // Load NSO modules modules.clear(); - const VAddr base_address{GetInteger(process.PageTable().GetCodeRegionStart())}; + const VAddr base_address{GetInteger(process.GetPageTable().GetCodeRegionStart())}; VAddr next_load_addr{base_address}; const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), 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, } codeset.memory = std::move(program_image); - const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart()); + const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); process.LoadModule(std::move(codeset), base_address); 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) // Load codeset for current process codeset.memory = std::move(program_image); - process.LoadModule(std::move(codeset), process.PageTable().GetCodeRegionStart()); + process.LoadModule(std::move(codeset), process.GetPageTable().GetCodeRegionStart()); return true; } 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 modules.clear(); // Load module - const VAddr base_address = GetInteger(process.PageTable().GetCodeRegionStart()); + const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); if (!LoadModule(process, system, *file, base_address, true, true)) { return {ResultStatus::ErrorLoadingNSO, {}}; } 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 @@ namespace Core::Memory { +namespace { + +bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessAddress addr, + const std::size_t size) { + const Common::ProcessAddress max_addr = 1ULL << table.GetAddressSpaceBits(); + return addr + size >= addr && addr + size <= max_addr; +} + +} // namespace + // Implementation class used to keep the specifics of the memory subsystem hidden // from outside classes. This also allows modification to the internals of the memory // subsystem without needing to rebuild all files that make use of the memory interface. @@ -31,10 +41,10 @@ struct Memory::Impl { explicit Impl(Core::System& system_) : system{system_} {} void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { - current_page_table = &process.PageTable().PageTableImpl(); + current_page_table = &process.GetPageTable().PageTableImpl(); current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer(); - const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth(); + const std::size_t address_space_width = process.GetPageTable().GetAddressSpaceWidth(); system.ArmInterface(core_id).PageTableChanged(*current_page_table, address_space_width); } @@ -73,7 +83,7 @@ struct Memory::Impl { return {}; } - return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr; + return system.DeviceMemory().GetPointer<u8>(paddr + vaddr); } [[nodiscard]] u8* GetPointerFromDebugMemory(u64 vaddr) const { @@ -84,7 +94,7 @@ struct Memory::Impl { return {}; } - return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr; + return system.DeviceMemory().GetPointer<u8>(paddr + vaddr); } u8 Read8(const Common::ProcessAddress addr) { @@ -183,13 +193,18 @@ struct Memory::Impl { return string; } - void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr, - const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer, - auto increment) { - const auto& page_table = process.PageTable().PageTableImpl(); + bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped, + auto on_memory, auto on_rasterizer, auto increment) { + const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl(); std::size_t remaining_size = size; std::size_t page_index = addr >> YUZU_PAGEBITS; std::size_t page_offset = addr & YUZU_PAGEMASK; + bool user_accessible = true; + + if (!AddressSpaceContains(page_table, addr, size)) [[unlikely]] { + on_unmapped(size, addr); + return false; + } while (remaining_size) { const std::size_t copy_amount = @@ -200,11 +215,13 @@ struct Memory::Impl { const auto [pointer, type] = page_table.pointers[page_index].PointerType(); switch (type) { case Common::PageType::Unmapped: { + user_accessible = false; on_unmapped(copy_amount, current_vaddr); break; } case Common::PageType::Memory: { - u8* mem_ptr = pointer + page_offset + (page_index << YUZU_PAGEBITS); + u8* mem_ptr = + reinterpret_cast<u8*>(pointer + page_offset + (page_index << YUZU_PAGEBITS)); on_memory(copy_amount, mem_ptr); break; } @@ -227,13 +244,15 @@ struct Memory::Impl { increment(copy_amount); remaining_size -= copy_amount; } + + return user_accessible; } template <bool UNSAFE> - void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr, - void* dest_buffer, const std::size_t size) { - WalkBlock( - process, src_addr, size, + bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer, + const std::size_t size) { + return WalkBlock( + src_addr, size, [src_addr, size, &dest_buffer](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, @@ -256,14 +275,14 @@ struct Memory::Impl { }); } - void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, + bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, const std::size_t size) { - ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size); + return ReadBlockImpl<false>(src_addr, dest_buffer, size); } - void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, + bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, const std::size_t size) { - ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size); + return ReadBlockImpl<true>(src_addr, dest_buffer, size); } const u8* GetSpan(const VAddr src_addr, const std::size_t size) const { @@ -283,10 +302,10 @@ struct Memory::Impl { } template <bool UNSAFE> - void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, - const void* src_buffer, const std::size_t size) { - WalkBlock( - process, dest_addr, size, + bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer, + const std::size_t size) { + return WalkBlock( + dest_addr, size, [dest_addr, size](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, @@ -308,20 +327,19 @@ struct Memory::Impl { }); } - void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, + bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, const std::size_t size) { - WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size); + return WriteBlockImpl<false>(dest_addr, src_buffer, size); } - void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, + bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, const std::size_t size) { - WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size); + return WriteBlockImpl<true>(dest_addr, src_buffer, size); } - void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, - const std::size_t size) { - WalkBlock( - process, dest_addr, size, + bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) { + return WalkBlock( + dest_addr, size, [dest_addr, size](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, @@ -339,23 +357,23 @@ struct Memory::Impl { [](const std::size_t copy_amount) {}); } - void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, - Common::ProcessAddress src_addr, const std::size_t size) { - WalkBlock( - process, dest_addr, size, + bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, + const std::size_t size) { + return WalkBlock( + dest_addr, size, [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", GetInteger(current_vaddr), GetInteger(src_addr), size); - ZeroBlock(process, dest_addr, copy_amount); + ZeroBlock(dest_addr, copy_amount); }, [&](const std::size_t copy_amount, const u8* const src_ptr) { - WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount); + WriteBlockImpl<false>(dest_addr, src_ptr, copy_amount); }, [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, u8* const host_ptr) { HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount); - WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount); + WriteBlockImpl<false>(dest_addr, host_ptr, copy_amount); }, [&](const std::size_t copy_amount) { dest_addr += copy_amount; @@ -364,13 +382,13 @@ struct Memory::Impl { } template <typename Callback> - Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, - std::size_t size, Callback&& cb) { + Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size, + Callback&& cb) { class InvalidMemoryException : public std::exception {}; try { WalkBlock( - process, dest_addr, size, + dest_addr, size, [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) { LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", GetInteger(current_vaddr)); @@ -387,41 +405,38 @@ struct Memory::Impl { return ResultSuccess; } - Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, - std::size_t size) { + Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size) { auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, const std::size_t block_size) { // dc ivac: Invalidate to point of coherency // GPU flush -> CPU invalidate HandleRasterizerDownload(GetInteger(current_vaddr), block_size); }; - return PerformCacheOperation(process, dest_addr, size, on_rasterizer); + return PerformCacheOperation(dest_addr, size, on_rasterizer); } - Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, - std::size_t size) { + Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size) { auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, const std::size_t block_size) { // dc cvac: Store to point of coherency // CPU flush -> GPU invalidate system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); }; - return PerformCacheOperation(process, dest_addr, size, on_rasterizer); + return PerformCacheOperation(dest_addr, size, on_rasterizer); } - Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, - std::size_t size) { + Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size) { auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, const std::size_t block_size) { // dc civac: Store to point of coherency, and invalidate from cache // CPU flush -> GPU invalidate system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); }; - return PerformCacheOperation(process, dest_addr, size, on_rasterizer); + return PerformCacheOperation(dest_addr, size, on_rasterizer); } void MarkRegionDebug(u64 vaddr, u64 size, bool debug) { - if (vaddr == 0) { + if (vaddr == 0 || !AddressSpaceContains(*current_page_table, vaddr, size)) { return; } @@ -448,7 +463,7 @@ struct Memory::Impl { break; case Common::PageType::Memory: current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( - nullptr, Common::PageType::DebugMemory); + 0, Common::PageType::DebugMemory); break; default: UNREACHABLE(); @@ -466,7 +481,8 @@ struct Memory::Impl { case Common::PageType::DebugMemory: { u8* const pointer{GetPointerFromDebugMemory(vaddr & ~YUZU_PAGEMASK)}; current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( - pointer - (vaddr & ~YUZU_PAGEMASK), Common::PageType::Memory); + reinterpret_cast<uintptr_t>(pointer) - (vaddr & ~YUZU_PAGEMASK), + Common::PageType::Memory); break; } default: @@ -477,7 +493,7 @@ struct Memory::Impl { } void RasterizerMarkRegionCached(u64 vaddr, u64 size, bool cached) { - if (vaddr == 0) { + if (vaddr == 0 || !AddressSpaceContains(*current_page_table, vaddr, size)) { return; } @@ -506,7 +522,7 @@ struct Memory::Impl { case Common::PageType::DebugMemory: case Common::PageType::Memory: current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( - nullptr, Common::PageType::RasterizerCachedMemory); + 0, Common::PageType::RasterizerCachedMemory); break; case Common::PageType::RasterizerCachedMemory: // There can be more than one GPU region mapped per CPU region, so it's common @@ -534,10 +550,11 @@ struct Memory::Impl { // pagetable after unmapping a VMA. In that case the underlying VMA will no // longer exist, and we should just leave the pagetable entry blank. current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( - nullptr, Common::PageType::Unmapped); + 0, Common::PageType::Unmapped); } else { current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Store( - pointer - (vaddr & ~YUZU_PAGEMASK), Common::PageType::Memory); + reinterpret_cast<uintptr_t>(pointer) - (vaddr & ~YUZU_PAGEMASK), + Common::PageType::Memory); } break; } @@ -584,7 +601,7 @@ struct Memory::Impl { "Mapping memory page without a pointer @ {:016x}", base * YUZU_PAGESIZE); while (base != end) { - page_table.pointers[base].Store(nullptr, type); + page_table.pointers[base].Store(0, type); page_table.backing_addr[base] = 0; page_table.blocks[base] = 0; base += 1; @@ -593,7 +610,8 @@ struct Memory::Impl { auto orig_base = base; while (base != end) { auto host_ptr = - system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS); + reinterpret_cast<uintptr_t>(system.DeviceMemory().GetPointer<u8>(target)) - + (base << YUZU_PAGEBITS); auto backing = GetInteger(target) - (base << YUZU_PAGEBITS); page_table.pointers[base].Store(host_ptr, type); page_table.backing_addr[base] = backing; @@ -612,15 +630,15 @@ struct Memory::Impl { // AARCH64 masks the upper 16 bit of all memory accesses vaddr = vaddr & 0xffffffffffffULL; - if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { + if (!AddressSpaceContains(*current_page_table, vaddr, 1)) [[unlikely]] { on_unmapped(); return nullptr; } // Avoid adding any extra logic to this fast-path block const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw(); - if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { - return &pointer[vaddr]; + if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { + return reinterpret_cast<u8*>(pointer + vaddr); } switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) { case Common::PageType::Unmapped: @@ -808,13 +826,13 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { const Kernel::KProcess& process = *system.ApplicationProcess(); - const auto& page_table = process.PageTable().PageTableImpl(); + const auto& page_table = process.GetPageTable().PageTableImpl(); const size_t page = vaddr >> YUZU_PAGEBITS; if (page >= page_table.pointers.size()) { return false; } const auto [pointer, type] = page_table.pointers[page].PointerType(); - return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory || + return pointer != 0 || type == Common::PageType::RasterizerCachedMemory || type == Common::PageType::DebugMemory; } @@ -899,14 +917,14 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le return impl->ReadCString(vaddr, max_length); } -void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, +bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, const std::size_t size) { - impl->ReadBlock(src_addr, dest_buffer, size); + return impl->ReadBlock(src_addr, dest_buffer, size); } -void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, +bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, const std::size_t size) { - impl->ReadBlockUnsafe(src_addr, dest_buffer, size); + return impl->ReadBlockUnsafe(src_addr, dest_buffer, size); } const 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) { return impl->GetSpan(src_addr, size); } -void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, +bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, const std::size_t size) { - impl->WriteBlock(dest_addr, src_buffer, size); + return impl->WriteBlock(dest_addr, src_buffer, size); } -void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, +bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, const std::size_t size) { - impl->WriteBlockUnsafe(dest_addr, src_buffer, size); + return impl->WriteBlockUnsafe(dest_addr, src_buffer, size); } -void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, +bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, const std::size_t size) { - impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size); + return impl->CopyBlock(dest_addr, src_addr, size); } -void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) { - impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size); +bool Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) { + return impl->ZeroBlock(dest_addr, size); } void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) { @@ -941,15 +959,15 @@ void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers } Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { - return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size); + return impl->InvalidateDataCache(dest_addr, size); } Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { - return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size); + return impl->StoreDataCache(dest_addr, size); } Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { - return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size); + return impl->FlushDataCache(dest_addr, size); } void 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; } // namespace Core namespace Kernel { -class PhysicalMemory; class KProcess; } // namespace Kernel @@ -330,7 +329,7 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * current process' address space. */ - void ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); + bool ReadBlock(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); /** * Reads a contiguous block of bytes from the current process' address space. @@ -349,7 +348,7 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * current process' address space. */ - void ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); + bool ReadBlockUnsafe(Common::ProcessAddress src_addr, void* dest_buffer, std::size_t size); const u8* GetSpan(const VAddr src_addr, const std::size_t size) const; u8* GetSpan(const VAddr src_addr, const std::size_t size); @@ -373,7 +372,7 @@ public: * and will mark that region as invalidated to caches that the active * graphics backend may be maintaining over the course of execution. */ - void WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size); + bool WriteBlock(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size); /** * Writes a range of bytes into the current process' address space at the specified @@ -391,7 +390,7 @@ public: * will be ignored and an error will be logged. * */ - void WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer, + bool WriteBlockUnsafe(Common::ProcessAddress dest_addr, const void* src_buffer, std::size_t size); /** @@ -405,7 +404,7 @@ public: * @post The range [dest_addr, size) within the process' address space contains the * same data within the range [src_addr, size). */ - void CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, + bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, std::size_t size); /** @@ -418,7 +417,7 @@ public: * @post The range [dest_addr, size) within the process' address space contains the * value 0. */ - void ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size); + bool ZeroBlock(Common::ProcessAddress dest_addr, std::size_t size); /** * 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() { metadata.process_id = system.ApplicationProcess()->GetProcessId(); metadata.title_id = system.GetApplicationProcessProgramID(); - const auto& page_table = system.ApplicationProcess()->PageTable(); + const auto& page_table = system.ApplicationProcess()->GetPageTable(); metadata.heap_extents = { .base = GetInteger(page_table.GetHeapRegionStart()), .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) { arm.SaveContext(context); return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32", - GetInteger(process->PageTable().GetCodeRegionStart()), context.sp, - context.pc, context.pstate, context.cpu_registers); + GetInteger(process->GetPageTable().GetCodeRegionStart()), + context.sp, context.pc, context.pstate, context.cpu_registers); } json 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 @@ // #include <deque> +#include <map> #include <span> +#include <unordered_map> #include <variant> #include <vector> -#include <boost/container/flat_map.hpp> - #include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/opcodes.h" #include "shader_recompiler/frontend/ir/pred.h" @@ -52,7 +52,7 @@ struct IndirectBranchVariable { using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, OverflowFlagTag, GotoVariable, IndirectBranchVariable>; -using ValueMap = boost::container::flat_map<IR::Block*, IR::Value>; +using ValueMap = std::unordered_map<IR::Block*, IR::Value>; struct DefTable { const IR::Value& Def(IR::Block* block, IR::Reg variable) { @@ -112,7 +112,7 @@ struct DefTable { } std::array<ValueMap, IR::NUM_USER_PREDS> preds; - boost::container::flat_map<u32, ValueMap> goto_vars; + std::unordered_map<u32, ValueMap> goto_vars; ValueMap indirect_branch_var; ValueMap zero_flag; ValueMap sign_flag; @@ -295,8 +295,7 @@ private: return same; } - boost::container::flat_map<IR::Block*, boost::container::flat_map<Variant, IR::Inst*>> - incomplete_phis; + std::unordered_map<IR::Block*, std::map<Variant, IR::Inst*>> incomplete_phis; DefTable current_def; }; 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 vulkan_common/nsight_aftermath_tracker.cpp vulkan_common/nsight_aftermath_tracker.h vulkan_common/vma.cpp + vulkan_common/vma.h + vulkan_common/vulkan.h ) create_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() { template <class P> void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, u32 cbuf_offset, bool is_written) { + if (ssbo_index >= channel_state->compute_storage_buffers.size()) [[unlikely]] { + LOG_ERROR(HW_GPU, "Storage buffer index {} exceeds maximum storage buffer count", + ssbo_index); + return; + } channel_state->enabled_compute_storage_buffers |= 1U << ssbo_index; channel_state->written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index; @@ -464,6 +469,11 @@ void BufferCache<P>::UnbindComputeTextureBuffers() { template <class P> void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, PixelFormat format, bool is_written, bool is_image) { + if (tbo_index >= channel_state->compute_texture_buffers.size()) [[unlikely]] { + LOG_ERROR(HW_GPU, "Texture buffer index {} exceeds maximum texture buffer count", + tbo_index); + return; + } channel_state->enabled_compute_texture_buffers |= 1U << tbo_index; channel_state->written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index; 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; constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18; constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8; constexpr u32 NUM_STORAGE_BUFFERS = 16; -constexpr u32 NUM_TEXTURE_BUFFERS = 16; +constexpr u32 NUM_TEXTURE_BUFFERS = 32; constexpr u32 NUM_STAGES = 5; using 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: explicit QueryCacheBase(VideoCore::RasterizerInterface& rasterizer_, Core::Memory::Memory& cpu_memory_) : rasterizer{rasterizer_}, - cpu_memory{cpu_memory_}, streams{{CounterStream{static_cast<QueryCache&>(*this), + // Use reinterpret_cast instead of static_cast as workaround for + // UBSan bug (https://github.com/llvm/llvm-project/issues/59060) + cpu_memory{cpu_memory_}, streams{{CounterStream{reinterpret_cast<QueryCache&>(*this), VideoCore::QueryType::SamplesPassed}}} { (void)slot_async_jobs.insert(); // Null value } 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 { using namespace Core::Memory; -RasterizerAccelerated::RasterizerAccelerated(Memory& cpu_memory_) : cpu_memory{cpu_memory_} {} +RasterizerAccelerated::RasterizerAccelerated(Memory& cpu_memory_) + : cached_pages(std::make_unique<CachedPages>()), cpu_memory{cpu_memory_} {} RasterizerAccelerated::~RasterizerAccelerated() = default; @@ -26,7 +27,7 @@ void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int del std::atomic_thread_fence(std::memory_order_acquire); const u64 page_end = Common::DivCeil(addr + size, YUZU_PAGESIZE); for (u64 page = addr >> YUZU_PAGEBITS; page != page_end; ++page) { - std::atomic_uint16_t& count = cached_pages.at(page >> 2).Count(page); + std::atomic_uint16_t& count = cached_pages->at(page >> 2).Count(page); if (delta > 0) { 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: }; static_assert(sizeof(CacheEntry) == 8, "CacheEntry should be 8 bytes!"); - std::array<CacheEntry, 0x2000000> cached_pages; + using CachedPages = std::array<CacheEntry, 0x2000000>; + std::unique_ptr<CachedPages> cached_pages; Core::Memory::Memory& cpu_memory; }; 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() { const VkDescriptorPoolCreateInfo ci{ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .pNext = nullptr, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .flags = 0, .maxSets = static_cast<u32>(image_count), .poolSizeCount = static_cast<u32>(pool_sizes.size()), .pPoolSizes = pool_sizes.data(), @@ -576,7 +576,7 @@ void BlitScreen::CreateDescriptorPool() { const VkDescriptorPoolCreateInfo ci_aa{ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .pNext = nullptr, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .flags = 0, .maxSets = static_cast<u32>(image_count), .poolSizeCount = static_cast<u32>(pool_sizes_aa.size()), .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) { bank.pools.push_back(device.GetLogical().CreateDescriptorPool({ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .pNext = nullptr, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .flags = 0, .maxSets = sets_per_pool, .poolSizeCount = static_cast<u32>(pool_cursor), .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() { const VkDescriptorPoolCreateInfo ci{ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .pNext = nullptr, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .flags = 0, .maxSets = static_cast<u32>(image_count * 2), .poolSizeCount = static_cast<u32>(pool_sizes.size()), .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) { auto descriptor_pool = dld.CreateDescriptorPool(VkDescriptorPoolCreateInfo{ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .pNext = nullptr, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .flags = 0, .maxSets = 1, .poolSizeCount = 1, .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 @@ // SPDX-License-Identifier: GPL-2.0-or-later #define VMA_IMPLEMENTATION -#define VMA_STATIC_VULKAN_FUNCTIONS 0 -#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 -#include <vk_mem_alloc.h>
\ No newline at end of file +#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 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "video_core/vulkan_common/vulkan.h" + +#define VMA_STATIC_VULKAN_FUNCTIONS 0 +#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 + +#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 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#define VK_NO_PROTOTYPES +#ifdef _WIN32 +#define VK_USE_PLATFORM_WIN32_KHR +#elif defined(__APPLE__) +#define VK_USE_PLATFORM_METAL_EXT +#endif + +#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 @@ #include "common/polyfill_ranges.h" #include "common/settings.h" #include "video_core/vulkan_common/nsight_aftermath_tracker.h" +#include "video_core/vulkan_common/vma.h" #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_wrapper.h" @@ -22,8 +23,6 @@ #include <adrenotools/bcenabler.h> #endif -#include <vk_mem_alloc.h> - namespace Vulkan { using namespace Common::Literals; namespace { @@ -526,6 +525,13 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR dynamic_state3_enables = false; } } + if (extensions.extended_dynamic_state3 && is_amd_driver) { + LOG_WARNING(Render_Vulkan, + "AMD drivers have broken extendedDynamicState3ColorBlendEquation"); + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; + dynamic_state3_blending = false; + } if (extensions.vertex_input_dynamic_state && is_radv) { // TODO(ameerj): Blacklist only offending driver versions // TODO(ameerj): Confirm if RDNA1 is affected @@ -554,14 +560,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } sets_per_pool = 64; - if (extensions.extended_dynamic_state3 && is_amd_driver && - properties.properties.driverVersion >= VK_MAKE_API_VERSION(0, 2, 0, 270)) { - LOG_WARNING(Render_Vulkan, - "AMD drivers after 23.5.2 have broken extendedDynamicState3ColorBlendEquation"); - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; - dynamic_state3_blending = false; - } if (is_amd_driver) { // AMD drivers need a higher amount of Sets per Pool in certain circumstances like in XC2. 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 @@ #include "common/common_types.h" #include "common/logging/log.h" #include "common/polyfill_ranges.h" +#include "video_core/vulkan_common/vma.h" #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_memory_allocator.h" #include "video_core/vulkan_common/vulkan_wrapper.h" -#include <vk_mem_alloc.h> - namespace Vulkan { namespace { struct 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 @@ #include "common/common_types.h" #include "common/logging/log.h" - +#include "video_core/vulkan_common/vma.h" #include "video_core/vulkan_common/vulkan_wrapper.h" -#include <vk_mem_alloc.h> - namespace Vulkan::vk { namespace { 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 @@ #include <utility> #include <vector> -#define VK_NO_PROTOTYPES -#ifdef _WIN32 -#define VK_USE_PLATFORM_WIN32_KHR -#elif defined(__APPLE__) -#define VK_USE_PLATFORM_METAL_EXT -#endif -#include <vulkan/vulkan.h> +#include "common/common_types.h" +#include "video_core/vulkan_common/vulkan.h" // Sanitize macros #ifdef CreateEvent @@ -28,8 +23,6 @@ #undef CreateSemaphore #endif -#include "common/common_types.h" - #ifdef _MSC_VER #pragma warning(disable : 26812) // Disable prefer enum class over enum #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 @@ #include <chrono> #include <string> + +#include <QEventLoop> +#include <QNetworkAccessManager> +#include <QNetworkReply> + #include <discord_rpc.h> #include <fmt/format.h> -#include <httplib.h> + #include "common/common_types.h" #include "common/string_util.h" #include "core/core.h" @@ -31,7 +36,7 @@ void DiscordImpl::Pause() { Discord_ClearPresence(); } -static std::string GetGameString(const std::string& title) { +std::string DiscordImpl::GetGameString(const std::string& title) { // Convert to lowercase std::string icon_name = Common::ToLower(title); @@ -56,51 +61,56 @@ static std::string GetGameString(const std::string& title) { return icon_name; } -void DiscordImpl::Update() { +void DiscordImpl::UpdateGameStatus(bool use_default) { + const std::string default_text = "yuzu is an emulator for the Nintendo Switch"; + const std::string default_image = "yuzu_logo"; + const std::string url = use_default ? default_image : game_url; s64 start_time = std::chrono::duration_cast<std::chrono::seconds>( std::chrono::system_clock::now().time_since_epoch()) .count(); + DiscordRichPresence presence{}; + + presence.largeImageKey = url.c_str(); + presence.largeImageText = game_title.c_str(); + presence.smallImageKey = default_image.c_str(); + presence.smallImageText = default_text.c_str(); + presence.state = game_title.c_str(); + presence.details = "Currently in game"; + presence.startTimestamp = start_time; + Discord_UpdatePresence(&presence); +} + +void DiscordImpl::Update() { const std::string default_text = "yuzu is an emulator for the Nintendo Switch"; const std::string default_image = "yuzu_logo"; - std::string game_cover_url = "https://yuzu-emu.org"; - std::string title; - - DiscordRichPresence presence{}; if (system.IsPoweredOn()) { - system.GetAppLoader().ReadTitle(title); + system.GetAppLoader().ReadTitle(game_title); // Used to format Icon URL for yuzu website game compatibility page - std::string icon_name = GetGameString(title); - - // New Check for game cover - httplib::Client cli(game_cover_url); - cli.set_connection_timeout(std::chrono::seconds(3)); - cli.set_read_timeout(std::chrono::seconds(3)); - - if (auto res = cli.Head(fmt::format("/images/game/boxart/{}.png", icon_name))) { - if (res->status == 200) { - game_cover_url += fmt::format("/images/game/boxart/{}.png", icon_name); - } else { - game_cover_url = "yuzu_logo"; - } - } else { - game_cover_url = "yuzu_logo"; - } - - presence.largeImageKey = game_cover_url.c_str(); - presence.largeImageText = title.c_str(); - - presence.smallImageKey = default_image.c_str(); - presence.smallImageText = default_text.c_str(); - presence.state = title.c_str(); - presence.details = "Currently in game"; - } else { - presence.largeImageKey = default_image.c_str(); - presence.largeImageText = default_text.c_str(); - presence.details = "Currently not in game"; + std::string icon_name = GetGameString(game_title); + game_url = fmt::format("https://yuzu-emu.org/images/game/boxart/{}.png", icon_name); + + QNetworkAccessManager manager; + QNetworkRequest request; + request.setUrl(QUrl(QString::fromStdString(game_url))); + request.setTransferTimeout(3000); + QNetworkReply* reply = manager.head(request); + QEventLoop request_event_loop; + QObject::connect(reply, &QNetworkReply::finished, &request_event_loop, &QEventLoop::quit); + request_event_loop.exec(); + UpdateGameStatus(reply->error()); + return; } + s64 start_time = std::chrono::duration_cast<std::chrono::seconds>( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + + DiscordRichPresence presence{}; + presence.largeImageKey = default_image.c_str(); + presence.largeImageText = default_text.c_str(); + presence.details = "Currently not in game"; presence.startTimestamp = start_time; Discord_UpdatePresence(&presence); } 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: void Pause() override; void Update() override; +private: + std::string GetGameString(const std::string& title); + void UpdateGameStatus(bool use_default); + + std::string game_url{}; + std::string game_title{}; + Core::System& system; }; 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; void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { using namespace FileSys; - const auto& cache = dynamic_cast<ContentProviderUnion&>(system.GetContentProvider()); + const auto& cache = system.GetContentProviderUnion(); auto installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application, ContentRecordType::Program); @@ -265,7 +265,11 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { std::vector<u8> icon; std::string name; u64 program_id = 0; - loader->ReadProgramId(program_id); + const auto result = loader->ReadProgramId(program_id); + + if (result != Loader::ResultStatus::Success) { + continue; + } const PatchManager patch{program_id, system.GetFileSystemController(), system.GetContentProvider()}; |