diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..577f336af --- /dev/null +++ b/Dockerfile @@ -0,0 +1,80 @@ +FROM devkitpro/devkita64:20260219 + +ARG PYTHON_VERSION=2.7.18 +ARG PYTHON_SHA256=da3080e3b488f648a3d7a4560ddee895284c3380b11d6de75edb986526b9a814 +ARG PYTHON_LZ4_VERSION=2.2.1 +ARG PYTHON_LZ4_SHA256=9f529a443f9eb1b49d040f0791bb3934c64b9a927609a30319c3b82f93d9525a + +RUN apt update && \ + apt install automake build-essential ca-certificates wget libbz2-dev libffi-dev libgdbm-dev liblz4-dev libncurses5-dev libreadline-dev libsqlite3-dev libssl-dev liblzma-dev sudo tk-dev uuid-dev zlib1g-dev python3-lz4 python3-pip -y && \ + cd /tmp && \ + wget -q https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz && \ + echo "${PYTHON_SHA256} Python-${PYTHON_VERSION}.tgz" | sha256sum --check && \ + tar -xzf Python-${PYTHON_VERSION}.tgz && \ + cd /tmp/Python-${PYTHON_VERSION} && \ + ./configure --prefix=/usr/local --with-ensurepip=install && \ + make -j"$(nproc)" altinstall && \ + cd /tmp && \ + wget -q https://files.pythonhosted.org/packages/86/4f/028a9ff9cfc73f317c22dc3b8f29a7c5c94098d4da590405e6b78af00e57/lz4-${PYTHON_LZ4_VERSION}-cp27-cp27m-manylinux1_x86_64.whl && \ + echo "${PYTHON_LZ4_SHA256} lz4-${PYTHON_LZ4_VERSION}-cp27-cp27m-manylinux1_x86_64.whl" | sha256sum --check && \ + /usr/local/bin/python2.7 -m pip install --no-deps --no-index lz4-${PYTHON_LZ4_VERSION}-cp27-cp27m-manylinux1_x86_64.whl && \ + ln -fs /usr/local/bin/python2.7 /usr/local/bin/python2 && \ + ln -fs /usr/local/bin/python2.7 /usr/local/bin/python && \ + rm -rf /tmp/Python-${PYTHON_VERSION} /tmp/Python-${PYTHON_VERSION}.tgz /tmp/lz4-${PYTHON_LZ4_VERSION}-cp27-cp27m-manylinux1_x86_64.whl && \ + rm -rf /var/lib/apt/lists/* /var/cache/apt/* /usr/share/doc /usr/share/man + +# Install latest hactool & switch-tools from dkp pacman & update everything +RUN dkp-pacman -S switch-tools hactool --noconfirm && dkp-pacman -Syu --noconfirm + +# # Install hactool from Git (optional) +# ENV HACTOOL_REV=1d64a83450e025622f3468c28fc4164dad2c5ef6 +# RUN cd /tmp && \ +# mkdir -p /tmp/hactool && \ +# cd /tmp/hactool && \ +# git init && \ +# git remote add origin https://github.com/SciresM/hactool.git && \ +# git fetch --depth 1 origin $HACTOOL_REV && \ +# git reset --hard FETCH_HEAD && \ +# cp config.mk.template config.mk && \ +# make -j$(nproc) && \ +# cp hactool /opt/devkitpro/tools/bin/hactool && \ +# cd /tmp && \ +# rm -rf /tmp/hactool + +# # Install switch-tools from Git (optional) +# ENV SWITCH_TOOLS_REV=22756068dd0ed6ff9734c59cb4f99ebd3f62555b +# RUN cd /tmp && \ +# mkdir -p /tmp/switch-tools && \ +# cd /tmp/switch-tools && \ +# git init && \ +# git remote add origin https://github.com/switchbrew/switch-tools.git && \ +# git fetch --depth 1 origin $SWITCH_TOOLS_REV && \ +# git reset --hard FETCH_HEAD && \ +# ./autogen.sh && ./configure && make -j$(nproc) && \ +# make install prefix=/opt/devkitpro/tools && \ +# cd /tmp && \ +# rm -rf /tmp/switch-tools + +# Install libnx from Git (optional) +# ENV LIBNX_REV=146c3d1446d35546943c7b6cfcd479bc1f5e9b67 +# RUN cd /tmp && \ +# mkdir -p /tmp/libnx && \ +# cd /tmp/libnx && \ +# git init && \ +# git remote add origin https://github.com/switchbrew/libnx.git && \ +# git fetch --depth 1 origin $LIBNX_REV && \ +# git reset --hard FETCH_HEAD && \ +# make -j$(nproc) && \ +# cd nx && \ +# make install && \ +# cd /tmp && \ +# rm -rf /tmp/libnx + +RUN useradd -m atmosphere && \ + echo "atmosphere ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/atmosphere && \ + chmod 0440 /etc/sudoers.d/atmosphere && \ + echo "atmosphere:atmosphere" | chpasswd && \ + usermod -aG sudo atmosphere + +USER atmosphere +CMD ["/bin/bash"] diff --git a/docs/changelog.md b/docs/changelog.md index c1b43d17b..a5aa53a87 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,36 @@ # Changelog +## 1.12.0 ++ Support was added for 23.0.0. ++ Special thanks to @alula for handling the implementation of several kernel changes. + + The console should boot and atmosphère should be fully functional. + + **Please note**: As a result of changes made to nintendo's software in 23.0.0, there is even less memory available for custom system modules. + + The amount of memory we can steal from the applet pool has been reduced beyond 7MB and we can no longer launch browser applets (e.g.: eshop) without crashing. + + To compensate for this, a set of patches for the browser applets has been introduced. + + Thanks to the redesign of the browser applets in 22.0.0 there are only 3 applets we need to worry about: systemWeb, openWeb and LibAppletOff. + + With the added burden of maintaining patches for these applets, we can reclaim around 9MB of reserved memory by patching out their allocations. + + This memory is provably unused and stealing it should not affect the browser applets in any way as the applets themselves tag it as reserved and never access it. + + As a result, the memory available for custom system modules has been experimentally increased to 16MB. + + Preliminary testing has seemingly shown no downsides to the overall functioning of the OS and the browser applets in particular. + + Nonetheless, please report any issues you may face to ensure no edge cases have been missed and to determine if the memory amount needs to be adjusted. + + These patches may be deprecated at any point in the future if a better solution is devised. + + `exosphère` was updated to reflect the latest official secure monitor behavior. + + A new ConfigItem was added to the secure monitor for the first time since firmware 5.0.0. + + `mesosphère` was updated to reflect the latest official kernel behavior. + + The kernel now supports a 42bit wide address space. + + A new memory region dubbed ShadowStack has been introduced. + + Kernel RNG was changed to CTR-DRBG. + + `boot` was updated to reflect the latest official behavior and to implement a previously missing change. + + The way battery i2c shutdown was being enabled changed in firmware 18.0.0 and we missed it. + + It is possible this might have been related to a known battery draining issue reported to have started around firmware 18.0.0. Further testing will be needed to confirm. + + `loader` was updated to reflect the latest official behavior. + + `erpt` was updated to reflect the latest official behavior. + + `pgl` was updated to reflect the latest official behavior. + + `ro` was updated to reflect the latest official behavior. + + NROs can now be lz4 frame compressed. ++ ZBIC compresison/decompression has been properly implemented. Applications using it should now launch and work properly. ++ A dockerfile has been added to atmosphère (thanks @alula). ++ R_DISCARD macro has been adopted across the entire codebase where applicable. This finishes the work started in version 1.10.0 and eliminates the nodiscard warnings during compilation. ++ General system stability improvements to enhance the user's experience. ## 1.11.2 + Basic support was added for 22.5.0. + Atmosphère was updated to use GCC 16/newlib (latest devkitA64/devkitARM releases). diff --git a/emummc/.gitrepo b/emummc/.gitrepo index 503f95eb1..eea652603 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = f6b3a28ecea9834f96151a526de66abd11033b70 - parent = 1478f3443e8f04534edac8c15bf2d504663d0384 + commit = 5b966b6f3f83349ec65066a1877f7f948b48d08c + parent = 7442487ace6b79ddddf2cd0007b8dade8150bf5c method = merge cmdver = 0.4.9 diff --git a/emummc/README.md b/emummc/README.md index f63004065..752223788 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 22.5.0** +**1.0.0 - 23.0.0** ## Features * Arbitrary SDMMC backend selection diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index 133e0e816..f7a2bacf8 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -87,6 +87,8 @@ #include "offsets/2200_exfat.h" #include "offsets/2250.h" #include "offsets/2250_exfat.h" +#include "offsets/2300.h" +#include "offsets/2300_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -185,6 +187,8 @@ DEFINE_OFFSET_STRUCT(_2200); DEFINE_OFFSET_STRUCT(_2200_EXFAT); DEFINE_OFFSET_STRUCT(_2250); DEFINE_OFFSET_STRUCT(_2250_EXFAT); +DEFINE_OFFSET_STRUCT(_2300); +DEFINE_OFFSET_STRUCT(_2300_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -330,6 +334,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_2250)); case FS_VER_22_5_0_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_2250_EXFAT)); + case FS_VER_23_0_0: + return &(GET_OFFSET_STRUCT_NAME(_2300)); + case FS_VER_23_0_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_2300_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index af2913d0f..d2c240b20 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -127,6 +127,9 @@ enum FS_VER FS_VER_22_5_0, FS_VER_22_5_0_EXFAT, + + FS_VER_23_0_0, + FS_VER_23_0_0_EXFAT, FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/2300.h b/emummc/source/FS/offsets/2300.h new file mode 100644 index 000000000..87bd5b130 --- /dev/null +++ b/emummc/source/FS/offsets/2300.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_2300_H__ +#define __FS_2300_H__ + +// Accessor vtable getters +#define FS_OFFSET_2300_SDMMC_ACCESSOR_GC 0x1B3640 +#define FS_OFFSET_2300_SDMMC_ACCESSOR_SD 0x1B5640 +#define FS_OFFSET_2300_SDMMC_ACCESSOR_NAND 0x1B3C70 + +// Hooks +#define FS_OFFSET_2300_SDMMC_WRAPPER_READ 0x1AF570 +#define FS_OFFSET_2300_SDMMC_WRAPPER_WRITE 0x1AF5D0 +#define FS_OFFSET_2300_RTLD 0x2F520 +#define FS_OFFSET_2300_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) + +#define FS_OFFSET_2300_CLKRST_SET_MIN_V_CLK_RATE 0x1D27E0 + +// Misc funcs +#define FS_OFFSET_2300_LOCK_MUTEX 0x1A8090 +#define FS_OFFSET_2300_UNLOCK_MUTEX 0x1A80E0 + +#define FS_OFFSET_2300_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AF530 +#define FS_OFFSET_2300_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AF550 + +// Misc Data +#define FS_OFFSET_2300_SD_MUTEX 0xFF5408 +#define FS_OFFSET_2300_NAND_MUTEX 0xFF0D70 +#define FS_OFFSET_2300_ACTIVE_PARTITION 0xFF0DB0 +#define FS_OFFSET_2300_SDMMC_DAS_HANDLE 0xFD2BE8 + +// NOPs +#define FS_OFFSET_2300_SD_DAS_INIT 0x2CA98 + +// Nintendo Paths +#define FS_OFFSET_2300_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00072D7C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00081BA4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0008A668, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0009F97C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_2300_H__ diff --git a/emummc/source/FS/offsets/2300_exfat.h b/emummc/source/FS/offsets/2300_exfat.h new file mode 100644 index 000000000..a0f49372f --- /dev/null +++ b/emummc/source/FS/offsets/2300_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_2300_EXFAT_H__ +#define __FS_2300_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_2300_EXFAT_SDMMC_ACCESSOR_GC 0x1BE840 +#define FS_OFFSET_2300_EXFAT_SDMMC_ACCESSOR_SD 0x1C0840 +#define FS_OFFSET_2300_EXFAT_SDMMC_ACCESSOR_NAND 0x1BEE70 + +// Hooks +#define FS_OFFSET_2300_EXFAT_SDMMC_WRAPPER_READ 0x1BA770 +#define FS_OFFSET_2300_EXFAT_SDMMC_WRAPPER_WRITE 0x1BA7D0 +#define FS_OFFSET_2300_EXFAT_RTLD 0x2F530 +#define FS_OFFSET_2300_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) + +#define FS_OFFSET_2300_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1DD9E0 + +// Misc funcs +#define FS_OFFSET_2300_EXFAT_LOCK_MUTEX 0x1B3290 +#define FS_OFFSET_2300_EXFAT_UNLOCK_MUTEX 0x1B32E0 + +#define FS_OFFSET_2300_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1BA730 +#define FS_OFFSET_2300_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1BA750 + +// Misc Data +#define FS_OFFSET_2300_EXFAT_SD_MUTEX 0x1006408 +#define FS_OFFSET_2300_EXFAT_NAND_MUTEX 0x1001D70 +#define FS_OFFSET_2300_EXFAT_ACTIVE_PARTITION 0x1001DB0 +#define FS_OFFSET_2300_EXFAT_SDMMC_DAS_HANDLE 0xFDFBE8 + +// NOPs +#define FS_OFFSET_2300_EXFAT_SD_DAS_INIT 0x2CAA8 + +// Nintendo Paths +#define FS_OFFSET_2300_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00072D8C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00081BB4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0008A678, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0009F98C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_2300_EXFAT_H__ \ No newline at end of file diff --git a/exosphere/program/source/boot/secmon_boot_key_data.s b/exosphere/program/source/boot/secmon_boot_key_data.s index f418d25c9..8ccccbed3 100644 --- a/exosphere/program/source/boot/secmon_boot_key_data.s +++ b/exosphere/program/source/boot/secmon_boot_key_data.s @@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: /* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */ /* TODO: Update on next change of keys. */ /* Mariko Development Master Kek Source. */ -.byte 0x2E, 0x27, 0x44, 0xEA, 0x32, 0xF8, 0x2C, 0xF0, 0x6F, 0xCA, 0xCD, 0x77, 0xAE, 0xAE, 0x1A, 0x1B +.byte 0x2B, 0xCD, 0xE7, 0xA4, 0x93, 0x12, 0x0A, 0x72, 0x64, 0x2B, 0x9E, 0xA4, 0xC2, 0x9F, 0xED, 0x13 /* Mariko Production Master Kek Source. */ -.byte 0x82, 0xE2, 0x0A, 0x59, 0x67, 0xDF, 0xBF, 0x51, 0x47, 0x62, 0x11, 0xF2, 0x41, 0xD3, 0xEE, 0x13 +.byte 0x08, 0x11, 0xF7, 0xE8, 0x76, 0x9E, 0xA3, 0xD5, 0x3A, 0x3D, 0x7A, 0x68, 0x1A, 0x24, 0x2A, 0x99 /* Development Master Key Vectors. */ .byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */ @@ -113,6 +113,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE /* Master key 12 encrypted with Master key 13. */ .byte 0x74, 0xB2, 0x5F, 0xA0, 0x4B, 0x74, 0x6D, 0x47, 0x5B, 0xA9, 0xF5, 0x26, 0x46, 0xD7, 0x4B, 0x6E /* Master key 13 encrypted with Master key 14. */ .byte 0x97, 0xB3, 0x61, 0x88, 0x5C, 0x0D, 0xA1, 0x38, 0x73, 0xA4, 0x2F, 0x1A, 0x46, 0xA1, 0x09, 0xBF /* Master key 14 encrypted with Master key 15. */ +.byte 0xA6, 0x25, 0x12, 0x6D, 0xA1, 0x12, 0x1F, 0x15, 0x08, 0x2F, 0x30, 0x5F, 0xCB, 0x7D, 0x32, 0x82 /* Master key 15 encrypted with Master key 16. */ /* Production Master Key Vectors. */ .byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */ @@ -137,6 +138,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 /* Master key 12 encrypted with Master key 13. */ .byte 0xF7, 0x92, 0xC0, 0xEC, 0xF3, 0xA4, 0x8C, 0xB7, 0x0D, 0xB3, 0xF3, 0xAB, 0x10, 0x9B, 0x18, 0xBA /* Master key 13 encrypted with Master key 14. */ .byte 0x14, 0xCB, 0x60, 0x29, 0x3D, 0xE0, 0xFB, 0xF2, 0x5B, 0x60, 0xB6, 0xC5, 0x2E, 0x77, 0x8F, 0x98 /* Master key 14 encrypted with Master key 15. */ +.byte 0x26, 0x87, 0xDF, 0x21, 0x44, 0xD4, 0x5F, 0x4E, 0x61, 0x03, 0x9E, 0xF3, 0x40, 0x04, 0xC3, 0x87 /* Master Key 15 encrypted with Master Key 16. */ /* Device Master Key Source Sources. */ .byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */ @@ -158,6 +160,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 /* 20.0.0 Device Master Key Source Source. */ .byte 0xF9, 0x62, 0x05, 0x99, 0xE0, 0xB9, 0xA6, 0x9B, 0x9D, 0xAA, 0xB4, 0x12, 0x0B, 0x0F, 0xF5, 0x8F /* 21.0.0 Device Master Key Source Source. */ .byte 0xF8, 0xF4, 0x22, 0xA4, 0x34, 0xAE, 0x0E, 0x0C, 0x4D, 0x5C, 0x5B, 0xA1, 0x1B, 0x46, 0x1C, 0x78 /* 22.0.0 Device Master Key Source Source. */ +.byte 0x95, 0xC1, 0xAC, 0xB7, 0xB2, 0xCA, 0x9B, 0x8C, 0xD5, 0xEA, 0x40, 0xD9, 0x9C, 0xD2, 0x7C, 0x47 /* 23.0.0 Device Master Key Source Source. */ /* Development Device Master Kek Sources. */ .byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */ @@ -179,6 +182,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D /* 20.0.0 Device Master Kek Source. */ .byte 0x7A, 0x4C, 0x38, 0xB7, 0x03, 0x6B, 0x1E, 0x81, 0x20, 0x53, 0x14, 0x99, 0xA4, 0x21, 0x92, 0x9F /* 21.0.0 Device Master Kek Source. */ .byte 0xF3, 0xBC, 0xB5, 0xB5, 0x5F, 0x01, 0x50, 0x2B, 0x69, 0x69, 0x3A, 0x6B, 0xF9, 0x2C, 0x11, 0x9F /* 22.0.0 Device Master Kek Source. */ +.byte 0x54, 0xAD, 0x79, 0x15, 0x11, 0x7C, 0x1E, 0x52, 0xBF, 0x2E, 0x40, 0xBB, 0x8B, 0x11, 0x54, 0x38 /* 23.0.0 Device Master Kek Source. */ /* Production Device Master Kek Sources. */ .byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */ @@ -199,4 +203,5 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */ .byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */ .byte 0x92, 0xBF, 0x37, 0x80, 0x0E, 0x79, 0x56, 0x8C, 0x57, 0x75, 0x72, 0x0A, 0x48, 0xD8, 0x15, 0x39 /* 21.0.0 Device Master Kek Source. */ -.byte 0xC4, 0x6F, 0x0E, 0x72, 0x43, 0xCE, 0x87, 0xFC, 0x38, 0x95, 0x9B, 0xC9, 0x31, 0x44, 0x97, 0x63 /* 22.0.0 Device Master Kek Source. */ \ No newline at end of file +.byte 0xC4, 0x6F, 0x0E, 0x72, 0x43, 0xCE, 0x87, 0xFC, 0x38, 0x95, 0x9B, 0xC9, 0x31, 0x44, 0x97, 0x63 /* 22.0.0 Device Master Kek Source. */ +.byte 0xA0, 0xC8, 0x44, 0x39, 0x8A, 0x1F, 0xD8, 0x6A, 0x3D, 0x0A, 0x23, 0xFF, 0x43, 0xA6, 0x95, 0x80 /* 23.0.0 Device Master Kek Source. */ \ No newline at end of file diff --git a/exosphere/program/source/boot/secmon_package2.cpp b/exosphere/program/source/boot/secmon_package2.cpp index 005549f4a..cd8dfbb85 100644 --- a/exosphere/program/source/boot/secmon_package2.cpp +++ b/exosphere/program/source/boot/secmon_package2.cpp @@ -94,7 +94,7 @@ namespace ams::secmon::boot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 22); + static_assert(pkg1::KeyGeneration_Count == 23); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index 88cdeefe0..8c0710b04 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -271,6 +271,9 @@ namespace ams::secmon::smc { std::memcpy(std::addressof(args.r[1]), std::addressof(tmp_hash), sizeof(tmp_hash)); } break; + case ConfigItem::Unknown18: + args.r[1] = GetBootConfig().data.GetUnknown70(); + break; case ConfigItem::ExosphereApiVersion: /* Get information about the current exosphere version. */ if (kern || g_set_true_target_firmware) { diff --git a/exosphere/program/source/smc/secmon_smc_info.hpp b/exosphere/program/source/smc/secmon_smc_info.hpp index 605bbf333..2f81d066d 100644 --- a/exosphere/program/source/smc/secmon_smc_info.hpp +++ b/exosphere/program/source/smc/secmon_smc_info.hpp @@ -38,6 +38,7 @@ namespace ams::secmon::smc { RegulatorType = 15, DeviceUniqueKeyGeneration = 16, Package2Hash = 17, + Unknown18 = 18, /* Extension config items for exosphere. */ ExosphereApiVersion = 65000, diff --git a/fusee/program/source/fusee_key_derivation.cpp b/fusee/program/source/fusee_key_derivation.cpp index f392f67c6..ea9d3387e 100644 --- a/fusee/program/source/fusee_key_derivation.cpp +++ b/fusee/program/source/fusee_key_derivation.cpp @@ -23,17 +23,17 @@ namespace ams::nxboot { alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x82, 0xE2, 0x0A, 0x59, 0x67, 0xDF, 0xBF, 0x51, 0x47, 0x62, 0x11, 0xF2, 0x41, 0xD3, 0xEE, 0x13 + 0x08, 0x11, 0xF7, 0xE8, 0x76, 0x9E, 0xA3, 0xD5, 0x3A, 0x3D, 0x7A, 0x68, 0x1A, 0x24, 0x2A, 0x99 }; alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x2E, 0x27, 0x44, 0xEA, 0x32, 0xF8, 0x2C, 0xF0, 0x6F, 0xCA, 0xCD, 0x77, 0xAE, 0xAE, 0x1A, 0x1B + 0x2B, 0xCD, 0xE7, 0xA4, 0x93, 0x12, 0x0A, 0x72, 0x64, 0x2B, 0x9E, 0xA4, 0xC2, 0x9F, 0xED, 0x13 }; alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x15, 0xAC, 0x96, 0x34, 0xF5, 0x32, 0x56, 0x68, 0xFE, 0x5B, 0x9D, 0xD7, 0xED, 0x19, 0xB7, 0x8E + 0x92, 0xC8, 0x9C, 0x8A, 0x58, 0xE6, 0xE7, 0xB6, 0xE4, 0x27, 0xE2, 0x31, 0xEF, 0x4B, 0xD8, 0x82 }; alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = { @@ -76,6 +76,7 @@ namespace ams::nxboot { { 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 }, /* 20.0.0 Device Master Key Source Source. */ { 0xF9, 0x62, 0x05, 0x99, 0xE0, 0xB9, 0xA6, 0x9B, 0x9D, 0xAA, 0xB4, 0x12, 0x0B, 0x0F, 0xF5, 0x8F }, /* 21.0.0 Device Master Key Source Source. */ { 0xF8, 0xF4, 0x22, 0xA4, 0x34, 0xAE, 0x0E, 0x0C, 0x4D, 0x5C, 0x5B, 0xA1, 0x1B, 0x46, 0x1C, 0x78 }, /* 22.0.0 Device Master Key Source Source. */ + { 0x95, 0xC1, 0xAC, 0xB7, 0xB2, 0xCA, 0x9B, 0x8C, 0xD5, 0xEA, 0x40, 0xD9, 0x9C, 0xD2, 0x7C, 0x47 }, /* 23.0.0 Device Master Key Source Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -98,6 +99,7 @@ namespace ams::nxboot { { 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 }, /* 20.0.0 Device Master Kek Source. */ { 0x92, 0xBF, 0x37, 0x80, 0x0E, 0x79, 0x56, 0x8C, 0x57, 0x75, 0x72, 0x0A, 0x48, 0xD8, 0x15, 0x39 }, /* 21.0.0 Device Master Kek Source. */ { 0xC4, 0x6F, 0x0E, 0x72, 0x43, 0xCE, 0x87, 0xFC, 0x38, 0x95, 0x9B, 0xC9, 0x31, 0x44, 0x97, 0x63 }, /* 22.0.0 Device Master Kek Source. */ + { 0xA0, 0xC8, 0x44, 0x39, 0x8A, 0x1F, 0xD8, 0x6A, 0x3D, 0x0A, 0x23, 0xFF, 0x43, 0xA6, 0x95, 0x80 }, /* 23.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -120,6 +122,7 @@ namespace ams::nxboot { { 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D }, /* 20.0.0 Device Master Kek Source. */ { 0x7A, 0x4C, 0x38, 0xB7, 0x03, 0x6B, 0x1E, 0x81, 0x20, 0x53, 0x14, 0x99, 0xA4, 0x21, 0x92, 0x9F }, /* 21.0.0 Device Master Kek Source. */ { 0xF3, 0xBC, 0xB5, 0xB5, 0x5F, 0x01, 0x50, 0x2B, 0x69, 0x69, 0x3A, 0x6B, 0xF9, 0x2C, 0x11, 0x9F }, /* 22.0.0 Device Master Kek Source. */ + { 0x54, 0xAD, 0x79, 0x15, 0x11, 0x7C, 0x1E, 0x52, 0xBF, 0x2E, 0x40, 0xBB, 0x8B, 0x11, 0x54, 0x38 }, /* 23.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -145,6 +148,7 @@ namespace ams::nxboot { { 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 }, /* Master key 12 encrypted with Master key 13. */ { 0xF7, 0x92, 0xC0, 0xEC, 0xF3, 0xA4, 0x8C, 0xB7, 0x0D, 0xB3, 0xF3, 0xAB, 0x10, 0x9B, 0x18, 0xBA }, /* Master key 13 encrypted with Master key 14. */ { 0x14, 0xCB, 0x60, 0x29, 0x3D, 0xE0, 0xFB, 0xF2, 0x5B, 0x60, 0xB6, 0xC5, 0x2E, 0x77, 0x8F, 0x98 }, /* Master key 14 encrypted with Master key 15. */ + { 0x26, 0x87, 0xDF, 0x21, 0x44, 0xD4, 0x5F, 0x4E, 0x61, 0x03, 0x9E, 0xF3, 0x40, 0x04, 0xC3, 0x87 }, /* Master key 15 encrypted with Master key 16. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -170,6 +174,7 @@ namespace ams::nxboot { { 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE }, /* Master key 12 encrypted with Master key 13. */ { 0x74, 0xB2, 0x5F, 0xA0, 0x4B, 0x74, 0x6D, 0x47, 0x5B, 0xA9, 0xF5, 0x26, 0x46, 0xD7, 0x4B, 0x6E }, /* Master key 13 encrypted with Master key 14. */ { 0x97, 0xB3, 0x61, 0x88, 0x5C, 0x0D, 0xA1, 0x38, 0x73, 0xA4, 0x2F, 0x1A, 0x46, 0xA1, 0x09, 0xBF }, /* Master key 14 encrypted with Master key 15. */ + { 0xA6, 0x25, 0x12, 0x6D, 0xA1, 0x12, 0x1F, 0x15, 0x08, 0x2F, 0x30, 0x5F, 0xCB, 0x7D, 0x32, 0x82 }, /* Master key 15 encrypted with Master key 16. */ }; alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {}; diff --git a/fusee/program/source/fusee_package2.cpp b/fusee/program/source/fusee_package2.cpp index 236413eb7..83bfb7aac 100644 --- a/fusee/program/source/fusee_package2.cpp +++ b/fusee/program/source/fusee_package2.cpp @@ -80,7 +80,7 @@ namespace ams::nxboot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 22); + static_assert(pkg1::KeyGeneration_Count == 23); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_setup_horizon.cpp b/fusee/program/source/fusee_setup_horizon.cpp index f5ec03ce3..b978e513b 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -269,6 +269,8 @@ namespace ams::nxboot { return ams::TargetFirmware_21_0_0; } else if (std::memcmp(package1 + 0x10, "20260123", 8) == 0) { return ams::TargetFirmware_22_0_0; + } else if (std::memcmp(package1 + 0x10, "20260730", 8) == 0) { + return ams::TargetFirmware_23_0_0; } break; default: diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index 8f34237d6..884d691a5 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -198,6 +198,9 @@ namespace ams::nxboot { FsVersion_22_5_0, FsVersion_22_5_0_Exfat, + FsVersion_23_0_0, + FsVersion_23_0_0_Exfat, + FsVersion_Count, }; @@ -308,6 +311,9 @@ namespace ams::nxboot { { 0x53, 0x6D, 0x93, 0x84, 0x69, 0xFE, 0x73, 0xBE }, /* FsVersion_22_5_0 */ { 0xD4, 0x45, 0x28, 0x29, 0x5B, 0x41, 0x92, 0xBA }, /* FsVersion_22_5_0_Exfat */ + + { 0x34, 0x38, 0x3E, 0xE7, 0x99, 0x92, 0x63, 0x40 }, /* FsVersion_23_0_0 */ + { 0xFD, 0xAF, 0x16, 0x32, 0x88, 0xE1, 0x08, 0x05 }, /* FsVersion_23_0_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { @@ -733,6 +739,16 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x1BB445, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x18E250, NogcPatch1, sizeof(NogcPatch1)); break; + case FsVersion_23_0_0: + AddPatch(fs_meta, 0x1B36BD, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1B36D5, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x186340, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_23_0_0_Exfat: + AddPatch(fs_meta, 0x1BE8BD, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1BE8D5, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x191540, NogcPatch1, sizeof(NogcPatch1)); + break; default: break; } diff --git a/libraries/.gitrepo b/libraries/.gitrepo index e8ed07d70..56e7c065d 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = d3083af1827cd6ca2a96feb9316eb85cd01bae1f - parent = 974a1025b834136134e8133d8db23f69cb5ae0be + commit = aae2da0155a490abd3bfd17a70ccd16bb73c916a + parent = c68e08a101353a89777eb118d6bd21d1dba98ce5 method = merge cmdver = 0.4.9 diff --git a/libraries/libexosphere/include/exosphere/pkg1/pkg1_boot_config.hpp b/libraries/libexosphere/include/exosphere/pkg1/pkg1_boot_config.hpp index b61fb7e07..f7a67a1ec 100644 --- a/libraries/libexosphere/include/exosphere/pkg1/pkg1_boot_config.hpp +++ b/libraries/libexosphere/include/exosphere/pkg1/pkg1_boot_config.hpp @@ -61,14 +61,15 @@ namespace ams::pkg1 { } struct BootConfigData { - u32 version; - u32 reserved_04; + u64 version; u32 reserved_08; u32 reserved_0C; u8 flags1[0x10]; u8 flags0[0x10]; u64 initial_tsc_value; - u8 padding_38[0x200 - 0x38]; + u8 padding_38[0x38]; + u64 unknown_70; + u8 padding_78[0x200 - 0x78]; constexpr bool IsDevelopmentFunctionEnabled() const { return (this->flags1[0] & (1 << 1)) != 0; @@ -97,13 +98,16 @@ namespace ams::pkg1 { constexpr u64 GetInitialTscValue() const { return this->IsInitialTscValueValid() ? this->initial_tsc_value : 0; } + + constexpr u64 GetUnknown70() const { + return this->unknown_70; + } }; static_assert(util::is_pod::value); static_assert(sizeof(BootConfigData) == 0x200); struct BootConfigSignedData { - u32 version; - u32 reserved_04; + u64 version; u8 flags; u8 reserved_09[0x10 - 9]; u8 ecid[0x10]; diff --git a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp index f8480acc2..5453fdcb3 100644 --- a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp +++ b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp @@ -42,6 +42,7 @@ namespace ams::pkg1 { KeyGeneration_20_0_0 = 0x13, KeyGeneration_21_0_0 = 0x14, KeyGeneration_22_0_0 = 0x15, + KeyGeneration_23_0_0 = 0x16, KeyGeneration_Count, diff --git a/libraries/libexosphere/include/exosphere/pkg2.hpp b/libraries/libexosphere/include/exosphere/pkg2.hpp index d6649d9d0..be84a6ae7 100644 --- a/libraries/libexosphere/include/exosphere/pkg2.hpp +++ b/libraries/libexosphere/include/exosphere/pkg2.hpp @@ -24,7 +24,7 @@ namespace ams::pkg2 { constexpr inline int PayloadCount = 3; constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */ - constexpr inline int CurrentBootloaderVersion = 0x17; + constexpr inline int CurrentBootloaderVersion = 0x18; struct Package2Meta { using Magic = util::FourCC<'P','K','2','1'>; diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp index 927c611b3..2c0eb1f14 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -177,6 +177,7 @@ namespace ams::fuse { } constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { + TargetFirmware_23_0_0, TargetFirmware_22_0_0, TargetFirmware_21_0_0, TargetFirmware_20_0_0, diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp index 61e066fee..1b6d93201 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp @@ -81,6 +81,7 @@ namespace ams::kern::arch::arm64::cpu { MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(SpEl0, sp_el0) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(IdAa64Dfr0El1, id_aa64dfr0_el1) + MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(IdAa64Mmfr0El1, id_aa64mmfr0_el1) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(PmcrEl0, pmcr_el0) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(PmUserEnrEl0, pmuserenr_el0) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 2ab8527c9..240da83de 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace ams::kern::arch::arm64 { @@ -94,10 +95,10 @@ namespace ams::kern::arch::arm64 { return KPageTable::GetBlockSize(static_cast(KPageTable::GetBlockType(alignment) + 1)); } public: - /* TODO: How should this size be determined. Does the KProcess slab count need to go in a header as a define? */ - static constexpr size_t NumTtbr0Entries = 81; + static constexpr size_t NumPTEntries = ::ams::kern::init::SlabCountKProcess + 1; /* +1 for kernel. */ private: - static constinit inline const volatile u64 s_ttbr0_entries[NumTtbr0Entries] = {}; + static constinit inline const volatile u64 s_ttbr0_entries[NumPTEntries] = {}; + static constinit inline const volatile u64 s_tcr_el1_entries[NumPTEntries] = {}; private: KPageTableManager *m_manager; u8 m_asid; @@ -188,6 +189,12 @@ namespace ams::kern::arch::arm64 { return s_ttbr0_entries[0]; } + static const volatile u64 &GetTcrEL1Entry(size_t index) { return s_tcr_el1_entries[index]; } + + static ALWAYS_INLINE u64 GetKernelTcrEL1() { + return s_tcr_el1_entries[0]; + } + static ALWAYS_INLINE void ActivateKernel() { /* Activate, using asid 0 and process id = 0xFFFFFFFF */ cpu::SwitchProcess(GetKernelTtbr0(), 0xFFFFFFFF); @@ -198,7 +205,7 @@ namespace ams::kern::arch::arm64 { } NOINLINE void InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); - NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index); + NOINLINE Result InitializeForProcess(ams::svc::CreateProcessParameterFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index); void Finalize(); static void NoteUpdatedCallback(const void *pt) { diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index e18a6fbc8..c4180594c 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -28,10 +28,15 @@ namespace ams::kern::arch::arm64 { m_page_table.ActivateProcess(process_index, id); } - Result Initialize(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { + Result Initialize(ams::svc::CreateProcessParameterFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit, process_index)); } + static ALWAYS_INLINE u64 GetProcessTcrEl1(size_t process_index) { + /* The kernel's root table is entry zero; processes are indexed from one. */ + return KPageTable::GetTcrEL1Entry(process_index + 1); + } + void Finalize() { m_page_table.Finalize(); } ALWAYS_INLINE KScopedLightLock AcquireDeviceMapLock() { @@ -302,19 +307,25 @@ namespace ams::kern::arch::arm64 { bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { return m_page_table.CanContain(addr, size, state); } bool CanContain(KProcessAddress addr, size_t size, ams::svc::MemoryState state) const { return m_page_table.CanContain(addr, size, state); } - KProcessAddress GetAddressSpaceStart() const { return m_page_table.GetAddressSpaceStart(); } - KProcessAddress GetHeapRegionStart() const { return m_page_table.GetHeapRegionStart(); } - KProcessAddress GetAliasRegionStart() const { return m_page_table.GetAliasRegionStart(); } - KProcessAddress GetStackRegionStart() const { return m_page_table.GetStackRegionStart(); } - KProcessAddress GetKernelMapRegionStart() const { return m_page_table.GetKernelMapRegionStart(); } - KProcessAddress GetAliasCodeRegionStart() const { return m_page_table.GetAliasCodeRegionStart(); } + bool IsInShadowStackRegion(KProcessAddress addr, size_t size) const { return m_page_table.IsInShadowStackRegion(addr, size); } + bool IsInShadowStackRegion(KProcessAddress addr) const { return m_page_table.IsInShadowStackRegion(addr); } + bool IsSafeUserPointer(KProcessAddress addr, size_t size) const { return m_page_table.IsSafeUserPointer(addr, size); } - size_t GetAddressSpaceSize() const { return m_page_table.GetAddressSpaceSize(); } - size_t GetHeapRegionSize() const { return m_page_table.GetHeapRegionSize(); } - size_t GetAliasRegionSize() const { return m_page_table.GetAliasRegionSize(); } - size_t GetStackRegionSize() const { return m_page_table.GetStackRegionSize(); } - size_t GetKernelMapRegionSize() const { return m_page_table.GetKernelMapRegionSize(); } - size_t GetAliasCodeRegionSize() const { return m_page_table.GetAliasCodeRegionSize(); } + KProcessAddress GetAddressSpaceStart() const { return m_page_table.GetAddressSpaceStart(); } + KProcessAddress GetShadowStackRegionStart() const { return m_page_table.GetShadowStackRegionStart(); } + KProcessAddress GetHeapRegionStart() const { return m_page_table.GetHeapRegionStart(); } + KProcessAddress GetAliasRegionStart() const { return m_page_table.GetAliasRegionStart(); } + KProcessAddress GetStackRegionStart() const { return m_page_table.GetStackRegionStart(); } + KProcessAddress GetKernelMapRegionStart() const { return m_page_table.GetKernelMapRegionStart(); } + KProcessAddress GetAliasCodeRegionStart() const { return m_page_table.GetAliasCodeRegionStart(); } + + size_t GetAddressSpaceSize() const { return m_page_table.GetAddressSpaceSize(); } + size_t GetShadowStackRegionSize() const { return m_page_table.GetShadowStackRegionSize(); } + size_t GetHeapRegionSize() const { return m_page_table.GetHeapRegionSize(); } + size_t GetAliasRegionSize() const { return m_page_table.GetAliasRegionSize(); } + size_t GetStackRegionSize() const { return m_page_table.GetStackRegionSize(); } + size_t GetKernelMapRegionSize() const { return m_page_table.GetKernelMapRegionSize(); } + size_t GetAliasCodeRegionSize() const { return m_page_table.GetAliasCodeRegionSize(); } size_t GetAliasRegionExtraSize() const { return m_page_table.GetAliasRegionExtraSize(); } diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp index fc075178b..28580e038 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp @@ -77,7 +77,7 @@ namespace ams::kern::arch::arm64 { static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) { /* Check that the address is within the valid userspace range. */ - if (const uintptr_t src_uptr = reinterpret_cast(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion39Size) { + if (const uintptr_t src_uptr = reinterpret_cast(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion42Size) { return false; } diff --git a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp index 8e1829849..ae12326a1 100644 --- a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp +++ b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp @@ -51,9 +51,7 @@ namespace ams::kern::board::nintendo::nx { static NOINLINE u32 GetCreateProcessMemoryPool(); /* Randomness. */ - static void GenerateRandom(u64 *dst, size_t count); - static u64 GenerateRandomRange(u64 min, u64 max); - static u64 GenerateRandomU64(); + static void GenerateRandomBytesForUninitialized(void *dst, size_t size); /* Privileged Access. */ static void ReadWriteRegisterPrivileged(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value); diff --git a/libraries/libmesosphere/include/mesosphere/init/kern_init_slab_setup.hpp b/libraries/libmesosphere/include/mesosphere/init/kern_init_slab_setup.hpp index 209b8d732..32bba1e5a 100644 --- a/libraries/libmesosphere/include/mesosphere/init/kern_init_slab_setup.hpp +++ b/libraries/libmesosphere/include/mesosphere/init/kern_init_slab_setup.hpp @@ -18,6 +18,25 @@ #include namespace ams::kern::init { + /* Constexpr counts. */ + constexpr size_t SlabCountKProcess = 80; + constexpr size_t SlabCountKThread = 800; + constexpr size_t SlabCountKEvent = 900; + constexpr size_t SlabCountKInterruptEvent = 100; + constexpr size_t SlabCountKPort = 384; + constexpr size_t SlabCountKSharedMemory = 80; + constexpr size_t SlabCountKTransferMemory = 200; + constexpr size_t SlabCountKCodeMemory = 10; + constexpr size_t SlabCountKDeviceAddressSpace = 300; + constexpr size_t SlabCountKSession = 1133; + constexpr size_t SlabCountKLightSession = 100; + constexpr size_t SlabCountKObjectName = 7; + constexpr size_t SlabCountKResourceLimit = 5; + constexpr size_t SlabCountKDebug = cpu::NumCores; + constexpr size_t SlabCountKIoPool = 1; + constexpr size_t SlabCountKIoRegion = 6; + constexpr size_t SlabcountKSessionRequestMappings = 40; + struct KSlabResourceCounts { size_t num_KProcess; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp index 775c0054c..462ef3a71 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp @@ -24,7 +24,7 @@ namespace ams::kern { enum Type { Type_MapSmall = 0, Type_MapLarge = 1, - Type_Map39Bit = 2, + Type_MapHuge = 2, Type_Heap = 3, Type_Stack = 4, Type_Alias = 5, @@ -37,8 +37,8 @@ namespace ams::kern { size_t m_size; Type m_type; public: - static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type, size_t code_size); - static size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type); + static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessParameterFlag flags, Type type, size_t code_size); + static size_t GetAddressSpaceSize(ams::svc::CreateProcessParameterFlag flags, Type type); static void SetAddressSpaceSize(size_t width, Type type, size_t size); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index 57876fbcb..7e95a98cb 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -119,6 +119,8 @@ namespace ams::kern { KMemoryState_Insecure = ams::svc::MemoryState_Insecure | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped | KMemoryState_FlagCanChangeAttribute | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanQueryPhysical | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, + + KMemoryState_ShadowStack = ams::svc::MemoryState_ShadowStack, }; #if 1 @@ -147,6 +149,7 @@ namespace ams::kern { static_assert(KMemoryState_CodeOut == 0x04402015); static_assert(KMemoryState_Coverage == 0x00002016); /* TODO: Is this correct? */ static_assert(KMemoryState_Insecure == 0x055C3817); + static_assert(KMemoryState_ShadowStack == 0x0000001A); #endif enum KMemoryPermission : u8 { @@ -211,15 +214,15 @@ namespace ams::kern { uintptr_t m_address; size_t m_size; KMemoryState m_state; - u16 m_device_disable_merge_left_count; - u16 m_device_disable_merge_right_count; - u16 m_ipc_lock_count; - u16 m_device_use_count; - u16 m_ipc_disable_merge_count; KMemoryPermission m_permission; KMemoryAttribute m_attribute; KMemoryPermission m_original_permission; + u16 m_ipc_lock_count; + u16 m_device_use_count; KMemoryBlockDisableMergeAttribute m_disable_merge_attribute; + u16 m_ipc_disable_merge_count; + u16 m_device_disable_merge_left_count; + u16 m_device_disable_merge_right_count; constexpr ams::svc::MemoryInfo GetSvcMemoryInfo() const { return { @@ -365,15 +368,15 @@ namespace ams::kern { .m_address = GetInteger(this->GetAddress()), .m_size = this->GetSize(), .m_state = m_memory_state, - .m_device_disable_merge_left_count = m_device_disable_merge_left_count, - .m_device_disable_merge_right_count = m_device_disable_merge_right_count, - .m_ipc_lock_count = m_ipc_lock_count, - .m_device_use_count = m_device_use_count, - .m_ipc_disable_merge_count = m_ipc_disable_merge_count, .m_permission = m_permission, .m_attribute = m_attribute, .m_original_permission = m_original_permission, + .m_ipc_lock_count = m_ipc_lock_count, + .m_device_use_count = m_device_use_count, .m_disable_merge_attribute = m_disable_merge_attribute, + .m_ipc_disable_merge_count = m_ipc_disable_merge_count, + .m_device_disable_merge_left_count = m_device_disable_merge_left_count, + .m_device_disable_merge_right_count = m_device_disable_merge_right_count, }; } public: diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 25c149b7f..02c8eb5ea 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -90,10 +90,11 @@ namespace ams::kern { }; enum RegionType { - RegionType_KernelMap = 0, - RegionType_Stack = 1, - RegionType_Alias = 2, - RegionType_Heap = 3, + RegionType_KernelMap = 0, + RegionType_Stack = 1, + RegionType_Alias = 2, + RegionType_Heap = 3, + RegionType_ShadowStack = 4, RegionType_Count, }; @@ -150,14 +151,14 @@ namespace ams::kern { static constexpr u32 DefaultMemoryIgnoreAttr = KMemoryAttribute_IpcLocked | KMemoryAttribute_DeviceShared; - static constexpr size_t GetAddressSpaceWidth(ams::svc::CreateProcessFlag as_type) { - switch (static_cast(as_type & ams::svc::CreateProcessFlag_AddressSpaceMask)) { - case ams::svc::CreateProcessFlag_AddressSpace64Bit: + static constexpr size_t GetAddressSpaceWidth(ams::svc::CreateProcessParameterFlag as_type) { + switch (static_cast(as_type & ams::svc::CreateProcessParameterFlag_AddressSpaceMask)) { + case ams::svc::CreateProcessParameterFlag_AddressSpace64Bit39: return 39; - case ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated: + case ams::svc::CreateProcessParameterFlag_AddressSpace64Bit36: return 36; - case ams::svc::CreateProcessFlag_AddressSpace32Bit: - case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: + case ams::svc::CreateProcessParameterFlag_AddressSpace32Bit: + case ams::svc::CreateProcessParameterFlag_AddressSpace32BitNoReserved: return 32; MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } @@ -196,7 +197,6 @@ namespace ams::kern { KPageTableImpl m_impl; KMemoryBlockManager m_memory_block_manager; u32 m_allocate_option; - u32 m_address_space_width; bool m_is_kernel; bool m_enable_aslr; bool m_enable_device_address_space_merge; @@ -212,23 +212,24 @@ namespace ams::kern { public: constexpr explicit KPageTableBase(util::ConstantInitializeTag) : m_address_space_start(Null), m_address_space_end(Null), - m_region_starts{Null, Null, Null, Null}, - m_region_ends{Null, Null, Null, Null}, + m_region_starts{Null, Null, Null, Null, Null}, + m_region_ends{Null, Null, Null, Null, Null}, m_current_heap_end(Null), m_alias_code_region_start(Null), m_alias_code_region_end(Null), m_code_region_start(Null), m_code_region_end(Null), - m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(), m_alias_region_extra_size(), - m_general_lock(), m_map_physical_memory_lock(), m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize), - m_allocate_option(), m_address_space_width(), m_is_kernel(), m_enable_aslr(), m_enable_device_address_space_merge(), m_allowed_exec_device_mapping(), - m_memory_block_slab_manager(), m_block_info_manager(), m_resource_limit(), m_cached_physical_linear_region(), m_cached_physical_heap_region(), - m_heap_fill_value(), m_ipc_fill_value(), m_stack_fill_value() + m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), + m_mapped_ipc_server_memory(), m_alias_region_extra_size(), m_general_lock(), m_map_physical_memory_lock(), + m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize), + m_allocate_option(), m_is_kernel(), m_enable_aslr(), m_enable_device_address_space_merge(), m_allowed_exec_device_mapping(), + m_memory_block_slab_manager(), m_block_info_manager(), m_resource_limit(), m_cached_physical_linear_region(), + m_cached_physical_heap_region(), m_heap_fill_value(), m_ipc_fill_value(), m_stack_fill_value() { /* ... */ } explicit KPageTableBase() { /* ... */ } - NOINLINE void InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end); - NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); + NOINLINE void InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); + NOINLINE Result InitializeForProcess(ams::svc::CreateProcessParameterFlag flags, bool from_back, void *table, KProcessAddress start, KProcessAddress end, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); void Finalize(); @@ -247,6 +248,22 @@ namespace ams::kern { return this->Contains(addr, size) && m_region_starts[RegionType_Alias] <= addr && addr + size - 1 <= m_region_ends[RegionType_Alias] - 1; } + constexpr bool IsInShadowStackRegion(KProcessAddress addr, size_t size) const { + const auto start = m_region_starts[RegionType_ShadowStack]; + const auto end = m_region_ends[RegionType_ShadowStack]; + return start != end && addr < end && start < addr + size; + } + + constexpr bool IsInShadowStackRegion(KProcessAddress addr) const { + const auto start = m_region_starts[RegionType_ShadowStack]; + const auto end = m_region_ends[RegionType_ShadowStack]; + return start <= addr && addr < end; + } + + constexpr bool IsSafeUserPointer(KProcessAddress addr, size_t size) const { + return this->Contains(addr, size) && !this->IsInShadowStackRegion(addr, size); + } + bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const { /* Even though Unsafe physical memory is KMemoryState_Normal, it must be mapped inside the alias code region. */ return this->CanContain(addr, size, ams::svc::MemoryState_AliasCode); @@ -490,19 +507,21 @@ namespace ams::kern { public: KProcessAddress GetAddressSpaceStart() const { return m_address_space_start; } - KProcessAddress GetHeapRegionStart() const { return m_region_starts[RegionType_Heap]; } - KProcessAddress GetAliasRegionStart() const { return m_region_starts[RegionType_Alias]; } - KProcessAddress GetStackRegionStart() const { return m_region_starts[RegionType_Stack]; } - KProcessAddress GetKernelMapRegionStart() const { return m_region_starts[RegionType_KernelMap]; } + KProcessAddress GetShadowStackRegionStart() const { return m_region_starts[RegionType_ShadowStack]; } + KProcessAddress GetHeapRegionStart() const { return m_region_starts[RegionType_Heap]; } + KProcessAddress GetAliasRegionStart() const { return m_region_starts[RegionType_Alias]; } + KProcessAddress GetStackRegionStart() const { return m_region_starts[RegionType_Stack]; } + KProcessAddress GetKernelMapRegionStart() const { return m_region_starts[RegionType_KernelMap]; } KProcessAddress GetAliasCodeRegionStart() const { return m_alias_code_region_start; } size_t GetAddressSpaceSize() const { return m_address_space_end - m_address_space_start; } - size_t GetHeapRegionSize() const { return m_region_ends[RegionType_Heap] - m_region_starts[RegionType_Heap]; } - size_t GetAliasRegionSize() const { return m_region_ends[RegionType_Alias] - m_region_starts[RegionType_Alias]; } - size_t GetStackRegionSize() const { return m_region_ends[RegionType_Stack] - m_region_starts[RegionType_Stack]; } - size_t GetKernelMapRegionSize() const { return m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; } + size_t GetShadowStackRegionSize() const { return m_region_ends[RegionType_ShadowStack] - m_region_starts[RegionType_ShadowStack]; } + size_t GetHeapRegionSize() const { return m_region_ends[RegionType_Heap] - m_region_starts[RegionType_Heap]; } + size_t GetAliasRegionSize() const { return m_region_ends[RegionType_Alias] - m_region_starts[RegionType_Alias]; } + size_t GetStackRegionSize() const { return m_region_ends[RegionType_Stack] - m_region_starts[RegionType_Stack]; } + size_t GetKernelMapRegionSize() const { return m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; } size_t GetAliasCodeRegionSize() const { return m_alias_code_region_end - m_alias_code_region_start; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 0b0622869..dcc66f7d5 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -113,6 +113,7 @@ namespace ams::kern { u64 m_running_thread_idle_counts[cpu::NumCores]; u64 m_running_thread_switch_counts[cpu::NumCores]; KThread *m_pinned_threads[cpu::NumCores]; + s64 m_exit_tag; util::Atomic m_cpu_time; util::Atomic m_num_process_switches; util::Atomic m_num_thread_switches; @@ -142,11 +143,11 @@ namespace ams::kern { m_pinned_threads[core_id] = nullptr; } public: - explicit KProcess() : m_is_initialized(false) { /* ... */ } + explicit KProcess() : m_is_initialized(false), m_exit_tag(-1ll) { /* ... */ } Result Initialize(const ams::svc::CreateProcessParameter ¶ms, const KPageGroup &pg, const u32 *caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool, bool immortal); Result Initialize(const ams::svc::CreateProcessParameter ¶ms, svc::KUserPointer caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool); - void Exit(); + void Exit(s64 exit_tag); constexpr const char *GetName() const { return m_name; } @@ -155,19 +156,22 @@ namespace ams::kern { constexpr u64 GetProcessId() const { return m_process_id; } constexpr State GetState() const { return m_state; } + + constexpr s64 GetExitTag() const { return m_exit_tag; } constexpr u64 GetCoreMask() const { return m_capabilities.GetCoreMask(); } constexpr u64 GetPhysicalCoreMask() const { return m_capabilities.GetPhysicalCoreMask(); } constexpr u64 GetPriorityMask() const { return m_capabilities.GetPriorityMask(); } + constexpr u32 GetIntendedKernelMajorVersion() const { return m_capabilities.GetIntendedKernelMajorVersion(); } constexpr s32 GetIdealCoreId() const { return m_ideal_core_id; } constexpr void SetIdealCoreId(s32 core_id) { m_ideal_core_id = core_id; } constexpr bool CheckThreadPriority(s32 prio) const { return ((1ul << prio) & this->GetPriorityMask()) != 0; } - constexpr u32 GetCreateProcessFlags() const { return m_flags; } + constexpr u32 GetCreateProcessParameterFlags() const { return m_flags; } - constexpr bool Is64Bit() const { return m_flags & ams::svc::CreateProcessFlag_Is64Bit; } + constexpr bool Is64Bit() const { return m_flags & ams::svc::CreateProcessParameterFlag_64Bit; } constexpr KProcessAddress GetEntryPoint() const { return m_code_address; } @@ -184,7 +188,7 @@ namespace ams::kern { constexpr bool IsSuspended() const { return m_is_suspended; } constexpr void SetSuspended(bool suspended) { m_is_suspended = suspended; } - Result Terminate(); + Result Terminate(s64 exit_tag); constexpr bool IsTerminated() const { return m_state == State_Terminated; @@ -215,6 +219,7 @@ namespace ams::kern { } u32 GetAllocateOption() const { return m_page_table.GetAllocateOption(); } + size_t GetAddressSpaceSize() const { return m_page_table.GetAddressSpaceSize(); } ThreadList &GetThreadList() { return m_thread_list; } const ThreadList &GetThreadList() const { return m_thread_list; } @@ -409,6 +414,10 @@ namespace ams::kern { this->NotifyAvailable(); } } + + void SetExitTag(s64 exit_tag) { + m_exit_tag = exit_tag; + } ALWAYS_INLINE Result InitializeHandleTable(s32 size) { /* Try to initialize the handle table. */ diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp index 3d7ea5310..95d601959 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp @@ -37,13 +37,12 @@ namespace ams::kern { public: /* This can be overridden as needed. */ static constexpr size_t SecureAppletMemorySize = 0; - protected: - /* Nintendo uses std::mt19937_t for randomness. */ - /* To save space (and because mt19337_t isn't secure anyway), */ - /* We will use TinyMT. */ - static constinit inline bool s_uninitialized_random_generator{true}; - static constinit inline util::TinyMT s_random_generator{util::ConstantInitialize}; - static constinit inline KSpinLock s_random_lock; + private: + /* Randomness helpers. */ + static void InitializeRandomGenerator(const void *seed, size_t size); + static void ReseedRandomGeneratorInternal(); + static u32 GenerateRandomU32(); + static u64 GenerateRandomU64Internal(); public: class Init { private: @@ -66,7 +65,7 @@ namespace ams::kern { static u64 GenerateRandomRange(u64 min, u64 max); }; protected: - static NOINLINE void InitializePhase1Base(u64 seed); + static NOINLINE void InitializePhase1Base(const void *seed, size_t size); public: /* Initialization. */ static NOINLINE void ConfigureKTargetSystem(); @@ -78,6 +77,10 @@ namespace ams::kern { static void GenerateRandom(u64 *dst, size_t count); static u64 GenerateRandomRange(u64 min, u64 max); static u64 GenerateRandomU64(); + static void ReseedRandomGenerator(); + + /* Obtains random bytes while the generator is not yet initialized. Board-provided. */ + static void GenerateRandomBytesForUninitialized(void *dst, size_t size); /* Register access Access. */ static Result ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp index 949fd45ba..09cbac7b7 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp @@ -26,6 +26,7 @@ namespace ams::kern { private: struct KTargetSystemData { bool is_not_debug_mode; + bool is_not_debug_mode2; bool disable_debug_logging; bool disable_user_exception_handlers; bool disable_debug_memory_fill; @@ -37,6 +38,7 @@ namespace ams::kern { static inline constinit bool s_is_uninitialized = true; static inline constinit const volatile KTargetSystemData s_data = { .is_not_debug_mode = false, + .is_not_debug_mode2 = false, .disable_debug_logging = false, .disable_user_exception_handlers = false, .disable_debug_memory_fill = false, @@ -48,6 +50,7 @@ namespace ams::kern { static ALWAYS_INLINE void SetInitialized() { s_is_uninitialized = false; } public: static ALWAYS_INLINE bool IsDebugMode() { return !(s_is_uninitialized | s_data.is_not_debug_mode); } + static ALWAYS_INLINE bool IsDebugMode2() { return !(s_is_uninitialized | s_data.is_not_debug_mode2); } static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return !(s_is_uninitialized | s_data.disable_debug_logging); } static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return !(s_is_uninitialized | s_data.disable_user_exception_handlers); } static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return !(s_is_uninitialized | s_data.disable_debug_memory_fill); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp index 8904a6a92..429af04ec 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp @@ -29,6 +29,7 @@ namespace ams::kern { class KProcess; class KConditionVariable; class KAddressArbiter; + class KPageBuffer; using KThreadFunction = void (*)(uintptr_t); @@ -305,6 +306,8 @@ namespace ams::kern { u32 *m_light_ipc_data; KProcessAddress m_tls_address; void *m_tls_heap_address; + KProcessAddress m_shadow_stack_address; + KPageBuffer *m_shadow_stack_page; KLightLock m_activity_pause_lock; SyncObjectBuffer m_sync_object_buffer; s64 m_schedule_count; @@ -341,18 +344,19 @@ namespace ams::kern { bool m_debug_attached; s8 m_priority_inheritance_count; bool m_resource_limit_release_hint; + bool m_debug_unknown5; public: constexpr explicit KThread(util::ConstantInitializeTag) : KAutoObjectWithSlabHeapAndContainer(util::ConstantInitialize), KTimerTask(util::ConstantInitialize), m_process_list_node{}, m_condvar_arbiter_tree_node{util::ConstantInitialize}, m_priority{-1}, m_condvar_tree{}, m_condvar_key{}, m_caller_save_fpu_registers{}, m_virtual_affinity_mask{}, m_physical_affinity_mask{}, m_thread_id{}, m_cpu_time{0}, m_address_key{Null}, m_parent{}, - m_kernel_stack_top{}, m_light_ipc_data{}, m_tls_address{Null}, m_tls_heap_address{}, m_activity_pause_lock{}, m_sync_object_buffer{util::ConstantInitialize}, + m_kernel_stack_top{}, m_light_ipc_data{}, m_tls_address{Null}, m_tls_heap_address{}, m_shadow_stack_address{Null}, m_shadow_stack_page{}, m_activity_pause_lock{}, m_sync_object_buffer{util::ConstantInitialize}, m_schedule_count{}, m_last_scheduled_tick{}, m_per_core_priority_queue_entry{}, m_wait_queue{}, m_held_lock_info_list{}, m_waiting_lock_info{}, m_pinned_waiter_list{}, m_debug_params{}, m_closed_object{}, m_address_key_value{}, m_suspend_request_flags{}, m_suspend_allowed_flags{}, m_synced_index{}, m_wait_result{svc::ResultNoSynchronizationObject()}, m_debug_exception_result{ResultSuccess()}, m_base_priority{}, m_base_priority_on_unpin{}, m_physical_ideal_core_id{}, m_virtual_ideal_core_id{}, m_num_kernel_waiters{}, m_current_core_id{}, m_core_id{}, m_original_physical_affinity_mask{}, m_original_physical_ideal_core_id{}, m_num_core_migration_disables{}, m_thread_state{}, m_termination_requested{false}, m_wait_cancelled{}, - m_cancellable{}, m_signaled{}, m_initialized{}, m_debug_attached{}, m_priority_inheritance_count{}, m_resource_limit_release_hint{} + m_cancellable{}, m_signaled{}, m_initialized{}, m_debug_attached{}, m_priority_inheritance_count{}, m_resource_limit_release_hint{}, m_debug_unknown5{} { /* ... */ } @@ -683,6 +687,9 @@ namespace ams::kern { constexpr void SetDebugAttached() { m_debug_attached = true; } constexpr bool IsAttachedToDebugger() const { return m_debug_attached; } + constexpr void SetDebugUnknown5(bool value) { m_debug_unknown5 = value; } + constexpr bool IsDebugUnknown5() const { return m_debug_unknown5; } + void AddCpuTime(s32 core_id, s64 amount) { m_cpu_time += amount; /* TODO: Debug kernels track per-core tick counts. Should we? */ diff --git a/libraries/libmesosphere/libmesosphere.mk b/libraries/libmesosphere/libmesosphere.mk index 2ab310a25..7998d5f78 100644 --- a/libraries/libmesosphere/libmesosphere.mk +++ b/libraries/libmesosphere/libmesosphere.mk @@ -108,6 +108,8 @@ $(OFILES_SRC) : $(HFILES_BIN) kern_libc_generic.o: CFLAGS += -fno-builtin +crypto_aes_impl.arch.arm64.o: CXXFLAGS := $(filter-out -mgeneral-regs-only,$(CXXFLAGS)) + #--------------------------------------------------------------------------------- %_bin.h %.bin.o : %.bin #--------------------------------------------------------------------------------- diff --git a/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp b/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp index 4839349da..36d7f9b2a 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp @@ -220,6 +220,8 @@ namespace ams::kern::arch::arm64::cpu { virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override { MESOSPHERE_UNUSED(interrupt_id); + /* TODO: 23.0.0+ now yields here while m_target_cores doesn't have the current core id bit set. */ + /* Evaluate if we should do the same. */ this->ProcessOperation(); m_target_cores &= ~(1ul << GetCurrentCoreId()); return nullptr; diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index 6c21b455b..bfa6165a0 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -196,6 +196,7 @@ namespace ams::kern::arch::arm64 { case EsrEc_Cp14McrMrc: case EsrEc_Cp14Mrrc: case EsrEc_SystemInstruction64: + case EsrEc_SveZen: case EsrEc_BkptInstruction: case EsrEc_BrkInstruction: type = ams::svc::ExceptionType_InstructionAbort; @@ -267,6 +268,7 @@ namespace ams::kern::arch::arm64 { switch (ec) { case EsrEc_Unknown: case EsrEc_IllegalExecution: + case EsrEc_SveZen: case EsrEc_BkptInstruction: case EsrEc_BrkInstruction: { @@ -379,7 +381,7 @@ namespace ams::kern::arch::arm64 { } /* Exit the current process. */ - cur_process.Exit(); + cur_process.Exit(-1ll); } } @@ -474,6 +476,7 @@ namespace ams::kern::arch::arm64 { switch (ec) { case EsrEc_Unknown: case EsrEc_IllegalExecution: + case EsrEc_SveZen: case EsrEc_BkptInstruction: case EsrEc_BrkInstruction: { @@ -545,7 +548,7 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_EXCEPTION_LOG("Exception occurred. "); /* Exit the current process. */ - GetCurrentProcess().Exit(); + GetCurrentProcess().Exit(-1ll); } /* NOTE: This function is called from ASM. */ @@ -564,6 +567,7 @@ namespace ams::kern::arch::arm64 { switch ((esr >> 26) & 0x3F) { case EsrEc_Unknown: case EsrEc_IllegalExecution: + case EsrEc_SveZen: case EsrEc_BkptInstruction: case EsrEc_BrkInstruction: far = context->pc; diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 6992281dd..3b21ab818 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -125,10 +125,10 @@ namespace ams::kern::arch::arm64 { m_manager = Kernel::GetSystemSystemResource().GetPageTableManagerPointer(); /* Initialize the base page table. */ - KPageTableBase::InitializeForKernel(true, table, start, end); + KPageTableBase::InitializeForKernel(table, start, end); } - Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { + Result KPageTable::InitializeForProcess(ams::svc::CreateProcessParameterFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { /* Determine our ASID */ m_asid = process_index + 1; MESOSPHERE_ABORT_UNLESS(0 < m_asid && m_asid < util::size(s_ttbr0_entries)); @@ -144,7 +144,7 @@ namespace ams::kern::arch::arm64 { const size_t as_width = GetAddressSpaceWidth(flags); const KProcessAddress as_start = 0; const KProcessAddress as_end = (1ul << as_width); - R_TRY(KPageTableBase::InitializeForProcess(flags, from_back, pool, GetVoidPointer(ttbr0_virt), as_start, as_end, code_address, code_size, system_resource, resource_limit)); + R_TRY(KPageTableBase::InitializeForProcess(flags, from_back, GetVoidPointer(ttbr0_virt), as_start, as_end, pool, code_address, code_size, system_resource, resource_limit)); /* Note that we've updated the table (since we created it). */ this->NoteUpdated(); diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index bb7581c83..de463ce6b 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -74,12 +74,6 @@ namespace ams::kern::board::nintendo::nx { return value; } - ALWAYS_INLINE u64 GenerateRandomU64FromSmc() { - u64 value; - smc::GenerateRandomBytes(std::addressof(value), sizeof(value)); - return value; - } - ALWAYS_INLINE u64 GetConfigU64(smc::ConfigItem which) { u64 value; smc::GetConfig(&value, 1, which); @@ -363,7 +357,12 @@ namespace ams::kern::board::nintendo::nx { /* Return (possibly) adjusted size. */ /* NOTE: On 20.0.0+ (and even more-so 21.0.0+) the browser requires much more memory in the applet pool in order to function. */ /* Thus, we have to reduce our extra system memory size by 26 MB to compensate. */ - if (kern::GetTargetFirmware() >= ams::TargetFirmware_21_0_0) { + /* NOTE: On 23.0.0+ we are patching memory allocation for each browser applet since there are only 3 of them now. */ + /* Given that the root "Reserved" region is 0x43E000 bytes and the "ReservedTbd" subregion is 0x540000 bytes, we can safely reclaim 9MB.*/ + if (kern::GetTargetFirmware() >= ams::TargetFirmware_23_0_0) { + constexpr size_t ExtraSystemMemoryForAtmosphere_23_0_0 = 16_MB; + return base_pool_size - ExtraSystemMemoryForAtmosphere_23_0_0 - KTraceBufferSize; + } else if (kern::GetTargetFirmware() >= ams::TargetFirmware_21_0_0) { constexpr size_t ExtraSystemMemoryForAtmosphere_21_0_0 = 7_MB; return base_pool_size - ExtraSystemMemoryForAtmosphere_21_0_0 - KTraceBufferSize; } else if (kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0) { @@ -417,7 +416,10 @@ namespace ams::kern::board::nintendo::nx { { /* Set whether we're in debug mode. */ { - ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode); + ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode); + + /* TODO: 23.0.0+ split debug mode into 2 fields. Implement this properly for better accuracy. */ + ts->is_not_debug_mode2 = ts->is_not_debug_mode; /* If we're not in debug mode, we don't want to initialize uart logging. */ ts->disable_debug_logging = ts->is_not_debug_mode; @@ -477,9 +479,9 @@ namespace ams::kern::board::nintendo::nx { /* Initialize random and resource limit. */ { - u64 seed; - smc::GenerateRandomBytes(std::addressof(seed), sizeof(seed)); - KSystemControlBase::InitializePhase1Base(seed); + u8 seed[32]; + smc::GenerateRandomBytes(seed, sizeof(seed)); + KSystemControlBase::InitializePhase1Base(seed, sizeof(seed)); } /* Configure the Kernel Carveout region. */ @@ -524,32 +526,8 @@ namespace ams::kern::board::nintendo::nx { } /* Randomness. */ - void KSystemControl::GenerateRandom(u64 *dst, size_t count) { - MESOSPHERE_INIT_ABORT_UNLESS(count <= 7); - smc::GenerateRandomBytes(dst, count * sizeof(u64)); - } - - u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) { - KScopedInterruptDisable intr_disable; - KScopedSpinLock lk(s_random_lock); - - - if (AMS_LIKELY(!s_uninitialized_random_generator)) { - return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); }); - } else { - return KSystemControlBase::GenerateUniformRange(min, max, GenerateRandomU64FromSmc); - } - } - - u64 KSystemControl::GenerateRandomU64() { - KScopedInterruptDisable intr_disable; - KScopedSpinLock lk(s_random_lock); - - if (AMS_LIKELY(!s_uninitialized_random_generator)) { - return s_random_generator.GenerateRandomU64(); - } else { - return GenerateRandomU64FromSmc(); - } + void KSystemControl::GenerateRandomBytesForUninitialized(void *dst, size_t size) { + smc::GenerateRandomBytes(dst, size); } void KSystemControl::SleepSystem() { diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp index d55eb2c70..bd603f9e4 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp @@ -223,6 +223,8 @@ namespace ams::kern::board::nintendo::nx::smc { KScopedInterruptDisable di; /* Ensure we successfully show the error. */ + /* NOTE: On 23.0.0+ the SMC result is discarded. */ + /* The function now ends with an unconditional infinite loop and interrupts are never restored. */ MESOSPHERE_ABORT_UNLESS(ShowErrorImpl(color)); } diff --git a/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp b/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp index b82e78f84..3336c94a9 100644 --- a/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp +++ b/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp @@ -60,25 +60,6 @@ namespace ams::kern::init { #undef DEFINE_SLAB_TYPE_ENUM_MEMBER - /* Constexpr counts. */ - constexpr size_t SlabCountKProcess = 80; - constexpr size_t SlabCountKThread = 800; - constexpr size_t SlabCountKEvent = 900; - constexpr size_t SlabCountKInterruptEvent = 100; - constexpr size_t SlabCountKPort = 384; - constexpr size_t SlabCountKSharedMemory = 80; - constexpr size_t SlabCountKTransferMemory = 200; - constexpr size_t SlabCountKCodeMemory = 10; - constexpr size_t SlabCountKDeviceAddressSpace = 300; - constexpr size_t SlabCountKSession = 1133; - constexpr size_t SlabCountKLightSession = 100; - constexpr size_t SlabCountKObjectName = 7; - constexpr size_t SlabCountKResourceLimit = 5; - constexpr size_t SlabCountKDebug = cpu::NumCores; - constexpr size_t SlabCountKIoPool = 1; - constexpr size_t SlabCountKIoRegion = 6; - constexpr size_t SlabcountKSessionRequestMappings = 40; - constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread; namespace test { diff --git a/libraries/libmesosphere/source/kern_k_address_space_info.cpp b/libraries/libmesosphere/source/kern_k_address_space_info.cpp index 3aa24c5de..700e6dce9 100644 --- a/libraries/libmesosphere/source/kern_k_address_space_info.cpp +++ b/libraries/libmesosphere/source/kern_k_address_space_info.cpp @@ -30,30 +30,36 @@ namespace ams::kern { { 36, ams::svc::AddressLargeMap36Start, ams::svc::AddressLargeMap36Size, KAddressSpaceInfo::Type_MapLarge, }, { 36, Invalid, ams::svc::AddressMemoryRegionHeap36Size, KAddressSpaceInfo::Type_Heap, }, { 36, Invalid, ams::svc::AddressMemoryRegionAlias36Size, KAddressSpaceInfo::Type_Alias, }, - { 39, ams::svc::AddressMap39Start, ams::svc::AddressMap39Size, KAddressSpaceInfo::Type_Map39Bit, }, + { 39, ams::svc::AddressMap39Start, ams::svc::AddressMap39Size, KAddressSpaceInfo::Type_MapHuge, }, { 39, Invalid, ams::svc::AddressMemoryRegionSmall39Size, KAddressSpaceInfo::Type_MapSmall, }, { 39, Invalid, ams::svc::AddressMemoryRegionHeap39Size, KAddressSpaceInfo::Type_Heap, }, { 39, Invalid, ams::svc::AddressMemoryRegionAlias39Size, KAddressSpaceInfo::Type_Alias, }, { 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, }, + { 42, ams::svc::AddressMap42Start, ams::svc::AddressMap42Size, KAddressSpaceInfo::Type_MapHuge, }, + { 42, Invalid, ams::svc::AddressMemoryRegionSmall42Size, KAddressSpaceInfo::Type_MapSmall, }, + { 42, Invalid, 0, KAddressSpaceInfo::Type_Heap, }, + { 42, Invalid, ams::svc::AddressMemoryRegionAlias42Size, KAddressSpaceInfo::Type_Alias, }, + { 42, Invalid, ams::svc::AddressMemoryRegionStack42Size, KAddressSpaceInfo::Type_Stack, }, }; - constexpr u8 FlagsToAddressSpaceWidthTable[4] = { - 32, 36, 32, 39 + constexpr u8 FlagsToAddressSpaceWidthTable[5] = { + 32, 36, 32, 39, 42 }; - constexpr size_t GetAddressSpaceWidth(ams::svc::CreateProcessFlag flags) { + constexpr size_t GetAddressSpaceWidth(ams::svc::CreateProcessParameterFlag flags) { /* Convert the input flags to an array index. */ - const size_t idx = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask) >> ams::svc::CreateProcessFlag_AddressSpaceShift; + const size_t idx = (flags & ams::svc::CreateProcessParameterFlag_AddressSpaceMask) >> ams::svc::CreateProcessParameterFlag_AddressSpaceShift; MESOSPHERE_ABORT_UNLESS(idx < sizeof(FlagsToAddressSpaceWidthTable)); /* Return the width. */ return FlagsToAddressSpaceWidthTable[idx]; } - static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32Bit) == 32); - static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated) == 36); - static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) == 32); - static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64Bit) == 39); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessParameterFlag_AddressSpace32Bit) == 32); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessParameterFlag_AddressSpace64Bit36) == 36); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessParameterFlag_AddressSpace32BitNoReserved) == 32); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessParameterFlag_AddressSpace64Bit39) == 39); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessParameterFlag_AddressSpace64Bit42) == 42); KAddressSpaceInfo &GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) { for (auto &info : AddressSpaceInfos) { @@ -66,14 +72,14 @@ namespace ams::kern { } - uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type, size_t code_size) { + uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessParameterFlag flags, KAddressSpaceInfo::Type type, size_t code_size) { MESOSPHERE_UNUSED(code_size); return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress(); } - size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) { + size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessParameterFlag flags, KAddressSpaceInfo::Type type) { /* Extract the address space from the create process flags. */ - const auto as_flags = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask); + const auto as_flags = (flags & ams::svc::CreateProcessParameterFlag_AddressSpaceMask); /* Get the address space width. */ const auto as_width = GetAddressSpaceWidth(flags); @@ -82,7 +88,7 @@ namespace ams::kern { size_t as_size = GetAddressSpaceInfo(as_width, type).GetSize(); /* If we're getting size for 32-bit without alias, adjust the sizes accordingly. */ - if (as_flags == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) { + if (as_flags == ams::svc::CreateProcessParameterFlag_AddressSpace32BitNoReserved) { switch (type) { /* The heap space receives space that would otherwise go to the alias space. */ case KAddressSpaceInfo::Type_Heap: diff --git a/libraries/libmesosphere/source/kern_k_debug_base.cpp b/libraries/libmesosphere/source/kern_k_debug_base.cpp index 453eb745c..3e71fde77 100644 --- a/libraries/libmesosphere/source/kern_k_debug_base.cpp +++ b/libraries/libmesosphere/source/kern_k_debug_base.cpp @@ -100,8 +100,8 @@ namespace ams::kern { KProcessPageTable &target_pt = process->GetPageTable(); /* Verify that the regions are in range. */ - R_UNLESS(target_pt.Contains(address, size), svc::ResultInvalidCurrentMemory()); - R_UNLESS(debugger_pt.Contains(buffer, size), svc::ResultInvalidCurrentMemory()); + R_UNLESS(target_pt.Contains(address, size), svc::ResultInvalidCurrentMemory()); + R_UNLESS(debugger_pt.IsSafeUserPointer(buffer, size), svc::ResultInvalidCurrentMemory()); /* Iterate over the target process's memory blocks. */ KProcessAddress cur_address = address; @@ -166,8 +166,8 @@ namespace ams::kern { KProcessPageTable &target_pt = process->GetPageTable(); /* Verify that the regions are in range. */ - R_UNLESS(target_pt.Contains(address, size), svc::ResultInvalidCurrentMemory()); - R_UNLESS(debugger_pt.Contains(buffer, size), svc::ResultInvalidCurrentMemory()); + R_UNLESS(target_pt.Contains(address, size), svc::ResultInvalidCurrentMemory()); + R_UNLESS(debugger_pt.IsSafeUserPointer(buffer, size), svc::ResultInvalidCurrentMemory()); /* Iterate over the target process's memory blocks. */ KProcessAddress cur_address = address; @@ -417,7 +417,7 @@ namespace ams::kern { /* Terminate the process. */ /* NOTE: This result is seemingly-intentionally not checked by Nintendo. */ - static_cast(target->Terminate()); + static_cast(target->Terminate(-1ll)); R_SUCCEED(); } @@ -884,7 +884,7 @@ namespace ams::kern { { out->info.create_process.program_id = process->GetProgramId(); out->info.create_process.process_id = process->GetId(); - out->info.create_process.flags = process->GetCreateProcessFlags(); + out->info.create_process.flags = process->GetCreateProcessParameterFlags(); out->info.create_process.user_exception_context_address = GetInteger(process->GetProcessLocalRegionAddress()); std::memcpy(out->info.create_process.name, process->GetName(), sizeof(out->info.create_process.name)); diff --git a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp index 5d9164efb..6037c3b78 100644 --- a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp +++ b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp @@ -214,28 +214,28 @@ namespace ams::kern { /* Apply other flags. */ if (this->Is64Bit()) { - out->flags |= ams::svc::CreateProcessFlag_Is64Bit; + out->flags |= ams::svc::CreateProcessParameterFlag_64Bit; } if (this->Is64BitAddressSpace()) { - out->flags |= (GetTargetFirmware() >= TargetFirmware_2_0_0) ? ams::svc::CreateProcessFlag_AddressSpace64Bit : ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated; + out->flags |= (GetTargetFirmware() >= TargetFirmware_2_0_0) ? ams::svc::CreateProcessParameterFlag_AddressSpace64Bit39 : ams::svc::CreateProcessParameterFlag_AddressSpace64Bit36; } else { - out->flags |= ams::svc::CreateProcessFlag_AddressSpace32Bit; + out->flags |= ams::svc::CreateProcessParameterFlag_AddressSpace32Bit; } if (enable_aslr) { - out->flags |= ams::svc::CreateProcessFlag_EnableAslr; + out->flags |= ams::svc::CreateProcessParameterFlag_EnableAslr; } /* All initial processes should disable device address space merge. */ - out->flags |= ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge; + out->flags |= ams::svc::CreateProcessParameterFlag_DisableDeviceAddressSpaceMerge; /* Set and check code address. */ /* NOTE: Even though Nintendo passes a size to GetAddressSpaceStart at other call sites, they pass */ /* a number of pages here. Even though this is presumably only used for debug assertions, this is */ /* almost certainly a bug. */ using ASType = KAddressSpaceInfo::Type; - const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall; - const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(out->flags), as_type, out->code_num_pages); - const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(out->flags), as_type); + const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_MapHuge : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall; + const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(out->flags), as_type, out->code_num_pages); + const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(out->flags), as_type); const uintptr_t map_end = map_start + map_size; out->code_address = map_start + start_address; MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize)); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 5d34dbe1f..5f1a5b19b 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -88,14 +88,14 @@ namespace ams::kern { } } - void KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) { + void KPageTableBase::InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end) { /* Initialize our members. */ - m_address_space_width = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32); m_address_space_start = KProcessAddress(GetInteger(start)); m_address_space_end = KProcessAddress(GetInteger(end)); m_is_kernel = true; m_enable_aslr = true; m_enable_device_address_space_merge = false; + m_allowed_exec_device_mapping = false; for (auto i = 0; i < RegionType_Count; ++i) { m_region_starts[i] = 0; @@ -133,7 +133,7 @@ namespace ams::kern { MESOSPHERE_R_ABORT_UNLESS(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager)); } - Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { + Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessParameterFlag flags, bool from_back, void *table, KProcessAddress start, KProcessAddress end, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { /* Validate the region. */ MESOSPHERE_ABORT_UNLESS(start <= code_address); MESOSPHERE_ABORT_UNLESS(code_address < code_address + code_size); @@ -151,9 +151,9 @@ namespace ams::kern { m_alias_region_extra_size = 0; /* Set our width and heap/alias sizes. */ - m_address_space_width = GetAddressSpaceWidth(flags); - size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias); - size_t heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap); + size_t address_space_width = GetAddressSpaceWidth(flags); + size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias); + size_t heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap); /* Set code regions and determine remaining sizes. */ KProcessAddress process_code_start; @@ -162,12 +162,12 @@ namespace ams::kern { size_t kernel_map_region_size; KProcessAddress before_process_code_start, after_process_code_start; size_t before_process_code_size, after_process_code_size; - if (m_address_space_width == 39) { + if (address_space_width == 39 || address_space_width == 42) { stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Stack); kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); - m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_Map39Bit); - m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_Map39Bit); + m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_MapHuge); + m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_MapHuge); m_alias_code_region_start = m_code_region_start; m_alias_code_region_end = m_code_region_end; @@ -179,10 +179,10 @@ namespace ams::kern { after_process_code_start = process_code_end; after_process_code_size = m_code_region_end - process_code_end; - /* If we have a 39-bit address space and should, enable extra size to the alias region. */ - if (flags & ams::svc::CreateProcessFlag_EnableAliasRegionExtraSize) { + /* If we have a 39-bit address space and should, enable extra size for the address sanitizer. */ + if (flags & ams::svc::CreateProcessParameterFlag_EnableAddressSanitizer) { /* Extra size is 1/8th of the address space. */ - m_alias_region_extra_size = (static_cast(1) << m_address_space_width) / 8; + m_alias_region_extra_size = (static_cast(1) << address_space_width) / 8; alias_region_size += m_alias_region_extra_size; } @@ -208,9 +208,12 @@ namespace ams::kern { after_process_code_size = GetSpaceSize(KAddressSpaceInfo::Type_MapLarge); } + m_region_starts[RegionType_ShadowStack] = Null; + m_region_ends[RegionType_ShadowStack] = Null; + /* Set other basic fields. */ - m_enable_aslr = (flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; - m_enable_device_address_space_merge = (flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; + m_enable_aslr = (flags & ams::svc::CreateProcessParameterFlag_EnableAslr) != 0; + m_enable_device_address_space_merge = (flags & ams::svc::CreateProcessParameterFlag_DisableDeviceAddressSpaceMerge) == 0; m_allowed_exec_device_mapping = false; m_address_space_start = start; m_address_space_end = end; @@ -237,6 +240,9 @@ namespace ams::kern { region_layouts[num_regions++] = { .size = alias_region_size, .type = RegionType_Alias, .alloc_index = 0, }; region_layouts[num_regions++] = { .size = heap_region_size, .type = RegionType_Heap, .alloc_index = 0, }; + if (flags & ams::svc::CreateProcessParameterFlag_EnableShadowStack) { + region_layouts[num_regions++] = { .size = ams::svc::AddressShadowStackRegionSize, .type = RegionType_ShadowStack, .alloc_index = 0, }; + } /* Selection-sort the regions by size largest-to-smallest. */ for (size_t i = 0; i < num_regions - 1; ++i) { @@ -347,151 +353,36 @@ namespace ams::kern { const KProcessAddress process_code_last = process_code_end - 1; auto IsInAddressSpace = [&](KProcessAddress addr) ALWAYS_INLINE_LAMBDA { return m_address_space_start <= addr && addr <= m_address_space_end; }; - /* Ensure that the KernelMap region is valid. */ - for (size_t k = 0; k < num_regions; ++k) { - if (const auto &kmap_region = region_layouts[k]; kmap_region.type == RegionType_KernelMap) { - /* If there's no kmap region, we have nothing to check. */ - if (kmap_region.size == 0) { - break; - } - - /* Check that the kmap region is within our address space. */ - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_KernelMap])); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_KernelMap])); - - /* Check for overlap with process code. */ - const KProcessAddress kmap_start = m_region_starts[RegionType_KernelMap]; - const KProcessAddress kmap_last = m_region_ends[RegionType_KernelMap] - 1; - MESOSPHERE_ABORT_UNLESS(kernel_map_region_size == 0 || kmap_last < process_code_start || process_code_last < kmap_start); - - /* Check for overlap with stack. */ - for (size_t s = 0; s < num_regions; ++s) { - if (const auto &stack_region = region_layouts[s]; stack_region.type == RegionType_Stack) { - if (stack_region.size != 0) { - const KProcessAddress stack_start = m_region_starts[RegionType_Stack]; - const KProcessAddress stack_last = m_region_ends[RegionType_Stack] - 1; - MESOSPHERE_ABORT_UNLESS((kernel_map_region_size == 0 && stack_region_size == 0) || kmap_last < stack_start || stack_last < kmap_start); - } - break; - } - } - - /* Check for overlap with alias. */ - for (size_t a = 0; a < num_regions; ++a) { - if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { - if (alias_region.size != 0) { - const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; - const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; - MESOSPHERE_ABORT_UNLESS(kmap_last < alias_start || alias_last < kmap_start); - } - break; - } - } - - /* Check for overlap with heap. */ - for (size_t h = 0; h < num_regions; ++h) { - if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { - if (heap_region.size != 0) { - const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; - const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; - MESOSPHERE_ABORT_UNLESS(kmap_last < heap_start || heap_last < kmap_start); - } - break; - } - } - } + /* Map each region type to its layout entry. */ + const RegionLayoutInfo *region_layouts_by_type[RegionType_Count] = {}; + for (size_t i = 0; i < num_regions; ++i) { + region_layouts_by_type[region_layouts[i].type] = std::addressof(region_layouts[i]); } - /* Check that the Stack region is valid. */ - for (size_t s = 0; s < num_regions; ++s) { - if (const auto &stack_region = region_layouts[s]; stack_region.type == RegionType_Stack) { - /* If there's no stack region, we have nothing to check. */ - if (stack_region.size == 0) { - break; - } - - /* Check that the stack region is within our address space. */ - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Stack])); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Stack])); - - /* Check for overlap with process code. */ - const KProcessAddress stack_start = m_region_starts[RegionType_Stack]; - const KProcessAddress stack_last = m_region_ends[RegionType_Stack] - 1; - MESOSPHERE_ABORT_UNLESS(stack_region_size == 0 || stack_last < process_code_start || process_code_last < stack_start); - - /* Check for overlap with alias. */ - for (size_t a = 0; a < num_regions; ++a) { - if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { - if (alias_region.size != 0) { - const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; - const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; - MESOSPHERE_ABORT_UNLESS(stack_last < alias_start || alias_last < stack_start); - } - break; - } - } - - /* Check for overlap with heap. */ - for (size_t h = 0; h < num_regions; ++h) { - if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { - if (heap_region.size != 0) { - const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; - const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; - MESOSPHERE_ABORT_UNLESS(stack_last < heap_start || heap_last < stack_start); - } - break; - } - } + /* Validate each region. */ + for (size_t i = 0; i < RegionType_Count; ++i) { + /* If the region isn't present, there's nothing to check. */ + const RegionLayoutInfo * const region = region_layouts_by_type[i]; + if (region == nullptr || region->size == 0) { + continue; } - } - /* Check that the Alias region is valid. */ - for (size_t a = 0; a < num_regions; ++a) { - if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { - /* If there's no alias region, we have nothing to check. */ - if (alias_region.size == 0) { - break; + /* Check that the region is within our address space. */ + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[i])); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[i])); + + /* Check for overlap with process code. */ + MESOSPHERE_ABORT_UNLESS(m_region_ends[i] - 1 < process_code_start || process_code_last < m_region_starts[i]); + + /* Check for overlap with every later region. */ + for (size_t j = i; j < RegionType_ShadowStack; ++j) { + /* If the other region isn't present, there's nothing to check. */ + const RegionLayoutInfo * const other = region_layouts_by_type[j + 1]; + if (other == nullptr || other->size == 0) { + continue; } - /* Check that the alias region is within our address space. */ - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Alias])); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Alias])); - - /* Check for overlap with process code. */ - const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; - const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; - MESOSPHERE_ABORT_UNLESS(alias_last < process_code_start || process_code_last < alias_start); - - /* Check for overlap with heap. */ - for (size_t h = 0; h < num_regions; ++h) { - if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { - if (heap_region.size != 0) { - const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; - const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; - MESOSPHERE_ABORT_UNLESS(alias_last < heap_start || heap_last < alias_start); - } - break; - } - } - } - } - - /* Check that the Heap region is valid. */ - for (size_t h = 0; h < num_regions; ++h) { - if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { - /* If there's no heap region, we have nothing to check. */ - if (heap_region.size == 0) { - break; - } - - /* Check that the heap region is within our address space. */ - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Heap])); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Heap])); - - /* Check for overlap with process code. */ - const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; - const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; - MESOSPHERE_ABORT_UNLESS(heap_last < process_code_start || process_code_last < heap_start); + MESOSPHERE_ABORT_UNLESS(m_region_ends[i] - 1 < m_region_starts[j + 1] || m_region_ends[j + 1] - 1 < m_region_starts[i]); } } } @@ -561,6 +452,8 @@ namespace ams::kern { case ams::svc::MemoryState_Static: case ams::svc::MemoryState_ThreadLocal: return m_region_starts[RegionType_KernelMap]; + case ams::svc::MemoryState_ShadowStack: + return m_region_starts[RegionType_ShadowStack]; case ams::svc::MemoryState_Io: case ams::svc::MemoryState_Shared: case ams::svc::MemoryState_AliasCode: @@ -596,6 +489,8 @@ namespace ams::kern { case ams::svc::MemoryState_Static: case ams::svc::MemoryState_ThreadLocal: return m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; + case ams::svc::MemoryState_ShadowStack: + return m_region_ends[RegionType_ShadowStack] - m_region_starts[RegionType_ShadowStack]; case ams::svc::MemoryState_Io: case ams::svc::MemoryState_Shared: case ams::svc::MemoryState_AliasCode: @@ -622,12 +517,20 @@ namespace ams::kern { const KProcessAddress region_start = this->GetRegionAddress(state); const size_t region_size = this->GetRegionSize(state); + if (region_size == 0) { + return false; + } + const bool is_in_region = region_start <= addr && addr < end && last <= region_start + region_size - 1; - const bool is_in_heap = !(end <= m_region_starts[RegionType_Heap] || m_region_ends[RegionType_Heap] <= addr || m_region_starts[RegionType_Heap] == m_region_ends[RegionType_Heap]); - const bool is_in_alias = !(end <= m_region_starts[RegionType_Alias] || m_region_ends[RegionType_Alias] <= addr || m_region_starts[RegionType_Alias] == m_region_ends[RegionType_Alias]); + switch (state) { case ams::svc::MemoryState_Free: + case ams::svc::MemoryState_Normal: + case ams::svc::MemoryState_Ipc: + case ams::svc::MemoryState_NonSecureIpc: + case ams::svc::MemoryState_NonDeviceIpc: case ams::svc::MemoryState_Kernel: + case ams::svc::MemoryState_ShadowStack: return is_in_region; case ams::svc::MemoryState_Io: case ams::svc::MemoryState_Static: @@ -645,17 +548,32 @@ namespace ams::kern { case ams::svc::MemoryState_CodeOut: case ams::svc::MemoryState_Coverage: case ams::svc::MemoryState_Insecure: - return is_in_region && !is_in_heap && !is_in_alias; - case ams::svc::MemoryState_Normal: - MESOSPHERE_ASSERT(is_in_heap); - return is_in_region && !is_in_alias; - case ams::svc::MemoryState_Ipc: - case ams::svc::MemoryState_NonSecureIpc: - case ams::svc::MemoryState_NonDeviceIpc: - MESOSPHERE_ASSERT(is_in_alias); - return is_in_region && !is_in_heap; - default: - return false; + { + if (!is_in_region) { + return false; + } + + const auto heap_start = m_region_starts[RegionType_Heap]; + const auto heap_end = m_region_ends[RegionType_Heap]; + if (heap_start != heap_end && addr < heap_end && heap_start < end) { + return false; + } + + const auto alias_start = m_region_starts[RegionType_Alias]; + const auto alias_end = m_region_ends[RegionType_Alias]; + if (alias_start != alias_end && addr < alias_end && alias_start < end) { + return false; + } + + const auto shadow_start = m_region_starts[RegionType_ShadowStack]; + const auto shadow_end = m_region_ends[RegionType_ShadowStack]; + if (shadow_start != shadow_end && addr < shadow_end && shadow_start < end) { + return false; + } + + return true; + } + MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } @@ -1997,15 +1915,15 @@ namespace ams::kern { .m_address = GetInteger(m_address_space_end), .m_size = 0 - GetInteger(m_address_space_end), .m_state = static_cast(ams::svc::MemoryState_Inaccessible), - .m_device_disable_merge_left_count = 0, - .m_device_disable_merge_right_count = 0, - .m_ipc_lock_count = 0, - .m_device_use_count = 0, - .m_ipc_disable_merge_count = 0, .m_permission = KMemoryPermission_None, .m_attribute = KMemoryAttribute_None, .m_original_permission = KMemoryPermission_None, + .m_ipc_lock_count = 0, + .m_device_use_count = 0, .m_disable_merge_attribute = KMemoryBlockDisableMergeAttribute_None, + .m_ipc_disable_merge_count = 0, + .m_device_disable_merge_left_count = 0, + .m_device_disable_merge_right_count = 0, }; out_page_info->flags = 0; @@ -3287,7 +3205,7 @@ namespace ams::kern { Result KPageTableBase::CopyMemoryFromLinearToUser(KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr) { /* Lightly validate the range before doing anything else. */ - R_UNLESS(this->Contains(src_addr, size), svc::ResultInvalidCurrentMemory()); + R_UNLESS(this->IsSafeUserPointer(src_addr, size), svc::ResultInvalidCurrentMemory()); /* Copy the memory. */ { @@ -3436,7 +3354,7 @@ namespace ams::kern { Result KPageTableBase::CopyMemoryFromUserToLinear(KProcessAddress dst_addr, size_t size, u32 dst_state_mask, u32 dst_state, KMemoryPermission dst_test_perm, u32 dst_attr_mask, u32 dst_attr, KProcessAddress src_addr) { /* Lightly validate the range before doing anything else. */ - R_UNLESS(this->Contains(dst_addr, size), svc::ResultInvalidCurrentMemory()); + R_UNLESS(this->IsSafeUserPointer(dst_addr, size), svc::ResultInvalidCurrentMemory()); /* Copy the memory. */ { diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 91048f4f6..35648a37a 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -210,7 +210,7 @@ namespace ams::kern { m_program_id = params.program_id; m_code_address = params.code_address; m_code_size = params.code_num_pages * PageSize; - m_is_application = (params.flags & ams::svc::CreateProcessFlag_IsApplication); + m_is_application = (params.flags & ams::svc::CreateProcessParameterFlag_IsApplication); m_is_jit_debug = false; #if defined(MESOSPHERE_ENABLE_PROCESS_CREATION_TIME) @@ -226,7 +226,7 @@ namespace ams::kern { } /* Set max memory. */ - m_max_process_memory = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(m_flags), KAddressSpaceInfo::Type_Heap); + m_max_process_memory = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(m_flags), KAddressSpaceInfo::Type_Heap); /* Generate random entropy. */ KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy)); @@ -264,6 +264,11 @@ namespace ams::kern { m_is_default_application_system_resource = false; m_is_immortal = immortal; + /* Reseed the random generator on application launch. */ + if (params.flags & ams::svc::CreateProcessParameterFlag_IsApplication) { + KSystemControl::ReseedRandomGenerator(); + } + /* Setup our system resource. */ if (const size_t system_resource_num_pages = params.system_resource_num_pages; system_resource_num_pages != 0) { /* Create a secure system resource. */ @@ -279,7 +284,7 @@ namespace ams::kern { m_system_resource = secure_resource; } else { /* Use the system-wide system resource. */ - const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication); + const bool is_app = (params.flags & ams::svc::CreateProcessParameterFlag_IsApplication); m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource()); m_is_default_application_system_resource = is_app; @@ -293,8 +298,8 @@ namespace ams::kern { /* Setup page table. */ { - const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0; - R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit, this->GetSlabIndex())); + const bool from_back = (params.flags & ams::svc::CreateProcessParameterFlag_EnableAslr) == 0; + R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit, this->GetSlabIndex())); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; @@ -332,6 +337,11 @@ namespace ams::kern { m_is_default_application_system_resource = false; m_is_immortal = false; + /* Reseed the random generator on application launch. */ + if (params.flags & ams::svc::CreateProcessParameterFlag_IsApplication) { + KSystemControl::ReseedRandomGenerator(); + } + /* Get the memory sizes. */ const size_t code_num_pages = params.code_num_pages; const size_t system_resource_num_pages = params.system_resource_num_pages; @@ -358,7 +368,7 @@ namespace ams::kern { } else { /* Use the system-wide system resource. */ - const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication); + const bool is_app = (params.flags & ams::svc::CreateProcessParameterFlag_IsApplication); m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource()); m_is_default_application_system_resource = is_app; @@ -372,8 +382,8 @@ namespace ams::kern { /* Setup page table. */ { - const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0; - R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, code_size, m_system_resource, res_limit, this->GetSlabIndex())); + const bool from_back = (params.flags & ams::svc::CreateProcessParameterFlag_EnableAslr) == 0; + R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, code_size, m_system_resource, res_limit, this->GetSlabIndex())); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; @@ -392,7 +402,7 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(m_process_id <= ProcessIdMax); /* If we should optimize memory allocations, do so. */ - if (m_system_resource->IsSecureResource() && (params.flags & ams::svc::CreateProcessFlag_OptimizeMemoryAllocation) != 0) { + if (m_system_resource->IsSecureResource() && (params.flags & ams::svc::CreateProcessParameterFlag_OptimizeMemoryAllocation) != 0) { R_TRY(Kernel::GetMemoryManager().InitializeOptimizedMemory(m_process_id, pool)); } @@ -455,7 +465,7 @@ namespace ams::kern { } } - void KProcess::Exit() { + void KProcess::Exit(s64 exit_tag) { MESOSPHERE_ASSERT_THIS(); /* Determine whether we need to start terminating. */ @@ -470,6 +480,7 @@ namespace ams::kern { MESOSPHERE_ASSERT(m_state != State_Terminated); if (m_state == State_Running || m_state == State_RunningAttached || m_state == State_DebugBreak) { this->ChangeState(State_Terminating); + this->SetExitTag(exit_tag); needs_terminate = true; } } @@ -490,7 +501,7 @@ namespace ams::kern { MESOSPHERE_PANIC("Thread survived call to exit"); } - Result KProcess::Terminate() { + Result KProcess::Terminate(s64 exit_tag) { MESOSPHERE_ASSERT_THIS(); /* Determine whether we need to start terminating */ @@ -506,6 +517,7 @@ namespace ams::kern { if (m_state == State_Running || m_state == State_RunningAttached || m_state == State_Crashed || m_state == State_DebugBreak) { this->ChangeState(State_Terminating); + this->SetExitTag(exit_tag); needs_terminate = true; } } @@ -773,7 +785,7 @@ namespace ams::kern { MESOSPHERE_ASSERT(m_num_running_threads.Load() > 0); if (const auto prev = m_num_running_threads--; prev == 1) { - static_cast(this->Terminate()); + static_cast(this->Terminate(-1ll)); } } @@ -970,6 +982,9 @@ namespace ams::kern { /* Initialize the thread. */ R_TRY(KThread::InitializeUserThread(main_thread, reinterpret_cast(GetVoidPointer(this->GetEntryPoint())), 0, stack_top, priority, m_ideal_core_id, this)); + /* TODO: what is this? */ + main_thread->SetDebugUnknown5(true); + /* Register the thread, and commit our reservation. */ KThread::Register(main_thread); thread_reservation.Commit(); @@ -1189,7 +1204,7 @@ namespace ams::kern { MESOSPHERE_ASSERT(this == GetCurrentProcessPointer()); /* If we aren't allowed to enter jit debug, don't. */ - if ((m_flags & ams::svc::CreateProcessFlag_EnableDebug) == 0) { + if ((m_flags & ams::svc::CreateProcessParameterFlag_EnableJitDebug) == 0) { return false; } diff --git a/libraries/libmesosphere/source/kern_k_session_request.cpp b/libraries/libmesosphere/source/kern_k_session_request.cpp index deb1619d5..12acaee0e 100644 --- a/libraries/libmesosphere/source/kern_k_session_request.cpp +++ b/libraries/libmesosphere/source/kern_k_session_request.cpp @@ -28,6 +28,8 @@ namespace ams::kern { } else { /* Allocate dynamic mappings as necessary. */ if (m_dynamic_mappings == nullptr) { + /* 23.0.0+ now checks for IsDynamicResourceLimitsEnabled before allocating from slab heap. */ + R_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled(), svc::ResultOutOfMemory()); m_dynamic_mappings = DynamicMappings::Allocate(); R_UNLESS(m_dynamic_mappings != nullptr, svc::ResultOutOfMemory()); } @@ -44,16 +46,19 @@ namespace ams::kern { Result KSessionRequest::SessionMappings::PushSend(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) { MESOSPHERE_ASSERT(m_num_recv == 0); MESOSPHERE_ASSERT(m_num_exch == 0); - R_RETURN(this->PushMap(client, server, size, state, m_num_send++)); + ON_RESULT_SUCCESS { ++m_num_send; }; + R_RETURN(this->PushMap(client, server, size, state, m_num_send)); } Result KSessionRequest::SessionMappings::PushReceive(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) { MESOSPHERE_ASSERT(m_num_exch == 0); - R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv++)); + ON_RESULT_SUCCESS { ++m_num_recv; }; + R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv)); } Result KSessionRequest::SessionMappings::PushExchange(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) { - R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv + m_num_exch++)); + ON_RESULT_SUCCESS { ++m_num_exch; }; + R_RETURN(this->PushMap(client, server, size, state, m_num_send + m_num_recv + m_num_exch)); } void KSessionRequest::SessionMappings::Finalize() { diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index dece074ef..c92bbe60e 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -14,6 +14,8 @@ * along with this program. If not, see . */ #include +#include +#include #if defined(ATMOSPHERE_ARCH_ARM64) #include #endif @@ -27,6 +29,41 @@ namespace ams::kern { } + namespace { + + /* The kernel is otherwise FP/SIMD-free, but AES instructions require the NEON registers. */ + class KScopedFpuEnable { + private: + u64 m_saved_cpacr_el1; + public: + ALWAYS_INLINE KScopedFpuEnable() : m_saved_cpacr_el1(cpu::GetCpacrEl1()) { + cpu::SetCpacrEl1(m_saved_cpacr_el1 | 0x100000); + cpu::InstructionMemoryBarrier(); + } + + ALWAYS_INLINE ~KScopedFpuEnable() { + cpu::SetCpacrEl1(m_saved_cpacr_el1); + cpu::InstructionMemoryBarrier(); + } + }; + + using RandomGenerator = ::ams::crypto::impl::CtrDrbg<::ams::crypto::AesEncryptor128, 16, false>; + + constexpr size_t RandomGeneratorOutputSize = 8 * RandomGenerator::OutSize; + constexpr u32 RandomGeneratorOutputCount = RandomGeneratorOutputSize / sizeof(u32); + + constinit util::TypedStorage s_random_generator = {}; + constinit bool s_uninitialized_random_generator = true; + constinit u8 s_random_output[RandomGeneratorOutputSize] = {}; + constinit u32 s_random_remaining = 0; + constinit KSpinLock s_random_lock; + + void GenerateRandomSeed(void *dst, size_t size) { + KSystemControl::GenerateRandomBytesForUninitialized(dst, size); + } + + } + /* Initialization. */ size_t KSystemControlBase::Init::GetRealMemorySize() { return ams::kern::MainMemorySize; @@ -102,25 +139,13 @@ namespace ams::kern { /* Randomness for Initialization. */ void KSystemControlBase::Init::GenerateRandom(u64 *dst, size_t count) { - if (AMS_UNLIKELY(s_uninitialized_random_generator)) { - const u64 seed = KHardwareTimer::GetTick(); - s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_uninitialized_random_generator = false; - } - for (size_t i = 0; i < count; ++i) { - dst[i] = s_random_generator.GenerateRandomU64(); + dst[i] = KSystemControlBase::GenerateRandomU64(); } } u64 KSystemControlBase::Init::GenerateRandomRange(u64 min, u64 max) { - if (AMS_UNLIKELY(s_uninitialized_random_generator)) { - const u64 seed = KHardwareTimer::GetTick(); - s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_uninitialized_random_generator = false; - } - - return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); }); + return KSystemControlBase::GenerateRandomRange(min, max); } /* System Initialization. */ @@ -135,15 +160,17 @@ namespace ams::kern { } /* Initialize random and resource limit. */ - KSystemControlBase::InitializePhase1Base(KHardwareTimer::GetTick()); + u64 seed[4]; + for (size_t i = 0; i < util::size(seed); ++i) { + seed[i] = KHardwareTimer::GetTick(); + } + KSystemControlBase::InitializePhase1Base(seed, sizeof(seed)); } - void KSystemControlBase::InitializePhase1Base(u64 seed) { - /* Initialize the rng, if we somehow haven't already. */ - if (AMS_UNLIKELY(s_uninitialized_random_generator)) { - s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_uninitialized_random_generator = false; - } + void KSystemControlBase::InitializePhase1Base(const void *seed, size_t size) { + /* Initialize the random generator. */ + KSystemControlBase::InitializeRandomGenerator(seed, size); + s_uninitialized_random_generator = false; /* Initialize debug logging. */ KDebugLog::Initialize(); @@ -170,6 +197,13 @@ namespace ams::kern { KAddressSpaceInfo::SetAddressSpaceSize(39, KAddressSpaceInfo::Type_Alias, alias_size); } + /* Update 42-bit address space infos. */ + { + /* Heap should be equal to the total memory size, maximum 128 GB. */ + /* Alias/Stack/MapSmall are left at their static defaults. */ + KAddressSpaceInfo::SetAddressSpaceSize(42, KAddressSpaceInfo::Type_Heap, std::min(util::AlignUp(total_memory_size, 1_GB), 128_GB)); + } + const auto &slab_counts = init::GetSlabResourceCounts(); MESOSPHERE_R_ABORT_UNLESS(sys_res_limit.SetLimitValue(ams::svc::LimitableResource_PhysicalMemoryMax, total_memory_size)); MESOSPHERE_R_ABORT_UNLESS(sys_res_limit.SetLimitValue(ams::svc::LimitableResource_ThreadCountMax, slab_counts.num_KThread)); @@ -206,13 +240,77 @@ namespace ams::kern { R_THROW(svc::ResultNotImplemented()); } + /* Randomness helpers. Assume the caller holds the random lock. */ + void KSystemControlBase::InitializeRandomGenerator(const void *seed, size_t size) { + MESOSPHERE_ASSERT(size == RandomGenerator::SeedSize); + + KScopedFpuEnable fp_enabled; + + /* Construct the generator, and derive the initial state from the seed. */ + util::ConstructAt(s_random_generator); + util::GetReference(s_random_generator).Initialize(seed, size, nullptr, 0, nullptr, 0); + + s_random_remaining = 0; + } + + void KSystemControlBase::ReseedRandomGeneratorInternal() { + KScopedFpuEnable fp_enabled; + + /* Pull fresh entropy, then derive a new state from it. */ + u8 seed[RandomGenerator::SeedSize]; + GenerateRandomSeed(seed, sizeof(seed)); + util::GetReference(s_random_generator).Reseed(seed, sizeof(seed), nullptr, 0); + + s_random_remaining = 0; + } + + u32 KSystemControlBase::GenerateRandomU32() { + if (s_random_remaining == 0) { + KScopedFpuEnable fp_enabled; + + auto &drbg = util::GetReference(s_random_generator); + + /* Derive the next state, or reseed if we've exhausted this generation's entropy. */ + if (AMS_UNLIKELY(!drbg.Generate(s_random_output, sizeof(s_random_output), nullptr, 0))) { + u8 seed[RandomGenerator::SeedSize]; + GenerateRandomSeed(seed, sizeof(seed)); + drbg.Reseed(seed, sizeof(seed), nullptr, 0); + + MESOSPHERE_ABORT_UNLESS(drbg.Generate(s_random_output, sizeof(s_random_output), nullptr, 0)); + } + + s_random_remaining = RandomGeneratorOutputCount; + } + + /* Consume a word from the output buffer, zeroizing it in place for backtracking resistance. */ + const size_t index = RandomGeneratorOutputCount - s_random_remaining; + u32 value; + std::memcpy(std::addressof(value), s_random_output + sizeof(value) * index, sizeof(value)); + std::memset(s_random_output + sizeof(value) * index, 0, sizeof(value)); + --s_random_remaining; + return value; + } + + u64 KSystemControlBase::GenerateRandomU64Internal() { + /* Fall back to the board's raw source while the generator is uninitialized. */ + if (AMS_UNLIKELY(s_uninitialized_random_generator)) { + u64 value; + KSystemControl::GenerateRandomBytesForUninitialized(std::addressof(value), sizeof(value)); + return value; + } + + const u64 high = KSystemControlBase::GenerateRandomU32(); + const u64 low = KSystemControlBase::GenerateRandomU32(); + return (high << 32) | low; + } + /* Randomness. */ void KSystemControlBase::GenerateRandom(u64 *dst, size_t count) { KScopedInterruptDisable intr_disable; KScopedSpinLock lk(s_random_lock); for (size_t i = 0; i < count; ++i) { - dst[i] = s_random_generator.GenerateRandomU64(); + dst[i] = KSystemControlBase::GenerateRandomU64Internal(); } } @@ -220,14 +318,46 @@ namespace ams::kern { KScopedInterruptDisable intr_disable; KScopedSpinLock lk(s_random_lock); - return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); }); + /* While uninitialized, fall back to a raw single-draw modulo. */ + if (AMS_UNLIKELY(s_uninitialized_random_generator)) { + u64 value; + KSystemControl::GenerateRandomBytesForUninitialized(std::addressof(value), sizeof(value)); + + const u64 difference = max - min; + if (difference == std::numeric_limits::max()) { + return value; + } + + return min + (value % (difference + 1)); + } + + return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return KSystemControlBase::GenerateRandomU64Internal(); }); } u64 KSystemControlBase::GenerateRandomU64() { KScopedInterruptDisable intr_disable; KScopedSpinLock lk(s_random_lock); - return s_random_generator.GenerateRandomU64(); + return KSystemControlBase::GenerateRandomU64Internal(); + } + + void KSystemControlBase::ReseedRandomGenerator() { + /* This must be unreachable while the generator is uninitialized. */ + MESOSPHERE_ABORT_UNLESS(!s_uninitialized_random_generator); + + KScopedInterruptDisable intr_disable; + KScopedSpinLock lk(s_random_lock); + + KSystemControlBase::ReseedRandomGeneratorInternal(); + } + + void KSystemControlBase::GenerateRandomBytesForUninitialized(void *dst, size_t size) { + /* The default board has no secure monitor; fall back to the hardware timer. */ + u8 *dst_8 = static_cast(dst); + for (size_t offset = 0; offset < size; offset += sizeof(u64)) { + const u64 tick = KHardwareTimer::GetTick(); + std::memcpy(dst_8 + offset, std::addressof(tick), std::min(sizeof(tick), size - offset)); + } } void KSystemControlBase::SleepSystem() { diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index 9cf5ea862..b2ec76302 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -214,6 +214,10 @@ namespace ams::kern { m_tls_address = 0; m_tls_heap_address = 0; + /* Set shadow stack address and page. */ + m_shadow_stack_address = Null; + m_shadow_stack_page = nullptr; + /* Set parent and condvar tree. */ m_parent = nullptr; m_condvar_tree = nullptr; @@ -281,6 +285,29 @@ namespace ams::kern { R_TRY(owner->CreateThreadLocalRegion(std::addressof(m_tls_address))); m_tls_heap_address = owner->GetThreadLocalRegionPointer(m_tls_address); std::memset(m_tls_heap_address, 0, ams::svc::ThreadLocalRegionSize); + + /* If the owning process has a shadow stack, allocate and map a page for this thread. */ + if (owner->GetCreateProcessParameterFlags() & ams::svc::CreateProcessParameterFlag_EnableShadowStack) { + /* Allocate the backing page. */ + KPageBuffer *page = KPageBuffer::AllocateChecked(); + if (page == nullptr) { + owner->DeleteThreadLocalRegion(m_tls_address); + m_tls_address = Null; + R_THROW(svc::ResultOutOfMemory()); + } + + /* If we fail to map the page, free it and undo the TLS region we just created. */ + ON_RESULT_FAILURE { + KPageBuffer::Free(page); + owner->DeleteThreadLocalRegion(m_tls_address); + m_tls_address = Null; + }; + + /* Map the page into the process's shadow stack region. */ + R_TRY(owner->GetPageTable().MapPages(std::addressof(m_shadow_stack_address), 1, PageSize, page->GetPhysicalAddress(), KMemoryState_ShadowStack, KMemoryPermission_UserReadWrite)); + + m_shadow_stack_page = page; + } } /* Set parent, if relevant. */ @@ -390,6 +417,12 @@ namespace ams::kern { m_parent->UnregisterThread(this); } + /* If the thread has a shadow stack, unmap and free its page. */ + if (m_shadow_stack_address != Null) { + MESOSPHERE_R_ABORT_UNLESS(m_parent->GetPageTable().UnmapPages(m_shadow_stack_address, 1, KMemoryState_ShadowStack)); + KPageBuffer::Free(m_shadow_stack_page); + } + /* If the thread has a local region, delete it. */ if (m_tls_address != Null) { m_parent->DeleteThreadLocalRegion(m_tls_address); diff --git a/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp b/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp index 2b495ad45..939c29107 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp @@ -21,8 +21,10 @@ namespace ams::kern::svc { namespace { - constexpr bool IsKernelAddress(uintptr_t address) { - return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd; + constexpr bool IsValidAddress(uintptr_t address) { + if (KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd) return false; + if (GetCurrentProcess().GetPageTable().IsInShadowStackRegion(address)) return false; + return true; } constexpr bool IsValidSignalType(ams::svc::SignalType type) { @@ -50,7 +52,7 @@ namespace ams::kern::svc { Result WaitForAddress(uintptr_t address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { /* Validate input. */ - R_UNLESS(AMS_LIKELY(!IsKernelAddress(address)), svc::ResultInvalidCurrentMemory()); + R_UNLESS(AMS_LIKELY(IsValidAddress(address)), svc::ResultInvalidCurrentMemory()); if (arb_type == ams::svc::ArbitrationType_WaitIfEqual64) { R_UNLESS(util::IsAligned(address, sizeof(int64_t)), svc::ResultInvalidAddress()); } else { @@ -79,7 +81,7 @@ namespace ams::kern::svc { Result SignalToAddress(uintptr_t address, ams::svc::SignalType signal_type, int32_t value, int32_t count) { /* Validate input. */ - R_UNLESS(AMS_LIKELY(!IsKernelAddress(address)), svc::ResultInvalidCurrentMemory()); + R_UNLESS(AMS_LIKELY(IsValidAddress(address)), svc::ResultInvalidCurrentMemory()); R_UNLESS(util::IsAligned(address, sizeof(int32_t)), svc::ResultInvalidAddress()); R_UNLESS(IsValidSignalType(signal_type), svc::ResultInvalidEnumValue()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_cache.cpp b/libraries/libmesosphere/source/svc/kern_svc_cache.cpp index 00f84781f..895959f9a 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_cache.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_cache.cpp @@ -83,7 +83,7 @@ namespace ams::kern::svc { R_SUCCEED_IF(size == 0); /* Validate that the region is within range. */ - R_UNLESS(GetCurrentProcess().GetPageTable().Contains(address, size), svc::ResultInvalidCurrentMemory()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(address, size), svc::ResultInvalidCurrentMemory()); /* did N intend ResultInvalidPointer like everywhere else? */ /* Flush the cache. */ R_TRY(cpu::FlushDataCache(reinterpret_cast(address), size)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_condition_variable.cpp b/libraries/libmesosphere/source/svc/kern_svc_condition_variable.cpp index 2d3a031ef..aebe88443 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_condition_variable.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_condition_variable.cpp @@ -21,13 +21,15 @@ namespace ams::kern::svc { namespace { - constexpr bool IsKernelAddress(uintptr_t address) { - return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd; + constexpr bool IsValidAddress(uintptr_t address) { + if (KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd) return false; + if (GetCurrentProcess().GetPageTable().IsInShadowStackRegion(address)) return false; + return true; } Result WaitProcessWideKeyAtomic(uintptr_t address, uintptr_t cv_key, uint32_t tag, int64_t timeout_ns) { /* Validate input. */ - R_UNLESS(AMS_LIKELY(!IsKernelAddress(address)), svc::ResultInvalidCurrentMemory()); + R_UNLESS(AMS_LIKELY(IsValidAddress(address)), svc::ResultInvalidPointer()); R_UNLESS(util::IsAligned(address, sizeof(int32_t)), svc::ResultInvalidAddress()); /* Convert timeout from nanoseconds to ticks. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_debug.cpp b/libraries/libmesosphere/source/svc/kern_svc_debug.cpp index 986654ce4..3eb0958c1 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_debug.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_debug.cpp @@ -97,6 +97,8 @@ namespace ams::kern::svc { /* Only allow invoking the svc on development hardware or if force debug prod. */ R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(out_info.GetUnsafePointer()), sizeof(EventInfoType)), svc::ResultInvalidPointer()); + /* Get the debug object. */ KScopedAutoObject debug = GetCurrentProcess().GetHandleTable().GetObject(debug_handle); R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle()); @@ -142,6 +144,7 @@ namespace ams::kern::svc { /* Copy the threads from userspace. */ uint64_t thread_ids[MaximumDebuggableThreadCount]; if (num_thread_ids > 0) { + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(user_thread_ids.GetUnsafePointer()), num_thread_ids * sizeof(uint64_t)), svc::ResultInvalidPointer()); R_TRY(user_thread_ids.CopyArrayTo(thread_ids, num_thread_ids)); } @@ -172,6 +175,8 @@ namespace ams::kern::svc { /* Only allow invoking the svc on development hardware or if force debug prod. */ R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(out_context.GetUnsafePointer()), sizeof(ams::svc::ThreadContext)), svc::ResultInvalidPointer()); + /* Validate the context flags. */ R_UNLESS((context_flags | ams::svc::ThreadContextFlag_All) == ams::svc::ThreadContextFlag_All, svc::ResultInvalidEnumValue()); @@ -193,6 +198,8 @@ namespace ams::kern::svc { /* Only allow invoking the svc on development hardware. */ R_UNLESS(KTargetSystem::IsDebugMode(), svc::ResultNotImplemented()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(user_context.GetUnsafePointer()), sizeof(ams::svc::ThreadContext)), svc::ResultInvalidPointer()); + /* Validate the context flags. */ #if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP) { @@ -243,6 +250,8 @@ namespace ams::kern::svc { template Result QueryDebugProcessMemory(KUserPointer out_memory_info, ams::svc::PageInfo *out_page_info, ams::svc::Handle debug_handle, uint64_t address) { + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(out_memory_info.GetUnsafePointer()), sizeof(T)), svc::ResultInvalidPointer()); + /* Get an ams::svc::MemoryInfo for the region. */ ams::svc::MemoryInfo info = {}; R_TRY(QueryDebugProcessMemory(std::addressof(info), out_page_info, debug_handle, address)); @@ -429,6 +438,11 @@ namespace ams::kern::svc { *out_32 = affinity_mask; } break; + case ams::svc::DebugThreadParam_Unknown5: + { + *out_32 = thread->IsDebugUnknown5(); + } + break; default: R_THROW(ams::svc::ResultInvalidEnumValue()); } diff --git a/libraries/libmesosphere/source/svc/kern_svc_debug_string.cpp b/libraries/libmesosphere/source/svc/kern_svc_debug_string.cpp index c36c93ffe..5f15e77f4 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_debug_string.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_debug_string.cpp @@ -26,7 +26,7 @@ namespace ams::kern::svc { R_SUCCEED_IF(len == 0); /* Ensure that the data being output is in range. */ - R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(debug_str.GetUnsafePointer()), len), svc::ResultInvalidCurrentMemory()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(debug_str.GetUnsafePointer()), len), svc::ResultInvalidPointer()); /* Output the string. */ R_RETURN(KDebugLog::PrintUserString(debug_str, len)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_exception.cpp b/libraries/libmesosphere/source/svc/kern_svc_exception.cpp index 667646455..797b0d979 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_exception.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_exception.cpp @@ -70,7 +70,7 @@ namespace ams::kern::svc { } /* Exit the current process. */ - GetCurrentProcess().Exit(); + GetCurrentProcess().Exit(-1ll); } } diff --git a/libraries/libmesosphere/source/svc/kern_svc_info.cpp b/libraries/libmesosphere/source/svc/kern_svc_info.cpp index ec41ef59a..8b51c7fba 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_info.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_info.cpp @@ -109,6 +109,15 @@ namespace ams::kern::svc { case ams::svc::InfoType_AliasRegionExtraSize: *out = process->GetPageTable().GetAliasRegionExtraSize(); break; + case ams::svc::InfoType_AddressSpaceSize: + *out = process->GetAddressSpaceSize(); + break; + case ams::svc::InfoType_ShadowStackRegionAddress: + *out = GetInteger(process->GetPageTable().GetShadowStackRegionStart()); + break; + case ams::svc::InfoType_ShadowStackRegionSize: + *out = process->GetPageTable().GetShadowStackRegionSize(); + break; MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } @@ -138,6 +147,9 @@ namespace ams::kern::svc { case ams::svc::InfoType_IsApplication: case ams::svc::InfoType_FreeThreadCount: case ams::svc::InfoType_AliasRegionExtraSize: + case ams::svc::InfoType_AddressSpaceSize: + case ams::svc::InfoType_ShadowStackRegionAddress: + case ams::svc::InfoType_ShadowStackRegionSize: { /* These info types don't support non-zero subtypes. */ R_UNLESS(info_subtype == 0, svc::ResultInvalidCombination()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp b/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp index e2013a1b3..603db823c 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp @@ -110,7 +110,7 @@ namespace ams::kern::svc { /* Copy user handles. */ if (num_handles > 0) { /* Ensure that we can try to get the handles. */ - R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(user_handles.GetUnsafePointer()), num_handles * sizeof(ams::svc::Handle)), svc::ResultInvalidPointer()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(user_handles.GetUnsafePointer()), num_handles * sizeof(ams::svc::Handle)), svc::ResultInvalidPointer()); /* Get the handles. */ R_TRY(user_handles.CopyArrayTo(handles, num_handles)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_lock.cpp b/libraries/libmesosphere/source/svc/kern_svc_lock.cpp index be19bc0ed..9ada8d0fc 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_lock.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_lock.cpp @@ -21,13 +21,15 @@ namespace ams::kern::svc { namespace { - constexpr bool IsKernelAddress(uintptr_t address) { - return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd; + constexpr bool IsValidAddress(uintptr_t address) { + if (KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd) return false; + if (GetCurrentProcess().GetPageTable().IsInShadowStackRegion(address)) return false; + return true; } Result ArbitrateLock(ams::svc::Handle thread_handle, uintptr_t address, uint32_t tag) { /* Validate the input address. */ - R_UNLESS(!IsKernelAddress(address), svc::ResultInvalidCurrentMemory()); + R_UNLESS(IsValidAddress(address), svc::ResultInvalidCurrentMemory()); R_UNLESS(util::IsAligned(address, sizeof(u32)), svc::ResultInvalidAddress()); R_RETURN(KConditionVariable::WaitForAddress(thread_handle, address, tag)); @@ -35,7 +37,7 @@ namespace ams::kern::svc { Result ArbitrateUnlock(uintptr_t address) { /* Validate the input address. */ - R_UNLESS(!IsKernelAddress(address), svc::ResultInvalidCurrentMemory()); + R_UNLESS(IsValidAddress(address), svc::ResultInvalidCurrentMemory()); R_UNLESS(util::IsAligned(address, sizeof(u32)), svc::ResultInvalidAddress()); R_RETURN(KConditionVariable::SignalToAddress(address)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_port.cpp b/libraries/libmesosphere/source/svc/kern_svc_port.cpp index 1ac5803d2..cfc13a3a8 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_port.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_port.cpp @@ -21,11 +21,22 @@ namespace ams::kern::svc { namespace { + static Result GetPortName(char (&name)[KObjectName::NameLengthMax], KUserPointer user_name) { + /* Copy the provided name from user memory to kernel memory. */ + R_TRY(user_name.CopyStringTo(name, sizeof(name))); + + /* Oddly enough N here first copies then validates if it's not in forbidden range. */ + const auto name_len = util::Strnlen(name, sizeof(name)); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(user_name.GetUnsafePointer()), name_len + 1), svc::ResultInvalidPointer()); + + R_SUCCEED(); + } + Result ManageNamedPort(ams::svc::Handle *out_server_handle, KUserPointer user_name, s32 max_sessions) { /* Copy the provided name from user memory to kernel memory. */ char name[KObjectName::NameLengthMax] = {}; - R_TRY(user_name.CopyStringTo(name, sizeof(name))); - + R_TRY(GetPortName(name, user_name)); + /* Validate that sessions and name are valid. */ R_UNLESS(max_sessions >= 0, svc::ResultOutOfRange()); R_UNLESS(name[sizeof(name) - 1] == '\x00', svc::ResultOutOfRange()); @@ -106,7 +117,7 @@ namespace ams::kern::svc { Result ConnectToNamedPort(ams::svc::Handle *out, KUserPointer user_name) { /* Copy the provided name from user memory to kernel memory. */ char name[KObjectName::NameLengthMax] = {}; - R_TRY(user_name.CopyStringTo(name, sizeof(name))); + R_TRY(GetPortName(name, user_name)); /* Validate that name is valid. */ R_UNLESS(name[sizeof(name) - 1] == '\x00', svc::ResultOutOfRange()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index 6e516a51f..83e2dc3e7 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -25,8 +25,9 @@ namespace ams::kern::svc { return (0 <= core_id && core_id < static_cast(cpu::NumVirtualCores)); } - void ExitProcess() { - GetCurrentProcess().Exit(); + void ExitProcess(int64_t exit_tag) { + const uint32_t intended_kernel_major_version = GetCurrentProcess().GetIntendedKernelMajorVersion(); + GetCurrentProcess().Exit(intended_kernel_major_version <= 26 ? -1ll : exit_tag); MESOSPHERE_PANIC("Process survived call to exit"); } @@ -79,13 +80,47 @@ namespace ams::kern::svc { /* Validate that the pointer is in range. */ if (max_out_count > 0) { - R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(out_process_ids.GetUnsafePointer()), max_out_count * sizeof(u64)), svc::ResultInvalidCurrentMemory()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(out_process_ids.GetUnsafePointer()), max_out_count * sizeof(u64)), svc::ResultInvalidPointer()); } /* Get the process list. */ R_RETURN(KProcess::GetProcessList(out_num_processes, out_process_ids, max_out_count)); } + constexpr size_t GetProcessSlotT0Sz(ams::svc::CreateProcessParameterFlag flags) { + if ((flags & ams::svc::CreateProcessParameterFlag_AddressSpaceMask) == ams::svc::CreateProcessParameterFlag_AddressSpace64Bit42) { + return (64 - 42); + } else { + return (64 - 39); + } + } + + KProcess *CreateProcessForAddressSpace(ams::svc::CreateProcessParameterFlag flags) { + /* Find a process slab slot whose root page table is meant for the requested address space. */ + const size_t desired_t0sz = GetProcessSlotT0Sz(flags); + + KProcess *process = nullptr; + KProcess *rejected[init::SlabCountKProcess]; + size_t num_rejected = 0; + while ((process = KProcess::Create()) != nullptr) { + /* Stop once we find a slot whose T0SZ matches. */ + if ((KProcessPageTable::GetProcessTcrEl1(process->GetSlabIndex()) & 0x3F) == desired_t0sz) { + break; + } + + /* Otherwise, park the process and try the next slot. */ + rejected[num_rejected++] = process; + process = nullptr; + } + + /* Release every process we parked while searching. */ + for (size_t i = 0; i < num_rejected; ++i) { + rejected[i]->Close(); + } + + return process; + } + Result CreateProcess(ams::svc::Handle *out, const ams::svc::CreateProcessParameter ¶ms, KUserPointer user_caps, int32_t num_caps) { /* Validate the capabilities pointer. */ R_UNLESS(num_caps >= 0, svc::ResultInvalidPointer()); @@ -94,14 +129,17 @@ namespace ams::kern::svc { R_UNLESS(((num_caps * sizeof(u32)) / sizeof(u32)) == static_cast(num_caps), svc::ResultInvalidPointer()); /* Validate that the pointer is in range. */ - R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(user_caps.GetUnsafePointer()), num_caps * sizeof(u32)), svc::ResultInvalidPointer()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(user_caps.GetUnsafePointer()), num_caps * sizeof(u32)), svc::ResultInvalidPointer()); } /* Validate that the parameter flags are valid. */ - R_UNLESS((params.flags & ~ams::svc::CreateProcessFlag_All) == 0, svc::ResultInvalidEnumValue()); + R_UNLESS((params.flags & ~ams::svc::CreateProcessParameterFlag_All) == 0, svc::ResultInvalidEnumValue()); + + /* The 64KB page size is not yet allowed. */ + R_UNLESS((params.flags & ams::svc::CreateProcessParameterFlag_AddressSpaceMask) != ams::svc::CreateProcessParameterFlag_AddressSpace64Bit42, svc::ResultInvalidCombination()); /* Validate that 64-bit process is okay. */ - const bool is_64_bit = (params.flags & ams::svc::CreateProcessFlag_Is64Bit) != 0; + const bool is_64_bit = (params.flags & ams::svc::CreateProcessParameterFlag_64Bit) != 0; if constexpr (sizeof(void *) < sizeof(u64)) { R_UNLESS(!is_64_bit, svc::ResultInvalidCombination()); } @@ -110,34 +148,35 @@ namespace ams::kern::svc { uintptr_t map_start, map_end; size_t map_size; const size_t code_size = params.code_num_pages * PageSize; - switch (params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) { - case ams::svc::CreateProcessFlag_AddressSpace32Bit: - case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: + switch (params.flags & ams::svc::CreateProcessParameterFlag_AddressSpaceMask) { + case ams::svc::CreateProcessParameterFlag_AddressSpace32Bit: + case ams::svc::CreateProcessParameterFlag_AddressSpace32BitNoReserved: { - map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } break; - case ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated: + case ams::svc::CreateProcessParameterFlag_AddressSpace64Bit36: { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } break; - case ams::svc::CreateProcessFlag_AddressSpace64Bit: + case ams::svc::CreateProcessParameterFlag_AddressSpace64Bit39: + case ams::svc::CreateProcessParameterFlag_AddressSpace64Bit42: { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit, code_size); - map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapHuge, code_size); + map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapHuge); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Heap); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Heap); } break; default: @@ -146,11 +185,11 @@ namespace ams::kern::svc { /* Validate the pool partition. */ if (GetTargetFirmware() >= TargetFirmware_5_0_0) { - switch (params.flags & ams::svc::CreateProcessFlag_PoolPartitionMask) { - case ams::svc::CreateProcessFlag_PoolPartitionApplication: - case ams::svc::CreateProcessFlag_PoolPartitionApplet: - case ams::svc::CreateProcessFlag_PoolPartitionSystem: - case ams::svc::CreateProcessFlag_PoolPartitionSystemNonSecure: + switch (params.flags & ams::svc::CreateProcessParameterFlag_PoolPartitionMask) { + case ams::svc::CreateProcessParameterFlag_PoolPartitionApplication: + case ams::svc::CreateProcessParameterFlag_PoolPartitionApplet: + case ams::svc::CreateProcessParameterFlag_PoolPartitionSystem: + case ams::svc::CreateProcessParameterFlag_PoolPartitionSystemNonSecure: break; default: R_THROW(svc::ResultInvalidEnumValue()); @@ -166,10 +205,10 @@ namespace ams::kern::svc { /* Check that the number of extra resource pages is >= 0. */ R_UNLESS(params.system_resource_num_pages >= 0, svc::ResultInvalidSize()); - /* Validate that the alias region extra size is allowed, if enabled. */ - if (params.flags & ams::svc::CreateProcessFlag_EnableAliasRegionExtraSize) { + /* Validate that the address sanitizer is allowed, if enabled. */ + if (params.flags & ams::svc::CreateProcessParameterFlag_EnableAddressSanitizer) { /* Check that we have a 64-bit address space. */ - R_UNLESS((params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) == ams::svc::CreateProcessFlag_AddressSpace64Bit, svc::ResultInvalidState()); + R_UNLESS((params.flags & ams::svc::CreateProcessParameterFlag_AddressSpaceMask) == ams::svc::CreateProcessParameterFlag_AddressSpace64Bit39, svc::ResultInvalidState()); /* Check that the system resource page count is non-zero. */ R_UNLESS(params.system_resource_num_pages > 0, svc::ResultInvalidState()); @@ -205,8 +244,8 @@ namespace ams::kern::svc { R_UNLESS(total_pages < (kern::MainMemorySizeMax / PageSize), svc::ResultOutOfMemory()); /* Check that optimized memory allocation is used only for applications. */ - const bool optimize_allocs = (params.flags & ams::svc::CreateProcessFlag_OptimizeMemoryAllocation) != 0; - const bool is_application = (params.flags & ams::svc::CreateProcessFlag_IsApplication) != 0; + const bool optimize_allocs = (params.flags & ams::svc::CreateProcessParameterFlag_OptimizeMemoryAllocation) != 0; + const bool is_application = (params.flags & ams::svc::CreateProcessParameterFlag_IsApplication) != 0; R_UNLESS(!optimize_allocs || is_application, svc::ResultBusy()); /* Check that the user-provided capabilities are accessible and refer to valid regions. */ @@ -215,8 +254,8 @@ namespace ams::kern::svc { /* Get the current handle table. */ auto &handle_table = GetCurrentProcess().GetHandleTable(); - /* Create the new process. */ - KProcess *process = KProcess::Create(); + /* Create the new process, ensuring its page table slot matches the requested address space. */ + KProcess *process = CreateProcessForAddressSpace(static_cast(params.flags)); R_UNLESS(process != nullptr, svc::ResultOutOfResource()); /* Ensure that the only reference to the process is in the handle table when we're done. */ @@ -232,19 +271,19 @@ namespace ams::kern::svc { /* Get the pool for the process. */ const auto pool = [](u32 flags) ALWAYS_INLINE_LAMBDA -> KMemoryManager::Pool { if (GetTargetFirmware() >= TargetFirmware_5_0_0) { - switch (flags & ams::svc::CreateProcessFlag_PoolPartitionMask) { - case ams::svc::CreateProcessFlag_PoolPartitionApplication: + switch (flags & ams::svc::CreateProcessParameterFlag_PoolPartitionMask) { + case ams::svc::CreateProcessParameterFlag_PoolPartitionApplication: return KMemoryManager::Pool_Application; - case ams::svc::CreateProcessFlag_PoolPartitionApplet: + case ams::svc::CreateProcessParameterFlag_PoolPartitionApplet: return KMemoryManager::Pool_Applet; - case ams::svc::CreateProcessFlag_PoolPartitionSystem: + case ams::svc::CreateProcessParameterFlag_PoolPartitionSystem: return KMemoryManager::Pool_System; - case ams::svc::CreateProcessFlag_PoolPartitionSystemNonSecure: + case ams::svc::CreateProcessParameterFlag_PoolPartitionSystemNonSecure: default: return KMemoryManager::Pool_SystemNonSecure; } } else if (GetTargetFirmware() >= TargetFirmware_4_0_0) { - if ((flags & ams::svc::CreateProcessFlag_DeprecatedUseSecureMemory) != 0) { + if ((flags & ams::svc::CreateProcessParameterFlag_DeprecatedUseSecureMemory) != 0) { return KMemoryManager::Pool_Secure; } else { return static_cast(KSystemControl::GetCreateProcessMemoryPool()); @@ -319,7 +358,7 @@ namespace ams::kern::svc { R_RETURN(process->Run(priority, static_cast(aligned_stack_size))); } - Result TerminateProcess(ams::svc::Handle process_handle) { + Result TerminateProcess(ams::svc::Handle process_handle, int64_t exit_tag) { /* Get the target process. */ KProcess *process = GetCurrentProcess().GetHandleTable().GetObject(process_handle).ReleasePointerUnsafe(); R_UNLESS(process != nullptr, svc::ResultInvalidHandle()); @@ -329,13 +368,13 @@ namespace ams::kern::svc { ON_SCOPE_EXIT { process->Close(); }; /* Terminate the process. */ - R_TRY(process->Terminate()); + R_TRY(process->Terminate(exit_tag)); } else { /* We're terminating ourselves. Close our reference immediately. */ process->Close(); /* Exit. */ - ExitProcess(); + ExitProcess(exit_tag); } R_SUCCEED(); @@ -373,6 +412,20 @@ namespace ams::kern::svc { } } break; + case ams::svc::ProcessInfoType_Unknown1: + { + /* TODO: 23.0.0+ added a new process info type. Figure out what this is. */ + /* For now just call it an exit tag since it's only set during Exit or Terminate. */ + int64_t exit_tag; + { + KScopedLightLock proc_lk(process->GetStateLock()); + + exit_tag = process->GetExitTag(); + } + + *out = exit_tag; + } + break; default: R_THROW(svc::ResultInvalidEnumValue()); } @@ -385,7 +438,9 @@ namespace ams::kern::svc { /* ============================= 64 ABI ============================= */ void ExitProcess64() { - return ExitProcess(); + /* TODO: 23.0.0+ changed the actual SVC handler. */ + /* For now just pass the default value for the exit tag. */ + return ExitProcess(-1ll); } Result GetProcessId64(uint64_t *out_process_id, ams::svc::Handle process_handle) { @@ -405,7 +460,9 @@ namespace ams::kern::svc { } Result TerminateProcess64(ams::svc::Handle process_handle) { - R_RETURN(TerminateProcess(process_handle)); + /* TODO: 23.0.0+ changed the actual SVC handler. */ + /* For now just pass the default value for the exit tag. */ + R_RETURN(TerminateProcess(process_handle, -1ll)); } Result GetProcessInfo64(int64_t *out_info, ams::svc::Handle process_handle, ams::svc::ProcessInfoType info_type) { @@ -415,7 +472,9 @@ namespace ams::kern::svc { /* ============================= 64From32 ABI ============================= */ void ExitProcess64From32() { - return ExitProcess(); + /* TODO: 23.0.0+ changed the actual SVC handler. */ + /* For now just pass the default value for the exit tag. */ + return ExitProcess(-1ll); } Result GetProcessId64From32(uint64_t *out_process_id, ams::svc::Handle process_handle) { @@ -435,7 +494,9 @@ namespace ams::kern::svc { } Result TerminateProcess64From32(ams::svc::Handle process_handle) { - R_RETURN(TerminateProcess(process_handle)); + /* TODO: 23.0.0+ changed the actual SVC handler. */ + /* For now just pass the default value for the exit tag. */ + R_RETURN(TerminateProcess(process_handle, -1ll)); } Result GetProcessInfo64From32(int64_t *out_info, ams::svc::Handle process_handle, ams::svc::ProcessInfoType info_type) { diff --git a/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp index 41420ca06..56978b1cd 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp @@ -148,7 +148,7 @@ namespace ams::kern::svc { /* Validate that the mapping is in range. */ auto &page_table = process->GetPageTable(); R_UNLESS(page_table.Contains(src_address, size), svc::ResultInvalidCurrentMemory()); - R_UNLESS(page_table.CanContain(dst_address, size, KMemoryState_AliasCode), svc::ResultInvalidCurrentMemory()); + R_UNLESS(page_table.CanContain(dst_address, size, KMemoryState_AliasCode), svc::ResultInvalidMemoryRegion()); /* Map the memory. */ R_TRY(page_table.MapCodeMemory(dst_address, src_address, size)); @@ -175,7 +175,7 @@ namespace ams::kern::svc { /* Validate that the mapping is in range. */ auto &page_table = process->GetPageTable(); R_UNLESS(page_table.Contains(src_address, size), svc::ResultInvalidCurrentMemory()); - R_UNLESS(page_table.CanContain(dst_address, size, KMemoryState_AliasCode), svc::ResultInvalidCurrentMemory()); + R_UNLESS(page_table.CanContain(dst_address, size, KMemoryState_AliasCode), svc::ResultInvalidMemoryRegion()); /* Unmap the memory. */ R_TRY(page_table.UnmapCodeMemory(dst_address, src_address, size)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_query_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_query_memory.cpp index 555130743..d93e3310f 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_query_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_query_memory.cpp @@ -37,6 +37,8 @@ namespace ams::kern::svc { template Result QueryProcessMemory(KUserPointer out_memory_info, ams::svc::PageInfo *out_page_info, ams::svc::Handle process_handle, uint64_t address) { + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(out_memory_info.GetUnsafePointer()), sizeof(T)), svc::ResultInvalidPointer()); + /* Get an ams::svc::MemoryInfo for the region. */ ams::svc::MemoryInfo info = {}; R_TRY(QueryProcessMemory(std::addressof(info), out_page_info, process_handle, address)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_secure_monitor_call.cpp b/libraries/libmesosphere/source/svc/kern_svc_secure_monitor_call.cpp index 9300a576d..8723b7da7 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_secure_monitor_call.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_secure_monitor_call.cpp @@ -28,6 +28,8 @@ namespace ams::kern::svc { /* ============================= 64 ABI ============================= */ void CallSecureMonitor64(ams::svc::lp64::SecureMonitorArguments *args) { + /* TODO: 23.0.0+ added a second argument to CallSecureMonitorFromUser. */ + /* On NX, CallSecureMonitor64 always passes 0 for this argument. */ KSystemControl::CallSecureMonitorFromUser(args); } diff --git a/libraries/libmesosphere/source/svc/kern_svc_synchronization.cpp b/libraries/libmesosphere/source/svc/kern_svc_synchronization.cpp index 20e025bb5..ae23f50bd 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_synchronization.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_synchronization.cpp @@ -82,7 +82,7 @@ namespace ams::kern::svc { /* Copy user handles. */ if (num_handles > 0) { /* Ensure that we can try to get the handles. */ - R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(user_handles.GetUnsafePointer()), num_handles * sizeof(ams::svc::Handle)), svc::ResultInvalidPointer()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(user_handles.GetUnsafePointer()), num_handles * sizeof(ams::svc::Handle)), svc::ResultInvalidPointer()); /* Get the handles. */ R_TRY(user_handles.CopyArrayTo(handles, num_handles)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp index 14af1bb11..d0c3dc012 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp @@ -204,6 +204,8 @@ namespace ams::kern::svc { /* Get the thread from its handle. */ KScopedAutoObject thread = GetCurrentProcess().GetHandleTable().GetObject(thread_handle); R_UNLESS(thread.IsNotNull(), svc::ResultInvalidHandle()); + + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(out_context.GetUnsafePointer()), sizeof(ams::svc::ThreadContext)), svc::ResultInvalidPointer()); /* Require the handle be to a non-current thread in the current process. */ R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(), svc::ResultInvalidHandle()); @@ -228,7 +230,7 @@ namespace ams::kern::svc { /* Validate that the pointer is in range. */ if (max_out_count > 0) { - R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(out_thread_ids.GetUnsafePointer()), max_out_count * sizeof(u64)), svc::ResultInvalidCurrentMemory()); + R_UNLESS(GetCurrentProcess().GetPageTable().IsSafeUserPointer(KProcessAddress(out_thread_ids.GetUnsafePointer()), max_out_count * sizeof(u64)), svc::ResultInvalidPointer()); } /* Get the handle table. */ diff --git a/libraries/libstratosphere/include/stratosphere/cfg/cfg_types.hpp b/libraries/libstratosphere/include/stratosphere/cfg/cfg_types.hpp index dd898a96f..785c278dc 100644 --- a/libraries/libstratosphere/include/stratosphere/cfg/cfg_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/cfg/cfg_types.hpp @@ -31,10 +31,11 @@ namespace ams::cfg { OverrideStatusFlag_AddressSpaceMask = ((1u << 2) - 1) << OverrideStatusFlag_AddressSpaceShift, #if defined(ATMOSPHERE_OS_HORIZON) - OverrideStatusFlag_AddressSpace32Bit = (svc::CreateProcessFlag_AddressSpace32Bit >> svc::CreateProcessFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, - OverrideStatusFlag_AddressSpace64BitDeprecated = (svc::CreateProcessFlag_AddressSpace64BitDeprecated >> svc::CreateProcessFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, - OverrideStatusFlag_AddressSpace32BitWithoutAlias = (svc::CreateProcessFlag_AddressSpace32BitWithoutAlias >> svc::CreateProcessFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, - OverrideStatusFlag_AddressSpace64Bit = (svc::CreateProcessFlag_AddressSpace64Bit >> svc::CreateProcessFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, + OverrideStatusFlag_AddressSpace32Bit = (svc::CreateProcessParameterFlag_AddressSpace32Bit >> svc::CreateProcessParameterFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, + OverrideStatusFlag_AddressSpace64Bit36 = (svc::CreateProcessParameterFlag_AddressSpace64Bit36 >> svc::CreateProcessParameterFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, + OverrideStatusFlag_AddressSpace32BitNoReserved = (svc::CreateProcessParameterFlag_AddressSpace32BitNoReserved >> svc::CreateProcessParameterFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, + OverrideStatusFlag_AddressSpace64Bit39 = (svc::CreateProcessParameterFlag_AddressSpace64Bit39 >> svc::CreateProcessParameterFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, + OverrideStatusFlag_AddressSpace64Bit42 = (svc::CreateProcessParameterFlag_AddressSpace64Bit42 >> svc::CreateProcessParameterFlag_AddressSpaceShift) << OverrideStatusFlag_AddressSpaceShift, #endif }; diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index cb4272bfd..7aabf7299 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -195,6 +195,8 @@ HANDLER(PscTransitionStateInfo, 154 ) \ HANDLER(FsProxyErrorInfo3, 155 ) \ HANDLER(BluetoothErrorInfo, 156 ) \ + HANDLER(SystemConfigInfo, 157 ) \ + HANDLER(ClockContextInfo, 158 ) \ HANDLER(TestNx, 1000) \ HANDLER(NANDTypeInfo, 1001) \ HANDLER(NANDExtendedCsd, 1002) \ @@ -239,9 +241,9 @@ HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableWifiFlag, 38, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableBluetoothFlag, 39, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableNFCFlag, 40, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ @@ -259,9 +261,9 @@ HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentLanguage, 58, SystemConfigInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseNetworkTimeProtocolFlag, 59, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TimeZone, 60, SystemConfigInfo, FieldType_String, FieldFlag_None ) \ HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ @@ -272,23 +274,23 @@ HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(MuteOnHeadsetUnpluggedFlag, 71, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerVibrationVolume, 74, SystemConfigInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LockScreenFlag, 75, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NotifyInGameDownloadCompletionFlag, 79, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NotificationSoundFlag, 80, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HandheldModeTimeToScreenSleep, 85, SystemConfigInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleModeTimeToScreenSleep, 86, SystemConfigInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ @@ -611,7 +613,7 @@ HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(RetailInteractiveDisplayFlag, 410, SystemConfigInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ @@ -627,7 +629,7 @@ HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ErrorReportSharePermission, 426, SystemConfigInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ @@ -673,10 +675,10 @@ HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextOffset, 472, ClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextTimeStampValue, 473, ClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextOffset, 474, ClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextTimeStampValue, 475, ClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ @@ -819,16 +821,16 @@ HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountLimit, 619, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountLimit, 620, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountLimit, 622, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountPeak, 624, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountPeak, 625, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountPeak, 627, ResourceLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryLimit, 618, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountLimit, 619, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountLimit, 620, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountLimit, 621, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountLimit, 622, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryPeak, 623, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountPeak, 624, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountPeak, 625, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountPeak, 626, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountPeak, 627, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ @@ -886,10 +888,10 @@ HANDLER(AppletId, 682, ApplicationInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(PrevReportIdentifier, 683, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ HANDLER(SyslogStartupTimeBase, 684, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NxdmpIsAttached, 685, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ScreenshotIsAttached, 686, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(SyslogIsAttached, 687, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(SaveSyslogResult, 688, AttachmentFileInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NxdmpIsAttached, 685, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ScreenshotIsAttached, 686, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SyslogIsAttached, 687, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SaveSyslogResult, 688, ErrorInfoAuto, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(EncryptionKeyGeneration, 689, ErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FsBufferManagerNonBlockingRetriedCount, 690, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(FsPooledBufferNonBlockingRetriedCount, 691, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ @@ -897,11 +899,11 @@ HANDLER(LastConnectionTestUploadSpeed64, 693, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(EncryptionKeyV1, 694, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(GpuCrashDumpAttachmentId, 695, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GpuCrashDumpIsAttached, 696, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(GpuCrashDumpIsAttached, 696, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ HANDLER(CallerIdentifier, 697, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(WlanMainState, 698, WlanInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(WlanSubState, 699, WlanInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AdspSyslogIsAttached, 702, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AdspSyslogIsAttached, 702, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ HANDLER(LastHalfAwakeTime, 703, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(LastHalfAwakeTimeAfterBackgroundTaskDone, 704, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(LastHalfAwakeTimeAfterStateUnlocked, 705, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ @@ -979,7 +981,17 @@ HANDLER(FsSaveDataFileSystemPeakMountCount, 777, FsProxyErrorInfo3, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(TestBool, 778, Test, FieldType_Bool, FieldFlag_None ) \ HANDLER(TestI8Array, 779, Test, FieldType_I8Array, FieldFlag_None ) \ + HANDLER(CloudFrontAmzCfId, 780, ErrorInfo, FieldType_String, FieldFlag_None ) \ HANDLER(SslProcessHeapAllocatable, 781, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AppletSyslogIsAttached, 782, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FsBisSaveDataFailedRetryMountCount, 783, FsProxyErrorInfo3, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsSdSaveDataFailedRetryMountCount, 784, FsProxyErrorInfo3, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsBisSaveDataRecoveredRetryMountCount, 785, FsProxyErrorInfo3, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsSdSaveDataRecoveredRetryMountCount, 786, FsProxyErrorInfo3, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(BrowserEngineOpenUrl, 787, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsVariant, 788, SystemSettingInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(KnownServerFqdnId, 789, ErrorInfoAuto, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpStreamPlaySaveDataKeyType, 790, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \ HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp index c3b92f62e..c07aec05e 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp @@ -272,5 +272,14 @@ namespace ams::erpt { char product_model[16]; const char *region; }; + + struct SubmitAttachmentOptionFlag { + using Lz4Compression = util::BitFlagSet::Flag<0>; + using Unknown0x10000 = util::BitFlagSet::Flag<16>; /* TODO: Figure out what this is. Always forced to 1. */ + }; + + using SubmitAttachmentOptionFlagSet = util::BitFlagSet; + static_assert(util::is_pod::value); + static_assert(sizeof(SubmitAttachmentOptionFlagSet) == sizeof(u32)); } diff --git a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp index d1244bb46..2fece2bc9 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp @@ -34,14 +34,15 @@ AMS_SF_METHOD_INFO(C, H, 7, Result, RegisterRunningApplicationInfo, (ncm::ApplicationId app_id, ncm::ProgramId program_id), (app_id, program_id), hos::Version_21_0_0) \ AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0, hos::Version_20_5_0) \ AMS_SF_METHOD_INFO(C, H, 8, Result, UnregisterRunningApplicationInfo, (), (), hos::Version_21_0_0) \ - AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \ + AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachmentDeprecated, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0, hos::Version_22_5_0) \ AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \ AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \ AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \ AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \ AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \ - AMS_SF_METHOD_INFO(C, H, 13, Result, SubmitAttachmentWithLz4Compression, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 13, Result, SubmitAttachmentWithLz4Compression, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_20_0_0, hos::Version_22_5_0) \ AMS_SF_METHOD_INFO(C, H, 14, Result, CreateReportWithSpecifiedReprotId, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const erpt::ReportId &report_id), (report_type, ctx_buffer, str_buffer, meta_buffer, attachment_ids_buffer, result, flags, report_id), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 15, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data, erpt::SubmitAttachmentOptionFlagSet flags), (out, attachment_name, attachment_data, flags), hos::Version_23_0_0) \ AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \ diff --git a/libraries/libstratosphere/include/stratosphere/gpio/sf/gpio_sf_i_manager.hpp b/libraries/libstratosphere/include/stratosphere/gpio/sf/gpio_sf_i_manager.hpp index 077885fc8..fee82ffe8 100644 --- a/libraries/libstratosphere/include/stratosphere/gpio/sf/gpio_sf_i_manager.hpp +++ b/libraries/libstratosphere/include/stratosphere/gpio/sf/gpio_sf_i_manager.hpp @@ -21,17 +21,17 @@ #include #include -#define AMS_GPIO_I_MANAGER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenSessionForDev, (ams::sf::Out> out, s32 pad_descriptor), (out, pad_descriptor) ) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, OpenSession, (ams::sf::Out> out, gpio::GpioPadName pad_name), (out, pad_name) ) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, OpenSessionForTest, (ams::sf::Out> out, gpio::GpioPadName pad_name), (out, pad_name) ) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, IsWakeEventActive, (ams::sf::Out out, gpio::GpioPadName pad_name), (out, pad_name), hos::Version_Min, hos::Version_6_2_0) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, GetWakeEventActiveFlagSet, (ams::sf::Out out), (out), hos::Version_Min, hos::Version_6_2_0) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, SetWakeEventActiveFlagSetForDebug, (gpio::GpioPadName pad_name, bool is_enabled), (pad_name, is_enabled), hos::Version_Min, hos::Version_6_2_0) \ - AMS_SF_METHOD_INFO(C, H, 6, Result, SetWakePinDebugMode, (s32 mode), (mode) ) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, OpenSession2, (ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode), (out, device_code, access_mode), hos::Version_5_0_0 ) \ - AMS_SF_METHOD_INFO(C, H, 8, Result, IsWakeEventActive2, (ams::sf::Out out, DeviceCode device_code), (out, device_code), hos::Version_5_0_0 ) \ - AMS_SF_METHOD_INFO(C, H, 9, Result, SetWakeEventActiveFlagSetForDebug2, (DeviceCode device_code, bool is_enabled), (device_code, is_enabled), hos::Version_5_0_0 ) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, SetRetryValues, (u32 arg0, u32 arg1), (arg0, arg1), hos::Version_6_0_0 ) +#define AMS_GPIO_I_MANAGER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenSessionForDevDeprecated, (ams::sf::Out> out, s32 pad_descriptor), (out, pad_descriptor)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, OpenSessionDeprecated, (ams::sf::Out> out, gpio::GpioPadName pad_name), (out, pad_name)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, OpenSessionForTestDeprecated, (ams::sf::Out> out, gpio::GpioPadName pad_name), (out, pad_name)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, IsWakeEventActiveDeprecated, (ams::sf::Out out, gpio::GpioPadName pad_name), (out, pad_name), hos::Version_1_0_0, hos::Version_6_2_0) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, GetWakeEventActiveFlagSetDeprecated, (ams::sf::Out out), (out), hos::Version_1_0_0, hos::Version_6_2_0) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, SetWakeEventActiveFlagSetForDebugDeprecated, (gpio::GpioPadName pad_name, bool is_enabled), (pad_name, is_enabled), hos::Version_1_0_0, hos::Version_6_2_0) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, SetWakePinDebugMode, (s32 mode), (mode)) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, OpenSession, (ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode), (out, device_code, access_mode), hos::Version_5_0_0) \ + AMS_SF_METHOD_INFO(C, H, 8, Result, IsWakeEventActive, (ams::sf::Out out, DeviceCode device_code), (out, device_code), hos::Version_5_0_0) \ + AMS_SF_METHOD_INFO(C, H, 9, Result, SetWakeEventActiveFlagSetForDebug, (DeviceCode device_code, bool is_enabled), (device_code, is_enabled), hos::Version_5_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, DumpStateForDebug, (u32 arg0, u32 arg1), (arg0, arg1), hos::Version_6_0_0) AMS_SF_DEFINE_INTERFACE(ams::gpio::sf, IManager, AMS_GPIO_I_MANAGER_INTERFACE_INFO, 0xD219501E) diff --git a/libraries/libstratosphere/include/stratosphere/gpio/sf/gpio_sf_i_pad_session.hpp b/libraries/libstratosphere/include/stratosphere/gpio/sf/gpio_sf_i_pad_session.hpp index 9c0fb619e..eaf055b1d 100644 --- a/libraries/libstratosphere/include/stratosphere/gpio/sf/gpio_sf_i_pad_session.hpp +++ b/libraries/libstratosphere/include/stratosphere/gpio/sf/gpio_sf_i_pad_session.hpp @@ -18,24 +18,28 @@ #include #include -#define AMS_GPIO_I_PAD_SESSION_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, SetDirection, (gpio::Direction direction), (direction) ) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetDirection, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, SetInterruptMode, (gpio::InterruptMode mode), (mode) ) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, GetInterruptMode, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, SetInterruptEnable, (bool enable), (enable) ) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, GetInterruptEnable, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 6, Result, GetInterruptStatus, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, ClearInterruptStatus, (), () ) \ - AMS_SF_METHOD_INFO(C, H, 8, Result, SetValue, (gpio::GpioValue value), (value) ) \ - AMS_SF_METHOD_INFO(C, H, 9, Result, GetValue, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, BindInterrupt, (ams::sf::OutCopyHandle out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 11, Result, UnbindInterrupt, (), () ) \ - AMS_SF_METHOD_INFO(C, H, 12, Result, SetDebounceEnabled, (bool enable), (enable) ) \ - AMS_SF_METHOD_INFO(C, H, 13, Result, GetDebounceEnabled, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 14, Result, SetDebounceTime, (s32 ms), (ms) ) \ - AMS_SF_METHOD_INFO(C, H, 15, Result, GetDebounceTime, (ams::sf::Out out), (out) ) \ - AMS_SF_METHOD_INFO(C, H, 16, Result, SetValueForSleepState, (gpio::GpioValue value), (value), hos::Version_4_0_0) \ - AMS_SF_METHOD_INFO(C, H, 16, Result, GetValueForSleepState, (ams::sf::Out out), (out), hos::Version_6_0_0) +#define AMS_GPIO_I_PAD_SESSION_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, SetDirectionDeprecated, (gpio::Direction direction), (direction)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetDirection, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetInterruptMode, (gpio::InterruptMode mode), (mode)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, GetInterruptMode, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, SetInterruptEnable, (bool enable), (enable)) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, GetInterruptEnable, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, GetInterruptStatus, (ams::sf::Out out), (out), hos::Version_1_0_0, hos::Version_16_1_0) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, ClearInterruptStatus, (), (), hos::Version_1_0_0, hos::Version_16_1_0) \ + AMS_SF_METHOD_INFO(C, H, 8, Result, SetValue, (gpio::GpioValue value), (value)) \ + AMS_SF_METHOD_INFO(C, H, 9, Result, GetValue, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, BindInterrupt, (ams::sf::OutCopyHandle out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 11, Result, UnbindInterrupt, (), ()) \ + AMS_SF_METHOD_INFO(C, H, 12, Result, SetDebounceEnabled, (bool enable), (enable)) \ + AMS_SF_METHOD_INFO(C, H, 13, Result, GetDebounceEnabled, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 14, Result, SetDebounceTime, (s32 ms), (ms)) \ + AMS_SF_METHOD_INFO(C, H, 15, Result, GetDebounceTime, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 16, Result, SetValueForSleepState, (gpio::GpioValue value), (value), hos::Version_4_0_0) \ + AMS_SF_METHOD_INFO(C, H, 17, Result, GetMaxDebounceTime, (ams::sf::Out out), (out), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 18, Result, SetDirectionInput, (), (), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 19, Result, SetDirectionOutput, (gpio::GpioValue value), (value), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 20, Result, SetUnknownEnabled, (bool enable), (enable), hos::Version_23_0_0) \ + AMS_SF_METHOD_INFO(C, H, 21, Result, GetUnknownEnabled, (ams::sf::Out out), (out), hos::Version_23_0_0) AMS_SF_DEFINE_INTERFACE(ams::gpio::sf, IPadSession, AMS_GPIO_I_PAD_SESSION_INTERFACE_INFO, 0x7448A8A7) diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index c9ee30d02..70f9bec97 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -103,6 +103,7 @@ namespace ams::hos { Version_22_0_0 = ::ams::TargetFirmware_22_0_0, Version_22_1_0 = ::ams::TargetFirmware_22_1_0, Version_22_5_0 = ::ams::TargetFirmware_22_5_0, + Version_23_0_0 = ::ams::TargetFirmware_23_0_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libstratosphere/include/stratosphere/i2c/sf/i2c_sf_i_manager.hpp b/libraries/libstratosphere/include/stratosphere/i2c/sf/i2c_sf_i_manager.hpp index 7342f08c7..b0888381c 100644 --- a/libraries/libstratosphere/include/stratosphere/i2c/sf/i2c_sf_i_manager.hpp +++ b/libraries/libstratosphere/include/stratosphere/i2c/sf/i2c_sf_i_manager.hpp @@ -20,11 +20,11 @@ #include #include -#define AMS_I2C_I_MANAGER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenSessionForDev, (ams::sf::Out> out, s32 bus_idx, u16 slave_address, i2c::AddressingMode addressing_mode, i2c::SpeedMode speed_mode), (out, bus_idx, slave_address, addressing_mode, speed_mode) ) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, OpenSession, (ams::sf::Out> out, i2c::I2cDevice device), (out, device) ) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, HasDevice, (ams::sf::Out out, i2c::I2cDevice device), (out, device), hos::Version_Min, hos::Version_5_1_0) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, HasDeviceForDev, (ams::sf::Out out, i2c::I2cDevice device), (out, device), hos::Version_Min, hos::Version_5_1_0) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, OpenSession2, (ams::sf::Out> out, DeviceCode device_code), (out, device_code), hos::Version_6_0_0 ) +#define AMS_I2C_I_MANAGER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenSessionForDev, (ams::sf::Out> out, s32 bus_idx, u16 slave_address, i2c::AddressingMode addressing_mode, i2c::SpeedMode speed_mode), (out, bus_idx, slave_address, addressing_mode, speed_mode)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, OpenSession, (ams::sf::Out> out, i2c::I2cDevice device), (out, device)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, HasDevice, (ams::sf::Out out, i2c::I2cDevice device), (out, device), hos::Version_1_0_0, hos::Version_5_1_0) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, HasDeviceForDev, (ams::sf::Out out, i2c::I2cDevice device), (out, device), hos::Version_1_0_0, hos::Version_5_1_0) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, OpenSession2, (ams::sf::Out> out, DeviceCode device_code), (out, device_code), hos::Version_6_0_0) AMS_SF_DEFINE_INTERFACE(ams::i2c::sf, IManager, AMS_I2C_I_MANAGER_INTERFACE_INFO, 0xE4C9D8F0) diff --git a/libraries/libstratosphere/include/stratosphere/i2c/sf/i2c_sf_i_session.hpp b/libraries/libstratosphere/include/stratosphere/i2c/sf/i2c_sf_i_session.hpp index 22cf9afa8..aee01e4b6 100644 --- a/libraries/libstratosphere/include/stratosphere/i2c/sf/i2c_sf_i_session.hpp +++ b/libraries/libstratosphere/include/stratosphere/i2c/sf/i2c_sf_i_session.hpp @@ -18,13 +18,13 @@ #include #include -#define AMS_I2C_I_SESSION_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, SendOld, (const ams::sf::InBuffer &in_data, i2c::TransactionOption option), (in_data, option), hos::Version_Min, hos::Version_5_1_0) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, ReceiveOld, (const ams::sf::OutBuffer &out_data, i2c::TransactionOption option), (out_data, option), hos::Version_Min, hos::Version_5_1_0) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, ExecuteCommandListOld, (const ams::sf::OutBuffer &rcv_buf, const ams::sf::InPointerArray &command_list), (rcv_buf, command_list), hos::Version_Min, hos::Version_5_1_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, Send, (const ams::sf::InAutoSelectBuffer &in_data, i2c::TransactionOption option), (in_data, option) ) \ - AMS_SF_METHOD_INFO(C, H, 11, Result, Receive, (const ams::sf::OutAutoSelectBuffer &out_data, i2c::TransactionOption option), (out_data, option) ) \ - AMS_SF_METHOD_INFO(C, H, 12, Result, ExecuteCommandList, (const ams::sf::OutAutoSelectBuffer &rcv_buf, const ams::sf::InPointerArray &command_list), (rcv_buf, command_list) ) \ - AMS_SF_METHOD_INFO(C, H, 13, Result, SetRetryPolicy, (s32 max_retry_count, s32 retry_interval_us), (max_retry_count, retry_interval_us), hos::Version_6_0_0 ) +#define AMS_I2C_I_SESSION_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, SendOld, (const ams::sf::InBuffer &in_data, i2c::TransactionOption option), (in_data, option), hos::Version_1_0_0, hos::Version_5_1_0) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, ReceiveOld, (const ams::sf::OutBuffer &out_data, i2c::TransactionOption option), (out_data, option), hos::Version_1_0_0, hos::Version_5_1_0) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, ExecuteCommandListOld, (const ams::sf::OutBuffer &rcv_buf, const ams::sf::InPointerArray &command_list), (rcv_buf, command_list), hos::Version_1_0_0, hos::Version_5_1_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, Send, (const ams::sf::InAutoSelectBuffer &in_data, i2c::TransactionOption option), (in_data, option)) \ + AMS_SF_METHOD_INFO(C, H, 11, Result, Receive, (const ams::sf::OutAutoSelectBuffer &out_data, i2c::TransactionOption option), (out_data, option)) \ + AMS_SF_METHOD_INFO(C, H, 12, Result, ExecuteCommandList, (const ams::sf::OutAutoSelectBuffer &rcv_buf, const ams::sf::InPointerArray &command_list), (rcv_buf, command_list)) \ + AMS_SF_METHOD_INFO(C, H, 13, Result, SetRetryPolicy, (s32 max_retry_count, s32 retry_interval_us), (max_retry_count, retry_interval_us), hos::Version_6_0_0, hos::Version_22_5_0) AMS_SF_DEFINE_INTERFACE(ams::i2c::sf, ISession, AMS_I2C_I_SESSION_INTERFACE_INFO, 0x40154EFE) diff --git a/libraries/libstratosphere/include/stratosphere/kvdb/kvdb_memory_key_value_store.hpp b/libraries/libstratosphere/include/stratosphere/kvdb/kvdb_memory_key_value_store.hpp index 0b09098d5..567afd8ce 100644 --- a/libraries/libstratosphere/include/stratosphere/kvdb/kvdb_memory_key_value_store.hpp +++ b/libraries/libstratosphere/include/stratosphere/kvdb/kvdb_memory_key_value_store.hpp @@ -489,7 +489,7 @@ namespace ams::kvdb { private: Result SaveArchiveToFile(const char *path, const void *buf, size_t size) { /* Try to delete the archive, but allow deletion failure. */ - fs::DeleteFile(path); + R_DISCARD(fs::DeleteFile(path)); /* Create new archive. */ R_TRY(fs::CreateFile(path, size)); @@ -514,7 +514,7 @@ namespace ams::kvdb { R_TRY(SaveArchiveToFile(m_temp_path.Get(), buffer.Get(), buffer.GetSize())); /* Try to delete the saved archive, but allow deletion failure. */ - fs::DeleteFile(m_path.Get()); + R_DISCARD(fs::DeleteFile(m_path.Get())); /* Rename the path. */ R_TRY(fs::RenameFile(m_temp_path.Get(), m_path.Get())); diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp index aa33b4e15..7d36cae1c 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -50,9 +50,9 @@ namespace ams::ldr { ProgramInfoFlag_AllowDebug = (1 << 2), }; - enum CreateProcessFlag { - CreateProcessFlag_EnableDebug = (1 << 0), - CreateProcessFlag_DisableAslr = (1 << 1), + enum CreateProcessParameterFlag { + CreateProcessParameterFlag_EnableJitDebug = (1 << 0), + CreateProcessParameterFlag_DisableAslr = (1 << 1), }; struct ProgramArguments { @@ -194,10 +194,10 @@ namespace ams::ldr { }; #if defined(ATMOSPHERE_OS_HORIZON) - static_assert(PoolPartition_Application == (svc::CreateProcessFlag_PoolPartitionApplication >> svc::CreateProcessFlag_PoolPartitionShift)); - static_assert(PoolPartition_Applet == (svc::CreateProcessFlag_PoolPartitionApplet >> svc::CreateProcessFlag_PoolPartitionShift)); - static_assert(PoolPartition_System == (svc::CreateProcessFlag_PoolPartitionSystem >> svc::CreateProcessFlag_PoolPartitionShift)); - static_assert(PoolPartition_SystemNonSecure == (svc::CreateProcessFlag_PoolPartitionSystemNonSecure >> svc::CreateProcessFlag_PoolPartitionShift)); + static_assert(PoolPartition_Application == (svc::CreateProcessParameterFlag_PoolPartitionApplication >> svc::CreateProcessParameterFlag_PoolPartitionShift)); + static_assert(PoolPartition_Applet == (svc::CreateProcessParameterFlag_PoolPartitionApplet >> svc::CreateProcessParameterFlag_PoolPartitionShift)); + static_assert(PoolPartition_System == (svc::CreateProcessParameterFlag_PoolPartitionSystem >> svc::CreateProcessParameterFlag_PoolPartitionShift)); + static_assert(PoolPartition_SystemNonSecure == (svc::CreateProcessParameterFlag_PoolPartitionSystemNonSecure >> svc::CreateProcessParameterFlag_PoolPartitionShift)); #endif u8 signature[0x100]; @@ -223,37 +223,43 @@ namespace ams::ldr { struct Npdm { static constexpr u32 Magic = util::FourCC<'M','E','T','A'>::Code; - enum MetaFlag { - MetaFlag_Is64Bit = (1 << 0), + enum MetaFlag0 { + MetaFlag0_Is64BitInstruction = (1 << 0), - MetaFlag_AddressSpaceTypeShift = 1, - MetaFlag_AddressSpaceTypeMask = (7 << MetaFlag_AddressSpaceTypeShift), + MetaFlag0_ProcessAddressSpaceShift = 1, + MetaFlag0_ProcessAddressSpaceMask = (7 << MetaFlag0_ProcessAddressSpaceShift), - MetaFlag_OptimizeMemoryAllocation = (1 << 4), - MetaFlag_DisableDeviceAddressSpaceMerge = (1 << 5), - MetaFlag_EnableAliasRegionExtraSize = (1 << 6), - MetaFlag_PreventCodeReads = (1 << 7), + MetaFlag0_OptimizeMemoryAllocation = (1 << 4), + MetaFlag0_DisableDeviceAddressSpaceMerge = (1 << 5), + MetaFlag0_EnableAddressSanitizer = (1 << 6), + MetaFlag0_PreventCodeReads = (1 << 7), }; - enum AddressSpaceType { - AddressSpaceType_32Bit = 0, - AddressSpaceType_64BitDeprecated = 1, - AddressSpaceType_32BitWithoutAlias = 2, - AddressSpaceType_64Bit = 3, + enum MetaFlag1 { + MetaFlag1_EnableShadowStack = (1 << 0), + }; + + enum ProcessAddressSpace { + ProcessAddressSpace_32Bit = 0, + ProcessAddressSpace_64Bit36 = 1, + ProcessAddressSpace_32BitNoReserved = 2, + ProcessAddressSpace_64Bit39 = 3, + ProcessAddressSpace_64Bit42 = 4, }; #if defined(ATMOSPHERE_OS_HORIZON) - static_assert(AddressSpaceType_32Bit == (svc::CreateProcessFlag_AddressSpace32Bit >> svc::CreateProcessFlag_AddressSpaceShift)); - static_assert(AddressSpaceType_64BitDeprecated == (svc::CreateProcessFlag_AddressSpace64BitDeprecated >> svc::CreateProcessFlag_AddressSpaceShift)); - static_assert(AddressSpaceType_32BitWithoutAlias == (svc::CreateProcessFlag_AddressSpace32BitWithoutAlias >> svc::CreateProcessFlag_AddressSpaceShift)); - static_assert(AddressSpaceType_64Bit == (svc::CreateProcessFlag_AddressSpace64Bit >> svc::CreateProcessFlag_AddressSpaceShift)); + static_assert(ProcessAddressSpace_32Bit == (svc::CreateProcessParameterFlag_AddressSpace32Bit >> svc::CreateProcessParameterFlag_AddressSpaceShift)); + static_assert(ProcessAddressSpace_64Bit36 == (svc::CreateProcessParameterFlag_AddressSpace64Bit36 >> svc::CreateProcessParameterFlag_AddressSpaceShift)); + static_assert(ProcessAddressSpace_32BitNoReserved == (svc::CreateProcessParameterFlag_AddressSpace32BitNoReserved >> svc::CreateProcessParameterFlag_AddressSpaceShift)); + static_assert(ProcessAddressSpace_64Bit39 == (svc::CreateProcessParameterFlag_AddressSpace64Bit39 >> svc::CreateProcessParameterFlag_AddressSpaceShift)); + static_assert(ProcessAddressSpace_64Bit42 == (svc::CreateProcessParameterFlag_AddressSpace64Bit42 >> svc::CreateProcessParameterFlag_AddressSpaceShift)); #endif u32 magic; u32 signature_key_generation; u8 reserved_08[4]; - u8 flags; - u8 reserved_0D; + u8 flags0; + u8 flags1; u8 main_thread_priority; u8 default_cpu_id; u8 reserved_10[4]; diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp index f6cfc77a0..930d44e00 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp @@ -398,6 +398,9 @@ namespace ams::ncm { static const SystemAppletId Story; + static const SystemAppletId SystemWeb; + static const SystemAppletId OpenWeb; + static const SystemAppletId End; }; @@ -433,6 +436,9 @@ namespace ams::ncm { inline constexpr const SystemAppletId SystemAppletId::Story = { 0x0100000000001020ul }; + inline constexpr const SystemAppletId SystemAppletId::SystemWeb = { 0x0100000000001042ul }; + inline constexpr const SystemAppletId SystemAppletId::OpenWeb = { 0x0100000000001043ul }; + inline constexpr const SystemAppletId SystemAppletId::End = { 0x0100000000001FFFul }; inline constexpr bool IsSystemAppletId(const ProgramId &program_id) { @@ -500,6 +506,8 @@ namespace ams::ncm { static const LibraryAppletId LoginShare; static const LibraryAppletId WifiWebAuth; static const LibraryAppletId MyPage; + static const LibraryAppletId SystemWeb; + static const LibraryAppletId OpenWeb; }; @@ -515,6 +523,8 @@ namespace ams::ncm { inline constexpr const LibraryAppletId LibraryAppletId::LoginShare = { SystemAppletId::LoginShare.value }; inline constexpr const LibraryAppletId LibraryAppletId::WifiWebAuth = { SystemAppletId::WifiWebAuth.value }; inline constexpr const LibraryAppletId LibraryAppletId::MyPage = { SystemAppletId::MyPage.value }; + inline constexpr const LibraryAppletId LibraryAppletId::SystemWeb = { SystemAppletId::SystemWeb.value }; + inline constexpr const LibraryAppletId LibraryAppletId::OpenWeb = { SystemAppletId::OpenWeb.value }; inline constexpr bool IsLibraryAppletId(const ProgramId &id) { return id == LibraryAppletId::Auth || @@ -528,7 +538,9 @@ namespace ams::ncm { id == LibraryAppletId::OfflineWeb || id == LibraryAppletId::LoginShare || id == LibraryAppletId::WifiWebAuth || - id == LibraryAppletId::MyPage; + id == LibraryAppletId::MyPage || + id == LibraryAppletId::SystemWeb || + id == LibraryAppletId::OpenWeb; } inline constexpr bool IsLibraryAppletId(const LibraryAppletId &) { @@ -558,6 +570,8 @@ namespace ams::ncm { static const WebAppletId OfflineWeb; static const WebAppletId LoginShare; static const WebAppletId WifiWebAuth; + static const WebAppletId SystemWeb; + static const WebAppletId OpenWeb; }; inline constexpr const WebAppletId WebAppletId::Web = { LibraryAppletId::Web.value }; @@ -565,13 +579,17 @@ namespace ams::ncm { inline constexpr const WebAppletId WebAppletId::OfflineWeb = { LibraryAppletId::OfflineWeb.value }; inline constexpr const WebAppletId WebAppletId::LoginShare = { LibraryAppletId::LoginShare.value }; inline constexpr const WebAppletId WebAppletId::WifiWebAuth = { LibraryAppletId::WifiWebAuth.value }; + inline constexpr const WebAppletId WebAppletId::SystemWeb = { LibraryAppletId::SystemWeb.value }; + inline constexpr const WebAppletId WebAppletId::OpenWeb = { LibraryAppletId::OpenWeb.value }; inline constexpr bool IsWebAppletId(const ProgramId &id) { return id == WebAppletId::Web || id == WebAppletId::Shop || id == WebAppletId::OfflineWeb || id == WebAppletId::LoginShare || - id == WebAppletId::WifiWebAuth; + id == WebAppletId::WifiWebAuth || + id == WebAppletId::SystemWeb || + id == WebAppletId::OpenWeb; } inline constexpr bool IsWebAppletId(const WebAppletId &) { diff --git a/libraries/libstratosphere/include/stratosphere/pgl/pgl_event_observer.hpp b/libraries/libstratosphere/include/stratosphere/pgl/pgl_event_observer.hpp index 2a9eff313..3a98dfa14 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/pgl_event_observer.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/pgl_event_observer.hpp @@ -33,8 +33,8 @@ namespace ams::pgl { virtual ~EventObserverInterface() { /* ... */ } - virtual Result GetSystemEvent(os::SystemEventType *out) = 0; - virtual Result GetProcessEventInfo(pm::ProcessEventInfo *out) = 0; + virtual Result GetShellEvent(os::SystemEventType *out) = 0; + virtual Result GetShellEventInfo(pm::ProcessEventInfo *out) = 0; }; class EventObserverByCmif final : public EventObserverInterface { @@ -45,9 +45,9 @@ namespace ams::pgl { public: explicit EventObserverByCmif(ams::sf::SharedPointer intf) : m_cmif_interface(intf) { /* ... */ } public: - virtual Result GetSystemEvent(os::SystemEventType *out) override { + virtual Result GetShellEvent(os::SystemEventType *out) override { ams::sf::NativeHandle handle; - R_TRY(m_cmif_interface->GetProcessEventHandle(std::addressof(handle))); + R_TRY(m_cmif_interface->GetShellEvent(std::addressof(handle))); os::AttachReadableHandleToSystemEvent(out, handle.GetOsHandle(), handle.IsManaged(), os::EventClearMode_AutoClear); handle.Detach(); @@ -55,8 +55,8 @@ namespace ams::pgl { R_SUCCEED(); } - virtual Result GetProcessEventInfo(pm::ProcessEventInfo *out) override { - R_RETURN(m_cmif_interface->GetProcessEventInfo(out)); + virtual Result GetShellEventInfo(pm::ProcessEventInfo *out) override { + R_RETURN(m_cmif_interface->GetShellEventInfo(out)); } }; @@ -70,15 +70,15 @@ namespace ams::pgl { template explicit EventObserverByTipc(Args &&... args) : m_tipc_interface(std::forward(args)...) { /* ... */ } public: - virtual Result GetSystemEvent(os::SystemEventType *out) override { + virtual Result GetShellEvent(os::SystemEventType *out) override { os::NativeHandle handle; - R_TRY(m_tipc_interface.GetProcessEventHandle(std::addressof(handle))); + R_TRY(m_tipc_interface.GetShellEvent(std::addressof(handle))); os::AttachReadableHandleToSystemEvent(out, handle, true, os::EventClearMode_AutoClear); R_SUCCEED(); } - virtual Result GetProcessEventInfo(pm::ProcessEventInfo *out) override { - R_RETURN(m_tipc_interface.GetProcessEventInfo(ams::tipc::Out(out))); + virtual Result GetShellEventInfo(pm::ProcessEventInfo *out) override { + R_RETURN(m_tipc_interface.GetShellEventInfo(ams::tipc::Out(out))); } }; @@ -112,12 +112,12 @@ namespace ams::pgl { std::swap(m_impl, rhs.m_impl); } public: - Result GetSystemEvent(os::SystemEventType *out) { - R_RETURN(m_impl->GetSystemEvent(out)); + Result GetShellEvent(os::SystemEventType *out) { + R_RETURN(m_impl->GetShellEvent(out)); } - Result GetProcessEventInfo(pm::ProcessEventInfo *out) { - R_RETURN(m_impl->GetProcessEventInfo(out)); + Result GetShellEventInfo(pm::ProcessEventInfo *out) { + R_RETURN(m_impl->GetShellEventInfo(out)); } }; diff --git a/libraries/libstratosphere/include/stratosphere/pgl/pgl_shell_api.hpp b/libraries/libstratosphere/include/stratosphere/pgl/pgl_shell_api.hpp index f61d008e6..e6dbeed31 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/pgl_shell_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/pgl_shell_api.hpp @@ -27,15 +27,15 @@ namespace ams::pgl { Result LaunchProgram(os::ProcessId *out, const ncm::ProgramLocation &loc, u32 process_flags, u8 pgl_flags); Result TerminateProcess(os::ProcessId process_id); Result LaunchProgramFromHost(os::ProcessId *out, const char *content_path, u32 process_flags); - Result GetHostContentMetaInfo(pgl::ContentMetaInfo *out, const char *content_path); - Result GetApplicationProcessId(os::ProcessId *out); + Result GetProgramLaunchPropertyFromHost(pgl::ProgramLaunchProperty *out, const char *content_path); + Result GetRunningApplicationProcessId(os::ProcessId *out); Result BoostSystemMemoryResourceLimit(u64 size); - Result IsProcessTracked(bool *out, os::ProcessId process_id); + Result IsRunningProcess(bool *out, os::ProcessId process_id); Result EnableApplicationCrashReport(bool enabled); Result IsApplicationCrashReportEnabled(bool *out); Result EnableApplicationAllThreadDumpOnCrash(bool enabled); - Result TriggerApplicationSnapShotDumper(const char *arg, SnapShotDumpType dump_type); - - Result GetEventObserver(pgl::EventObserver *out); + Result TriggerSnapShotDumper(const char *arg, SnapShotDumpType dump_type); + Result CreateShellEvent(pgl::EventObserver *out); + Result EnableApplicationCrashReport2(os::ProcessId process_id, bool enabled); } diff --git a/libraries/libstratosphere/include/stratosphere/pgl/pgl_types.hpp b/libraries/libstratosphere/include/stratosphere/pgl/pgl_types.hpp index 25ed20d9c..268c3e6f6 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/pgl_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/pgl_types.hpp @@ -35,8 +35,7 @@ namespace ams::pgl { Full = 2, }; - /* TODO: Is this really nn::ncm::ContentInfo? */ - struct ContentMetaInfo { + struct ProgramLaunchProperty { u64 id; u32 version; ncm::ContentType content_type; @@ -44,7 +43,7 @@ namespace ams::pgl { ncm::ContentMetaType content_meta_type; u8 reserved_0F; - static constexpr ContentMetaInfo Make(u64 id, u32 version, ncm::ContentType content_type, u8 id_offset) { + static constexpr ProgramLaunchProperty Make(u64 id, u32 version, ncm::ContentType content_type, u8 id_offset) { return { .id = id, .version = version, @@ -53,6 +52,6 @@ namespace ams::pgl { }; } }; - static_assert(sizeof(ContentMetaInfo) == 0x10 && util::is_pod::value); + static_assert(sizeof(ProgramLaunchProperty) == 0x10 && util::is_pod::value); } diff --git a/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_event_observer.hpp b/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_event_observer.hpp index 387fb8147..d08ce89bb 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_event_observer.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_event_observer.hpp @@ -21,8 +21,8 @@ #include #define AMS_PGL_SF_I_EVENT_OBSERVER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, GetProcessEventHandle, (ams::sf::OutCopyHandle out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetProcessEventInfo, (ams::sf::Out out), (out)) + AMS_SF_METHOD_INFO(C, H, 0, Result, GetShellEvent, (ams::sf::OutCopyHandle out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetShellEventInfo, (ams::sf::Out out), (out)) AMS_SF_DEFINE_INTERFACE(ams::pgl::sf, IEventObserver, AMS_PGL_SF_I_EVENT_OBSERVER_INTERFACE_INFO, 0x00000000); diff --git a/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp b/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp index bafda6364..405b54650 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/sf/pgl_sf_i_shell_interface.hpp @@ -25,16 +25,15 @@ AMS_SF_METHOD_INFO(C, H, 0, Result, LaunchProgram, (ams::sf::Out out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags), (out, loc, pm_flags, pgl_flags)) \ AMS_SF_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \ AMS_SF_METHOD_INFO(C, H, 2, Result, LaunchProgramFromHost, (ams::sf::Out out, const ams::sf::InBuffer &content_path, u32 pm_flags), (out, content_path, pm_flags)) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, GetHostContentMetaInfo, (ams::sf::Out out, const ams::sf::InBuffer &content_path), (out, content_path)) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, GetApplicationProcessId, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, GetProgramLaunchPropertyFromHost, (ams::sf::Out out, const ams::sf::InBuffer &content_path), (out, content_path)) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, GetRunningApplicationProcessId, (ams::sf::Out out), (out)) \ AMS_SF_METHOD_INFO(C, H, 6, Result, BoostSystemMemoryResourceLimit, (u64 size), (size)) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, IsProcessTracked, (ams::sf::Out out, os::ProcessId process_id), (out, process_id)) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, IsRunningProcess, (ams::sf::Out out, os::ProcessId process_id), (out, process_id)) \ AMS_SF_METHOD_INFO(C, H, 8, Result, EnableApplicationCrashReport, (bool enabled), (enabled)) \ AMS_SF_METHOD_INFO(C, H, 9, Result, IsApplicationCrashReportEnabled, (ams::sf::Out out), (out)) \ AMS_SF_METHOD_INFO(C, H, 10, Result, EnableApplicationAllThreadDumpOnCrash, (bool enabled), (enabled)) \ - AMS_SF_METHOD_INFO(C, H, 11, Result, GetProcessId, (ams::sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ - AMS_SF_METHOD_INFO(C, H, 12, Result, TriggerApplicationSnapShotDumper, (pgl::SnapShotDumpType dump_type, const ams::sf::InBuffer &arg), (dump_type, arg)) \ - AMS_SF_METHOD_INFO(C, H, 20, Result, GetShellEventObserver, (ams::sf::Out> out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 12, Result, TriggerSnapShotDumper, (pgl::SnapShotDumpType dump_type, const ams::sf::InBuffer &arg), (dump_type, arg), hos::Version_10_0_0) \ + AMS_SF_METHOD_INFO(C, H, 20, Result, CreateShellEvent, (ams::sf::Out> out), (out)) \ AMS_SF_METHOD_INFO(C, H, 21, Result, Command21NotImplemented, (ams::sf::Out out, u32 in, const ams::sf::InBuffer &buf1, const ams::sf::InBuffer &buf2), (out, in, buf1, buf2), hos::Version_11_0_0) AMS_SF_DEFINE_INTERFACE(ams::pgl::sf, IShellInterface, AMS_PGL_I_SHELL_INTERFACE_INTERFACE_INFO, 0x00000000); diff --git a/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp b/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp index 9f488b318..a9d534d9e 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/srv/pgl_srv_shell_interface.hpp @@ -30,15 +30,16 @@ namespace ams::pgl::srv { Result LaunchProgramImpl(os::ProcessId *out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags); Result TerminateProcessImpl(os::ProcessId process_id); Result LaunchProgramFromHostImpl(os::ProcessId *out, const void *content_path, size_t content_path_size, u32 pm_flags); - Result GetHostContentMetaInfoImpl(pgl::ContentMetaInfo *out, const void *content_path, size_t content_path_size); - Result GetApplicationProcessIdImpl(os::ProcessId *out); + Result GetProgramLaunchPropertyFromHostImpl(pgl::ProgramLaunchProperty *out, const void *content_path, size_t content_path_size); + Result GetRunningApplicationProcessIdImpl(os::ProcessId *out); Result BoostSystemMemoryResourceLimitImpl(u64 size); - Result IsProcessTrackedImpl(bool *out, os::ProcessId process_id); + Result IsRunningProcessImpl(bool *out, os::ProcessId process_id); Result EnableApplicationCrashReportImpl(bool enabled); Result IsApplicationCrashReportEnabledImpl(bool *out); Result EnableApplicationAllThreadDumpOnCrashImpl(bool enabled); - Result GetProcessId(os::ProcessId *out, ncm::ProgramId program_id); - Result TriggerApplicationSnapShotDumperImpl(SnapShotDumpType dump_type, const void *arg, size_t arg_size); + Result GetProcessIdImpl(os::ProcessId *out, ncm::ProgramId program_id); + Result TriggerSnapShotDumperImpl(SnapShotDumpType dump_type, const void *arg, size_t arg_size); + Result EnableApplicationCrashReport2Impl(os::ProcessId process_id, bool enabled); }; class ShellInterfaceCmif : public ShellInterfaceCommon { @@ -56,17 +57,15 @@ namespace ams::pgl::srv { Result LaunchProgram(ams::sf::Out out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags); Result TerminateProcess(os::ProcessId process_id); Result LaunchProgramFromHost(ams::sf::Out out, const ams::sf::InBuffer &content_path, u32 pm_flags); - Result GetHostContentMetaInfo(ams::sf::Out out, const ams::sf::InBuffer &content_path); - Result GetApplicationProcessId(ams::sf::Out out); + Result GetProgramLaunchPropertyFromHost(ams::sf::Out out, const ams::sf::InBuffer &content_path); + Result GetRunningApplicationProcessId(ams::sf::Out out); Result BoostSystemMemoryResourceLimit(u64 size); - Result IsProcessTracked(ams::sf::Out out, os::ProcessId process_id); + Result IsRunningProcess(ams::sf::Out out, os::ProcessId process_id); Result EnableApplicationCrashReport(bool enabled); Result IsApplicationCrashReportEnabled(ams::sf::Out out); Result EnableApplicationAllThreadDumpOnCrash(bool enabled); - Result GetProcessId(ams::sf::Out out, ncm::ProgramId program_id); - Result TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const ams::sf::InBuffer &arg); - - Result GetShellEventObserver(ams::sf::Out> out); + Result TriggerSnapShotDumper(SnapShotDumpType dump_type, const ams::sf::InBuffer &arg); + Result CreateShellEvent(ams::sf::Out> out); Result Command21NotImplemented(ams::sf::Out out, u32 in, const ams::sf::InBuffer &buf1, const ams::sf::InBuffer &buf2); }; static_assert(pgl::sf::IsIShellInterface); @@ -81,15 +80,16 @@ namespace ams::pgl::srv { Result LaunchProgram(ams::tipc::Out out, const ncm::ProgramLocation loc, u32 pm_flags, u8 pgl_flags); Result TerminateProcess(os::ProcessId process_id); Result LaunchProgramFromHost(ams::tipc::Out out, const ams::tipc::InBuffer content_path, u32 pm_flags); - Result GetHostContentMetaInfo(ams::tipc::Out out, const ams::tipc::InBuffer content_path); - Result GetApplicationProcessId(ams::tipc::Out out); + Result GetProgramLaunchPropertyFromHost(ams::tipc::Out out, const ams::tipc::InBuffer content_path); + Result GetRunningApplicationProcessId(ams::tipc::Out out); Result BoostSystemMemoryResourceLimit(u64 size); - Result IsProcessTracked(ams::tipc::Out out, os::ProcessId process_id); + Result IsRunningProcess(ams::tipc::Out out, os::ProcessId process_id); Result EnableApplicationCrashReport(bool enabled); Result IsApplicationCrashReportEnabled(ams::tipc::Out out); Result EnableApplicationAllThreadDumpOnCrash(bool enabled); Result GetProcessId(ams::tipc::Out out, ncm::ProgramId program_id); - Result GetShellEventObserver(ams::tipc::OutMoveHandle out); + Result CreateShellEvent(ams::tipc::OutMoveHandle out); + Result EnableApplicationCrashReport2(os::ProcessId process_id, bool enabled); }; static_assert(pgl::tipc::IsIShellInterface); diff --git a/libraries/libstratosphere/include/stratosphere/pgl/tipc/pgl_tipc_i_event_observer.hpp b/libraries/libstratosphere/include/stratosphere/pgl/tipc/pgl_tipc_i_event_observer.hpp index 2287344c5..7036e9922 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/tipc/pgl_tipc_i_event_observer.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/tipc/pgl_tipc_i_event_observer.hpp @@ -22,8 +22,8 @@ #include #define AMS_PGL_TIPC_I_EVENT_OBSERVER_INTERFACE_INFO(C, H) \ - AMS_TIPC_METHOD_INFO(C, H, 0, Result, GetProcessEventHandle, (ams::tipc::OutCopyHandle out), (out)) \ - AMS_TIPC_METHOD_INFO(C, H, 1, Result, GetProcessEventInfo, (ams::tipc::Out out), (out)) + AMS_TIPC_METHOD_INFO(C, H, 0, Result, GetShellEvent, (ams::tipc::OutCopyHandle out), (out)) \ + AMS_TIPC_METHOD_INFO(C, H, 1, Result, GetShellEventInfo, (ams::tipc::Out out), (out)) AMS_TIPC_DEFINE_INTERFACE(ams::pgl::tipc, IEventObserver, AMS_PGL_TIPC_I_EVENT_OBSERVER_INTERFACE_INFO); diff --git a/libraries/libstratosphere/include/stratosphere/pgl/tipc/pgl_tipc_i_shell_interface.hpp b/libraries/libstratosphere/include/stratosphere/pgl/tipc/pgl_tipc_i_shell_interface.hpp index ad61a71e4..02c54738a 100644 --- a/libraries/libstratosphere/include/stratosphere/pgl/tipc/pgl_tipc_i_shell_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pgl/tipc/pgl_tipc_i_shell_interface.hpp @@ -22,17 +22,19 @@ #include #include -#define AMS_PGL_TIPC_I_SHELL_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_TIPC_METHOD_INFO(C, H, 0, Result, LaunchProgram, (ams::tipc::Out out, const ncm::ProgramLocation loc, u32 pm_flags, u8 pgl_flags), (out, loc, pm_flags, pgl_flags)) \ - AMS_TIPC_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \ - AMS_TIPC_METHOD_INFO(C, H, 2, Result, LaunchProgramFromHost, (ams::tipc::Out out, const ams::tipc::InBuffer content_path, u32 pm_flags), (out, content_path, pm_flags)) \ - AMS_TIPC_METHOD_INFO(C, H, 4, Result, GetHostContentMetaInfo, (ams::tipc::Out out, const ams::tipc::InBuffer content_path), (out, content_path)) \ - AMS_TIPC_METHOD_INFO(C, H, 5, Result, GetApplicationProcessId, (ams::tipc::Out out), (out)) \ - AMS_TIPC_METHOD_INFO(C, H, 6, Result, BoostSystemMemoryResourceLimit, (u64 size), (size)) \ - AMS_TIPC_METHOD_INFO(C, H, 7, Result, IsProcessTracked, (ams::tipc::Out out, os::ProcessId process_id), (out, process_id)) \ - AMS_TIPC_METHOD_INFO(C, H, 8, Result, EnableApplicationCrashReport, (bool enabled), (enabled)) \ - AMS_TIPC_METHOD_INFO(C, H, 9, Result, IsApplicationCrashReportEnabled, (ams::tipc::Out out), (out)) \ - AMS_TIPC_METHOD_INFO(C, H, 10, Result, EnableApplicationAllThreadDumpOnCrash, (bool enabled), (enabled)) \ - AMS_TIPC_METHOD_INFO(C, H, 20, Result, GetShellEventObserver, (ams::tipc::OutMoveHandle out), (out)) +#define AMS_PGL_TIPC_I_SHELL_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_TIPC_METHOD_INFO(C, H, 0, Result, LaunchProgram, (ams::tipc::Out out, const ncm::ProgramLocation loc, u32 pm_flags, u8 pgl_flags), (out, loc, pm_flags, pgl_flags)) \ + AMS_TIPC_METHOD_INFO(C, H, 1, Result, TerminateProcess, (os::ProcessId process_id), (process_id)) \ + AMS_TIPC_METHOD_INFO(C, H, 2, Result, LaunchProgramFromHost, (ams::tipc::Out out, const ams::tipc::InBuffer content_path, u32 pm_flags), (out, content_path, pm_flags)) \ + AMS_TIPC_METHOD_INFO(C, H, 4, Result, GetProgramLaunchPropertyFromHost, (ams::tipc::Out out, const ams::tipc::InBuffer content_path), (out, content_path)) \ + AMS_TIPC_METHOD_INFO(C, H, 5, Result, GetRunningApplicationProcessId, (ams::tipc::Out out), (out)) \ + AMS_TIPC_METHOD_INFO(C, H, 6, Result, BoostSystemMemoryResourceLimit, (u64 size), (size)) \ + AMS_TIPC_METHOD_INFO(C, H, 7, Result, IsRunningProcess, (ams::tipc::Out out, os::ProcessId process_id), (out, process_id)) \ + AMS_TIPC_METHOD_INFO(C, H, 8, Result, EnableApplicationCrashReport, (bool enabled), (enabled)) \ + AMS_TIPC_METHOD_INFO(C, H, 9, Result, IsApplicationCrashReportEnabled, (ams::tipc::Out out), (out)) \ + AMS_TIPC_METHOD_INFO(C, H, 10, Result, EnableApplicationAllThreadDumpOnCrash, (bool enabled), (enabled)) \ + AMS_TIPC_METHOD_INFO(C, H, 11, Result, GetProcessId, (ams::tipc::Out out, ncm::ProgramId program_id), (out, program_id), hos::Version_19_0_0) \ + AMS_TIPC_METHOD_INFO(C, H, 20, Result, CreateShellEvent, (ams::tipc::OutMoveHandle out), (out)) \ + AMS_TIPC_METHOD_INFO(C, H, 31, Result, EnableApplicationCrashReport2, (os::ProcessId process_id, bool enabled), (process_id, enabled), hos::Version_23_0_0) AMS_TIPC_DEFINE_INTERFACE(ams::pgl::tipc, IShellInterface, AMS_PGL_TIPC_I_SHELL_INTERFACE_INTERFACE_INFO); diff --git a/libraries/libstratosphere/include/stratosphere/ro/impl/ro_ro_interface.hpp b/libraries/libstratosphere/include/stratosphere/ro/impl/ro_ro_interface.hpp index 8a993f65b..e84a6fcf2 100644 --- a/libraries/libstratosphere/include/stratosphere/ro/impl/ro_ro_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/ro/impl/ro_ro_interface.hpp @@ -19,12 +19,12 @@ #include #include -#define AMS_RO_I_RO_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, MapManualLoadModuleMemory, (sf::Out out_load_address, const sf::ClientProcessId &client_pid, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size), (out_load_address, client_pid, nro_address, nro_size, bss_address, bss_size)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, UnmapManualLoadModuleMemory, (const sf::ClientProcessId &client_pid, u64 nro_address), (client_pid, nro_address)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, RegisterModuleInfo, (const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size), (client_pid, nrr_address, nrr_size)) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, UnregisterModuleInfo, (const sf::ClientProcessId &client_pid, u64 nrr_address), (client_pid, nrr_address)) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, RegisterProcessHandle, (const sf::ClientProcessId &client_pid, sf::CopyHandle &&process_h), (client_pid, std::move(process_h))) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, RegisterProcessModuleInfo, (const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle &&process_h), (client_pid, nrr_address, nrr_size, std::move(process_h)), hos::Version_7_0_0) +#define AMS_RO_I_RO_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, MapManualLoadModuleMemory, (sf::Out out_load_address, const sf::ClientProcessId &client_pid, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size), (out_load_address, client_pid, nro_address, nro_size, bss_address, bss_size)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, UnmapManualLoadModuleMemory, (const sf::ClientProcessId &client_pid, u64 nro_address), (client_pid, nro_address)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, RegisterModuleInfo, (const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size), (client_pid, nrr_address, nrr_size)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, UnregisterModuleInfo, (const sf::ClientProcessId &client_pid, u64 nrr_address), (client_pid, nrr_address)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, RegisterProcessHandle, (const sf::ClientProcessId &client_pid, sf::CopyHandle &&process_h), (client_pid, std::move(process_h))) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, RegisterModuleInfoWithUserProcessHandle, (const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle &&process_h), (client_pid, nrr_address, nrr_size, std::move(process_h)), hos::Version_7_0_0) AMS_SF_DEFINE_INTERFACE(ams::ro::impl, IRoInterface, AMS_RO_I_RO_INTERFACE_INTERFACE_INFO, 0xA52C55A9) diff --git a/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp b/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp index 4a1ce2684..86c57d0fc 100644 --- a/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp @@ -17,6 +17,7 @@ #pragma once #include #include +#include namespace ams::ro { @@ -40,30 +41,30 @@ namespace ams::ro { u64 program_id_mask; u64 program_id_pattern; u8 reserved_10[0x10]; - u8 modulus[RsaKeySize]; - u8 signature[RsaKeySize]; + u8 public_key[RsaKeySize]; + u8 sign[RsaKeySize]; }; static_assert(sizeof(NrrCertification) == NrrCertification::RsaKeySize + NrrCertification::SignedSize); class NrrHeader { public: - static constexpr u32 Magic = util::FourCC<'N','R','R','0'>::Code; + static constexpr u32 Signature = util::FourCC<'N','R','R','0'>::Code; private: - u32 m_magic; + u32 m_signature; u32 m_key_generation; u8 m_reserved_08[0x08]; NrrCertification m_certification; - u8 m_signature[0x100]; + u8 m_sign[0x100]; ncm::ProgramId m_program_id; u32 m_size; u8 m_nrr_kind; /* 7.0.0+ */ u8 m_reserved_33D[3]; - u32 m_hashes_offset; - u32 m_num_hashes; + u32 m_hash_list_offset_address; + u32 m_num_hash; u8 m_reserved_348[8]; public: bool IsMagicValid() const { - return m_magic == Magic; + return m_signature == Signature; } bool IsProgramIdValid() const { @@ -85,11 +86,11 @@ namespace ams::ro { } u32 GetNumHashes() const { - return m_num_hashes; + return m_num_hash; } size_t GetHashesOffset() const { - return m_hashes_offset; + return m_hash_list_offset_address; } uintptr_t GetHashes() const { @@ -101,7 +102,7 @@ namespace ams::ro { } const u8 *GetCertificationSignature() const { - return m_certification.signature; + return m_certification.sign; } const u8 *GetCertificationSignedArea() const { @@ -109,11 +110,11 @@ namespace ams::ro { } const u8 *GetCertificationModulus() const { - return m_certification.modulus; + return m_certification.public_key; } const u8 *GetSignature() const { - return m_signature; + return m_sign; } const u8 *GetSignedArea() const { @@ -131,32 +132,45 @@ namespace ams::ro { constexpr size_t NrrHeader::GetSignedAreaOffset() { return AMS_OFFSETOF(NrrHeader, m_program_id); } + + static constexpr size_t RocrtHeaderSize = 0x10; + struct RocrtHeader { + rocrt::ModuleHeaderLocation module_header_location; + u32 reserved; + }; + static_assert(sizeof(RocrtHeader) == RocrtHeaderSize); class NroHeader { public: - static constexpr u32 Magic = util::FourCC<'N','R','O','0'>::Code; + static constexpr u32 Signature = util::FourCC<'N','R','O','0'>::Code; static constexpr u32 FlagAlignedHeader = 1; + static constexpr u32 FlagCompress = 2; private: - u32 m_entrypoint_insn; - u32 m_mod_offset; - u8 m_reserved_08[0x8]; - u32 m_magic; - u8 m_version; + RocrtHeader m_rocrt; + u32 m_signature; + u32 m_version; u32 m_size; u32 m_flags; - u32 m_text_offset; + u32 m_text_memory_offset; u32 m_text_size; - u32 m_ro_offset; + u32 m_ro_memory_offset; u32 m_ro_size; - u32 m_rw_offset; - u32 m_rw_size; + u32 m_data_memory_offset; + u32 m_data_size; u32 m_bss_size; - u8 m_reserved_3C[0x4]; + u32 m_additional_header_offset; /* 23.0.0+ */ ModuleId m_module_id; - u8 m_reserved_60[0x20]; + u32 m_dso_handle_offset; + u32 m_reserved_64; + u32 m_embedded_offset; + u32 m_embedded_size; + u32 m_dyn_str_offset; + u32 m_dyn_str_size; + u32 m_dyn_sym_offset; + u32 m_dyn_sym_size; public: bool IsMagicValid() const { - return m_magic == Magic; + return m_signature == Signature; } u32 GetVersion() const { @@ -174,9 +188,13 @@ namespace ams::ro { bool IsAlignedHeader() const { return m_flags & FlagAlignedHeader; } + + bool IsCompress() const { + return m_flags & FlagCompress; + } u32 GetTextOffset() const { - return m_text_offset; + return m_text_memory_offset; } u32 GetTextSize() const { @@ -184,7 +202,7 @@ namespace ams::ro { } u32 GetRoOffset() const { - return m_ro_offset; + return m_ro_memory_offset; } u32 GetRoSize() const { @@ -192,21 +210,60 @@ namespace ams::ro { } u32 GetRwOffset() const { - return m_rw_offset; + return m_data_memory_offset; } u32 GetRwSize() const { - return m_rw_size; + return m_data_size; } u32 GetBssSize() const { return m_bss_size; } + + u32 GetAdditionalHeaderOffset() const { + return m_additional_header_offset; + } const ModuleId *GetModuleId() const { return std::addressof(m_module_id); } }; static_assert(sizeof(NroHeader) == 0x80, "NroHeader definition!"); + + class AdditionalNroHeader { + public: + static constexpr u32 Signature = util::FourCC<'N','R','A','0'>::Code; + private: + u32 m_signature; + u8 m_reserved_04[0xC]; + u32 m_compressed_size; + u32 m_reserved_14; + u32 m_hash_size; + u32 m_hash_offset; + u8 m_reserved_20[0x40]; + u8 m_hash[0x20]; + public: + bool IsMagicValid() const { + return m_signature == Signature; + } + + u32 GetCompressedSize() const { + return m_compressed_size; + } + + u32 GetHashSize() const { + return m_hash_size; + } + + u32 GetHashOffset() const { + return m_hash_offset; + } + + const u8 *GetHash() const { + return m_hash; + } + }; + static_assert(sizeof(AdditionalNroHeader) == 0x80, "AdditionalNroHeader definition!"); } diff --git a/libraries/libstratosphere/include/stratosphere/rocrt/rocrt.hpp b/libraries/libstratosphere/include/stratosphere/rocrt/rocrt.hpp index 6a4c0ce82..0758c9648 100644 --- a/libraries/libstratosphere/include/stratosphere/rocrt/rocrt.hpp +++ b/libraries/libstratosphere/include/stratosphere/rocrt/rocrt.hpp @@ -29,11 +29,18 @@ namespace ams::rocrt { u32 exception_info_start_offset; u32 exception_info_end_offset; u32 module_offset; + u32 relro_start_offset; /* 19.0.0+ */ + u32 full_relro_end_offset; /* 19.0.0+ */ + u32 nx_debug_link_start_offset; /* 19.0.0+ */ + u32 nx_debug_link_end_offset; /* 19.0.0+ */ + u32 note_gnu_build_id_start_offset; /* 19.0.0+ */ + u32 note_gnu_build_id_end_offset; /* 19.0.0+ */ }; struct ModuleHeaderLocation { - u32 pad; + u32 version; u32 header_offset; + u32 version_offset; }; constexpr inline u32 CheckModuleHeaderSignature(const ModuleHeader *header) { diff --git a/libraries/libstratosphere/include/stratosphere/spl/spl_api.hpp b/libraries/libstratosphere/include/stratosphere/spl/spl_api.hpp index 3d60504fe..ec6de4ebc 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/spl_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/spl_api.hpp @@ -89,6 +89,12 @@ namespace ams::spl { return ::ams::spl::GetConfigBool(::ams::spl::ConfigItem::ExosphereForceEnableUsb30); } + inline std::pair GetLogConfiguration() { + u64 v; + R_ABORT_UNLESS(::ams::spl::GetConfig(std::addressof(v), ::ams::spl::ConfigItem::ExosphereLogConfiguration)); + return std::make_pair(static_cast(v >> 32), static_cast(v)); + } + Result SetBootReason(BootReasonValue boot_reason); Result GetBootReason(BootReasonValue *out); diff --git a/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp b/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp index 11c80ad48..65c25fe58 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp @@ -230,6 +230,7 @@ namespace ams::spl { RegulatorType = 15, DeviceUniqueKeyGeneration = 16, Package2Hash = 17, + Unknown18 = 18, /* Extension config items for exosphere. */ ExosphereApiVersion = 65000, diff --git a/libraries/libstratosphere/include/stratosphere/sprofile/sprofile_types.hpp b/libraries/libstratosphere/include/stratosphere/sprofile/sprofile_types.hpp index 362a823cd..3fa6a84a8 100644 --- a/libraries/libstratosphere/include/stratosphere/sprofile/sprofile_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/sprofile/sprofile_types.hpp @@ -18,18 +18,18 @@ namespace ams::sprofile { - struct Identifier { + struct HashKey { u8 data[7]; - friend bool operator==(const Identifier &lhs, const Identifier &rhs) { + friend bool operator==(const HashKey &lhs, const HashKey &rhs) { return std::memcmp(lhs.data, rhs.data, sizeof(lhs.data)) == 0; } - friend bool operator!=(const Identifier &lhs, const Identifier &rhs) { + friend bool operator!=(const HashKey &lhs, const HashKey &rhs) { return !(lhs == rhs); } }; - static_assert(sizeof(Identifier) == 7); - static_assert(util::is_pod::value); + static_assert(sizeof(HashKey) == 7); + static_assert(util::is_pod::value); } diff --git a/libraries/libstratosphere/include/stratosphere/util/util_compression.hpp b/libraries/libstratosphere/include/stratosphere/util/util_compression.hpp index 543503d65..4a11dec61 100644 --- a/libraries/libstratosphere/include/stratosphere/util/util_compression.hpp +++ b/libraries/libstratosphere/include/stratosphere/util/util_compression.hpp @@ -28,6 +28,7 @@ namespace ams::util { /* Decompression utilities. */ int DecompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size); + int DecompressLZ4Frame(size_t* out_size, void *dst, size_t dst_size, const void *src, size_t src_size, void *src_work, size_t src_work_size, void *dst_work, size_t dst_work_size); size_t DecompressZstd(void *dst, size_t dst_size, const void *src, size_t src_size); size_t DecompressZstdWithBic(void *dst, size_t dst_size, const void *src, size_t src_size); bool DecompressZstdWithBic(void* workspace, size_t workspace_size, void *dst, size_t dst_size, size_t expected_dec_size, const void *src, size_t src_size); diff --git a/libraries/libstratosphere/source/cfg/cfg_override.board.nintendo_nx.inc b/libraries/libstratosphere/source/cfg/cfg_override.board.nintendo_nx.inc index a91da9268..ecdc1ecaf 100644 --- a/libraries/libstratosphere/source/cfg/cfg_override.board.nintendo_nx.inc +++ b/libraries/libstratosphere/source/cfg/cfg_override.board.nintendo_nx.inc @@ -79,20 +79,20 @@ namespace ams::cfg { InvalidProgramOverrideKey, }, .program_as_flags = { - impl::OverrideStatusFlag_AddressSpace64Bit, - impl::OverrideStatusFlag_AddressSpace64Bit, - impl::OverrideStatusFlag_AddressSpace64Bit, - impl::OverrideStatusFlag_AddressSpace64Bit, - impl::OverrideStatusFlag_AddressSpace64Bit, - impl::OverrideStatusFlag_AddressSpace64Bit, - impl::OverrideStatusFlag_AddressSpace64Bit, - impl::OverrideStatusFlag_AddressSpace64Bit, + impl::OverrideStatusFlag_AddressSpace64Bit39, + impl::OverrideStatusFlag_AddressSpace64Bit39, + impl::OverrideStatusFlag_AddressSpace64Bit39, + impl::OverrideStatusFlag_AddressSpace64Bit39, + impl::OverrideStatusFlag_AddressSpace64Bit39, + impl::OverrideStatusFlag_AddressSpace64Bit39, + impl::OverrideStatusFlag_AddressSpace64Bit39, + impl::OverrideStatusFlag_AddressSpace64Bit39, }, .override_any_app_key = { .key_combination = HidNpadButton_R, .override_by_default = false, }, - .override_any_app_as_flag = impl::OverrideStatusFlag_AddressSpace64Bit, + .override_any_app_as_flag = impl::OverrideStatusFlag_AddressSpace64Bit39, .override_any_app = true, }; @@ -152,9 +152,11 @@ namespace ams::cfg { impl::OverrideStatusFlag ParseOverrideAddressSpace(const char *value) { if (strcasecmp(value, "39_bit") == 0 || strcasecmp(value, "39") == 0) { - return impl::OverrideStatusFlag_AddressSpace64Bit; + return impl::OverrideStatusFlag_AddressSpace64Bit39; + } else if (strcasecmp(value, "42_bit") == 0 || strcasecmp(value, "42") == 0) { + return impl::OverrideStatusFlag_AddressSpace64Bit42; } else if (strcasecmp(value, "36_bit") == 0 || strcasecmp(value, "36") == 0) { - return impl::OverrideStatusFlag_AddressSpace64BitDeprecated; + return impl::OverrideStatusFlag_AddressSpace64Bit36; } else if (strcasecmp(value, "32_bit") == 0 || strcasecmp(value, "32") == 0) { return impl::OverrideStatusFlag_AddressSpace32Bit; } else if (strcasecmp(value, "32_bit_without_alias") == 0 || @@ -166,10 +168,10 @@ namespace ams::cfg { strcasecmp(value, "32_without_map") == 0 || strcasecmp(value, "32_no_map") == 0) { - return impl::OverrideStatusFlag_AddressSpace32BitWithoutAlias; + return impl::OverrideStatusFlag_AddressSpace32BitNoReserved; } else { /* Default to 39-bit. */ - return impl::OverrideStatusFlag_AddressSpace64Bit; + return impl::OverrideStatusFlag_AddressSpace64Bit39; } } diff --git a/libraries/libstratosphere/source/crypto/crypto_csrng.os.generic.cpp b/libraries/libstratosphere/source/crypto/crypto_csrng.os.generic.cpp index ecb9e2d0a..414953364 100644 --- a/libraries/libstratosphere/source/crypto/crypto_csrng.os.generic.cpp +++ b/libraries/libstratosphere/source/crypto/crypto_csrng.os.generic.cpp @@ -14,14 +14,14 @@ * along with this program. If not, see . */ #include -#include "../spl/impl/spl_ctr_drbg.hpp" +#include #include namespace ams::crypto { namespace { - using Drbg = ::ams::spl::impl::CtrDrbg; + using Drbg = ::ams::crypto::impl::CtrDrbg; constinit util::TypedStorage g_drbg = {}; diff --git a/libraries/libstratosphere/source/diag/impl/diag_print_debug_string.os.horizon.cpp b/libraries/libstratosphere/source/diag/impl/diag_print_debug_string.os.horizon.cpp index 55bbcb931..deb5fe51f 100644 --- a/libraries/libstratosphere/source/diag/impl/diag_print_debug_string.os.horizon.cpp +++ b/libraries/libstratosphere/source/diag/impl/diag_print_debug_string.os.horizon.cpp @@ -22,7 +22,7 @@ namespace ams::diag::impl { AMS_AUDIT(msg != nullptr || size == 0); if (size != 0) { - svc::OutputDebugString(msg, size); + R_DISCARD(svc::OutputDebugString(msg, size)); } } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp index 125501821..43d32e9b5 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp @@ -73,9 +73,30 @@ namespace ams::erpt::srv { /* We succeeded. */ R_SUCCEED(); } + + Result SubmitAttachmentImpl(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data, bool lz4_compression, bool unk) { + const char *name = reinterpret_cast(attachment_name.GetPointer()); + const u8 *data = reinterpret_cast(attachment_data.GetPointer()); + const u32 name_size = static_cast(attachment_name.GetSize()); + const u32 data_size = static_cast(attachment_data.GetSize()); + + R_UNLESS(data != nullptr, erpt::ResultInvalidArgument()); + R_UNLESS(data_size <= AttachmentSizeMax, erpt::ResultInvalidArgument()); + R_UNLESS(name != nullptr, erpt::ResultInvalidArgument()); + R_UNLESS(name_size <= AttachmentNameSizeMax, erpt::ResultInvalidArgument()); + + char name_safe[AttachmentNameSizeMax]; + util::Strlcpy(name_safe, name, sizeof(name_safe)); + + /* NOTE: This is tested, but goes unused and is never passed to JournalForAttachments. */ + AMS_UNUSED(unk); + + R_RETURN(JournalForAttachments::SubmitAttachment(out.GetPointer(), name_safe, data, data_size, lz4_compression)); + } + } - + Result ContextImpl::SubmitContext(const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer) { const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); const u8 *data = reinterpret_cast(data_buffer.GetPointer()); @@ -213,27 +234,14 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result ContextImpl::SubmitAttachment(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data) { - const char *name = reinterpret_cast(attachment_name.GetPointer()); - const u8 *data = reinterpret_cast(attachment_data.GetPointer()); - - const u32 name_size = static_cast(attachment_name.GetSize()); - const u32 data_size = static_cast(attachment_data.GetSize()); - - R_UNLESS(data != nullptr, erpt::ResultInvalidArgument()); - R_UNLESS(data_size <= AttachmentSizeMax, erpt::ResultInvalidArgument()); - R_UNLESS(name != nullptr, erpt::ResultInvalidArgument()); - R_UNLESS(name_size <= AttachmentNameSizeMax, erpt::ResultInvalidArgument()); - - char name_safe[AttachmentNameSizeMax]; - util::Strlcpy(name_safe, name, sizeof(name_safe)); - - R_RETURN(JournalForAttachments::SubmitAttachment(out.GetPointer(), name_safe, data, data_size)); + Result ContextImpl::SubmitAttachmentDeprecated(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data) { + R_RETURN(SubmitAttachmentImpl(out, attachment_name, attachment_data, false, false)); } Result ContextImpl::SubmitAttachmentWithLz4Compression(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data) { - /* TODO: Implement LZ4 compression on attachments. */ - R_RETURN(this->SubmitAttachment(out, attachment_name, attachment_data)); + /* NOTE: This should actually call JournalForAttachments::SubmitAttachmentWithLz4Compression. */ + /* We consolidate the logic in the new SubmitAttachmentImpl for simplicity (that's what ends up happening in JournalForAttachments anyway). */ + R_RETURN(SubmitAttachmentImpl(out, attachment_name, attachment_data, true, false)); } Result ContextImpl::CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags) { @@ -285,6 +293,10 @@ namespace ams::erpt::srv { R_SUCCEED(); } + + Result ContextImpl::SubmitAttachment(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data, erpt::SubmitAttachmentOptionFlagSet flags) { + R_RETURN(SubmitAttachmentImpl(out, attachment_name, attachment_data, flags.Test(), flags.Test())); + } Result ContextImpl::RegisterRunningApplet(ncm::ProgramId program_id) { R_RETURN(Reporter::RegisterRunningApplet(program_id)); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp index 506a5c244..af5915389 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp @@ -33,7 +33,7 @@ namespace ams::erpt::srv { Result RegisterRunningApplicationInfo(ncm::ApplicationId app_id, ncm::ProgramId program_id); Result ClearApplicationLaunchTime(); Result UnregisterRunningApplicationInfo(); - Result SubmitAttachment(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data); + Result SubmitAttachmentDeprecated(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data); Result CreateReportWithAttachmentsDeprecated(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer); Result CreateReportWithAttachmentsDeprecated2(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result); Result CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags); @@ -41,6 +41,7 @@ namespace ams::erpt::srv { Result CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags); Result SubmitAttachmentWithLz4Compression(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data); Result CreateReportWithSpecifiedReprotId(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_data, Result result, erpt::CreateReportOptionFlagSet flags, const ReportId &report_id); + Result SubmitAttachment(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data, erpt::SubmitAttachmentOptionFlagSet flags); Result RegisterRunningApplet(ncm::ProgramId program_id); Result UnregisterRunningApplet(ncm::ProgramId program_id); Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp index dda71d939..49aeb27ee 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp @@ -499,26 +499,26 @@ namespace ams::erpt::srv { } void ClearFsInfo() { - Context::ClearContext(CategoryId_NANDTypeInfo); - Context::ClearContext(CategoryId_NANDSpeedModeInfo); - Context::ClearContext(CategoryId_NANDExtendedCsd); - Context::ClearContext(CategoryId_NANDPatrolInfo); - Context::ClearContext(CategoryId_NANDErrorInfo); - Context::ClearContext(CategoryId_NANDDriverLog); - Context::ClearContext(CategoryId_MicroSDTypeInfo); - Context::ClearContext(CategoryId_MicroSDSpeedModeInfo); - Context::ClearContext(CategoryId_SdCardSizeSpec); - Context::ClearContext(CategoryId_SdCardActivationInfo); - Context::ClearContext(CategoryId_SdCardErrorInfo); - Context::ClearContext(CategoryId_SdCardDriverLog); - Context::ClearContext(CategoryId_GameCardCIDInfo); - Context::ClearContext(CategoryId_GameCardErrorInfo); - Context::ClearContext(CategoryId_GameCardDetailedErrorInfo); - Context::ClearContext(CategoryId_GameCardLogInfo); - Context::ClearContext(CategoryId_FsProxyErrorInfo); - Context::ClearContext(CategoryId_FsProxyErrorInfo2); - Context::ClearContext(CategoryId_FsProxyErrorInfo3); - Context::ClearContext(CategoryId_FsMemoryInfo); + R_DISCARD(Context::ClearContext(CategoryId_NANDTypeInfo)); + R_DISCARD(Context::ClearContext(CategoryId_NANDSpeedModeInfo)); + R_DISCARD(Context::ClearContext(CategoryId_NANDExtendedCsd)); + R_DISCARD(Context::ClearContext(CategoryId_NANDPatrolInfo)); + R_DISCARD(Context::ClearContext(CategoryId_NANDErrorInfo)); + R_DISCARD(Context::ClearContext(CategoryId_NANDDriverLog)); + R_DISCARD(Context::ClearContext(CategoryId_MicroSDTypeInfo)); + R_DISCARD(Context::ClearContext(CategoryId_MicroSDSpeedModeInfo)); + R_DISCARD(Context::ClearContext(CategoryId_SdCardSizeSpec)); + R_DISCARD(Context::ClearContext(CategoryId_SdCardActivationInfo)); + R_DISCARD(Context::ClearContext(CategoryId_SdCardErrorInfo)); + R_DISCARD(Context::ClearContext(CategoryId_SdCardDriverLog)); + R_DISCARD(Context::ClearContext(CategoryId_GameCardCIDInfo)); + R_DISCARD(Context::ClearContext(CategoryId_GameCardErrorInfo)); + R_DISCARD(Context::ClearContext(CategoryId_GameCardDetailedErrorInfo)); + R_DISCARD(Context::ClearContext(CategoryId_GameCardLogInfo)); + R_DISCARD(Context::ClearContext(CategoryId_FsProxyErrorInfo)); + R_DISCARD(Context::ClearContext(CategoryId_FsProxyErrorInfo2)); + R_DISCARD(Context::ClearContext(CategoryId_FsProxyErrorInfo3)); + R_DISCARD(Context::ClearContext(CategoryId_FsMemoryInfo)); } } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp index 16011e75a..ceaff7f4b 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp @@ -90,7 +90,7 @@ namespace ams::erpt::srv { static Result SetOwner(AttachmentId attachment_id, ReportId report_id); static Result StoreRecord(JournalRecord *record); - static Result SubmitAttachment(AttachmentId *out, char *name, const u8 *data, u32 data_size); + static Result SubmitAttachment(AttachmentId *out, char *name, const u8 *data, u32 data_size, bool lz4_compression); }; class Journal { diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp index d2a9bedfb..762d15e3f 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp @@ -185,8 +185,11 @@ namespace ams::erpt::srv { R_SUCCEED(); } - - Result JournalForAttachments::SubmitAttachment(AttachmentId *out, char *name, const u8 *data, u32 data_size) { + + Result JournalForAttachments::SubmitAttachment(AttachmentId *out, char *name, const u8 *data, u32 data_size, bool lz4_compression) { + /* TODO: Implement LZ4 compression on attachments. */ + AMS_UNUSED(lz4_compression); + R_UNLESS(data_size > 0, erpt::ResultInvalidArgument()); R_UNLESS(data_size < AttachmentSizeMax, erpt::ResultInvalidArgument()); @@ -229,5 +232,5 @@ namespace ams::erpt::srv { R_SUCCEED(); } - + } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp index 54754cee0..9ecabaf51 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp @@ -195,7 +195,7 @@ namespace ams::erpt::srv { } } else{ /* Pre 21.0.0, Nintendo just calls restore and ignores the result. */ - Journal::Restore(); + R_DISCARD(Journal::Restore()); } Reporter::UpdatePowerOnTime(); diff --git a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp index f38e8b4be..a1e1ac6ac 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp +++ b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp @@ -21,7 +21,7 @@ namespace ams::fs::impl { #define ADD_ENUM_CASE(v) case v: return #v template<> const char *IdString::ToString(pkg1::KeyGeneration id) { - static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_22_0_0); + static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_23_0_0); switch (id) { using enum pkg1::KeyGeneration; case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; @@ -45,7 +45,8 @@ namespace ams::fs::impl { case KeyGeneration_19_0_0: return "19.0.0-19.0.1"; case KeyGeneration_20_0_0: return "20.0.0-20.5.0"; case KeyGeneration_21_0_0: return "21.0.0-21.2.0"; - case KeyGeneration_22_0_0: return "22.0.0"; + case KeyGeneration_22_0_0: return "22.0.0-22.5.0"; + case KeyGeneration_23_0_0: return "23.0.0"; default: return "Unknown"; } } diff --git a/libraries/libstratosphere/source/gpio/gpio_client_api.cpp b/libraries/libstratosphere/source/gpio/gpio_client_api.cpp index ce51b8cef..8da47933d 100644 --- a/libraries/libstratosphere/source/gpio/gpio_client_api.cpp +++ b/libraries/libstratosphere/source/gpio/gpio_client_api.cpp @@ -81,9 +81,9 @@ namespace ams::gpio { ams::sf::SharedPointer session; { if (hos::GetVersion() >= hos::Version_7_0_0) { - R_TRY(g_manager->OpenSession2(std::addressof(session), device_code, ddsf::AccessMode_ReadWrite)); + R_TRY(g_manager->OpenSession(std::addressof(session), device_code, ddsf::AccessMode_ReadWrite)); } else { - R_TRY(g_manager->OpenSession(std::addressof(session), ConvertToGpioPadName(device_code))); + R_TRY(g_manager->OpenSessionDeprecated(std::addressof(session), ConvertToGpioPadName(device_code))); } } @@ -110,9 +110,9 @@ namespace ams::gpio { Result IsWakeEventActive(bool *out_is_active, ams::DeviceCode device_code) { if (hos::GetVersion() >= hos::Version_7_0_0) { - R_TRY(g_manager->IsWakeEventActive2(out_is_active, device_code)); + R_TRY(g_manager->IsWakeEventActive(out_is_active, device_code)); } else { - R_TRY(g_manager->IsWakeEventActive(out_is_active, ConvertToGpioPadName(device_code))); + R_TRY(g_manager->IsWakeEventActiveDeprecated(out_is_active, ConvertToGpioPadName(device_code))); } R_SUCCEED(); @@ -125,7 +125,7 @@ namespace ams::gpio { } void SetDirection(GpioPadSession *session, Direction direction) { - R_ABORT_UNLESS(GetInterface(session)->SetDirection(direction)); + R_ABORT_UNLESS(GetInterface(session)->SetDirectionDeprecated(direction)); } GpioValue GetValue(GpioPadSession *session) { diff --git a/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.cpp b/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.cpp index 72da31d0e..968c2769a 100644 --- a/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.cpp +++ b/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.cpp @@ -34,7 +34,7 @@ namespace ams::gpio { } - Result RemoteManagerImpl::OpenSession(ams::sf::Out> out, gpio::GpioPadName pad_name) { + Result RemoteManagerImpl::OpenSessionDeprecated(ams::sf::Out> out, gpio::GpioPadName pad_name) { ::GpioPadSession p; R_TRY(::gpioOpenSession(std::addressof(p), static_cast<::GpioPadName>(static_cast(pad_name)))); @@ -42,7 +42,7 @@ namespace ams::gpio { R_SUCCEED(); } - Result RemoteManagerImpl::OpenSession2(ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode) { + Result RemoteManagerImpl::OpenSession(ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode) { ::GpioPadSession p; R_TRY(::gpioOpenSession2(std::addressof(p), device_code.GetInternalValue(), access_mode)); diff --git a/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.hpp b/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.hpp index bd6e47fcd..ec3ad8c6c 100644 --- a/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.hpp +++ b/libraries/libstratosphere/source/gpio/gpio_remote_manager_impl.hpp @@ -27,31 +27,31 @@ namespace ams::gpio { ~RemoteManagerImpl() { /* ... */ } public: /* Actual commands. */ - Result OpenSessionForDev(ams::sf::Out> out, s32 pad_descriptor) { + Result OpenSessionForDevDeprecated(ams::sf::Out> out, s32 pad_descriptor) { /* TODO: libnx bindings */ AMS_UNUSED(out, pad_descriptor); AMS_ABORT(); } - Result OpenSession(ams::sf::Out> out, gpio::GpioPadName pad_name); + Result OpenSessionDeprecated(ams::sf::Out> out, gpio::GpioPadName pad_name); - Result OpenSessionForTest(ams::sf::Out> out, gpio::GpioPadName pad_name) { + Result OpenSessionForTestDeprecated(ams::sf::Out> out, gpio::GpioPadName pad_name) { /* TODO: libnx bindings */ AMS_UNUSED(out, pad_name); AMS_ABORT(); } - Result IsWakeEventActive(ams::sf::Out out, gpio::GpioPadName pad_name) { + Result IsWakeEventActiveDeprecated(ams::sf::Out out, gpio::GpioPadName pad_name) { R_RETURN(::gpioIsWakeEventActive2(out.GetPointer(), static_cast<::GpioPadName>(static_cast(pad_name)))); } - Result GetWakeEventActiveFlagSet(ams::sf::Out out) { + Result GetWakeEventActiveFlagSetDeprecated(ams::sf::Out out) { /* TODO: libnx bindings */ AMS_UNUSED(out); AMS_ABORT(); } - Result SetWakeEventActiveFlagSetForDebug(gpio::GpioPadName pad_name, bool is_enabled) { + Result SetWakeEventActiveFlagSetForDebugDeprecated(gpio::GpioPadName pad_name, bool is_enabled) { /* TODO: libnx bindings */ AMS_UNUSED(pad_name, is_enabled); AMS_ABORT(); @@ -63,19 +63,19 @@ namespace ams::gpio { AMS_ABORT(); } - Result OpenSession2(ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode); + Result OpenSession(ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode); - Result IsWakeEventActive2(ams::sf::Out out, DeviceCode device_code) { + Result IsWakeEventActive(ams::sf::Out out, DeviceCode device_code) { R_RETURN(::gpioIsWakeEventActive2(out.GetPointer(), device_code.GetInternalValue())); } - Result SetWakeEventActiveFlagSetForDebug2(DeviceCode device_code, bool is_enabled) { + Result SetWakeEventActiveFlagSetForDebug(DeviceCode device_code, bool is_enabled) { /* TODO: libnx bindings */ AMS_UNUSED(device_code, is_enabled); AMS_ABORT(); } - Result SetRetryValues(u32 arg0, u32 arg1) { + Result DumpStateForDebug(u32 arg0, u32 arg1) { /* TODO: libnx bindings */ AMS_UNUSED(arg0, arg1); AMS_ABORT(); diff --git a/libraries/libstratosphere/source/gpio/gpio_remote_pad_session_impl.hpp b/libraries/libstratosphere/source/gpio/gpio_remote_pad_session_impl.hpp index ee5874504..18f63d61e 100644 --- a/libraries/libstratosphere/source/gpio/gpio_remote_pad_session_impl.hpp +++ b/libraries/libstratosphere/source/gpio/gpio_remote_pad_session_impl.hpp @@ -28,7 +28,7 @@ namespace ams::gpio { ~RemotePadSessionImpl() { ::gpioPadClose(std::addressof(m_srv)); } public: /* Actual commands. */ - Result SetDirection(gpio::Direction direction) { + Result SetDirectionDeprecated(gpio::Direction direction) { R_RETURN(::gpioPadSetDirection(std::addressof(m_srv), static_cast<::GpioDirection>(static_cast(direction)))); } @@ -105,7 +105,30 @@ namespace ams::gpio { AMS_ABORT(); } - Result GetValueForSleepState(ams::sf::Out out) { + Result GetMaxDebounceTime(ams::sf::Out out) { + /* TODO: libnx bindings. */ + AMS_UNUSED(out); + AMS_ABORT(); + } + + Result SetDirectionInput() { + /* TODO: libnx bindings. */ + AMS_ABORT(); + } + + Result SetDirectionOutput(gpio::GpioValue value) { + /* TODO: libnx bindings. */ + AMS_UNUSED(value); + AMS_ABORT(); + } + + Result SetUnknownEnabled(bool enable) { + /* TODO: libnx bindings. */ + AMS_UNUSED(enable); + AMS_ABORT(); + } + + Result GetUnknownEnabled(ams::sf::Out out) { /* TODO: libnx bindings. */ AMS_UNUSED(out); AMS_ABORT(); diff --git a/libraries/libstratosphere/source/gpio/server/gpio_server_manager_impl.cpp b/libraries/libstratosphere/source/gpio/server/gpio_server_manager_impl.cpp index 226813219..052541bec 100644 --- a/libraries/libstratosphere/source/gpio/server/gpio_server_manager_impl.cpp +++ b/libraries/libstratosphere/source/gpio/server/gpio_server_manager_impl.cpp @@ -27,35 +27,35 @@ namespace ams::gpio::server { lmem::DestroyExpHeap(m_heap_handle); } - Result ManagerImpl::OpenSessionForDev(ams::sf::Out> out, s32 pad_descriptor) { + Result ManagerImpl::OpenSessionForDevDeprecated(ams::sf::Out> out, s32 pad_descriptor) { /* TODO */ AMS_UNUSED(out, pad_descriptor); AMS_ABORT(); } - Result ManagerImpl::OpenSession(ams::sf::Out> out, gpio::GpioPadName pad_name) { - R_RETURN(this->OpenSession2(out, ConvertToDeviceCode(pad_name), ddsf::AccessMode_ReadWrite)); + Result ManagerImpl::OpenSessionDeprecated(ams::sf::Out> out, gpio::GpioPadName pad_name) { + R_RETURN(this->OpenSession(out, ConvertToDeviceCode(pad_name), ddsf::AccessMode_ReadWrite)); } - Result ManagerImpl::OpenSessionForTest(ams::sf::Out> out, gpio::GpioPadName pad_name) { + Result ManagerImpl::OpenSessionForTestDeprecated(ams::sf::Out> out, gpio::GpioPadName pad_name) { /* TODO */ AMS_UNUSED(out, pad_name); AMS_ABORT(); } - Result ManagerImpl::IsWakeEventActive(ams::sf::Out out, gpio::GpioPadName pad_name) { + Result ManagerImpl::IsWakeEventActiveDeprecated(ams::sf::Out out, gpio::GpioPadName pad_name) { /* TODO */ AMS_UNUSED(out, pad_name); AMS_ABORT(); } - Result ManagerImpl::GetWakeEventActiveFlagSet(ams::sf::Out out) { + Result ManagerImpl::GetWakeEventActiveFlagSetDeprecated(ams::sf::Out out) { /* TODO */ AMS_UNUSED(out); AMS_ABORT(); } - Result ManagerImpl::SetWakeEventActiveFlagSetForDebug(gpio::GpioPadName pad_name, bool is_enabled) { + Result ManagerImpl::SetWakeEventActiveFlagSetForDebugDeprecated(gpio::GpioPadName pad_name, bool is_enabled) { /* TODO */ AMS_UNUSED(pad_name, is_enabled); AMS_ABORT(); @@ -67,7 +67,7 @@ namespace ams::gpio::server { AMS_ABORT(); } - Result ManagerImpl::OpenSession2(ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode) { + Result ManagerImpl::OpenSession(ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode) { /* Allocate a session. */ auto session = Factory::CreateSharedEmplaced(std::addressof(m_pad_allocator), this); @@ -79,19 +79,19 @@ namespace ams::gpio::server { R_SUCCEED(); } - Result ManagerImpl::IsWakeEventActive2(ams::sf::Out out, DeviceCode device_code) { + Result ManagerImpl::IsWakeEventActive(ams::sf::Out out, DeviceCode device_code) { /* TODO */ AMS_UNUSED(out, device_code); AMS_ABORT(); } - Result ManagerImpl::SetWakeEventActiveFlagSetForDebug2(DeviceCode device_code, bool is_enabled) { + Result ManagerImpl::SetWakeEventActiveFlagSetForDebug(DeviceCode device_code, bool is_enabled) { /* TODO */ AMS_UNUSED(device_code, is_enabled); AMS_ABORT(); } - Result ManagerImpl::SetRetryValues(u32 arg0, u32 arg1) { + Result ManagerImpl::DumpStateForDebug(u32 arg0, u32 arg1) { /* TODO */ AMS_UNUSED(arg0, arg1); AMS_ABORT(); diff --git a/libraries/libstratosphere/source/gpio/server/gpio_server_manager_impl.hpp b/libraries/libstratosphere/source/gpio/server/gpio_server_manager_impl.hpp index be5d862ab..2e51f0fda 100644 --- a/libraries/libstratosphere/source/gpio/server/gpio_server_manager_impl.hpp +++ b/libraries/libstratosphere/source/gpio/server/gpio_server_manager_impl.hpp @@ -33,17 +33,17 @@ namespace ams::gpio::server { ~ManagerImpl(); public: /* Actual commands. */ - Result OpenSessionForDev(ams::sf::Out> out, s32 pad_descriptor); - Result OpenSession(ams::sf::Out> out, gpio::GpioPadName pad_name); - Result OpenSessionForTest(ams::sf::Out> out, gpio::GpioPadName pad_name); - Result IsWakeEventActive(ams::sf::Out out, gpio::GpioPadName pad_name); - Result GetWakeEventActiveFlagSet(ams::sf::Out out); - Result SetWakeEventActiveFlagSetForDebug(gpio::GpioPadName pad_name, bool is_enabled); + Result OpenSessionForDevDeprecated(ams::sf::Out> out, s32 pad_descriptor); + Result OpenSessionDeprecated(ams::sf::Out> out, gpio::GpioPadName pad_name); + Result OpenSessionForTestDeprecated(ams::sf::Out> out, gpio::GpioPadName pad_name); + Result IsWakeEventActiveDeprecated(ams::sf::Out out, gpio::GpioPadName pad_name); + Result GetWakeEventActiveFlagSetDeprecated(ams::sf::Out out); + Result SetWakeEventActiveFlagSetForDebugDeprecated(gpio::GpioPadName pad_name, bool is_enabled); Result SetWakePinDebugMode(s32 mode); - Result OpenSession2(ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode); - Result IsWakeEventActive2(ams::sf::Out out, DeviceCode device_code); - Result SetWakeEventActiveFlagSetForDebug2(DeviceCode device_code, bool is_enabled); - Result SetRetryValues(u32 arg0, u32 arg1); + Result OpenSession(ams::sf::Out> out, DeviceCode device_code, ddsf::AccessMode access_mode); + Result IsWakeEventActive(ams::sf::Out out, DeviceCode device_code); + Result SetWakeEventActiveFlagSetForDebug(DeviceCode device_code, bool is_enabled); + Result DumpStateForDebug(u32 arg0, u32 arg1); }; static_assert(gpio::sf::IsIManager); diff --git a/libraries/libstratosphere/source/gpio/server/gpio_server_pad_session_impl.hpp b/libraries/libstratosphere/source/gpio/server/gpio_server_pad_session_impl.hpp index a1ce1e6a5..441534888 100644 --- a/libraries/libstratosphere/source/gpio/server/gpio_server_pad_session_impl.hpp +++ b/libraries/libstratosphere/source/gpio/server/gpio_server_pad_session_impl.hpp @@ -44,7 +44,7 @@ namespace ams::gpio::server { } public: /* Actual commands. */ - Result SetDirection(gpio::Direction direction) { + Result SetDirectionDeprecated(gpio::Direction direction) { /* Validate our state. */ AMS_ASSERT(m_has_session); @@ -205,7 +205,42 @@ namespace ams::gpio::server { AMS_ABORT(); } - Result GetValueForSleepState(ams::sf::Out out) { + Result GetMaxDebounceTime(ams::sf::Out out) { + /* Validate our state. */ + AMS_ASSERT(m_has_session); + + /* TODO */ + AMS_UNUSED(out); + AMS_ABORT(); + } + + Result SetDirectionInput() { + /* Validate our state. */ + AMS_ASSERT(m_has_session); + + /* TODO */ + AMS_ABORT(); + } + + Result SetDirectionOutput(gpio::GpioValue value) { + /* Validate our state. */ + AMS_ASSERT(m_has_session); + + /* TODO */ + AMS_UNUSED(value); + AMS_ABORT(); + } + + Result SetUnknownEnabled(bool enable) { + /* Validate our state. */ + AMS_ASSERT(m_has_session); + + /* TODO */ + AMS_UNUSED(enable); + AMS_ABORT(); + } + + Result GetUnknownEnabled(ams::sf::Out out) { /* Validate our state. */ AMS_ASSERT(m_has_session); diff --git a/libraries/libstratosphere/source/htcfs/htcfs_client_impl.cpp b/libraries/libstratosphere/source/htcfs/htcfs_client_impl.cpp index 50fa2ee81..313f54a9c 100644 --- a/libraries/libstratosphere/source/htcfs/htcfs_client_impl.cpp +++ b/libraries/libstratosphere/source/htcfs/htcfs_client_impl.cpp @@ -532,8 +532,8 @@ namespace ams::htcfs { Header request, response; /* Create header for the request. */ - const auto old_path_len = std::strlen(new_path); - const auto new_path_len = std::strlen(old_path); + const auto old_path_len = std::strlen(old_path); + const auto new_path_len = std::strlen(new_path); m_header_factory.MakeRenameFileHeader(std::addressof(request), old_path_len, new_path_len, case_sensitive); /* Send the request to the host. */ @@ -734,8 +734,8 @@ namespace ams::htcfs { Header request, response; /* Create header for the request. */ - const auto old_path_len = std::strlen(new_path); - const auto new_path_len = std::strlen(old_path); + const auto old_path_len = std::strlen(old_path); + const auto new_path_len = std::strlen(new_path); m_header_factory.MakeRenameDirectoryHeader(std::addressof(request), old_path_len, new_path_len, case_sensitive); /* Send the request to the host. */ diff --git a/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/impl/i2c_bus_accessor.cpp b/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/impl/i2c_bus_accessor.cpp index a59c6d65d..50a204e42 100644 --- a/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/impl/i2c_bus_accessor.cpp +++ b/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/impl/i2c_bus_accessor.cpp @@ -114,7 +114,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { /* If we have a regulator session, set voltage to 2.9V. */ if (m_has_regulator_session) { /* NOTE: Nintendo does not check the result, here. */ - regulator::SetVoltageValue(std::addressof(m_regulator_session), 2'900'000u); + R_DISCARD(regulator::SetVoltageValue(std::addressof(m_regulator_session), 2'900'000u)); } /* Initialize clock/reset library. */ @@ -130,7 +130,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { const bool was_enabled = regulator::GetVoltageEnabled(std::addressof(m_regulator_session)); /* NOTE: Nintendo does not check the result of this call. */ - regulator::SetVoltageEnabled(std::addressof(m_regulator_session), true); + R_DISCARD(regulator::SetVoltageEnabled(std::addressof(m_regulator_session), true)); /* If we enabled voltage, delay to give our enable time to take. */ if (!was_enabled) { @@ -163,7 +163,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { /* If we have a regulator session, disable voltage. */ if (m_has_regulator_session) { /* NOTE: Nintendo does not check the result of this call. */ - regulator::SetVoltageEnabled(std::addressof(m_regulator_session), false); + R_DISCARD(regulator::SetVoltageEnabled(std::addressof(m_regulator_session), false)); } /* Finalize the clock/reset library. */ @@ -233,7 +233,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { /* Disable voltage. */ if (m_has_regulator_session) { - regulator::SetVoltageEnabled(std::addressof(m_regulator_session), false); + R_DISCARD(regulator::SetVoltageEnabled(std::addressof(m_regulator_session), false)); } } @@ -272,7 +272,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { const bool was_enabled = regulator::GetVoltageEnabled(std::addressof(m_regulator_session)); /* NOTE: Nintendo does not check the result of this call. */ - regulator::SetVoltageEnabled(std::addressof(m_regulator_session), true); + R_DISCARD(regulator::SetVoltageEnabled(std::addressof(m_regulator_session), true)); /* If we enabled voltage, delay to give our enable time to take. */ if (!was_enabled) { @@ -337,7 +337,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { this->SetPacketModeRegisters(); /* Flush fifos. */ - this->FlushFifos(); + R_DISCARD(this->FlushFifos()); } Result I2cBusAccessor::Send(const u8 *src, size_t src_size, TransactionOption option, u16 slave_address, AddressingMode addressing_mode) { @@ -516,7 +516,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { const u32 slave_addr = ((static_cast(slave_address) & 0x7F) << 1) | (is_read ? 1 : 0); /* Flush fifos. */ - this->FlushFifos(); + R_DISCARD(this->FlushFifos()); /* Enqueue the first header word. */ reg::Write(m_registers->tx_packet_fifo, IO_PACKET_BITS_ENUM (HEADER_WORD0_PROT_HDR_SZ, 1_WORD), @@ -765,7 +765,7 @@ namespace ams::i2c::driver::board::nintendo::nx::impl { this->SetPacketModeRegisters(); /* Flush fifos. */ - this->FlushFifos(); + R_DISCARD(this->FlushFifos()); } } R_END_TRY_CATCH_WITH_ABORT_UNLESS; } diff --git a/libraries/libstratosphere/source/kvdb/kvdb_file_key_value_store.cpp b/libraries/libstratosphere/source/kvdb/kvdb_file_key_value_store.cpp index 955ae0ef0..2e72aaf26 100644 --- a/libraries/libstratosphere/source/kvdb/kvdb_file_key_value_store.cpp +++ b/libraries/libstratosphere/source/kvdb/kvdb_file_key_value_store.cpp @@ -273,7 +273,7 @@ namespace ams::kvdb { /* Delete the file, if it exists. Don't check result, since it's okay if it's already deleted. */ auto key_path = this->GetPath(key, key_size); - fs::DeleteFile(key_path); + R_DISCARD(fs::DeleteFile(key_path)); /* Create the new value file. */ R_TRY(fs::CreateFile(key_path, value_size)); diff --git a/libraries/libstratosphere/source/lm/lm_api.cpp b/libraries/libstratosphere/source/lm/lm_api.cpp index ee4a22e75..15bf66e10 100644 --- a/libraries/libstratosphere/source/lm/lm_api.cpp +++ b/libraries/libstratosphere/source/lm/lm_api.cpp @@ -115,7 +115,7 @@ namespace ams::lm { } void SetDestination(u32 destination) { - g_logger->SetDestination(destination); + R_DISCARD(g_logger->SetDestination(destination)); } } diff --git a/libraries/libstratosphere/source/lr/lr_location_resolver_manager_impl.cpp b/libraries/libstratosphere/source/lr/lr_location_resolver_manager_impl.cpp index a7925fa93..c60acdcb5 100644 --- a/libraries/libstratosphere/source/lr/lr_location_resolver_manager_impl.cpp +++ b/libraries/libstratosphere/source/lr/lr_location_resolver_manager_impl.cpp @@ -88,7 +88,7 @@ namespace ams::lr { /* Refresh the resolver. */ if (storage_id != ncm::StorageId::Host) { - (*resolver)->Refresh(); + R_DISCARD((*resolver)->Refresh()); } R_SUCCEED(); diff --git a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp index dded90f31..6007b894a 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp @@ -274,7 +274,7 @@ namespace ams::ncm { if (root.content_storage != nullptr) { /* N doesn't bother checking the result of this. */ - root.content_storage->DisableForcibly(); + R_DISCARD(root.content_storage->DisableForcibly()); root.content_storage = nullptr; if (root.storage_id == StorageId::Host) { @@ -514,7 +514,7 @@ namespace ams::ncm { if (root.content_meta_database != nullptr) { /* N doesn't bother checking the result of this. */ - root.content_meta_database->DisableForcibly(); + R_DISCARD(root.content_meta_database->DisableForcibly()); root.content_meta_database = nullptr; root.kvs = util::nullopt; @@ -618,12 +618,12 @@ namespace ams::ncm { /* Disable and unmount all content storage roots. */ for (size_t i = 0; i < m_num_integrated_content_storage_entries; ++i) { - this->InactivateContentStorage(m_integrated_content_storage_roots[i].m_config->storage_id); + R_DISCARD(this->InactivateContentStorage(m_integrated_content_storage_roots[i].m_config->storage_id)); } /* Disable and unmount all content meta database roots. */ for (size_t i = 0; i < m_num_integrated_content_meta_entries; ++i) { - this->InactivateContentMetaDatabase(m_integrated_content_meta_database_roots[i].m_config->storage_id); + R_DISCARD(this->InactivateContentMetaDatabase(m_integrated_content_meta_database_roots[i].m_config->storage_id)); } } @@ -796,7 +796,7 @@ namespace ams::ncm { Result ContentManagerImpl::BuildContentMetaDatabaseImpl(StorageId storage_id) { /* Temporarily activate the database. */ R_TRY(this->ActivateContentMetaDatabase(storage_id)); - ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(storage_id); }; + ON_SCOPE_EXIT { R_DISCARD(this->InactivateContentMetaDatabase(storage_id)); }; /* Open the content meta database and storage. */ ContentMetaDatabase meta_db; @@ -848,7 +848,7 @@ namespace ams::ncm { if (R_FAILED(this->ActivateContentMetaDatabase(StorageId::BuiltInSystem))) { return true; } - ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(StorageId::BuiltInSystem); }; + ON_SCOPE_EXIT { R_DISCARD(this->InactivateContentMetaDatabase(StorageId::BuiltInSystem)); }; /* Open the content meta db. */ ContentMetaDatabase meta_db; @@ -976,7 +976,7 @@ namespace ams::ncm { /* or an empty kvs, both of which we can fix by performing a rebuild. */ if (this->IsNeedRebuildSystemContentMetaDatabase()) { /* Clean up the system content meta database, to ensure creation can succeed. */ - this->CleanupContentMetaDatabase(StorageId::BuiltInSystem); + R_DISCARD(this->CleanupContentMetaDatabase(StorageId::BuiltInSystem)); /* Create the content meta database. */ R_TRY(this->CreateContentMetaDatabase(StorageId::BuiltInSystem)); @@ -1005,7 +1005,7 @@ namespace ams::ncm { /* NOTE: Nintendo does not check this succeeds, and it does on older system versions. */ /* We will not check the error, either, even though this kind of defeats the call's purpose. */ if (hos::GetVersion() >= hos::Version_2_0_0) { - EnsureBuiltInSystemSaveDataFlags(); + R_DISCARD(EnsureBuiltInSystemSaveDataFlags()); } /* Activate the content meta database. */ diff --git a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp index db0387503..cc31c7299 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp @@ -510,7 +510,7 @@ namespace ams::ncm { PlaceHolderAccessor::MakeBaseDirectoryPath(std::addressof(placeholder_dir), m_root_path); /* Cleanup the placeholder base directory. */ - CleanDirectoryRecursively(placeholder_dir); + R_DISCARD(CleanDirectoryRecursively(placeholder_dir)); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/ncm/ncm_extended_data_mapper.hpp b/libraries/libstratosphere/source/ncm/ncm_extended_data_mapper.hpp index 633ffd809..a4bf6f2bc 100644 --- a/libraries/libstratosphere/source/ncm/ncm_extended_data_mapper.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_extended_data_mapper.hpp @@ -47,7 +47,7 @@ namespace ams::ncm { void Finalize() { /* If we're unused and mapped, we should unmap. */ if (!m_is_using && m_is_mapped) { - this->Unmap(); + R_DISCARD(this->Unmap()); } } private: diff --git a/libraries/libstratosphere/source/ncm/ncm_install_task_base.cpp b/libraries/libstratosphere/source/ncm/ncm_install_task_base.cpp index 231d18064..fc1785705 100644 --- a/libraries/libstratosphere/source/ncm/ncm_install_task_base.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_install_task_base.cpp @@ -189,7 +189,7 @@ namespace ams::ncm { /* Cleanup the content meta. */ /* N doesn't check the result of this. */ - this->CleanupOne(content_meta); + R_DISCARD(this->CleanupOne(content_meta)); } /* Cleanup the data and progress. */ @@ -215,7 +215,7 @@ namespace ams::ncm { /* Delete placeholders for Prepared or Installed content infos. */ if (content_info->install_state == InstallState::Prepared || content_info->install_state == InstallState::Installed) { - content_storage.DeletePlaceHolder(content_info->placeholder_id); + R_DISCARD(content_storage.DeletePlaceHolder(content_info->placeholder_id)); } } @@ -344,7 +344,7 @@ namespace ams::ncm { /* Write all prepared content infos. */ { /* If we fail while writing, update (but don't check the result). */ - ON_RESULT_FAILURE { m_data->Update(content_meta, i); }; + ON_RESULT_FAILURE { R_DISCARD(m_data->Update(content_meta, i)); }; /* Create a writer. */ const auto writer = content_meta.GetWriter(); @@ -449,7 +449,7 @@ namespace ams::ncm { /* Commit the current meta. */ { /* Ensure that if something goes wrong during commit, we still try to update. */ - ON_RESULT_FAILURE { m_data->Update(content_meta, i); }; + ON_RESULT_FAILURE { R_DISCARD(m_data->Update(content_meta, i)); }; /* Open a writer. */ const auto writer = content_meta.GetWriter(); @@ -636,7 +636,7 @@ namespace ams::ncm { /* Update the data (and check result) when we are done. */ { - ON_RESULT_FAILURE { m_data->Update(content_meta, i); }; + ON_RESULT_FAILURE { R_DISCARD(m_data->Update(content_meta, i)); }; /* Automatically choose a suitable storage id. */ auto reader = content_meta.GetReader(); @@ -713,7 +713,7 @@ namespace ams::ncm { /* Create the placeholder. */ R_TRY(storage->CreatePlaceHolder(placeholder_id, meta_info.content_id, meta_info.content_size)); - ON_RESULT_FAILURE { storage->DeletePlaceHolder(placeholder_id); }; + ON_RESULT_FAILURE { R_DISCARD(storage->DeletePlaceHolder(placeholder_id)); }; /* Output install content info. */ *out_install_content_info = this->MakeInstallContentInfoFrom(meta_info, placeholder_id, is_temporary); @@ -740,7 +740,7 @@ namespace ams::ncm { content_storage.GetPlaceHolderPath(std::addressof(path), content_info.GetPlaceHolderId()); /* If we fail, delete the placeholder. */ - ON_RESULT_FAILURE { content_storage.DeletePlaceHolder(content_info.GetPlaceHolderId()); }; + ON_RESULT_FAILURE { R_DISCARD(content_storage.DeletePlaceHolder(content_info.GetPlaceHolderId())); }; /* Create a new temporary InstallContentInfo if relevant. */ const bool is_temporary = content_info.is_temporary; @@ -775,7 +775,7 @@ namespace ams::ncm { /* If the placeholder is temporary, delete it. */ if (is_temporary) { - content_storage.DeletePlaceHolder(content_info.GetPlaceHolderId()); + R_DISCARD(content_storage.DeletePlaceHolder(content_info.GetPlaceHolderId())); } R_SUCCEED(); @@ -793,7 +793,7 @@ namespace ams::ncm { reader.ConvertToInstallContentMeta(tmp_buffer.Get(), tmp_buffer.GetSize(), InstallContentInfo::Make(ContentInfo::Make(content_id, size, ContentInfo::DefaultContentAttributes, ContentType::Meta), meta_type)); /* Push the content meta. */ - m_data->Push(tmp_buffer.Get(), tmp_buffer.GetSize()); + R_DISCARD(m_data->Push(tmp_buffer.Get(), tmp_buffer.GetSize())); R_SUCCEED(); } @@ -807,7 +807,7 @@ namespace ams::ncm { Result InstallTaskBase::PrepareSystemUpdateDependency() { /* Cleanup on failure. */ - ON_RESULT_FAILURE { this->Cleanup(); }; + ON_RESULT_FAILURE { R_DISCARD(this->Cleanup()); }; /* Count the number of content meta entries. */ s32 count; @@ -1066,7 +1066,7 @@ namespace ams::ncm { void InstallTaskBase::SetLastResult(Result last_result) { std::scoped_lock lk(m_progress_mutex); - m_data->SetLastResult(last_result); + R_DISCARD(m_data->SetLastResult(last_result)); m_progress.SetLastResult(last_result); } @@ -1183,7 +1183,7 @@ namespace ams::ncm { R_TRY(ReadVariationContentMetaInfoList(out_count, out_meta_infos, path, attr, m_firmware_variation_id)); /* Delete the placeholder. */ - content_storage.DeletePlaceHolder(placeholder_id); + R_DISCARD(content_storage.DeletePlaceHolder(placeholder_id)); R_SUCCEED(); } @@ -1275,7 +1275,7 @@ namespace ams::ncm { void InstallTaskBase::SetProgressState(InstallProgressState state) { std::scoped_lock lk(m_progress_mutex); - m_data->SetState(state); + R_DISCARD(m_data->SetState(state)); m_progress.state = state; } diff --git a/libraries/libstratosphere/source/ncm/ncm_install_task_data.cpp b/libraries/libstratosphere/source/ncm/ncm_install_task_data.cpp index 362876163..307c63d13 100644 --- a/libraries/libstratosphere/source/ncm/ncm_install_task_data.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_install_task_data.cpp @@ -357,7 +357,7 @@ namespace ams::ncm { } /* NOTE: Nintendo doesn't check that this operation succeeds. */ - install_task_data.Push(content_meta.data.get(), content_meta.size); + R_DISCARD(install_task_data.Push(content_meta.data.get(), content_meta.size)); } /* Change from our current data to the new data. */ diff --git a/libraries/libstratosphere/source/ncm/ncm_package_system_downgrade_task.cpp b/libraries/libstratosphere/source/ncm/ncm_package_system_downgrade_task.cpp index f8abab57b..259c99315 100644 --- a/libraries/libstratosphere/source/ncm/ncm_package_system_downgrade_task.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_package_system_downgrade_task.cpp @@ -53,7 +53,7 @@ namespace ams::ncm { /* Remove matching keys. */ for (auto i = 0; i < count.total; i++) { - meta_db.Remove(keys[i]); + R_DISCARD(meta_db.Remove(keys[i])); } } } diff --git a/libraries/libstratosphere/source/ncm/ncm_package_system_update_task.cpp b/libraries/libstratosphere/source/ncm/ncm_package_system_update_task.cpp index 5332d7e60..2684b98ac 100644 --- a/libraries/libstratosphere/source/ncm/ncm_package_system_update_task.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_package_system_update_task.cpp @@ -19,14 +19,14 @@ namespace ams::ncm { PackageSystemUpdateTask::~PackageSystemUpdateTask() { if (m_context_path.GetLength() > 0) { - fs::DeleteFile(m_context_path); + R_DISCARD(fs::DeleteFile(m_context_path)); } this->Inactivate(); } void PackageSystemUpdateTask::Inactivate() { if (m_gamecard_content_meta_database_active) { - InactivateContentMetaDatabase(StorageId::GameCard); + R_DISCARD(InactivateContentMetaDatabase(StorageId::GameCard)); m_gamecard_content_meta_database_active = false; } } @@ -41,7 +41,7 @@ namespace ams::ncm { auto meta_db_guard = SCOPE_GUARD { this->Inactivate(); }; /* Open the game card content meta database. */ - OpenContentMetaDatabase(std::addressof(m_package_db), StorageId::GameCard); + R_DISCARD(OpenContentMetaDatabase(std::addressof(m_package_db), StorageId::GameCard)); ContentMetaDatabaseBuilder builder(std::addressof(m_package_db)); @@ -50,9 +50,9 @@ namespace ams::ncm { R_TRY(builder.BuildFromPackage(package_root)); /* Create a new context file. */ - fs::DeleteFile(context_path); + R_DISCARD(fs::DeleteFile(context_path)); R_TRY(FileInstallTaskData::Create(context_path, GameCardMaxContentMetaCount)); - auto context_guard = SCOPE_GUARD { fs::DeleteFile(context_path); }; + auto context_guard = SCOPE_GUARD { R_DISCARD(fs::DeleteFile(context_path)); }; /* Initialize data. */ R_TRY(m_data.Initialize(context_path)); diff --git a/libraries/libstratosphere/source/ncm/ncm_placeholder_accessor.cpp b/libraries/libstratosphere/source/ncm/ncm_placeholder_accessor.cpp index 4b392c218..b4e360204 100644 --- a/libraries/libstratosphere/source/ncm/ncm_placeholder_accessor.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_placeholder_accessor.cpp @@ -115,7 +115,7 @@ namespace ams::ncm { void PlaceHolderAccessor::Invalidate(CacheEntry *entry) { /* Flush and close the cached entry's file. */ if (entry != nullptr) { - fs::FlushFile(entry->handle); + R_DISCARD(fs::FlushFile(entry->handle)); fs::CloseFile(entry->handle); entry->id = InvalidPlaceHolderId; } diff --git a/libraries/libstratosphere/source/ncm/ncm_submission_package_install_task.cpp b/libraries/libstratosphere/source/ncm/ncm_submission_package_install_task.cpp index 6e1be6f24..a9e587e33 100644 --- a/libraries/libstratosphere/source/ncm/ncm_submission_package_install_task.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_submission_package_install_task.cpp @@ -69,7 +69,7 @@ namespace ams::ncm { R_TRY(m_impl->Initialize()); /* Initialize parent. N doesn't check the result. */ - PackageInstallTask::Initialize(impl::GetRootDirectoryPath(m_impl->GetMountName()).str, storage_id, buffer, buffer_size, ignore_ticket); + R_DISCARD(PackageInstallTask::Initialize(impl::GetRootDirectoryPath(m_impl->GetMountName()).str, storage_id, buffer, buffer_size, ignore_ticket)); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/os/impl/os_address_space_allocator.hpp b/libraries/libstratosphere/source/os/impl/os_address_space_allocator.hpp index d0a9f77d5..de7515fd9 100644 --- a/libraries/libstratosphere/source/os/impl/os_address_space_allocator.hpp +++ b/libraries/libstratosphere/source/os/impl/os_address_space_allocator.hpp @@ -33,7 +33,7 @@ namespace ams::os::impl { using AddressType = AddressType_; using SizeType = SizeType_; private: - static constexpr size_t MaxForbiddenRegions = 2; + static constexpr size_t MaxForbiddenRegions = 3; private: InternalCriticalSection m_critical_section; AddressType m_start_page; diff --git a/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_impl.os.horizon.hpp b/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_impl.os.horizon.hpp index 0e4305493..198d68d0b 100644 --- a/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_impl.os.horizon.hpp +++ b/libraries/libstratosphere/source/os/impl/os_aslr_space_manager_impl.os.horizon.hpp @@ -30,7 +30,7 @@ namespace ams::os::impl { static constexpr u64 AslrBase64Bit = 0x0008000000ul; static constexpr u64 AslrSize64Bit = 0x7FF8000000ul; - static constexpr size_t ForbiddenRegionCount = 2; + static constexpr size_t ForbiddenRegionCount = 3; private: static u64 GetAslrInfo(os::NativeHandle process_handle, svc::InfoType type) { u64 value; @@ -75,6 +75,14 @@ namespace ams::os::impl { static u64 GetAliasSpaceSize(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { return GetAslrInfo(process_handle, svc::InfoType_AliasRegionSize); } + + static u64 GetShadowStackSpaceBeginAddress(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { + return GetAslrInfo(process_handle, svc::InfoType_ShadowStackRegionAddress); + } + + static u64 GetShadowStackSpaceSize(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { + return GetAslrInfo(process_handle, svc::InfoType_ShadowStackRegionSize); + } static u64 GetAslrSpaceBeginAddress(os::NativeHandle process_handle = svc::PseudoHandle::CurrentProcess) { return GetAslrInfo(process_handle, svc::InfoType_AslrRegionAddress); @@ -87,6 +95,14 @@ namespace ams::os::impl { void InitializeForbiddenRegions(os::NativeHandle process_handle) { m_forbidden_regions[0] = { .address = GetHeapSpaceBeginAddress(process_handle), .size = GetHeapSpaceSize(process_handle) }; m_forbidden_regions[1] = { .address = GetAliasSpaceBeginAddress(process_handle), .size = GetAliasSpaceSize(process_handle) }; + /* 23.0.0+ added ShadowStack to the forbidden region list. */ + /* Unconditionally create the region, but set it's size to 0 on < 23.0.0. */ + /* This should be fine because the address space allocator discards 0 sized regions without changing the final forbidden region count. */ + if (hos::GetVersion() >= hos::Version_23_0_0) { + m_forbidden_regions[2] = { .address = GetShadowStackSpaceBeginAddress(process_handle), .size = GetShadowStackSpaceSize(process_handle) }; + } else { + m_forbidden_regions[2] = { .address = 0, .size = 0 }; + } } }; diff --git a/libraries/libstratosphere/source/os/impl/os_vamm_manager.cpp b/libraries/libstratosphere/source/os/impl/os_vamm_manager.cpp index 7bdfbb2da..ebd8fa719 100644 --- a/libraries/libstratosphere/source/os/impl/os_vamm_manager.cpp +++ b/libraries/libstratosphere/source/os/impl/os_vamm_manager.cpp @@ -107,7 +107,7 @@ namespace ams::os::impl { public: DynamicUnitHeap(uintptr_t address, size_t size, size_t unit_size) : m_start(address), m_end(address + size) { /* Allocate the start of our buffer. */ - VammManagerImpl::AllocatePhysicalMemoryImpl(m_start, PhysicalMemoryUnitSize); + R_DISCARD(VammManagerImpl::AllocatePhysicalMemoryImpl(m_start, PhysicalMemoryUnitSize)); /* Set our current limit. */ m_limit = m_start + PhysicalMemoryUnitSize; diff --git a/libraries/libstratosphere/source/osdbg/impl/osdbg_thread_info.os.horizon.hpp b/libraries/libstratosphere/source/osdbg/impl/osdbg_thread_info.os.horizon.hpp index e43fec1e1..4ab701ea3 100644 --- a/libraries/libstratosphere/source/osdbg/impl/osdbg_thread_info.os.horizon.hpp +++ b/libraries/libstratosphere/source/osdbg/impl/osdbg_thread_info.os.horizon.hpp @@ -27,12 +27,14 @@ namespace ams::osdbg::impl { using ThreadInfoImpl = ThreadInfoHorizonImpl; constexpr inline bool IsLp64(const ThreadInfo *info) { - const auto as = info->_debug_info_create_process.flags & svc::CreateProcessFlag_AddressSpaceMask; - return as == svc::CreateProcessFlag_AddressSpace64Bit || as == svc::CreateProcessFlag_AddressSpace64BitDeprecated; + const auto as = info->_debug_info_create_process.flags & svc::CreateProcessParameterFlag_AddressSpaceMask; + return as == svc::CreateProcessParameterFlag_AddressSpace64Bit39 + || as == svc::CreateProcessParameterFlag_AddressSpace64Bit36 + || as == svc::CreateProcessParameterFlag_AddressSpace64Bit42; } constexpr inline bool Is64BitArch(const ThreadInfo *info) { - return (info->_debug_info_create_process.flags & svc::CreateProcessFlag_Is64Bit); + return (info->_debug_info_create_process.flags & svc::CreateProcessParameterFlag_64Bit); } } diff --git a/libraries/libstratosphere/source/pgl/pgl_remote_event_observer.hpp b/libraries/libstratosphere/source/pgl/pgl_remote_event_observer.hpp index 96f45f6eb..b31a3fc5e 100644 --- a/libraries/libstratosphere/source/pgl/pgl_remote_event_observer.hpp +++ b/libraries/libstratosphere/source/pgl/pgl_remote_event_observer.hpp @@ -30,28 +30,28 @@ namespace ams::pgl { ::pglEventObserverClose(std::addressof(m_observer)); } - Result GetProcessEventHandle(ams::sf::OutCopyHandle out) { + Result GetShellEvent(ams::sf::OutCopyHandle out) { ::Event ev; ON_RESULT_SUCCESS { out.SetValue(ev.revent, true); }; - R_RETURN(::pglEventObserverGetProcessEvent(std::addressof(m_observer), std::addressof(ev))); + R_RETURN(::pglEventObserverGetShellEvent(std::addressof(m_observer), std::addressof(ev))); } - Result GetProcessEventInfo(ams::sf::Out out) { + Result GetShellEventInfo(ams::sf::Out out) { static_assert(sizeof(*out.GetPointer()) == sizeof(::PmProcessEventInfo)); - R_RETURN(::pglEventObserverGetProcessEventInfo(std::addressof(m_observer), reinterpret_cast<::PmProcessEventInfo *>(out.GetPointer()))); + R_RETURN(::pglEventObserverGetShellEventInfo(std::addressof(m_observer), reinterpret_cast<::PmProcessEventInfo *>(out.GetPointer()))); } - Result GetProcessEventHandle(ams::tipc::OutCopyHandle out) { + Result GetShellEvent(ams::tipc::OutCopyHandle out) { ::Event ev; ON_RESULT_SUCCESS { out.SetValue(ev.revent); }; - R_RETURN(::pglEventObserverGetProcessEvent(std::addressof(m_observer), std::addressof(ev))); + R_RETURN(::pglEventObserverGetShellEvent(std::addressof(m_observer), std::addressof(ev))); } - Result GetProcessEventInfo(ams::tipc::Out out) { + Result GetShellEventInfo(ams::tipc::Out out) { static_assert(sizeof(*out.GetPointer()) == sizeof(::PmProcessEventInfo)); - R_RETURN(::pglEventObserverGetProcessEventInfo(std::addressof(m_observer), reinterpret_cast<::PmProcessEventInfo *>(out.GetPointer()))); + R_RETURN(::pglEventObserverGetShellEventInfo(std::addressof(m_observer), reinterpret_cast<::PmProcessEventInfo *>(out.GetPointer()))); } }; static_assert(pgl::sf::IsIEventObserver); diff --git a/libraries/libstratosphere/source/pgl/pgl_shell_api.cpp b/libraries/libstratosphere/source/pgl/pgl_shell_api.cpp index 8bbd0da0b..336fcac91 100644 --- a/libraries/libstratosphere/source/pgl/pgl_shell_api.cpp +++ b/libraries/libstratosphere/source/pgl/pgl_shell_api.cpp @@ -80,22 +80,22 @@ namespace ams::pgl { R_RETURN(::pglLaunchProgramFromHost(reinterpret_cast(out), content_path, process_flags)); } - Result GetHostContentMetaInfo(pgl::ContentMetaInfo *out, const char *content_path) { - static_assert(sizeof(*out) == sizeof(::PglContentMetaInfo)); - R_RETURN(::pglGetHostContentMetaInfo(reinterpret_cast<::PglContentMetaInfo *>(out), content_path)); + Result GetHostProgramLaunchProperty(pgl::ProgramLaunchProperty *out, const char *content_path) { + static_assert(sizeof(*out) == sizeof(::PglProgramLaunchProperty)); + R_RETURN(::pglGetHostProgramLaunchProperty(reinterpret_cast<::PglProgramLaunchProperty *>(out), content_path)); } - Result GetApplicationProcessId(os::ProcessId *out) { + Result GetRunningApplicationProcessId(os::ProcessId *out) { static_assert(sizeof(*out) == sizeof(u64)); - R_RETURN(::pglGetApplicationProcessId(reinterpret_cast(out))); + R_RETURN(::pglGetRunningApplicationProcessId(reinterpret_cast(out))); } Result BoostSystemMemoryResourceLimit(u64 size) { R_RETURN(::pglBoostSystemMemoryResourceLimit(size)); } - Result IsProcessTracked(bool *out, os::ProcessId process_id) { - R_RETURN(::pglIsProcessTracked(out, static_cast(process_id))); + Result IsRunningProcess(bool *out, os::ProcessId process_id) { + R_RETURN(::pglIsRunningProcess(out, static_cast(process_id))); } Result EnableApplicationCrashReport(bool enabled) { @@ -110,13 +110,13 @@ namespace ams::pgl { R_RETURN(::pglEnableApplicationAllThreadDumpOnCrash(enabled)); } - Result TriggerApplicationSnapShotDumper(const char *arg, SnapShotDumpType dump_type) { - R_RETURN(::pglTriggerApplicationSnapShotDumper(static_cast<::PglSnapShotDumpType>(dump_type), arg)); + Result TriggerSnapShotDumper(const char *arg, SnapShotDumpType dump_type) { + R_RETURN(::pglTriggerSnapShotDumper(static_cast<::PglSnapShotDumpType>(dump_type), arg)); } - Result GetEventObserver(pgl::EventObserver *out) { + Result CreateShellEvent(pgl::EventObserver *out) { ::PglEventObserver obs; - R_TRY(::pglGetEventObserver(std::addressof(obs))); + R_TRY(::pglCreateShellEvent(std::addressof(obs))); if (hos::GetVersion() >= hos::Version_12_0_0) { auto observer_holder = MakeUniqueFromStaticExpHeap>(obs); @@ -135,6 +135,10 @@ namespace ams::pgl { R_SUCCEED(); } + + Result EnableApplicationCrashReport2(os::ProcessId process_id, bool enabled) { + R_RETURN(::pglEnableApplicationCrashReport2(static_cast(process_id), enabled)); + } #else Result Initialize() { AMS_ABORT("TODO"); @@ -159,12 +163,12 @@ namespace ams::pgl { AMS_ABORT("TODO"); } - Result GetHostContentMetaInfo(pgl::ContentMetaInfo *out, const char *content_path) { + Result GetHostProgramLaunchProperty(pgl::ProgramLaunchProperty *out, const char *content_path) { AMS_UNUSED(out, content_path); AMS_ABORT("TODO"); } - Result GetApplicationProcessId(os::ProcessId *out) { + Result GetRunningApplicationProcessId(os::ProcessId *out) { AMS_UNUSED(out); AMS_ABORT("TODO"); } @@ -174,7 +178,7 @@ namespace ams::pgl { AMS_ABORT("TODO"); } - Result IsProcessTracked(bool *out, os::ProcessId process_id) { + Result IsRunningProcess(bool *out, os::ProcessId process_id) { AMS_UNUSED(out, process_id); AMS_ABORT("TODO"); } @@ -194,15 +198,20 @@ namespace ams::pgl { AMS_ABORT("TODO"); } - Result TriggerApplicationSnapShotDumper(const char *arg, SnapShotDumpType dump_type) { + Result TriggerSnapShotDumper(const char *arg, SnapShotDumpType dump_type) { AMS_UNUSED(arg, dump_type); AMS_ABORT("TODO"); } - Result GetEventObserver(pgl::EventObserver *out) { + Result CreateShellEvent(pgl::EventObserver *out) { AMS_UNUSED(out); AMS_ABORT("TODO"); } + + Result EnableApplicationCrashReport2(os::ProcessId process_id, bool enabled) { + AMS_UNUSED(process_id, enabled); + AMS_ABORT("TODO"); + } #endif } \ No newline at end of file diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_api.cpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_api.cpp index 77c4580db..2d0a058db 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_api.cpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_api.cpp @@ -161,7 +161,7 @@ namespace ams::pgl::srv { const size_t sz = settings::fwdbg::GetSettingsItemValue(std::addressof(enable_application_extra_thread), sizeof(enable_application_extra_thread), "application_extra_thread", "enable_application_extra_thread"); if (sz == sizeof(enable_application_extra_thread) && enable_application_extra_thread != 0) { /* NOTE: Nintendo does not check that this succeeds. */ - pm::shell::BoostApplicationThreadResourceLimit(); + R_DISCARD(pm::shell::BoostApplicationThreadResourceLimit()); } } @@ -171,7 +171,7 @@ namespace ams::pgl::srv { const size_t sz = settings::fwdbg::GetSettingsItemValue(std::addressof(enable_system_extra_thread), sizeof(enable_system_extra_thread), "application_extra_thread", "enable_system_extra_thread"); if (sz == sizeof(enable_system_extra_thread) && enable_system_extra_thread != 0) { /* NOTE: Nintendo does not check that this succeeds. */ - pm::shell::BoostSystemThreadResourceLimit(); + R_DISCARD(pm::shell::BoostSystemThreadResourceLimit()); } } diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell.cpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell.cpp index 577f59560..76c5c217a 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell.cpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell.cpp @@ -85,7 +85,7 @@ namespace ams::pgl::srv { } } - util::optional GetRunningApplicationProcessId() { + util::optional GetRunningApplicationProcessIdInternal() { os::ProcessId process_id; if (R_SUCCEEDED(pm::shell::GetApplicationProcessIdForShell(std::addressof(process_id)))) { return process_id; @@ -173,7 +173,7 @@ namespace ams::pgl::srv { } void TriggerSnapShotDumper(os::ProcessId process_id) { - TriggerSnapShotDumper(process_id, GetSnapShotDumpType(), nullptr); + R_DISCARD(TriggerSnapShotDumper(process_id, GetSnapShotDumpType(), nullptr)); } s32 GetCrashReportDetailedArgument(u32 data_flags) { @@ -195,8 +195,8 @@ namespace ams::pgl::srv { void TriggerCrashReport(os::ProcessId process_id) { /* If the program that crashed is creport, we should just terminate both processes and return. */ if (process_id == g_creport_process_id) { - TerminateProcess(g_crashed_process_id); - TerminateProcess(g_creport_process_id); + R_DISCARD(TerminateProcess(g_crashed_process_id)); + R_DISCARD(TerminateProcess(g_creport_process_id)); g_crashed_process_id = os::InvalidProcessId; g_creport_process_id = os::InvalidProcessId; return; @@ -244,7 +244,7 @@ namespace ams::pgl::srv { if (data != nullptr) { TriggerSnapShotDumper(process_id); } else { - TerminateProcess(process_id); + R_DISCARD(TerminateProcess(process_id)); } } else { /* Otherwise, we want to launch creport. */ @@ -403,9 +403,9 @@ namespace ams::pgl::srv { R_RETURN(pm::shell::TerminateProcess(process_id)); } - Result GetApplicationProcessId(os::ProcessId *out) { - /* Get the application process id. */ - auto application_process_id = GetRunningApplicationProcessId(); + Result GetRunningApplicationProcessId(os::ProcessId *out) { + /* Get the running application process id. */ + auto application_process_id = GetRunningApplicationProcessIdInternal(); R_UNLESS(application_process_id, pgl::ResultApplicationNotRunning()); /* Return the id. */ @@ -418,7 +418,7 @@ namespace ams::pgl::srv { R_RETURN(pm::shell::BoostSystemMemoryResourceLimit(size)); } - bool IsProcessTracked(os::ProcessId process_id) { + bool IsRunningProcess(os::ProcessId process_id) { /* Check whether a ProcessData exists for the process. */ std::scoped_lock lk(g_process_data_mutex); return FindProcessData(process_id) != nullptr; @@ -426,7 +426,7 @@ namespace ams::pgl::srv { void EnableApplicationCrashReport(bool enabled) { /* Get the application process id. */ - auto application_process_id = GetRunningApplicationProcessId(); + auto application_process_id = GetRunningApplicationProcessIdInternal(); if (application_process_id) { /* Find the data for the application process. */ std::scoped_lock lk(g_process_data_mutex); @@ -446,7 +446,7 @@ namespace ams::pgl::srv { bool IsApplicationCrashReportEnabled() { /* Get the application process id. */ - auto application_process_id = GetRunningApplicationProcessId(); + auto application_process_id = GetRunningApplicationProcessIdInternal(); if (!application_process_id) { return false; } @@ -462,7 +462,7 @@ namespace ams::pgl::srv { void EnableApplicationAllThreadDumpOnCrash(bool enabled) { /* Get the application process id. */ - auto application_process_id = GetRunningApplicationProcessId(); + auto application_process_id = GetRunningApplicationProcessIdInternal(); if (application_process_id) { /* Find the data for the application process. */ std::scoped_lock lk(g_process_data_mutex); @@ -486,7 +486,7 @@ namespace ams::pgl::srv { } } - Result TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const char *arg) { + Result TriggerSnapShotDumper(SnapShotDumpType dump_type, const char *arg) { /* Try to get the application process id. */ os::ProcessId process_id; R_TRY(pm::shell::GetApplicationProcessIdForShell(std::addressof(process_id))); @@ -495,5 +495,21 @@ namespace ams::pgl::srv { ON_SCOPE_EXIT { g_ssd_process_id = os::InvalidProcessId; }; R_RETURN(TriggerSnapShotDumper(process_id, dump_type, arg)); } + + void EnableApplicationCrashReport2(os::ProcessId process_id, bool enabled) { + /* Find the data for the process. */ + std::scoped_lock lk(g_process_data_mutex); + ProcessData *data = FindProcessData(process_id); + /* It's okay if we aren't tracking the process. */ + if (data != nullptr) { + /* Set or clear the flag. */ + if (enabled) { + data->flags |= ProcessDataFlag_DetailedCrashReportEnabled; + } else { + data->flags &= ~ProcessDataFlag_DetailedCrashReportEnabled; + } + } + } + } diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell.hpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell.hpp index 11228d78a..b4001e4ab 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell.hpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell.hpp @@ -27,12 +27,13 @@ namespace ams::pgl::srv { Result LaunchProgram(os::ProcessId *out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags); Result TerminateProcess(os::ProcessId process_id); - Result GetApplicationProcessId(os::ProcessId *out); + Result GetRunningApplicationProcessId(os::ProcessId *out); Result BoostSystemMemoryResourceLimit(u64 size); - bool IsProcessTracked(os::ProcessId process_id); + bool IsRunningProcess(os::ProcessId process_id); void EnableApplicationCrashReport(bool enabled); bool IsApplicationCrashReportEnabled(); void EnableApplicationAllThreadDumpOnCrash(bool enabled); - Result TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const char *arg); + Result TriggerSnapShotDumper(SnapShotDumpType dump_type, const char *arg); + void EnableApplicationCrashReport2(os::ProcessId process_id, bool enabled); } diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_event_observer.cpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_event_observer.cpp index 047123d36..e60712816 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_event_observer.cpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_event_observer.cpp @@ -65,21 +65,21 @@ namespace ams::pgl::srv { m_event.Signal(); } - Result ShellEventObserverCmif::GetProcessEventHandle(ams::sf::OutCopyHandle out) { + Result ShellEventObserverCmif::GetShellEvent(ams::sf::OutCopyHandle out) { out.SetValue(this->GetEvent().GetReadableHandle(), false); R_SUCCEED(); } - Result ShellEventObserverCmif::GetProcessEventInfo(ams::sf::Out out) { + Result ShellEventObserverCmif::GetShellEventInfo(ams::sf::Out out) { R_RETURN(this->PopEventInfo(out.GetPointer())); } - Result ShellEventObserverTipc::GetProcessEventHandle(ams::tipc::OutCopyHandle out) { + Result ShellEventObserverTipc::GetShellEvent(ams::tipc::OutCopyHandle out) { out.SetValue(this->GetEvent().GetReadableHandle()); R_SUCCEED(); } - Result ShellEventObserverTipc::GetProcessEventInfo(ams::tipc::Out out) { + Result ShellEventObserverTipc::GetShellEventInfo(ams::tipc::Out out) { R_RETURN(this->PopEventInfo(out.GetPointer())); } diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_event_observer.hpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_event_observer.hpp index 8fc52d0ed..d55163af1 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_event_observer.hpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_event_observer.hpp @@ -60,15 +60,15 @@ namespace ams::pgl::srv { class ShellEventObserverCmif : public ShellEventObserverImpl { public: - Result GetProcessEventHandle(ams::sf::OutCopyHandle out); - Result GetProcessEventInfo(ams::sf::Out out); + Result GetShellEvent(ams::sf::OutCopyHandle out); + Result GetShellEventInfo(ams::sf::Out out); }; static_assert(pgl::sf::IsIEventObserver); class ShellEventObserverTipc : public ShellEventObserverImpl { public: - Result GetProcessEventHandle(ams::tipc::OutCopyHandle out); - Result GetProcessEventInfo(ams::tipc::Out out); + Result GetShellEvent(ams::tipc::OutCopyHandle out); + Result GetShellEventInfo(ams::tipc::Out out); }; static_assert(pgl::tipc::IsIEventObserver); diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp index 720ff476a..0cb14b620 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.cpp @@ -335,7 +335,7 @@ namespace ams::pgl::srv { R_RETURN(pgl::srv::LaunchProgram(out, ncm::ProgramLocation::Make(reader.GetProgramId(), ncm::StorageId::Host), pm_flags, pgl::LaunchFlags_None)); } - Result GetHostContentMetaInfo(pgl::ContentMetaInfo *out, const char *package_path) { + Result GetProgramLaunchPropertyFromHost(pgl::ProgramLaunchProperty *out, const char *package_path) { /* Read the package. */ HostPackageReader reader; R_TRY(reader.Initialize(package_path, HostPackageMountName)); @@ -343,7 +343,7 @@ namespace ams::pgl::srv { /* Read the program info. */ R_TRY(reader.ReadProgramInfo()); - /* Get the content meta info. */ + /* Get the program launch property. */ *out = { .id = reader.GetProgramId().value, .version = reader.GetProgramVersion(), diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.hpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.hpp index 263f813b7..d09755fb9 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.hpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_host_utils.hpp @@ -19,6 +19,6 @@ namespace ams::pgl::srv { Result LaunchProgramFromHost(os::ProcessId *out, const char *content_path, u32 pm_flags); - Result GetHostContentMetaInfo(pgl::ContentMetaInfo *out, const char *content_path); + Result GetProgramLaunchPropertyFromHost(pgl::ProgramLaunchProperty *out, const char *content_path); } diff --git a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp index f6c018bf0..63a53f892 100644 --- a/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp +++ b/libraries/libstratosphere/source/pgl/srv/pgl_srv_shell_interface.cpp @@ -34,21 +34,21 @@ namespace ams::pgl::srv { R_RETURN(pgl::srv::LaunchProgramFromHost(out, static_cast(content_path), pm_flags)); } - Result ShellInterfaceCommon::GetHostContentMetaInfoImpl(pgl::ContentMetaInfo *out, const void *content_path, size_t content_path_size) { + Result ShellInterfaceCommon::GetProgramLaunchPropertyFromHostImpl(pgl::ProgramLaunchProperty *out, const void *content_path, size_t content_path_size) { AMS_UNUSED(content_path_size); - R_RETURN(pgl::srv::GetHostContentMetaInfo(out, static_cast(content_path))); + R_RETURN(pgl::srv::GetProgramLaunchPropertyFromHost(out, static_cast(content_path))); } - Result ShellInterfaceCommon::GetApplicationProcessIdImpl(os::ProcessId *out) { - R_RETURN(pgl::srv::GetApplicationProcessId(out)); + Result ShellInterfaceCommon::GetRunningApplicationProcessIdImpl(os::ProcessId *out) { + R_RETURN(pgl::srv::GetRunningApplicationProcessId(out)); } Result ShellInterfaceCommon::BoostSystemMemoryResourceLimitImpl(u64 size) { R_RETURN(pgl::srv::BoostSystemMemoryResourceLimit(size)); } - Result ShellInterfaceCommon::IsProcessTrackedImpl(bool *out, os::ProcessId process_id) { - *out = pgl::srv::IsProcessTracked(process_id); + Result ShellInterfaceCommon::IsRunningProcessImpl(bool *out, os::ProcessId process_id) { + *out = pgl::srv::IsRunningProcess(process_id); R_SUCCEED(); } @@ -67,13 +67,18 @@ namespace ams::pgl::srv { R_SUCCEED(); } - Result ShellInterfaceCommon::GetProcessId(os::ProcessId *out, ncm::ProgramId program_id) { + Result ShellInterfaceCommon::GetProcessIdImpl(os::ProcessId *out, ncm::ProgramId program_id) { R_RETURN(pm::shell::GetProcessId(out, program_id)); } - Result ShellInterfaceCommon::TriggerApplicationSnapShotDumperImpl(SnapShotDumpType dump_type, const void *arg, size_t arg_size) { + Result ShellInterfaceCommon::TriggerSnapShotDumperImpl(SnapShotDumpType dump_type, const void *arg, size_t arg_size) { AMS_UNUSED(arg_size); - R_RETURN(pgl::srv::TriggerApplicationSnapShotDumper(dump_type, static_cast(arg))); + R_RETURN(pgl::srv::TriggerSnapShotDumper(dump_type, static_cast(arg))); + } + + Result ShellInterfaceCommon::EnableApplicationCrashReport2Impl(os::ProcessId process_id, bool enabled) { + pgl::srv::EnableApplicationCrashReport2(process_id, enabled); + R_SUCCEED(); } Result ShellInterfaceCmif::LaunchProgram(ams::sf::Out out, const ncm::ProgramLocation &loc, u32 pm_flags, u8 pgl_flags) { @@ -88,20 +93,20 @@ namespace ams::pgl::srv { R_RETURN(this->LaunchProgramFromHostImpl(out.GetPointer(), content_path.GetPointer(), content_path.GetSize(), pm_flags)); } - Result ShellInterfaceCmif::GetHostContentMetaInfo(ams::sf::Out out, const ams::sf::InBuffer &content_path) { - R_RETURN(this->GetHostContentMetaInfoImpl(out.GetPointer(), content_path.GetPointer(), content_path.GetSize())); + Result ShellInterfaceCmif::GetProgramLaunchPropertyFromHost(ams::sf::Out out, const ams::sf::InBuffer &content_path) { + R_RETURN(this->GetProgramLaunchPropertyFromHostImpl(out.GetPointer(), content_path.GetPointer(), content_path.GetSize())); } - Result ShellInterfaceCmif::GetApplicationProcessId(ams::sf::Out out) { - R_RETURN(this->GetApplicationProcessIdImpl(out.GetPointer())); + Result ShellInterfaceCmif::GetRunningApplicationProcessId(ams::sf::Out out) { + R_RETURN(this->GetRunningApplicationProcessIdImpl(out.GetPointer())); } Result ShellInterfaceCmif::BoostSystemMemoryResourceLimit(u64 size) { R_RETURN(this->BoostSystemMemoryResourceLimitImpl(size)); } - Result ShellInterfaceCmif::IsProcessTracked(ams::sf::Out out, os::ProcessId process_id) { - R_RETURN(this->IsProcessTrackedImpl(out.GetPointer(), process_id)); + Result ShellInterfaceCmif::IsRunningProcess(ams::sf::Out out, os::ProcessId process_id) { + R_RETURN(this->IsRunningProcessImpl(out.GetPointer(), process_id)); } Result ShellInterfaceCmif::EnableApplicationCrashReport(bool enabled) { @@ -116,15 +121,11 @@ namespace ams::pgl::srv { R_RETURN(this->EnableApplicationAllThreadDumpOnCrashImpl(enabled)); } - Result ShellInterfaceCmif::TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const ams::sf::InBuffer &arg) { - R_RETURN(this->TriggerApplicationSnapShotDumperImpl(dump_type, arg.GetPointer(), arg.GetSize())); + Result ShellInterfaceCmif::TriggerSnapShotDumper(SnapShotDumpType dump_type, const ams::sf::InBuffer &arg) { + R_RETURN(this->TriggerSnapShotDumperImpl(dump_type, arg.GetPointer(), arg.GetSize())); } - Result ShellInterfaceCmif::GetProcessId(ams::sf::Out out, ncm::ProgramId program_id) { - R_RETURN(ShellInterfaceCommon::GetProcessId(out.GetPointer(), program_id)); - } - - Result ShellInterfaceCmif::GetShellEventObserver(ams::sf::Out> out) { + Result ShellInterfaceCmif::CreateShellEvent(ams::sf::Out> out) { /* Allocate a new interface. */ auto session = ObjectFactory::CreateSharedEmplaced(m_allocator); R_UNLESS(session != nullptr, pgl::ResultOutOfMemory()); @@ -150,20 +151,20 @@ namespace ams::pgl::srv { R_RETURN(this->LaunchProgramFromHostImpl(out.GetPointer(), content_path.GetPointer(), content_path.GetSize(), pm_flags)); } - Result ShellInterfaceTipc::GetHostContentMetaInfo(ams::tipc::Out out, const ams::tipc::InBuffer content_path) { - R_RETURN(this->GetHostContentMetaInfoImpl(out.GetPointer(), content_path.GetPointer(), content_path.GetSize())); + Result ShellInterfaceTipc::GetProgramLaunchPropertyFromHost(ams::tipc::Out out, const ams::tipc::InBuffer content_path) { + R_RETURN(this->GetProgramLaunchPropertyFromHostImpl(out.GetPointer(), content_path.GetPointer(), content_path.GetSize())); } - Result ShellInterfaceTipc::GetApplicationProcessId(ams::tipc::Out out) { - R_RETURN(this->GetApplicationProcessIdImpl(out.GetPointer())); + Result ShellInterfaceTipc::GetRunningApplicationProcessId(ams::tipc::Out out) { + R_RETURN(this->GetRunningApplicationProcessIdImpl(out.GetPointer())); } Result ShellInterfaceTipc::BoostSystemMemoryResourceLimit(u64 size) { R_RETURN(this->BoostSystemMemoryResourceLimitImpl(size)); } - Result ShellInterfaceTipc::IsProcessTracked(ams::tipc::Out out, os::ProcessId process_id) { - R_RETURN(this->IsProcessTrackedImpl(out.GetPointer(), process_id)); + Result ShellInterfaceTipc::IsRunningProcess(ams::tipc::Out out, os::ProcessId process_id) { + R_RETURN(this->IsRunningProcessImpl(out.GetPointer(), process_id)); } Result ShellInterfaceTipc::EnableApplicationCrashReport(bool enabled) { @@ -179,11 +180,14 @@ namespace ams::pgl::srv { } Result ShellInterfaceTipc::GetProcessId(ams::tipc::Out out, ncm::ProgramId program_id) { - R_RETURN(ShellInterfaceCommon::GetProcessId(out.GetPointer(), program_id)); + R_RETURN(this->GetProcessIdImpl(out.GetPointer(), program_id)); } - Result ShellInterfaceTipc::GetShellEventObserver(ams::tipc::OutMoveHandle out) { + Result ShellInterfaceTipc::CreateShellEvent(ams::tipc::OutMoveHandle out) { R_RETURN(pgl::srv::AllocateShellEventObserverForTipc(out.GetPointer())); } - + + Result ShellInterfaceTipc::EnableApplicationCrashReport2(os::ProcessId process_id, bool enabled) { + R_RETURN(this->EnableApplicationCrashReport2Impl(process_id, enabled)); + } } diff --git a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_board_driver_api.cpp b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_board_driver_api.cpp index e687f9bbc..5212724cc 100644 --- a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_board_driver_api.cpp +++ b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_board_driver_api.cpp @@ -17,7 +17,6 @@ #include "pinmux_pad_index.hpp" #include "pinmux_board_driver_api.hpp" #include "pinmux_platform_pads.hpp" -#include "pinmux_build_config.hpp" namespace ams::pinmux::driver::board::nintendo::nx { @@ -101,30 +100,33 @@ namespace ams::pinmux::driver::board::nintendo::nx { UpdateSinglePinmuxPad({ PinmuxPadIndex_Sdmmc2Dat7, 0x2000, 0x2000 }); } - #if defined(AMS_PINMUX_CONFIG_RIGHT_RAIL_AS_UART) - UpdateSinglePinmuxPad({ - .index = PinmuxPadIndex_Uart2Tx, - .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Output, - .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, - }); - UpdateSinglePinmuxPad({ - .index = PinmuxPadIndex_Uart2Cts, - .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Input, - .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, - }); - #endif - #if defined(AMS_PINMUX_CONFIG_LEFT_RAIL_AS_UART) - UpdateSinglePinmuxPad({ - .index = PinmuxPadIndex_Uart3Tx, - .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Output, - .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, - }); - UpdateSinglePinmuxPad({ - .index = PinmuxPadIndex_Uart3Cts, - .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Input, - .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, - }); - #endif + auto [log_port, log_baud_rate] = spl::GetLogConfiguration(); + AMS_UNUSED(log_baud_rate); + + if (log_port == 1) { + UpdateSinglePinmuxPad({ + .index = PinmuxPadIndex_Uart2Tx, + .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Output, + .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, + }); + UpdateSinglePinmuxPad({ + .index = PinmuxPadIndex_Uart2Cts, + .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Input, + .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, + }); + } + if (log_port == 2) { + UpdateSinglePinmuxPad({ + .index = PinmuxPadIndex_Uart3Tx, + .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Output, + .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, + }); + UpdateSinglePinmuxPad({ + .index = PinmuxPadIndex_Uart3Cts, + .option = (u32)PinmuxPadPm_Pm0 | PinmuxOpt_NoPupd | PinmuxOpt_Input, + .option_mask = (u32)PinmuxOptBitMask_Pm | PinmuxOptBitMask_Pupd | PinmuxOptBitMask_Dir, + }); + } } void SetInitialDrivePadConfig() { diff --git a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_build_config.hpp b/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_build_config.hpp deleted file mode 100644 index 530af4325..000000000 --- a/libraries/libstratosphere/source/pinmux/driver/board/nintendo/nx/pinmux_build_config.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#pragma once -#include - -// #define AMS_PINMUX_CONFIG_RIGHT_RAIL_AS_UART -// #define AMS_PINMUX_CONFIG_LEFT_RAIL_AS_UART \ No newline at end of file diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_battery_driver.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_battery_driver.cpp index 2b4330080..f72a3bad9 100644 --- a/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_battery_driver.cpp +++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_battery_driver.cpp @@ -38,7 +38,7 @@ namespace ams::powctl::impl::board::nintendo::nx { BatteryDevice::BatteryDevice(bool ev) : m_use_event_handler(ev), m_event_handler() { if (m_use_event_handler) { /* Create the system event. */ - os::CreateSystemEvent(std::addressof(m_system_event), os::EventClearMode_ManualClear, true); + R_DISCARD(os::CreateSystemEvent(std::addressof(m_system_event), os::EventClearMode_ManualClear, true)); /* Create the handler. */ m_event_handler.emplace(this); diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_charger_driver.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_charger_driver.cpp index 0cf1a6209..2995772b6 100644 --- a/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_charger_driver.cpp +++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_charger_driver.cpp @@ -36,7 +36,7 @@ namespace ams::powctl::impl::board::nintendo::nx { ChargerDevice::ChargerDevice(bool ev) : m_gpio_pad_session(), m_watchdog_timer_enabled(false), m_watchdog_timer_timeout(0), m_use_event_handler(ev), m_event_handler() { if (m_use_event_handler) { /* Create the system event. */ - os::CreateSystemEvent(std::addressof(m_system_event), os::EventClearMode_ManualClear, true); + R_DISCARD(os::CreateSystemEvent(std::addressof(m_system_event), os::EventClearMode_ManualClear, true)); /* Create the handler. */ m_event_handler.emplace(this); diff --git a/libraries/libstratosphere/source/pwm/driver/board/nintendo/nx/impl/pwm_pwm_driver_impl.cpp b/libraries/libstratosphere/source/pwm/driver/board/nintendo/nx/impl/pwm_pwm_driver_impl.cpp index cc4049e1e..956116890 100644 --- a/libraries/libstratosphere/source/pwm/driver/board/nintendo/nx/impl/pwm_pwm_driver_impl.cpp +++ b/libraries/libstratosphere/source/pwm/driver/board/nintendo/nx/impl/pwm_pwm_driver_impl.cpp @@ -51,8 +51,8 @@ namespace ams::pwm::driver::board::nintendo::nx::impl { void PwmDriverImpl::PowerOff() { /* Disable clock and hold pwm in reset. */ /* NOTE: Nintendo does not check this succeeds. */ - pcv::SetClockEnabled(pcv::Module_Pwm, false); - pcv::SetReset(pcv::Module_Pwm, true); + R_DISCARD(pcv::SetClockEnabled(pcv::Module_Pwm, false)); + R_DISCARD(pcv::SetReset(pcv::Module_Pwm, true)); /* Finalize pcv driver. */ pcv::Finalize(); @@ -78,9 +78,9 @@ namespace ams::pwm::driver::board::nintendo::nx::impl { /* Configure initial settings. */ /* NOTE: None of these results are checked. */ - this->SetEnabled(device, false); - this->SetScale(device, 0.0); - this->SetPeriod(device, DefaultChannelPeriod); + R_DISCARD(this->SetEnabled(device, false)); + R_DISCARD(this->SetScale(device, 0.0)); + R_DISCARD(this->SetPeriod(device, DefaultChannelPeriod)); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/scs/scs_shell.cpp b/libraries/libstratosphere/source/scs/scs_shell.cpp index 841b36e41..9a1cd336b 100644 --- a/libraries/libstratosphere/source/scs/scs_shell.cpp +++ b/libraries/libstratosphere/source/scs/scs_shell.cpp @@ -279,11 +279,11 @@ namespace ams::scs { void EventHandlerThread(void *) { /* Get event observer. */ pgl::EventObserver observer; - R_ABORT_UNLESS(pgl::GetEventObserver(std::addressof(observer))); + R_ABORT_UNLESS(pgl::CreateShellEvent(std::addressof(observer))); /* Get the observer's event. */ os::SystemEventType shell_event; - R_ABORT_UNLESS(observer.GetSystemEvent(std::addressof(shell_event))); + R_ABORT_UNLESS(observer.GetShellEvent(std::addressof(shell_event))); /* Loop handling events. */ while (true) { @@ -294,7 +294,7 @@ namespace ams::scs { while (true) { /* Get the next event info. */ pm::ProcessEventInfo event_info; - if (R_FAILED(observer.GetProcessEventInfo(std::addressof(event_info)))) { + if (R_FAILED(observer.GetShellEventInfo(std::addressof(event_info)))) { break; } @@ -344,7 +344,7 @@ namespace ams::scs { void FlushProgramArgument(ncm::ProgramId program_id) { /* Ensure there are no arguments for the program. */ - ldr::SetProgramArgument(program_id, "", 1); + R_DISCARD(ldr::SetProgramArgument(program_id, "", 1)); } } @@ -382,7 +382,7 @@ namespace ams::scs { Result LaunchProgram(os::ProcessId *out, const ncm::ProgramLocation &loc, const void *args, size_t args_size, u32 process_flags) { /* Set up the arguments. */ - PrepareToLaunchProgram(loc.program_id, args, args_size); + R_DISCARD(PrepareToLaunchProgram(loc.program_id, args, args_size)); /* Ensure arguments are managed correctly. */ ON_SCOPE_EXIT { FlushProgramArgument(loc.program_id); }; diff --git a/libraries/libstratosphere/source/settings/impl/settings_key_value_store.cpp b/libraries/libstratosphere/source/settings/impl/settings_key_value_store.cpp index d15e42c19..e49211e7d 100644 --- a/libraries/libstratosphere/source/settings/impl/settings_key_value_store.cpp +++ b/libraries/libstratosphere/source/settings/impl/settings_key_value_store.cpp @@ -1167,7 +1167,7 @@ namespace ams::settings::impl { map_value.current_value_size = prev_value_size; map_value.current_value = prev_value; - SaveKeyValueStoreMap(*map); + R_DISCARD(SaveKeyValueStoreMap(*map)); }; /* Attempt to save the key value store map. */ @@ -1239,7 +1239,7 @@ namespace ams::settings::impl { std::swap(map_value.current_value_size, value_size); std::swap(map_value.current_value, value_buffer); - SaveKeyValueStoreMap(*map); + R_DISCARD(SaveKeyValueStoreMap(*map)); }; /* Attempt to save the key value store map. */ diff --git a/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_session_manager.cpp b/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_session_manager.cpp index 692ed092b..b8bf1ee19 100644 --- a/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_session_manager.cpp +++ b/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_session_manager.cpp @@ -60,7 +60,16 @@ namespace ams::sf::hipc { PreProcessCommandBufferForMitm(ctx, m_pointer_buffer, reinterpret_cast(message_buffer)); /* Dispatch forwards. */ - R_TRY(svc::SendSyncRequest(util::GetReference(m_forward_service)->session)); + { + ON_SCOPE_EXIT { + const auto saved_request = hipcParseRequest(const_cast(m_saved_message.GetPointer())); + for (u32 i = 0; i < saved_request.meta.num_copy_handles; i++) { + os::CloseNativeHandle(saved_request.data.copy_handles[i]); + } + }; + + R_TRY(svc::SendSyncRequest(util::GetReference(m_forward_service)->session)); + } /* Parse, to ensure we catch any copy handles and close them. */ { diff --git a/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp b/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp index c5c450b1b..820050397 100644 --- a/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp +++ b/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp @@ -14,7 +14,7 @@ * along with this program. If not, see . */ #include -#include "spl_ctr_drbg.hpp" +#include #include "spl_device_address_mapper.hpp" #include "spl_key_slot_cache.hpp" @@ -29,7 +29,7 @@ namespace ams::spl::impl { namespace { /* Drbg type. */ - using Drbg = CtrDrbg; + using Drbg = crypto::impl::CtrDrbg; /* Convenient defines. */ #if defined(ATMOSPHERE_OS_HORIZON) @@ -178,7 +178,7 @@ namespace ams::spl::impl { } ~ScopedAesKeySlot() { if (m_allocated) { - DeallocateAesKeySlot(m_slot_index); + R_DISCARD(DeallocateAesKeySlot(m_slot_index)); } } @@ -226,7 +226,7 @@ namespace ams::spl::impl { void InitializeAsyncOperation() { #if defined(ATMOSPHERE_OS_HORIZON) u64 interrupt_number; - impl::GetConfig(std::addressof(interrupt_number), ConfigItem::SecurityEngineInterruptNumber); + R_DISCARD(impl::GetConfig(std::addressof(interrupt_number), ConfigItem::SecurityEngineInterruptNumber)); g_interrupt_name = static_cast(interrupt_number); os::InitializeInterruptEvent(std::addressof(g_interrupt), g_interrupt_name, os::EventClearMode_AutoClear); diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_controller_for_debug.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_controller_for_debug.hpp index 7d51c7df2..4713e7894 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_controller_for_debug.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_controller_for_debug.hpp @@ -17,8 +17,8 @@ #include #define AMS_SPROFILE_I_PROFILE_CONTROLLER_FOR_DEBUG_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 2000, Result, Reset, (), ()) \ - AMS_SF_METHOD_INFO(C, H, 2001, Result, GetRaw, (sf::Out out_type, sf::Out out_value, sprofile::Identifier profile, sprofile::Identifier key), (out_type, out_value, profile, key)) - + AMS_SF_METHOD_INFO(C, H, 2000, Result, ClearSaveData, (), ()) \ + AMS_SF_METHOD_INFO(C, H, 2001, Result, QueryValue, (sf::Out out_type, sf::Out out_value, sprofile::HashKey profile, sprofile::HashKey key), (out_type, out_value, profile, key)) \ + AMS_SF_METHOD_INFO(C, H, 2002, Result, QueryValueArray, (sf::Out out_type, sf::Out out_count, const sf::OutBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key), (out_type, out_count, out_buffer, profile, key), hos::Version_23_0_0) AMS_SF_DEFINE_INTERFACE(ams::sprofile::srv, IProfileControllerForDebug, AMS_SPROFILE_I_PROFILE_CONTROLLER_FOR_DEBUG_INTERFACE_INFO, 0xA8C14F64) diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_importer.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_importer.hpp index 8d0c2b32b..5c07e9b81 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_importer.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_importer.hpp @@ -18,8 +18,8 @@ #include "sprofile_srv_types.hpp" #define AMS_SPROFILE_I_PROFILE_IMPORTER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, ImportProfile, (const sprofile::srv::ProfileDataForImportData &import), (import)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, Commit, (), ()) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, ImportMetadata, (const sprofile::srv::ProfileMetadataForImportMetadata &import), (import)) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, ImportProfile, (const sprofile::srv::ProfilePayload &import), (import)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, Commit, (), (), hos::Version_13_0_0, hos::Version_22_5_0) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, ImportMetadata, (const sprofile::srv::MetadataPayload &import), (import), hos::Version_13_0_0, hos::Version_22_5_0) AMS_SF_DEFINE_INTERFACE(ams::sprofile::srv, IProfileImporter, AMS_SPROFILE_I_PROFILE_IMPORTER_INTERFACE_INFO, 0x1629C4E6) diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_reader.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_reader.hpp index e9a48faae..699c99a63 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_reader.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_reader.hpp @@ -17,10 +17,18 @@ #include #define AMS_SPROFILE_I_PROFILE_READER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, GetSigned64, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetUnsigned64, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, GetSigned32, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, GetUnsigned32, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, GetByte, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) + AMS_SF_METHOD_INFO(C, H, 0, Result, GetInt64Value, (sf::Out out, sprofile::HashKey profile, sprofile::HashKey key), (out, profile, key)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetUInt64Value, (sf::Out out, sprofile::HashKey profile, sprofile::HashKey key), (out, profile, key)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, GetInt32Value, (sf::Out out, sprofile::HashKey profile, sprofile::HashKey key), (out, profile, key)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, GetUInt32Value, (sf::Out out, sprofile::HashKey profile, sprofile::HashKey key), (out, profile, key)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, GetBooleanValue, (sf::Out out, sprofile::HashKey profile, sprofile::HashKey key), (out, profile, key)) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, GetAnyValue, (sf::Out out, sprofile::HashKey profile, sprofile::HashKey key), (out, profile, key), hos::Version_23_0_0) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, GetInt8ValueArray, (sf::Out out, const sf::OutBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key), (out, out_buffer, profile, key), hos::Version_23_0_0) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, GetInt64ValueArray, (sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key), (out, out_buffer, profile, key), hos::Version_23_0_0) \ + AMS_SF_METHOD_INFO(C, H, 8, Result, GetUInt64ValueArray, (sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key), (out, out_buffer, profile, key), hos::Version_23_0_0) \ + AMS_SF_METHOD_INFO(C, H, 9, Result, GetInt32ValueArray, (sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key), (out, out_buffer, profile, key), hos::Version_23_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, GetUInt32ValueArray, (sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key), (out, out_buffer, profile, key), hos::Version_23_0_0) \ + AMS_SF_METHOD_INFO(C, H, 11, Result, GetUInt8ValueArray, (sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key), (out, out_buffer, profile, key), hos::Version_23_0_0) \ + AMS_SF_METHOD_INFO(C, H, 12, Result, GetAnyValueArray, (sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key), (out, out_buffer, profile, key), hos::Version_23_0_0) AMS_SF_DEFINE_INTERFACE(ams::sprofile::srv, IProfileReader, AMS_SPROFILE_I_PROFILE_READER_INTERFACE_INFO, 0x97090D4D) diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_update_observer.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_update_observer.hpp index ab68ad3bf..1f5b1d6fa 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_update_observer.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_update_observer.hpp @@ -17,8 +17,8 @@ #include #define AMS_SPROFILE_I_PROFILE_UPDATE_OBSERVER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, Listen, (sprofile::Identifier profile), (profile)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, Unlisten, (sprofile::Identifier profile), (profile)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, GetEventHandle, (ams::sf::OutCopyHandle out), (out)) + AMS_SF_METHOD_INFO(C, H, 0, Result, Subscribe, (sprofile::HashKey profile), (profile)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, Unsubscribe, (sprofile::HashKey profile), (profile)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, GetUpdateEventNativeHandle, (ams::sf::OutCopyHandle out), (out)) AMS_SF_DEFINE_INTERFACE(ams::sprofile::srv, IProfileUpdateObserver, AMS_SPROFILE_I_PROFILE_UPDATE_OBSERVER_INTERFACE_INFO, 0xB52A765C) diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_service_for_bg_agent.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_service_for_bg_agent.hpp index 5edce1d7d..e0f86adca 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_service_for_bg_agent.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_service_for_bg_agent.hpp @@ -17,10 +17,10 @@ #include #include "sprofile_srv_i_profile_importer.hpp" -#define AMS_SPROFILE_I_SPROFILE_SERVICE_FOR_BG_AGENT_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 100, Result, OpenProfileImporter, (sf::Out> out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 200, Result, GetImportableProfileUrls, (sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg), (out_count, out, arg)) \ - AMS_SF_METHOD_INFO(C, H, 201, Result, IsUpdateNeeded, (sf::Out out, sprofile::Identifier revision_key), (out, revision_key)) \ - AMS_SF_METHOD_INFO(C, H, 2000, Result, Reset, (), ()) +#define AMS_SPROFILE_I_SPROFILE_SERVICE_FOR_BG_AGENT_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 100, Result, OpenProfileImporter, (sf::Out> out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 200, Result, GetProfileDownloadUrlList, (sf::Out out_count, const sf::OutArray &out, const sprofile::srv::MetadataPayload &arg), (out_count, out, arg), hos::Version_13_0_0, hos::Version_22_5_0) \ + AMS_SF_METHOD_INFO(C, H, 201, Result, GetMetadataNewness, (sf::Out out, sprofile::HashKey revision_key), (out, revision_key), hos::Version_13_0_0, hos::Version_22_5_0) \ + AMS_SF_METHOD_INFO(C, H, 2000, Result, ClearSaveDataForTest, (), ()) AMS_SF_DEFINE_INTERFACE(ams::sprofile::srv, ISprofileServiceForBgAgent, AMS_SPROFILE_I_SPROFILE_SERVICE_FOR_BG_AGENT_INTERFACE_INFO, 0xCCD828EC) diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_controller_for_debug_impl.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_controller_for_debug_impl.cpp index 1bf965f21..af31ba30c 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_controller_for_debug_impl.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_controller_for_debug_impl.cpp @@ -19,12 +19,18 @@ namespace ams::sprofile::srv { - Result ProfileControllerForDebugImpl::Reset() { + Result ProfileControllerForDebugImpl::ClearSaveData() { R_RETURN(m_manager->ResetSaveData()); } - Result ProfileControllerForDebugImpl::GetRaw(sf::Out out_type, sf::Out out_value, sprofile::Identifier profile, sprofile::Identifier key) { - R_RETURN(m_manager->GetRaw(out_type.GetPointer(), out_value.GetPointer(), profile, key)); + Result ProfileControllerForDebugImpl::QueryValue(sf::Out out_type, sf::Out out_value, sprofile::HashKey profile, sprofile::HashKey key) { + R_RETURN(m_manager->QueryValue(out_type.GetPointer(), out_value.GetPointer(), profile, key)); + } + + Result ProfileControllerForDebugImpl::QueryValueArray(sf::Out out_type, sf::Out out_count, const sf::OutBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out_type, out_count, out_buffer, profile, key); + R_SUCCEED(); } } diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_controller_for_debug_impl.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_controller_for_debug_impl.hpp index edb9d9eb2..1a6bb7cd6 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_controller_for_debug_impl.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_controller_for_debug_impl.hpp @@ -27,8 +27,9 @@ namespace ams::sprofile::srv { public: ProfileControllerForDebugImpl(ProfileManager *manager) : m_manager(manager) { /* ... */ } public: - Result Reset(); - Result GetRaw(sf::Out out_type, sf::Out out_value, sprofile::Identifier profile, sprofile::Identifier key); + Result ClearSaveData(); + Result QueryValue(sf::Out out_type, sf::Out out_value, sprofile::HashKey profile, sprofile::HashKey key); + Result QueryValueArray(sf::Out out_type, sf::Out out_count, const sf::OutBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key); }; static_assert(IsIProfileControllerForDebug); diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer.hpp index 20df0fbe2..c2e5a5c00 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer.hpp @@ -22,8 +22,8 @@ namespace ams::sprofile::srv { class ProfileImporter { private: struct ImportingProfile { - Identifier identifier_0; - Identifier identifier_1; + HashKey hash_key_0; + HashKey hash_key_1; bool is_new_import; }; private: @@ -33,7 +33,7 @@ namespace ams::sprofile::srv { util::optional m_metadata; ImportingProfile m_importing_profiles[50]; util::BitFlagSet<50> m_is_profile_importable; - Identifier m_revision_key; + HashKey m_revision_key; public: ProfileImporter(const util::optional &meta) : m_committed(false), m_imported_metadata(false), m_importing_count(0), m_metadata(util::nullopt), m_is_profile_importable(), m_revision_key() { if (meta.has_value()) { @@ -41,12 +41,12 @@ namespace ams::sprofile::srv { } } public: - bool HasProfile(Identifier id0, Identifier id1) { + bool HasProfile(HashKey id0, HashKey id1) { /* Require that we have metadata. */ if (m_metadata.has_value()) { for (auto i = 0u; i < std::min(m_metadata->num_entries, util::size(m_metadata->entries)); ++i) { const auto &entry = m_metadata->entries[i]; - if (entry.identifier_0 == id0 && entry.identifier_1 == id1) { + if (entry.hash_key_0 == id0 && entry.hash_key_1 == id1) { return true; } } @@ -80,23 +80,23 @@ namespace ams::sprofile::srv { for (auto i = 0; i < m_importing_count; ++i) { const auto &import_entry = meta.entries[i]; - const bool is_new_import = !this->HasProfile(import_entry.identifier_0, import_entry.identifier_1); + const bool is_new_import = !this->HasProfile(import_entry.hash_key_0, import_entry.hash_key_1); m_importing_profiles[i] = { - .identifier_0 = import_entry.identifier_0, - .identifier_1 = import_entry.identifier_1, + .hash_key_0 = import_entry.hash_key_0, + .hash_key_1 = import_entry.hash_key_1, .is_new_import = is_new_import, }; m_is_profile_importable[i] = is_new_import; } } - bool CanImportProfile(Identifier profile) { + bool CanImportProfile(HashKey profile) { /* Require that we imported metadata. */ if (m_imported_metadata) { /* Find the specified profile. */ for (auto i = 0; i < m_importing_count; ++i) { - if (m_importing_profiles[i].identifier_0 == profile) { + if (m_importing_profiles[i].hash_key_0 == profile) { /* Require the profile be importable. */ return m_is_profile_importable[i]; } @@ -107,10 +107,10 @@ namespace ams::sprofile::srv { return false; } - void OnImportProfile(Identifier profile) { + void OnImportProfile(HashKey profile) { /* Set the profile as not importable (as it's imported). */ for (auto i = 0; i < m_importing_count; ++i) { - if (m_importing_profiles[i].identifier_0 == profile) { + if (m_importing_profiles[i].hash_key_0 == profile) { m_is_profile_importable[i] = false; break; } @@ -135,15 +135,15 @@ namespace ams::sprofile::srv { int GetImportingCount() const { return m_importing_count; } const ImportingProfile &GetImportingProfile(int i) const { return m_importing_profiles[i]; } - Identifier GetRevisionKey() const { return m_revision_key; } + HashKey GetRevisionKey() const { return m_revision_key; } Result CleanupOrphanedProfiles(auto cleanup_impl) const { /* Cleanup any orphaned profiles in our metadata. */ if (m_metadata.has_value()) { for (auto i = 0u; i < std::min(m_metadata->num_entries, util::size(m_metadata->entries)); ++i) { const auto &entry = m_metadata->entries[i]; - if (!this->IsImportingProfile(entry.identifier_0)) { - R_TRY(cleanup_impl(entry.identifier_0)); + if (!this->IsImportingProfile(entry.hash_key_0)) { + R_TRY(cleanup_impl(entry.hash_key_0)); } } } @@ -151,10 +151,10 @@ namespace ams::sprofile::srv { R_SUCCEED(); } private: - bool IsImportingProfile(Identifier profile) const { + bool IsImportingProfile(HashKey profile) const { /* Check if we're importing the desired profile. */ for (auto i = 0; i < m_importing_count; ++i) { - if (m_importing_profiles[i].identifier_0 == profile) { + if (m_importing_profiles[i].hash_key_0 == profile) { return true; } } diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.cpp index 7e64a3a48..0b49dbd2f 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.cpp @@ -19,7 +19,7 @@ namespace ams::sprofile::srv { - Result ProfileImporterImpl::ImportProfile(const sprofile::srv::ProfileDataForImportData &import) { + Result ProfileImporterImpl::ImportProfile(const sprofile::srv::ProfilePayload &import) { R_RETURN(m_manager->ImportProfile(import)); } @@ -27,7 +27,7 @@ namespace ams::sprofile::srv { R_RETURN(m_manager->Commit()); } - Result ProfileImporterImpl::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import) { + Result ProfileImporterImpl::ImportMetadata(const sprofile::srv::MetadataPayload &import) { R_RETURN(m_manager->ImportMetadata(import)); } diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.hpp index fce94f2b0..0f7e0d41f 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.hpp @@ -31,9 +31,9 @@ namespace ams::sprofile::srv { m_manager->CloseProfileImporter(); } public: - Result ImportProfile(const sprofile::srv::ProfileDataForImportData &import); + Result ImportProfile(const sprofile::srv::ProfilePayload &import); Result Commit(); - Result ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import); + Result ImportMetadata(const sprofile::srv::MetadataPayload &import); }; static_assert(IsIProfileImporter); diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.cpp index 0167371ba..cdd2036f6 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.cpp @@ -54,15 +54,15 @@ namespace ams::sprofile::srv { CreateMetadataPathImpl(dst, dst_size, mount, TemporaryDirectoryName); } - void CreateProfilePathImpl(char *dst, size_t dst_size, const char *mount, const char *dir, const Identifier &id) { + void CreateProfilePathImpl(char *dst, size_t dst_size, const char *mount, const char *dir, const HashKey &id) { SafePrint(dst, dst_size, "%s:/%s/profiles/%02x%02x%02x%02x%02x%02x%02x", mount, dir, id.data[0], id.data[1], id.data[2], id.data[3], id.data[4], id.data[5], id.data[6]); } - void CreatePrimaryProfilePath(char *dst, size_t dst_size, const char *mount, const Identifier &id) { + void CreatePrimaryProfilePath(char *dst, size_t dst_size, const char *mount, const HashKey &id) { CreateProfilePathImpl(dst, dst_size, mount, PrimaryDirectoryName, id); } - void CreateTemporaryProfilePath(char *dst, size_t dst_size, const char *mount, const Identifier &id) { + void CreateTemporaryProfilePath(char *dst, size_t dst_size, const char *mount, const HashKey &id) { CreateProfilePathImpl(dst, dst_size, mount, TemporaryDirectoryName, id); } @@ -148,7 +148,7 @@ namespace ams::sprofile::srv { R_UNLESS(!m_profile_importer.has_value(), sprofile::ResultInvalidState()); /* Try to load profile metadata. NOTE: result is not checked, it is okay if this fails. */ - this->LoadPrimaryMetadataImpl(); + R_DISCARD(this->LoadPrimaryMetadataImpl()); /* Create importer. */ m_profile_importer.emplace(m_profile_metadata); @@ -185,7 +185,12 @@ namespace ams::sprofile::srv { this->CloseProfileImporterImpl(); } - Result ProfileManager::ImportProfile(const sprofile::srv::ProfileDataForImportData &import) { + Result ProfileManager::ImportProfile(const sprofile::srv::ProfilePayload &import) { + /* On 23.0.0+ profile importing is no longer supported. */ + if (hos::GetVersion() >= hos::Version_23_0_0) { + R_THROW(sprofile::ResultNotImplemented()); + } + /* Acquire locks. */ std::scoped_lock lk1(m_profile_importer_mutex); std::scoped_lock lk2(m_fs_mutex); @@ -211,21 +216,21 @@ namespace ams::sprofile::srv { } /* Succeed if we already have the profile. */ - R_SUCCEED_IF(m_profile_importer->HasProfile(import.header.identifier_0, import.header.identifier_1)); + R_SUCCEED_IF(m_profile_importer->HasProfile(import.header.hash_key_0, import.header.hash_key_1)); /* Check that we're importing the profile. */ - R_UNLESS(m_profile_importer->CanImportProfile(import.header.identifier_0), sprofile::ResultInvalidState()); + R_UNLESS(m_profile_importer->CanImportProfile(import.header.hash_key_0), sprofile::ResultInvalidState()); /* Create temporary directories. */ R_TRY(this->EnsureTemporaryDirectories()); /* Create profile. */ char path[0x30]; - CreateTemporaryProfilePath(path, sizeof(path), m_save_data_info.mount_name, import.header.identifier_0); + CreateTemporaryProfilePath(path, sizeof(path), m_save_data_info.mount_name, import.header.hash_key_0); R_TRY(WriteFile(path, std::addressof(import.data), sizeof(import.data))); /* Set profile imported. */ - m_profile_importer->OnImportProfile(import.header.identifier_0); + m_profile_importer->OnImportProfile(import.header.hash_key_0); R_SUCCEED(); } @@ -266,7 +271,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ProfileManager::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import) { + Result ProfileManager::ImportMetadata(const sprofile::srv::MetadataPayload &import) { /* Acquire locks. */ std::scoped_lock lk1(m_profile_importer_mutex); std::scoped_lock lk2(m_fs_mutex); @@ -340,7 +345,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ProfileManager::LoadProfile(Identifier profile) { + Result ProfileManager::LoadProfile(HashKey profile) { /* Check if we already have the profile. */ if (m_service_profile.has_value()) { R_SUCCEED_IF(m_service_profile->name == profile); @@ -362,7 +367,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ProfileManager::GetDataEntry(ProfileDataEntry *out, Identifier profile, Identifier key) { + Result ProfileManager::GetDataEntry(ProfileDataEntry *out, HashKey profile, HashKey key) { /* Acquire locks. */ std::scoped_lock lk1(m_service_profile_mutex); std::scoped_lock lk2(m_general_mutex); @@ -381,7 +386,7 @@ namespace ams::sprofile::srv { R_THROW(sprofile::ResultKeyNotFound()); } - Result ProfileManager::GetSigned64(s64 *out, Identifier profile, Identifier key) { + Result ProfileManager::GetInt64Value(s64 *out, HashKey profile, HashKey key) { /* Get the data entry. */ ProfileDataEntry entry; R_TRY(this->GetDataEntry(std::addressof(entry), profile, key)); @@ -394,7 +399,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ProfileManager::GetUnsigned64(u64 *out, Identifier profile, Identifier key) { + Result ProfileManager::GetUInt64Value(u64 *out, HashKey profile, HashKey key) { /* Get the data entry. */ ProfileDataEntry entry; R_TRY(this->GetDataEntry(std::addressof(entry), profile, key)); @@ -407,7 +412,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ProfileManager::GetSigned32(s32 *out, Identifier profile, Identifier key) { + Result ProfileManager::GetInt32Value(s32 *out, HashKey profile, HashKey key) { /* Get the data entry. */ ProfileDataEntry entry; R_TRY(this->GetDataEntry(std::addressof(entry), profile, key)); @@ -420,7 +425,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ProfileManager::GetUnsigned32(u32 *out, Identifier profile, Identifier key) { + Result ProfileManager::GetUInt32Value(u32 *out, HashKey profile, HashKey key) { /* Get the data entry. */ ProfileDataEntry entry; R_TRY(this->GetDataEntry(std::addressof(entry), profile, key)); @@ -433,7 +438,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ProfileManager::GetByte(u8 *out, Identifier profile, Identifier key) { + Result ProfileManager::GetBooleanValue(u8 *out, HashKey profile, HashKey key) { /* Get the data entry. */ ProfileDataEntry entry; R_TRY(this->GetDataEntry(std::addressof(entry), profile, key)); @@ -446,7 +451,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ProfileManager::GetRaw(u8 *out_type, u64 *out_value, Identifier profile, Identifier key) { + Result ProfileManager::QueryValue(u8 *out_type, u64 *out_value, HashKey profile, HashKey key) { /* Get the data entry. */ ProfileDataEntry entry; R_TRY(this->GetDataEntry(std::addressof(entry), profile, key)); @@ -477,8 +482,8 @@ namespace ams::sprofile::srv { const auto &profile = m_profile_importer->GetImportingProfile(i); if (profile.is_new_import) { - CreateTemporaryProfilePath(tmp_path, sizeof(tmp_path), m_save_data_info.mount_name, profile.identifier_0); - CreatePrimaryProfilePath(pri_path, sizeof(pri_path), m_save_data_info.mount_name, profile.identifier_0); + CreateTemporaryProfilePath(tmp_path, sizeof(tmp_path), m_save_data_info.mount_name, profile.hash_key_0); + CreatePrimaryProfilePath(pri_path, sizeof(pri_path), m_save_data_info.mount_name, profile.hash_key_0); R_TRY(MoveFile(tmp_path, pri_path)); } } @@ -494,7 +499,7 @@ namespace ams::sprofile::srv { char pri_path[0x30]; /* Cleanup the profiles. */ - R_RETURN(m_profile_importer->CleanupOrphanedProfiles([&](Identifier profile) ALWAYS_INLINE_LAMBDA -> Result { + R_RETURN(m_profile_importer->CleanupOrphanedProfiles([&](HashKey profile) ALWAYS_INLINE_LAMBDA -> Result { CreatePrimaryProfilePath(pri_path, sizeof(pri_path), m_save_data_info.mount_name, profile); R_RETURN(DeleteFile(pri_path)); })); @@ -506,7 +511,7 @@ namespace ams::sprofile::srv { /* If we need to, invalidate the loaded service profile. */ if (m_service_profile.has_value()) { for (auto i = 0; i < m_profile_importer->GetImportingCount(); ++i) { - if (m_service_profile->name == m_profile_importer->GetImportingProfile(i).identifier_0) { + if (m_service_profile->name == m_profile_importer->GetImportingProfile(i).hash_key_0) { m_service_profile = util::nullopt; break; } @@ -521,7 +526,7 @@ namespace ams::sprofile::srv { const auto &profile = m_profile_importer->GetImportingProfile(i); if (profile.is_new_import) { - m_update_observer_manager.OnUpdate(profile.identifier_0); + m_update_observer_manager.OnUpdate(profile.hash_key_0); } } diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.hpp index 40484b998..6154a73fd 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.hpp @@ -52,19 +52,19 @@ namespace ams::sprofile::srv { Result OpenProfileImporter(); void CloseProfileImporter(); - Result ImportProfile(const sprofile::srv::ProfileDataForImportData &data); + Result ImportProfile(const sprofile::srv::ProfilePayload &data); Result Commit(); - Result ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &data); + Result ImportMetadata(const sprofile::srv::MetadataPayload &data); Result LoadPrimaryMetadata(ProfileMetadata *out); - Result GetSigned64(s64 *out, Identifier profile, Identifier key); - Result GetUnsigned64(u64 *out, Identifier profile, Identifier key); - Result GetSigned32(s32 *out, Identifier profile, Identifier key); - Result GetUnsigned32(u32 *out, Identifier profile, Identifier key); - Result GetByte(u8 *out, Identifier profile, Identifier key); + Result GetInt64Value(s64 *out, HashKey profile, HashKey key); + Result GetUInt64Value(u64 *out, HashKey profile, HashKey key); + Result GetInt32Value(s32 *out, HashKey profile, HashKey key); + Result GetUInt32Value(u32 *out, HashKey profile, HashKey key); + Result GetBooleanValue(u8 *out, HashKey profile, HashKey key); - Result GetRaw(u8 *out_type, u64 *out_value, Identifier profile, Identifier key); + Result QueryValue(u8 *out_type, u64 *out_value, HashKey profile, HashKey key); ProfileUpdateObserverManager &GetUpdateObserverManager() { return m_update_observer_manager; } private: @@ -76,9 +76,9 @@ namespace ams::sprofile::srv { void OnCommitted(); - Result GetDataEntry(ProfileDataEntry *out, Identifier profile, Identifier key); + Result GetDataEntry(ProfileDataEntry *out, HashKey profile, HashKey key); - Result LoadProfile(Identifier profile); + Result LoadProfile(HashKey profile); Result EnsurePrimaryDirectories(); Result EnsureTemporaryDirectories(); diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_reader_impl.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_reader_impl.cpp index b601764af..d2a981bd4 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_reader_impl.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_reader_impl.cpp @@ -19,24 +19,72 @@ namespace ams::sprofile::srv { - Result ProfileReaderImpl::GetSigned64(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key) { - R_RETURN(m_manager->GetSigned64(out.GetPointer(), profile, key)); + Result ProfileReaderImpl::GetInt64Value(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key) { + R_RETURN(m_manager->GetInt64Value(out.GetPointer(), profile, key)); } - Result ProfileReaderImpl::GetUnsigned64(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key) { - R_RETURN(m_manager->GetUnsigned64(out.GetPointer(), profile, key)); + Result ProfileReaderImpl::GetUInt64Value(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key) { + R_RETURN(m_manager->GetUInt64Value(out.GetPointer(), profile, key)); } - Result ProfileReaderImpl::GetSigned32(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key) { - R_RETURN(m_manager->GetSigned32(out.GetPointer(), profile, key)); + Result ProfileReaderImpl::GetInt32Value(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key) { + R_RETURN(m_manager->GetInt32Value(out.GetPointer(), profile, key)); } - Result ProfileReaderImpl::GetUnsigned32(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key) { - R_RETURN(m_manager->GetUnsigned32(out.GetPointer(), profile, key)); + Result ProfileReaderImpl::GetUInt32Value(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key) { + R_RETURN(m_manager->GetUInt32Value(out.GetPointer(), profile, key)); } - Result ProfileReaderImpl::GetByte(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key) { - R_RETURN(m_manager->GetByte(out.GetPointer(), profile, key)); + Result ProfileReaderImpl::GetBooleanValue(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key) { + R_RETURN(m_manager->GetBooleanValue(out.GetPointer(), profile, key)); + } + + Result ProfileReaderImpl::GetAnyValue(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out, profile, key); + R_SUCCEED(); + } + + Result ProfileReaderImpl::GetInt8ValueArray(sf::Out out, const sf::OutBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out, out_buffer, profile, key); + R_SUCCEED(); + } + + Result ProfileReaderImpl::GetInt64ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out, out_buffer, profile, key); + R_SUCCEED(); + } + + Result ProfileReaderImpl::GetUInt64ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out, out_buffer, profile, key); + R_SUCCEED(); + } + + Result ProfileReaderImpl::GetInt32ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out, out_buffer, profile, key); + R_SUCCEED(); + } + + Result ProfileReaderImpl::GetUInt32ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out, out_buffer, profile, key); + R_SUCCEED(); + } + + Result ProfileReaderImpl::GetUInt8ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out, out_buffer, profile, key); + R_SUCCEED(); + } + + Result ProfileReaderImpl::GetAnyValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key) { + /* On 23.0.0+ this isn't reachable from HIPC. */ + AMS_UNUSED(out, out_buffer, profile, key); + R_SUCCEED(); } } diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_reader_impl.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_reader_impl.hpp index 4768538e4..2f193cd80 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_reader_impl.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_reader_impl.hpp @@ -27,11 +27,19 @@ namespace ams::sprofile::srv { public: ProfileReaderImpl(ProfileManager *manager) : m_manager(manager) { /* ... */ } public: - Result GetSigned64(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key); - Result GetUnsigned64(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key); - Result GetSigned32(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key); - Result GetUnsigned32(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key); - Result GetByte(sf::Out out, sprofile::Identifier profile, sprofile::Identifier key); + Result GetInt64Value(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key); + Result GetUInt64Value(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key); + Result GetInt32Value(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key); + Result GetUInt32Value(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key); + Result GetBooleanValue(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key); + Result GetAnyValue(sf::Out out, sprofile::HashKey profile, sprofile::HashKey key); + Result GetInt8ValueArray(sf::Out out, const sf::OutBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key); + Result GetInt64ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key); + Result GetUInt64ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key); + Result GetInt32ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key); + Result GetUInt32ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key); + Result GetUInt8ValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key); + Result GetAnyValueArray(sf::Out out, const sf::OutPointerBuffer &out_buffer, sprofile::HashKey profile, sprofile::HashKey key); }; static_assert(IsIProfileReader); diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_update_observer_impl.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_update_observer_impl.hpp index f54d230d4..b7c8dbee7 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_update_observer_impl.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_update_observer_impl.hpp @@ -24,7 +24,7 @@ namespace ams::sprofile::srv { static constexpr auto MaxProfiles = 4; private: os::SystemEvent m_event; - Identifier m_profiles[MaxProfiles]; + HashKey m_profiles[MaxProfiles]; int m_profile_count; os::SdkMutex m_mutex; public: @@ -34,7 +34,7 @@ namespace ams::sprofile::srv { os::SystemEvent &GetEvent() { return m_event; } const os::SystemEvent &GetEvent() const { return m_event; } public: - Result Listen(Identifier profile) { + Result Subscribe(HashKey profile) { /* Lock ourselves. */ std::scoped_lock lk(m_mutex); @@ -51,7 +51,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result Unlisten(Identifier profile) { + Result Unsubscribe(HashKey profile) { /* Check that we're listening. */ for (auto i = 0; i < m_profile_count; ++i) { if (m_profiles[i] == profile) { @@ -64,12 +64,12 @@ namespace ams::sprofile::srv { R_THROW(sprofile::ResultNotListening()); } - Result GetEventHandle(sf::OutCopyHandle out) { + Result GetUpdateEventNativeHandle(sf::OutCopyHandle out) { out.SetValue(m_event.GetReadableHandle(), false); R_SUCCEED(); } public: - void OnUpdate(Identifier profile) { + void OnUpdate(HashKey profile) { for (auto i = 0; i < m_profile_count; ++i) { if (m_profiles[i] == profile) { m_event.Signal(); @@ -93,7 +93,7 @@ namespace ams::sprofile::srv { Result OpenObserver(sf::Out> &out, MemoryResource *memory_resource); void CloseObserver(ProfileUpdateObserverImpl *observer); - void OnUpdate(Identifier profile) { + void OnUpdate(HashKey profile) { std::scoped_lock lk(m_mutex); for (auto i = 0; i < m_observer_count; ++i) { diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.cpp index c8e4e5036..43f3ed9af 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.cpp @@ -34,7 +34,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ServiceForBgAgent::GetImportableProfileUrls(sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg) { + Result ServiceForBgAgent::GetProfileDownloadUrlList(sf::Out out_count, const sf::OutArray &out, const sprofile::srv::MetadataPayload &arg) { /* Check size. */ R_UNLESS(out.GetSize() >= arg.metadata.num_entries, sprofile::ResultInvalidArgument()); @@ -57,7 +57,7 @@ namespace ams::sprofile::srv { for (u32 j = 0; j < primary_metadata.num_entries; ++j) { const auto &pri_entry = primary_metadata.entries[j]; - if (pri_entry.identifier_0 == arg_entry.identifier_0 && pri_entry.identifier_1 == arg_entry.identifier_1) { + if (pri_entry.hash_key_0 == arg_entry.hash_key_0 && pri_entry.hash_key_1 == arg_entry.hash_key_1) { have_entry = true; break; } @@ -75,7 +75,7 @@ namespace ams::sprofile::srv { } - Result ServiceForBgAgent::IsUpdateNeeded(sf::Out out, Identifier revision_key) { + Result ServiceForBgAgent::GetMetadataNewness(sf::Out out, HashKey revision_key) { /* Load primary metadata. */ bool loaded_metadata = true; sprofile::srv::ProfileMetadata primary_metadata; @@ -91,7 +91,7 @@ namespace ams::sprofile::srv { R_SUCCEED(); } - Result ServiceForBgAgent::Reset() { + Result ServiceForBgAgent::ClearSaveDataForTest() { R_RETURN(m_profile_manager->ResetSaveData()); } diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.hpp index 43d308966..66416fd1a 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.hpp @@ -29,9 +29,9 @@ namespace ams::sprofile::srv { constexpr ServiceForBgAgent(MemoryResource *mr, ProfileManager *pm) : m_memory_resource(mr), m_profile_manager(pm) { /* ... */ } public: Result OpenProfileImporter(sf::Out> out); - Result GetImportableProfileUrls(sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg); - Result IsUpdateNeeded(sf::Out out, Identifier revision_key); - Result Reset(); + Result GetProfileDownloadUrlList(sf::Out out_count, const sf::OutArray &out, const sprofile::srv::MetadataPayload &arg); + Result GetMetadataNewness(sf::Out out, HashKey revision_key); + Result ClearSaveDataForTest(); }; static_assert(sprofile::srv::IsISprofileServiceForBgAgent); diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_types.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_types.hpp index d20610a17..ddddaa26e 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_types.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_types.hpp @@ -33,7 +33,7 @@ namespace ams::sprofile::srv { }; struct ProfileDataEntry { - Identifier key; + HashKey key; ValueType type; union { s64 value_s64; @@ -65,7 +65,7 @@ namespace ams::sprofile::srv { static_assert(AMS_OFFSETOF(ProfileData, entries) == 0x30); struct ServiceProfile { - Identifier name; + HashKey name; ProfileData data; }; static_assert(util::is_pod::value); @@ -74,10 +74,10 @@ namespace ams::sprofile::srv { static_assert(AMS_OFFSETOF(ServiceProfile, name) == 0x00); static_assert(AMS_OFFSETOF(ServiceProfile, data) == 0x08); - struct ProfileDataForImportData : public sf::LargeData, public sf::PrefersMapAliasTransferMode { + struct ProfilePayload : public sf::LargeData, public sf::PrefersMapAliasTransferMode { struct { - Identifier identifier_0; - Identifier identifier_1; + HashKey hash_key_0; + HashKey hash_key_1; u8 unk_0E[2]; u32 version; u8 unk_14[0x1C]; @@ -86,25 +86,25 @@ namespace ams::sprofile::srv { ProfileData data; u8 unk_4040[0x4400 - 0x4040]; }; - static_assert(util::is_pod::value); - static_assert(sizeof(ProfileDataForImportData) == 0x4400); + static_assert(util::is_pod::value); + static_assert(sizeof(ProfilePayload) == 0x4400); - static_assert(AMS_OFFSETOF(ProfileDataForImportData, header) == 0x00); - static_assert(AMS_OFFSETOF(ProfileDataForImportData, hash) == 0x30); - static_assert(AMS_OFFSETOF(ProfileDataForImportData, data) == 0x40); - static_assert(AMS_OFFSETOF(ProfileDataForImportData, unk_4040) == 0x4040); + static_assert(AMS_OFFSETOF(ProfilePayload, header) == 0x00); + static_assert(AMS_OFFSETOF(ProfilePayload, hash) == 0x30); + static_assert(AMS_OFFSETOF(ProfilePayload, data) == 0x40); + static_assert(AMS_OFFSETOF(ProfilePayload, unk_4040) == 0x4040); struct ProfileMetadataEntry { - Identifier identifier_0; - Identifier identifier_1; + HashKey hash_key_0; + HashKey hash_key_1; u8 unk_0E[0x32]; }; static_assert(util::is_pod::value); static_assert(sizeof(ProfileMetadataEntry) == 0x40); - static_assert(AMS_OFFSETOF(ProfileMetadataEntry, identifier_0) == 0x00); - static_assert(AMS_OFFSETOF(ProfileMetadataEntry, identifier_1) == 0x07); - static_assert(AMS_OFFSETOF(ProfileMetadataEntry, unk_0E) == 0x0E); + static_assert(AMS_OFFSETOF(ProfileMetadataEntry, hash_key_0) == 0x00); + static_assert(AMS_OFFSETOF(ProfileMetadataEntry, hash_key_1) == 0x07); + static_assert(AMS_OFFSETOF(ProfileMetadataEntry, unk_0E) == 0x0E); struct ProfileUrl : public sf::PrefersMapAliasTransferMode { char url[0x100]; @@ -115,7 +115,7 @@ namespace ams::sprofile::srv { struct ProfileMetadata { u32 num_entries; u32 unk_04; - Identifier revision_key; + HashKey revision_key; u8 unk_0F[0x1]; u8 unk_10[0x30]; ProfileMetadataEntry entries[50]; @@ -130,7 +130,7 @@ namespace ams::sprofile::srv { static_assert(AMS_OFFSETOF(ProfileMetadata, unk_10) == 0x10); static_assert(AMS_OFFSETOF(ProfileMetadata, entries) == 0x40); - struct ProfileMetadataForImportMetadata : public sf::LargeData, public sf::PrefersMapAliasTransferMode { + struct MetadataPayload : public sf::LargeData, public sf::PrefersMapAliasTransferMode { struct { u32 version; u8 unk_04[0x1C]; @@ -140,13 +140,13 @@ namespace ams::sprofile::srv { ProfileUrl profile_urls[50]; u8 unk_3EF0[0x8000 - 0x3EF0]; }; - static_assert(util::is_pod::value); - static_assert(sizeof(ProfileMetadataForImportMetadata) == 0x8000); + static_assert(util::is_pod::value); + static_assert(sizeof(MetadataPayload) == 0x8000); - static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, header) == 0x00); - static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, hash) == 0x20); - static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, metadata) == 0x30); - static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, profile_urls) == 0xCF0); - static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, unk_3EF0) == 0x3EF0); + static_assert(AMS_OFFSETOF(MetadataPayload, header) == 0x00); + static_assert(AMS_OFFSETOF(MetadataPayload, hash) == 0x20); + static_assert(AMS_OFFSETOF(MetadataPayload, metadata) == 0x30); + static_assert(AMS_OFFSETOF(MetadataPayload, profile_urls) == 0xCF0); + static_assert(AMS_OFFSETOF(MetadataPayload, unk_3EF0) == 0x3EF0); } diff --git a/libraries/libstratosphere/source/usb/usb_device.cpp b/libraries/libstratosphere/source/usb/usb_device.cpp index 15a01d111..491bed2b3 100644 --- a/libraries/libstratosphere/source/usb/usb_device.cpp +++ b/libraries/libstratosphere/source/usb/usb_device.cpp @@ -254,7 +254,7 @@ namespace ams::usb { R_TRY(m_client->AddInterface(this, std::addressof(m_interface), m_interface_num)); /* Ensure we cleanup if we fail after this. */ - auto intf_guard = SCOPE_GUARD { m_client->DeleteInterface(m_interface_num); m_interface = nullptr; }; + auto intf_guard = SCOPE_GUARD { R_DISCARD(m_client->DeleteInterface(m_interface_num)); m_interface = nullptr; }; /* Get events. */ sf::NativeHandle setup_event_handle; @@ -313,7 +313,7 @@ namespace ams::usb { os::DestroySystemEvent(std::addressof(m_ctrl_out_completion_event)); /* Delete ourselves from our cleint. */ - m_client->DeleteInterface(m_interface_num); + R_DISCARD(m_client->DeleteInterface(m_interface_num)); /* Destroy our service. */ m_interface = nullptr; @@ -643,7 +643,7 @@ namespace ams::usb { m_address = bEndpointAddress; /* Ensure we clean up if we fail after this. */ - auto ep_guard = SCOPE_GUARD { m_interface->DeleteEndpoint(m_address); m_endpoint = nullptr; }; + auto ep_guard = SCOPE_GUARD { R_DISCARD(m_interface->DeleteEndpoint(m_address)); m_endpoint = nullptr; }; /* Get completion event. */ sf::NativeHandle event_handle; @@ -672,7 +672,7 @@ namespace ams::usb { R_UNLESS(m_is_initialized, usb::ResultNotInitialized()); /* Cancel any pending transactions. */ - m_endpoint->Cancel(); + R_DISCARD(m_endpoint->Cancel()); /* Wait for us to be at one reference count. */ while (m_reference_count > 1) { diff --git a/libraries/libstratosphere/source/util/util_compression_lz4.cpp b/libraries/libstratosphere/source/util/util_compression_lz4.cpp index f56904f71..97f3f6034 100644 --- a/libraries/libstratosphere/source/util/util_compression_lz4.cpp +++ b/libraries/libstratosphere/source/util/util_compression_lz4.cpp @@ -35,5 +35,157 @@ namespace ams::util { /* This is just a thin wrapper around LZ4. */ return LZ4_decompress_safe(reinterpret_cast(src), reinterpret_cast(dst), static_cast(src_size), static_cast(dst_size)); } - + + /* TODO: This was added for ro in 23.0.0+, but it's unclear if this is even part of the util namespace. */ + /* It's similar to the official lz4frame code, but has additional constraints and uses static work buffers. */ + /* Evaluate if we should use lz4frame instead and implement matching frame compression. */ + int DecompressLZ4Frame(size_t* out_size, void *dst, size_t dst_size, const void *src, size_t src_size, void *src_work, size_t src_work_size, void *dst_work, size_t dst_work_size) { + const u8 *src_buffer = reinterpret_cast(src); + u8 *dst_buffer = reinterpret_cast(dst); + + /* Destination buffer must be behind source buffer. */ + if (dst_buffer > src_buffer) { + std::memset(dst_buffer, 0, dst_size); + return -1; + } + + const u8 *src_buffer_start = src_buffer; + const u8 *src_buffer_end = src_buffer + src_size; + const u8 *dst_buffer_start = dst_buffer; + const u8 *dst_buffer_end = dst_buffer + dst_size; + + /* Size checks. */ + if ((src_buffer_end != dst_buffer_end) || (src_work_size != 0x10000) || (dst_work_size != 0x10000)) { + std::memset(dst_buffer, 0, dst_size); + return -1; + } + + /* Source size must at least include one frame header. */ + if (src_size < 7) { + std::memset(dst_buffer, 0, dst_size); + return -2; + } + + const u32 magic = *reinterpret_cast(src_buffer); + const u8 flg = src_buffer[4]; + const u8 bd = src_buffer[5]; + const u8 header_checksum = src_buffer[6]; + + /* Check for LZ4F_MAGICNUMBER, validate flags and block size. */ + if ((magic != 0x184D2204) || ((flg & 1) != 0) || (flg != 0x60) || (bd != 0x40)) { + std::memset(dst_buffer, 0, dst_size); + return -2; + } + + /* TODO: Implement header checksum validation. This requires xxhash, do we want to have xxhash in util? */ + AMS_UNUSED(header_checksum); + + /* Skip the frame header. */ + src_buffer += 7; + + /* Destination is too small. */ + if (src_buffer >= dst_buffer_end) { + std::memset(dst_buffer, 0, dst_size); + return -2; + } + + while (true) { + /* Not enough space left. */ + if ((dst_buffer_end - src_buffer) < 4) { + std::memset(dst_buffer, 0, dst_size); + return -4; + } + + const u32 block_header = *reinterpret_cast(src_buffer); + + /* Advance the block. */ + src_buffer += sizeof(block_header); + + /* We've reached the end. */ + if (!block_header) { + break; + } + + const u32 block_size = block_header & 0x7FFFFFFF; + + /* Block size is invalid. */ + if (block_size > 0x10000) { + std::memset(dst_buffer, 0, dst_size); + return -3; + } + + /* Block size is invalid. */ + if ((dst_buffer_end - src_buffer) < block_size) { + std::memset(dst_buffer, 0, dst_size); + return -4; + } + + /* Copy the data block to the source work buffer. */ + std::memcpy(static_cast(src_work), src_buffer, block_size); + + if ((block_header & 0x80000000) != 0) { + /* Block size is invalid. */ + if ((dst_buffer_end - dst_buffer) < block_size) { + std::memset(dst_buffer, 0, dst_size); + return -4; + } + + /* Destination is overrunning source. */ + if ((dst_buffer + block_size) > (src_buffer + block_size)) { + std::memset(dst_buffer, 0, dst_size); + return -5; + } + + /* This is a raw block, copy it. */ + std::memmove(dst_buffer, src_buffer, block_size); + + /* Advance buffers. */ + dst_buffer += block_size; + src_buffer += block_size; + } else { + /* This is a compressed block, decompress it. */ + int decompressed_size = LZ4_decompress_safe(reinterpret_cast(src_work), reinterpret_cast(dst_work), static_cast(block_size), 0x10000); + + /* Decompressed size is invalid. */ + if (decompressed_size < 1) { + std::memset(dst_buffer, 0, dst_size); + return -3; + } + + /* Decompressed size is invalid. */ + if (static_cast(dst_buffer_end - dst_buffer) < static_cast(decompressed_size)) { + std::memset(dst_buffer, 0, dst_size); + return -4; + } + + /* Destination is overrunning source. */ + if ((dst_buffer + decompressed_size) > (src_buffer + block_size)) { + std::memset(dst_buffer, 0, dst_size); + return -5; + } + + /* Copy the decompressed data back. */ + std::memcpy(dst_buffer, static_cast(dst_work), decompressed_size); + + /* Advance buffers. */ + dst_buffer += decompressed_size; + src_buffer += block_size; + } + + /* We've exceeded the destination's size. */ + if (src_buffer >= dst_buffer_end) { + std::memset(dst_buffer, 0, dst_size); + return -2; + } + } + + /* We didn't consume all data. */ + if (static_cast(src_buffer - src_buffer_start) != src_size) { + std::memset(dst_buffer, 0, dst_size); + return -2; + } + + *out_size = dst_buffer - dst_buffer_start; + return 0; + } } \ No newline at end of file diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 264737f0d..2fd987485 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -16,11 +16,11 @@ #pragma once #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 -#define ATMOSPHERE_RELEASE_VERSION_MINOR 11 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 2 +#define ATMOSPHERE_RELEASE_VERSION_MINOR 12 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 0 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 22 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 5 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 23 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 6791a99ca..109405664 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -101,8 +101,9 @@ #define ATMOSPHERE_TARGET_FIRMWARE_22_0_0 ATMOSPHERE_TARGET_FIRMWARE(22, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_22_1_0 ATMOSPHERE_TARGET_FIRMWARE(22, 1, 0) #define ATMOSPHERE_TARGET_FIRMWARE_22_5_0 ATMOSPHERE_TARGET_FIRMWARE(22, 5, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_23_0_0 ATMOSPHERE_TARGET_FIRMWARE(23, 0, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_22_5_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_23_0_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -196,6 +197,7 @@ namespace ams { TargetFirmware_22_0_0 = ATMOSPHERE_TARGET_FIRMWARE_22_0_0, TargetFirmware_22_1_0 = ATMOSPHERE_TARGET_FIRMWARE_22_1_0, TargetFirmware_22_5_0 = ATMOSPHERE_TARGET_FIRMWARE_22_5_0, + TargetFirmware_23_0_0 = ATMOSPHERE_TARGET_FIRMWARE_23_0_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, diff --git a/libraries/libvapours/include/vapours/crypto/impl/crypto_aes_impl.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_aes_impl.hpp index 066687771..42e72d7d6 100644 --- a/libraries/libvapours/include/vapours/crypto/impl/crypto_aes_impl.hpp +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_aes_impl.hpp @@ -33,7 +33,7 @@ namespace ams::crypto::impl { #ifdef ATMOSPHERE_IS_EXOSPHERE int m_slot; #endif - #ifdef ATMOSPHERE_IS_STRATOSPHERE + #if defined(ATMOSPHERE_IS_STRATOSPHERE) || defined(ATMOSPHERE_IS_MESOSPHERE) u32 m_round_keys[RoundKeySize / sizeof(u32)]; #endif public: @@ -43,7 +43,7 @@ namespace ams::crypto::impl { void EncryptBlock(void *dst, size_t dst_size, const void *src, size_t src_size) const; void DecryptBlock(void *dst, size_t dst_size, const void *src, size_t src_size) const; - #ifdef ATMOSPHERE_IS_STRATOSPHERE + #if defined(ATMOSPHERE_IS_STRATOSPHERE) || defined(ATMOSPHERE_IS_MESOSPHERE) const u8 *GetRoundKey() const { return reinterpret_cast(m_round_keys); } diff --git a/libraries/libstratosphere/source/spl/impl/spl_ctr_drbg.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_ctr_drbg.hpp similarity index 99% rename from libraries/libstratosphere/source/spl/impl/spl_ctr_drbg.hpp rename to libraries/libvapours/include/vapours/crypto/impl/crypto_ctr_drbg.hpp index b615f02c1..6454fae02 100644 --- a/libraries/libstratosphere/source/spl/impl/spl_ctr_drbg.hpp +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_ctr_drbg.hpp @@ -14,9 +14,9 @@ * along with this program. If not, see . */ #pragma once -#include +#include -namespace ams::spl::impl { +namespace ams::crypto::impl { constexpr inline int BitsPerByte = BITSIZEOF(u8); diff --git a/libraries/libvapours/include/vapours/results/ro_results.hpp b/libraries/libvapours/include/vapours/results/ro_results.hpp index c187749dc..e3ad6b53f 100644 --- a/libraries/libvapours/include/vapours/results/ro_results.hpp +++ b/libraries/libvapours/include/vapours/results/ro_results.hpp @@ -25,18 +25,20 @@ namespace ams::ro { R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 2); R_DEFINE_ERROR_RESULT(AlreadyLoaded, 3); R_DEFINE_ERROR_RESULT(InvalidNro, 4); - + R_DEFINE_ERROR_RESULT(NotFound, 5); R_DEFINE_ERROR_RESULT(InvalidNrr, 6); R_DEFINE_ERROR_RESULT(TooManyNro, 7); R_DEFINE_ERROR_RESULT(TooManyNrr, 8); R_DEFINE_ERROR_RESULT(NotAuthorized, 9); R_DEFINE_ERROR_RESULT(InvalidNrrKind, 10); - + R_DEFINE_ERROR_RESULT(InvalidBssSize, 11); + + R_DEFINE_ERROR_RESULT(NotImplemented, 1022); R_DEFINE_ERROR_RESULT(InternalError, 1023); R_DEFINE_ERROR_RESULT(InvalidAddress, 1025); R_DEFINE_ERROR_RESULT(InvalidSize, 1026); - + R_DEFINE_ERROR_RESULT(InvalidCurrentMemory, 1027); R_DEFINE_ERROR_RESULT(NotLoaded, 1028); R_DEFINE_ERROR_RESULT(NotRegistered, 1029); R_DEFINE_ERROR_RESULT(InvalidSession, 1030); diff --git a/libraries/libvapours/include/vapours/results/sprofile_results.hpp b/libraries/libvapours/include/vapours/results/sprofile_results.hpp index 4000bd8f1..78168028e 100644 --- a/libraries/libvapours/include/vapours/results/sprofile_results.hpp +++ b/libraries/libvapours/include/vapours/results/sprofile_results.hpp @@ -21,20 +21,23 @@ R_DEFINE_NAMESPACE_RESULT_MODULE(ams::sprofile, 246); namespace ams::sprofile { - R_DEFINE_ERROR_RESULT(InvalidArgument, 100); - R_DEFINE_ERROR_RESULT(InvalidState, 101); + R_DEFINE_ERROR_RESULT(InvalidArgument, 100); + R_DEFINE_ERROR_RESULT(InvalidState, 101); + + R_DEFINE_ERROR_RESULT(NotImplemented, 300); + R_DEFINE_ERROR_RESULT(NotSupported, 301); + R_DEFINE_ERROR_RESULT(Delayed, 302); + R_DEFINE_ERROR_RESULT(NotPermitted, 303); - R_DEFINE_ERROR_RESULT(NotPermitted, 303); + R_DEFINE_ERROR_RESULT(AllocationFailed, 401); - R_DEFINE_ERROR_RESULT(AllocationFailed, 401); + R_DEFINE_ERROR_RESULT(KeyNotFound, 600); + R_DEFINE_ERROR_RESULT(InvalidDataType, 601); - R_DEFINE_ERROR_RESULT(KeyNotFound, 600); - R_DEFINE_ERROR_RESULT(InvalidDataType, 601); - - R_DEFINE_ERROR_RESULT(MaxListeners, 620); - R_DEFINE_ERROR_RESULT(AlreadyListening, 621); - R_DEFINE_ERROR_RESULT(NotListening, 622); - R_DEFINE_ERROR_RESULT(MaxObservers, 623); + R_DEFINE_ERROR_RESULT(MaxListeners, 620); + R_DEFINE_ERROR_RESULT(AlreadyListening, 621); + R_DEFINE_ERROR_RESULT(NotListening, 622); + R_DEFINE_ERROR_RESULT(MaxObservers, 623); R_DEFINE_ERROR_RESULT(InvalidMetadataVersion, 3210); R_DEFINE_ERROR_RESULT(InvalidMetadataHash, 3211); diff --git a/libraries/libvapours/include/vapours/svc/svc_memory_map.hpp b/libraries/libvapours/include/vapours/svc/svc_memory_map.hpp index 08bf1773b..55bb5ec36 100644 --- a/libraries/libvapours/include/vapours/svc/svc_memory_map.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_memory_map.hpp @@ -37,6 +37,13 @@ namespace ams::svc { constexpr inline size_t AddressMemoryRegion39Size = 512_GB; + constexpr inline size_t AddressMemoryRegionSmall42Size = 64_GB; + constexpr inline size_t AddressMemoryRegionAlias42Size = 512_GB; + constexpr inline size_t AddressMemoryRegionStack42Size = 2_GB; + + constexpr inline size_t AddressMemoryRegion42Size = 4096_GB; + + constexpr inline size_t AddressShadowStackRegionSize = 4_GB; #elif defined(ATMOSPHERE_ARCH_ARM) constexpr inline size_t AddressMemoryRegionSmall32Size = 512_MB; @@ -56,6 +63,12 @@ namespace ams::svc { constexpr inline size_t AddressMemoryRegion39Size = 0; + constexpr inline size_t AddressMemoryRegionSmall42Size = 0; + constexpr inline size_t AddressMemoryRegionAlias42Size = 0; + constexpr inline size_t AddressMemoryRegionStack42Size = 0; + + constexpr inline size_t AddressMemoryRegion42Size = 0; + #else #error "Unknown architecture for svc::AddressMemoryRegion*Size" @@ -97,4 +110,7 @@ namespace ams::svc { constexpr inline uintptr_t AddressMap39End = AddressMemoryRegion39Size; constexpr inline size_t AddressMap39Size = AddressMap39End - AddressMap39Start; + constexpr inline uintptr_t AddressMap42Start = 0 + AddressNullGuard64Size; + constexpr inline uintptr_t AddressMap42End = AddressMemoryRegion42Size; + constexpr inline size_t AddressMap42Size = AddressMap42End - AddressMap42Start; } diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index 21ab685d0..52e105ed3 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -96,6 +96,8 @@ namespace ams::svc { MemoryState_CodeOut = 0x15, MemoryState_Coverage = 0x16, MemoryState_Insecure = 0x17, + /* ... */ + MemoryState_ShadowStack = 0x1A, }; enum MemoryPermission : u32 { @@ -191,8 +193,16 @@ namespace ams::svc { InfoType_IsSvcPermitted = 26, InfoType_IoRegionHint = 27, InfoType_AliasRegionExtraSize = 28, - /* ... */ + InfoType_RemoteRegionAddress = 29, + InfoType_RemoteRegionSize = 30, + InfoType_RemoteMemorySize = 31, + InfoType_RemoteMemoryUsageMax = 32, + InfoType_AllocateAlignment = 33, InfoType_TransferMemoryHint = 34, + /* ... */ + InfoType_AddressSpaceSize = 36, + InfoType_ShadowStackRegionAddress = 37, + InfoType_ShadowStackRegionSize = 38, InfoType_MesosphereMeta = 65000, InfoType_MesosphereCurrentProcess = 65001, @@ -378,6 +388,7 @@ namespace ams::svc { /* Process types. */ enum ProcessInfoType : u32 { ProcessInfoType_ProcessState = 0, + ProcessInfoType_Unknown1 = 1, }; enum ProcessState : u32 { @@ -402,57 +413,62 @@ namespace ams::svc { ProcessActivity_Paused = 1, }; - enum CreateProcessFlag : u32 { + enum CreateProcessParameterFlag : u32 { /* Is 64 bit? */ - CreateProcessFlag_Is64Bit = (1 << 0), + CreateProcessParameterFlag_64Bit = (1 << 0), /* What kind of address space? */ - CreateProcessFlag_AddressSpaceShift = 1, - CreateProcessFlag_AddressSpaceMask = (7 << CreateProcessFlag_AddressSpaceShift), - CreateProcessFlag_AddressSpace32Bit = (0 << CreateProcessFlag_AddressSpaceShift), - CreateProcessFlag_AddressSpace64BitDeprecated = (1 << CreateProcessFlag_AddressSpaceShift), - CreateProcessFlag_AddressSpace32BitWithoutAlias = (2 << CreateProcessFlag_AddressSpaceShift), - CreateProcessFlag_AddressSpace64Bit = (3 << CreateProcessFlag_AddressSpaceShift), + CreateProcessParameterFlag_AddressSpaceShift = 1, + CreateProcessParameterFlag_AddressSpaceMask = (7 << CreateProcessParameterFlag_AddressSpaceShift), /* Should be 15 but Nintendo didn't make 64K usable yet */ + CreateProcessParameterFlag_AddressSpace32Bit = (0 << CreateProcessParameterFlag_AddressSpaceShift), + CreateProcessParameterFlag_AddressSpace64Bit36 = (1 << CreateProcessParameterFlag_AddressSpaceShift), + CreateProcessParameterFlag_AddressSpace32BitNoReserved = (2 << CreateProcessParameterFlag_AddressSpaceShift), + CreateProcessParameterFlag_AddressSpace64Bit39 = (3 << CreateProcessParameterFlag_AddressSpaceShift), + CreateProcessParameterFlag_AddressSpace64Bit42 = (4 << CreateProcessParameterFlag_AddressSpaceShift), /* Should JIT debug be done on crash? */ - CreateProcessFlag_EnableDebug = (1 << 4), + CreateProcessParameterFlag_EnableJitDebug = (1 << 4), /* Should ASLR be enabled for the process? */ - CreateProcessFlag_EnableAslr = (1 << 5), + CreateProcessParameterFlag_EnableAslr = (1 << 5), /* Is the process an application? */ - CreateProcessFlag_IsApplication = (1 << 6), + CreateProcessParameterFlag_IsApplication = (1 << 6), /* 4.x deprecated: Should use secure memory? */ - CreateProcessFlag_DeprecatedUseSecureMemory = (1 << 7), + CreateProcessParameterFlag_DeprecatedUseSecureMemory = (1 << 7), /* 5.x+ Pool partition type. */ - CreateProcessFlag_PoolPartitionShift = 7, - CreateProcessFlag_PoolPartitionMask = (0xF << CreateProcessFlag_PoolPartitionShift), - CreateProcessFlag_PoolPartitionApplication = (0 << CreateProcessFlag_PoolPartitionShift), - CreateProcessFlag_PoolPartitionApplet = (1 << CreateProcessFlag_PoolPartitionShift), - CreateProcessFlag_PoolPartitionSystem = (2 << CreateProcessFlag_PoolPartitionShift), - CreateProcessFlag_PoolPartitionSystemNonSecure = (3 << CreateProcessFlag_PoolPartitionShift), + CreateProcessParameterFlag_PoolPartitionShift = 7, + CreateProcessParameterFlag_PoolPartitionMask = (0xF << CreateProcessParameterFlag_PoolPartitionShift), + CreateProcessParameterFlag_PoolPartitionApplication = (0 << CreateProcessParameterFlag_PoolPartitionShift), + CreateProcessParameterFlag_PoolPartitionApplet = (1 << CreateProcessParameterFlag_PoolPartitionShift), + CreateProcessParameterFlag_PoolPartitionSystem = (2 << CreateProcessParameterFlag_PoolPartitionShift), + CreateProcessParameterFlag_PoolPartitionSystemNonSecure = (3 << CreateProcessParameterFlag_PoolPartitionShift), /* 7.x+ Should memory allocation be optimized? This requires IsApplication. */ - CreateProcessFlag_OptimizeMemoryAllocation = (1 << 11), + CreateProcessParameterFlag_OptimizeMemoryAllocation = (1 << 11), /* 11.x+ DisableDeviceAddressSpaceMerge. */ - CreateProcessFlag_DisableDeviceAddressSpaceMerge = (1 << 12), + CreateProcessParameterFlag_DisableDeviceAddressSpaceMerge = (1 << 12), - /* 18.x EnableAliasRegionExtraSize. */ - CreateProcessFlag_EnableAliasRegionExtraSize = (1 << 13), + /* 18.x EnableAddressSanitizer. */ + CreateProcessParameterFlag_EnableAddressSanitizer = (1 << 13), + + /* 23.x EnableShadowStack. */ + CreateProcessParameterFlag_EnableShadowStack = (1 << 17), /* Mask of all flags. */ - CreateProcessFlag_All = CreateProcessFlag_Is64Bit | - CreateProcessFlag_AddressSpaceMask | - CreateProcessFlag_EnableDebug | - CreateProcessFlag_EnableAslr | - CreateProcessFlag_IsApplication | - CreateProcessFlag_PoolPartitionMask | - CreateProcessFlag_OptimizeMemoryAllocation | - CreateProcessFlag_DisableDeviceAddressSpaceMerge | - CreateProcessFlag_EnableAliasRegionExtraSize, + CreateProcessParameterFlag_All = CreateProcessParameterFlag_64Bit | + CreateProcessParameterFlag_AddressSpaceMask | + CreateProcessParameterFlag_EnableJitDebug | + CreateProcessParameterFlag_EnableAslr | + CreateProcessParameterFlag_IsApplication | + CreateProcessParameterFlag_PoolPartitionMask | + CreateProcessParameterFlag_OptimizeMemoryAllocation | + CreateProcessParameterFlag_DisableDeviceAddressSpaceMerge | + CreateProcessParameterFlag_EnableAddressSanitizer | + CreateProcessParameterFlag_EnableShadowStack, }; /* Debug types. */ @@ -470,6 +486,7 @@ namespace ams::svc { DebugThreadParam_IdealCore = 2, DebugThreadParam_CurrentCore = 3, DebugThreadParam_AffinityMask = 4, + DebugThreadParam_Unknown5 = 5, }; enum DebugException : u32 { diff --git a/libraries/libvapours/include/vapours/svc/svc_version.hpp b/libraries/libvapours/include/vapours/svc/svc_version.hpp index 500da0e21..e8c2b3ae8 100644 --- a/libraries/libvapours/include/vapours/svc/svc_version.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_version.hpp @@ -57,7 +57,7 @@ namespace ams::svc { /* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */ /* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */ - constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(22); + constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(23); constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 2); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); diff --git a/libraries/libvapours/source/crypto/impl/crypto_aes_impl.arch.arm64.cpp b/libraries/libvapours/source/crypto/impl/crypto_aes_impl.arch.arm64.cpp index 35fdf4fa2..c07a20f2e 100644 --- a/libraries/libvapours/source/crypto/impl/crypto_aes_impl.arch.arm64.cpp +++ b/libraries/libvapours/source/crypto/impl/crypto_aes_impl.arch.arm64.cpp @@ -14,13 +14,16 @@ * along with this program. If not, see . */ #include -#if defined(ATMOSPHERE_IS_STRATOSPHERE) +#if defined(ATMOSPHERE_IS_MESOSPHERE) +#include +#endif +#if defined(ATMOSPHERE_IS_STRATOSPHERE) || defined(ATMOSPHERE_IS_MESOSPHERE) #include #endif namespace ams::crypto::impl { -#if defined(ATMOSPHERE_IS_STRATOSPHERE) +#if defined(ATMOSPHERE_IS_STRATOSPHERE) || defined(ATMOSPHERE_IS_MESOSPHERE) namespace { diff --git a/libraries/libvapours/source/sdmmc/impl/sdmmc_device_detector.cpp b/libraries/libvapours/source/sdmmc/impl/sdmmc_device_detector.cpp index 48b9a25fc..7fb7210e0 100644 --- a/libraries/libvapours/source/sdmmc/impl/sdmmc_device_detector.cpp +++ b/libraries/libvapours/source/sdmmc/impl/sdmmc_device_detector.cpp @@ -61,7 +61,7 @@ namespace ams::sdmmc::impl { gpio::Initialize(); /* Open and configure the pad session. */ - gpio::OpenSession(std::addressof(m_gpio_pad_session), m_gpio_device_code); + R_DISCARD(gpio::OpenSession(std::addressof(m_gpio_pad_session), m_gpio_device_code)); gpio::SetDirection(std::addressof(m_gpio_pad_session), gpio::Direction_Input); gpio::SetDebounceTime(std::addressof(m_gpio_pad_session), m_gpio_debounce_ms); gpio::SetDebounceEnabled(std::addressof(m_gpio_pad_session), true); @@ -200,7 +200,7 @@ namespace ams::sdmmc::impl { os::InitializeEvent(std::addressof(m_detector_thread_end_event), false, os::EventClearMode_ManualClear); /* Create and start the detector thread. */ - os::CreateThread(std::addressof(m_detector_thread), DetectorThreadEntry, this, m_detector_thread_stack, sizeof(m_detector_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(sdmmc, DeviceDetector)); + R_DISCARD(os::CreateThread(std::addressof(m_detector_thread), DetectorThreadEntry, this, m_detector_thread_stack, sizeof(m_detector_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(sdmmc, DeviceDetector))); os::SetThreadNamePointer(std::addressof(m_detector_thread), AMS_GET_SYSTEM_THREAD_NAME(sdmmc, DeviceDetector)); os::StartThread(std::addressof(m_detector_thread)); } diff --git a/libraries/libvapours/source/sdmmc/impl/sdmmc_sdmmc_controller.board.nintendo_nx.cpp b/libraries/libvapours/source/sdmmc/impl/sdmmc_sdmmc_controller.board.nintendo_nx.cpp index c3d7a3766..66a9a1806 100644 --- a/libraries/libvapours/source/sdmmc/impl/sdmmc_sdmmc_controller.board.nintendo_nx.cpp +++ b/libraries/libvapours/source/sdmmc/impl/sdmmc_sdmmc_controller.board.nintendo_nx.cpp @@ -500,7 +500,7 @@ namespace ams::sdmmc::impl { this->ClearInterrupt(); R_SUCCEED(); } else if (sdmmc::ResultWaitInterruptSoftwareTimeout::Includes(result)) { - SdHostStandardController::AbortTransaction(); + R_DISCARD(SdHostStandardController::AbortTransaction()); R_THROW(sdmmc::ResultIssueTuningCommandSoftwareTimeout()); } else { R_RETURN(result); diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index 10a000c6d..e37780b7e 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -224,15 +224,20 @@ namespace ams::kern::init { static_assert(kern::arch::arm64::init::IsInitialPageAllocator); void SetupAllTtbr0Entries(KInitialPageTable &init_pt, KInitialPageAllocator &allocator) { - /* Validate that the ttbr0 array is in rodata. */ + /* Validate that the ttbr0/tcr_el1 arrays are in rodata. */ const uintptr_t rodata_start = reinterpret_cast(__rodata_start); const uintptr_t rodata_end = reinterpret_cast(__rodata_end); MESOSPHERE_INIT_ABORT_UNLESS(rodata_start < rodata_end); MESOSPHERE_INIT_ABORT_UNLESS(rodata_start <= reinterpret_cast(std::addressof(KPageTable::GetTtbr0Entry(0)))); - MESOSPHERE_INIT_ABORT_UNLESS(reinterpret_cast(std::addressof(KPageTable::GetTtbr0Entry(KPageTable::NumTtbr0Entries))) < rodata_end); + MESOSPHERE_INIT_ABORT_UNLESS(reinterpret_cast(std::addressof(KPageTable::GetTtbr0Entry(KPageTable::NumPTEntries))) < rodata_end); + MESOSPHERE_INIT_ABORT_UNLESS(rodata_start <= reinterpret_cast(std::addressof(KPageTable::GetTcrEL1Entry(0)))); + MESOSPHERE_INIT_ABORT_UNLESS(reinterpret_cast(std::addressof(KPageTable::GetTcrEL1Entry(KPageTable::NumPTEntries))) < rodata_end); + + /* Get the default tcr_el1 value, with T0SZ set for a 39-bit address space. */ + const u64 tcr_el1 = (cpu::GetTcrEl1() & ~UINT64_C(0x3F)) | (64 - 39); /* Allocate pages for all ttbr0 entries. */ - for (size_t i = 0; i < KPageTable::NumTtbr0Entries; ++i) { + for (size_t i = 0; i < KPageTable::NumPTEntries; ++i) { /* Allocate a page. */ KPhysicalAddress page = allocator.Allocate(PageSize); MESOSPHERE_INIT_ABORT_UNLESS(page != Null); @@ -245,6 +250,12 @@ namespace ams::kern::init { /* Set the entry to the newly allocated page. */ *reinterpret_cast(GetInteger(ttbr0_phys_ptr)) = (static_cast(i) << 48) | GetInteger(page); + + /* Get the physical address of the tcr_el1 entry. */ + const auto tcr_el1_phys_ptr = init_pt.GetPhysicalAddress(KVirtualAddress(std::addressof(KPageTable::GetTcrEL1Entry(i)))); + + /* Set the entry to the default tcr_el1 value. */ + *reinterpret_cast(GetInteger(tcr_el1_phys_ptr)) = tcr_el1; } } diff --git a/stratosphere/TioServer/source/tio_file_server_processor.cpp b/stratosphere/TioServer/source/tio_file_server_processor.cpp index 7a1f6e3bb..318fd2936 100644 --- a/stratosphere/TioServer/source/tio_file_server_processor.cpp +++ b/stratosphere/TioServer/source/tio_file_server_processor.cpp @@ -679,7 +679,7 @@ namespace ams::tio { /* NOTE: Nintendo does not check the output of this call. */ s64 read_count = 0; - fs::ReadDirectory(std::addressof(read_count), reinterpret_cast(body), handle, cur); + R_DISCARD(fs::ReadDirectory(std::addressof(read_count), reinterpret_cast(body), handle, cur)); /* Send the current entries. */ const ssize_t cur_size = read_count * sizeof(fs::DirectoryEntry); diff --git a/stratosphere/ams_mitm/source/amsmitm_initialization.cpp b/stratosphere/ams_mitm/source/amsmitm_initialization.cpp index e9979ce52..386048c73 100644 --- a/stratosphere/ams_mitm/source/amsmitm_initialization.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_initialization.cpp @@ -89,7 +89,7 @@ namespace ams::mitm { void CreateAutomaticBackups() { /* Create a backup directory, if one doesn't exist. */ - mitm::fs::CreateAtmosphereSdDirectory("/automatic_backups"); + R_DISCARD(mitm::fs::CreateAtmosphereSdDirectory("/automatic_backups")); /* Initialize PRODINFO and get a reference for the device. */ char device_reference[0x40] = {}; @@ -127,7 +127,7 @@ namespace ams::mitm { char bis_keys_backup_name[ams::fs::EntryNameLengthMax + 1]; GetBackupFileName(bis_keys_backup_name, sizeof(bis_keys_backup_name), device_reference, "BISKEYS.bin"); - mitm::fs::CreateAtmosphereSdFile(bis_keys_backup_name, sizeof(bis_keys), ams::fs::CreateOption_None); + R_DISCARD(mitm::fs::CreateAtmosphereSdFile(bis_keys_backup_name, sizeof(bis_keys), ams::fs::CreateOption_None)); R_ABORT_UNLESS(mitm::fs::OpenAtmosphereSdFile(std::addressof(g_bis_key_file), bis_keys_backup_name, ams::fs::OpenMode_ReadWrite)); R_ABORT_UNLESS(fsFileSetSize(std::addressof(g_bis_key_file), sizeof(bis_keys))); R_ABORT_UNLESS(fsFileWrite(std::addressof(g_bis_key_file), 0, bis_keys, sizeof(bis_keys), FsWriteOption_Flush)); @@ -153,11 +153,11 @@ namespace ams::mitm { mitm::fs::OpenGlobalSdCardFileSystem(); /* Mount the sd card at a convenient mountpoint. */ - ams::fs::MountSdCard(ams::fs::impl::SdCardFileSystemMountName); + R_DISCARD(ams::fs::MountSdCard(ams::fs::impl::SdCardFileSystemMountName)); /* Initialize the reboot manager (load a payload off the SD). */ /* Discard result, since it doesn't need to succeed. */ - mitm::bpc::LoadRebootPayload(); + R_DISCARD(mitm::bpc::LoadRebootPayload()); /* Backup Calibration Binary and BIS keys. */ CreateAutomaticBackups(); @@ -167,7 +167,7 @@ namespace ams::mitm { if (const char *emummc_file_path = emummc::GetFilePath(); emummc_file_path != nullptr) { char emummc_path[ams::fs::EntryNameLengthMax + 1]; util::SNPrintf(emummc_path, sizeof(emummc_path), "%s/eMMC", emummc_file_path); - mitm::fs::OpenSdFile(std::addressof(g_emummc_file), emummc_path, ams::fs::OpenMode_Read); + R_DISCARD(mitm::fs::OpenSdFile(std::addressof(g_emummc_file), emummc_path, ams::fs::OpenMode_Read)); } /* NOTE: due to an Atmosphere bug, NS accesses to the Nintendo dir accessed /Nintendo/Nintendo */ @@ -185,7 +185,7 @@ namespace ams::mitm { /* Ensure Contents directory exists for normal emummc. */ /* NOTE: Allowed to fail on already-exists. */ util::SNPrintf(emummc_path, sizeof(emummc_path), "%s:/%s/Contents", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); - ams::fs::CreateDirectory(emummc_path); + R_DISCARD(ams::fs::CreateDirectory(emummc_path)); /* Fix Contents/private */ util::SNPrintf(emummc_path, sizeof(emummc_path), "%s:/%s/Contents/private", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); diff --git a/stratosphere/ams_mitm/source/amsmitm_prodinfo_utils.cpp b/stratosphere/ams_mitm/source/amsmitm_prodinfo_utils.cpp index 8722877fd..1e419f8f8 100644 --- a/stratosphere/ams_mitm/source/amsmitm_prodinfo_utils.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_prodinfo_utils.cpp @@ -436,7 +436,7 @@ namespace ams::mitm { GetBackupFileName(backup_fn, sizeof(backup_fn), info); /* Create the file, in case it does not exist. */ - mitm::fs::CreateAtmosphereSdFile(backup_fn, sizeof(CalibrationInfo), ams::fs::CreateOption_None); + R_DISCARD(mitm::fs::CreateAtmosphereSdFile(backup_fn, sizeof(CalibrationInfo), ams::fs::CreateOption_None)); /* Open the file. */ FsFile libnx_file; diff --git a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_debug.cpp b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_debug.cpp index 477ac2f98..2c1672a25 100644 --- a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_debug.cpp +++ b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_debug.cpp @@ -40,10 +40,10 @@ namespace ams::mitm::socket::resolver { if (g_log_enabled) { /* Create the logs directory. */ - mitm::fs::CreateAtmosphereSdDirectory("/logs"); + R_DISCARD(mitm::fs::CreateAtmosphereSdDirectory("/logs")); /* Create the log file. */ - mitm::fs::CreateAtmosphereSdFile("/logs/dns_mitm_debug.log", 0, ams::fs::CreateOption_None); + R_DISCARD(mitm::fs::CreateAtmosphereSdFile("/logs/dns_mitm_debug.log", 0, ams::fs::CreateOption_None)); /* Open the log file. */ R_ABORT_UNLESS(mitm::fs::OpenAtmosphereSdFile(std::addressof(g_log_file), "/logs/dns_mitm_debug.log", ams::fs::OpenMode_ReadWrite | ams::fs::OpenMode_AllowAppend)); diff --git a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp index ea6f1eb09..d7364fa60 100644 --- a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp +++ b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp @@ -313,8 +313,8 @@ namespace ams::mitm::socket::resolver { /* Open log file. */ ::FsFile log_file; - mitm::fs::DeleteAtmosphereSdFile("/logs/dns_mitm_startup.log"); - mitm::fs::CreateAtmosphereSdDirectory("/logs"); + R_DISCARD(mitm::fs::DeleteAtmosphereSdFile("/logs/dns_mitm_startup.log")); + R_DISCARD(mitm::fs::CreateAtmosphereSdDirectory("/logs")); R_ABORT_UNLESS(mitm::fs::CreateAtmosphereSdFile("/logs/dns_mitm_startup.log", 0, ams::fs::CreateOption_None)); R_ABORT_UNLESS(mitm::fs::OpenAtmosphereSdFile(std::addressof(log_file), "/logs/dns_mitm_startup.log", ams::fs::OpenMode_ReadWrite | ams::fs::OpenMode_AllowAppend)); ON_SCOPE_EXIT { ::fsFileClose(std::addressof(log_file)); }; @@ -325,7 +325,7 @@ namespace ams::mitm::socket::resolver { if (!mitm::fs::HasAtmosphereSdFile("/hosts/default.txt")) { Log(log_file, "Creating /hosts/default.txt because it does not exist.\n"); - mitm::fs::CreateAtmosphereSdDirectory("/hosts"); + R_DISCARD(mitm::fs::CreateAtmosphereSdDirectory("/hosts")); R_ABORT_UNLESS(mitm::fs::CreateAtmosphereSdFile("/hosts/default.txt", sizeof(DefaultHostsFile) - 1, ams::fs::CreateOption_None)); ::FsFile default_file; diff --git a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_module.cpp b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_module.cpp index 004c3a1c4..5d185cc23 100644 --- a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_module.cpp +++ b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_module.cpp @@ -131,7 +131,7 @@ namespace ams::mitm::socket::resolver { } /* Initialize the socket allocator. */ - ams::socket::InitializeAllocatorForInternal(g_resolver_allocator_buffer, sizeof(g_resolver_allocator_buffer)); + R_DISCARD(ams::socket::InitializeAllocatorForInternal(g_resolver_allocator_buffer, sizeof(g_resolver_allocator_buffer))); /* Initialize debug. */ resolver::InitializeDebug(ShouldEnableDebugLog()); diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_mitm_service.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_mitm_service.cpp index f82a6e806..adaad71e2 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_mitm_service.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_mitm_service.cpp @@ -262,7 +262,7 @@ namespace ams::mitm::fs { constexpr const fs::Path root_path = fs::MakeConstantPath("/"); u8 savedata_copy_buffer[2_KB]; - fssystem::CopyDirectoryRecursively(dirsave_ifs.get(), save_ifs.get(), root_path, root_path, std::addressof(work_entry), savedata_copy_buffer, sizeof(savedata_copy_buffer)); + R_DISCARD(fssystem::CopyDirectoryRecursively(dirsave_ifs.get(), save_ifs.get(), root_path, root_path, std::addressof(work_entry), savedata_copy_buffer, sizeof(savedata_copy_buffer))); } /* Set output. */ diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp index 484e078ce..93f983fc1 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp @@ -36,6 +36,11 @@ namespace ams::mitm::fs { }; constexpr const ApplicationWithDynamicHeapInfo ApplicationsWithDynamicHeap[] = { + /* Danganronpa V3: Killing Harmony Anniversary Edition. */ + /* Requirement ? MB. 16 MB stolen heap fixes a crash, though. */ + /* Unknown heap sensitivity. */ + { 0x010063F014176000, 16_MB, 0_MB }, + /* Until Then. */ /* Requirement ~34 MB. */ /* No particular heap sensitivity. */ diff --git a/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp b/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp index 0915a10ab..eacadd8b4 100644 --- a/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp @@ -90,7 +90,7 @@ namespace ams::mitm::settings { } Result SetMitmService::GetLanguageCode(sf::Out out) { - this->EnsureLocale(); + R_DISCARD(this->EnsureLocale()); /* If there's no override locale, just use the actual one. */ if (AMS_UNLIKELY(!m_is_valid_language)) { @@ -109,7 +109,7 @@ namespace ams::mitm::settings { } Result SetMitmService::GetRegionCode(sf::Out out) { - this->EnsureLocale(); + R_DISCARD(this->EnsureLocale()); /* If there's no override locale, just use the actual one. */ if (AMS_UNLIKELY(!m_is_valid_region)) { diff --git a/stratosphere/boot/source/boot_check_battery.cpp b/stratosphere/boot/source/boot_check_battery.cpp index 33f2396f5..d6e3ef332 100644 --- a/stratosphere/boot/source/boot_check_battery.cpp +++ b/stratosphere/boot/source/boot_check_battery.cpp @@ -466,12 +466,21 @@ namespace ams::boot { boot::ShutdownSystem(); } } + + /* On 18.0.0+ i2c shutdown is unconditionally disabled here. */ + if (hos::GetVersion() >= hos::Version_18_0_0) { + if (R_FAILED(battery_driver.SetI2cShutdownEnabled(false))) { + boot::ShutdownSystem(); + } + } /* Get the boot reason. */ const auto boot_reason = boot::GetBootReason(); /* Initialize the charger driver. */ - if (R_FAILED(charger_driver.Initialize(boot_reason != spl::BootReason_RtcAlarm2))) + if (R_FAILED(charger_driver.Initialize(boot_reason != spl::BootReason_RtcAlarm2))) { + boot::ShutdownSystem(); + } /* Check that the charger input limit is greater than 150 milli-amps. */ { @@ -481,7 +490,7 @@ namespace ams::boot { } if (input_current_limit_ma <= 150) { - charger_driver.SetChargerConfiguration(powctl::ChargerConfiguration_ChargeDisable); + R_DISCARD(charger_driver.SetChargerConfiguration(powctl::ChargerConfiguration_ChargeDisable)); boot::ShutdownSystem(); } } diff --git a/stratosphere/boot/source/boot_display.cpp b/stratosphere/boot/source/boot_display.cpp index 52470c972..ee6fdc80a 100644 --- a/stratosphere/boot/source/boot_display.cpp +++ b/stratosphere/boot/source/boot_display.cpp @@ -262,10 +262,10 @@ namespace ams::boot { R_ABORT_UNLESS(i2c::driver::OpenSession(std::addressof(i2c_session), i2c::DeviceCode_Max77620Pmic)); if (g_soc_type == spl::SocType_Mariko) { - WriteI2cRegister(i2c_session, 0x18, 0x3A); - WriteI2cRegister(i2c_session, 0x1F, 0x71); + R_DISCARD(WriteI2cRegister(i2c_session, 0x18, 0x3A)); + R_DISCARD(WriteI2cRegister(i2c_session, 0x1F, 0x71)); } - WriteI2cRegister(i2c_session, 0x23, 0xD0); + R_DISCARD(WriteI2cRegister(i2c_session, 0x23, 0xD0)); i2c::driver::CloseSession(i2c_session); } diff --git a/stratosphere/boot/source/boot_pmic_driver.cpp b/stratosphere/boot/source/boot_pmic_driver.cpp index 893726de7..eb86a0734 100644 --- a/stratosphere/boot/source/boot_pmic_driver.cpp +++ b/stratosphere/boot/source/boot_pmic_driver.cpp @@ -74,11 +74,14 @@ namespace ams::boot { u8 on_off_1_val = 0; R_ABORT_UNLESS(ReadI2cRegister(m_i2c_session, std::addressof(on_off_1_val), sizeof(on_off_1_val), std::addressof(on_off_1_addr), sizeof(on_off_1_addr))); on_off_1_val |= 0x80; - - /* Finalize the battery on non-Calcio. */ - if (spl::GetHardwareType() != spl::HardwareType::Calcio) { - BatteryDriver battery_driver; - this->FinalizeBattery(battery_driver); + + /* 23.0.0+ no longer finalizes the battery on any hardware type. */ + if (hos::GetVersion() < hos::Version_23_0_0) { + /* Finalize the battery on non-Calcio. */ + if (spl::GetHardwareType() != spl::HardwareType::Calcio) { + BatteryDriver battery_driver; + this->FinalizeBattery(battery_driver); + } } /* Actually write the value to trigger shutdown/reset. */ @@ -116,7 +119,7 @@ namespace ams::boot { desired_shutdown_enabled &= use_desired_shutdown; if (shutdown_enabled != desired_shutdown_enabled) { - battery_driver.SetI2cShutdownEnabled(desired_shutdown_enabled); + R_DISCARD(battery_driver.SetI2cShutdownEnabled(desired_shutdown_enabled)); } } diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index fec6cbc67..6afb794c9 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -53,8 +53,8 @@ namespace ams::creport { } void TryCreateReportDirectories() { - fs::EnsureDirectory("sdmc:/atmosphere/crash_reports/dumps"); - fs::EnsureDirectory("sdmc:/atmosphere/fatal_reports/dumps"); + R_DISCARD(fs::EnsureDirectory("sdmc:/atmosphere/crash_reports/dumps")); + R_DISCARD(fs::EnsureDirectory("sdmc:/atmosphere/fatal_reports/dumps")); } constexpr const char *GetDebugExceptionString(const svc::DebugException type) { @@ -244,7 +244,7 @@ namespace ams::creport { m_result = creport::ResultUserBreak(); /* Try to parse out the user break result. */ if (hos::GetVersion() >= hos::Version_5_0_0) { - svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(m_result)), m_debug_handle, d.info.exception.specific.user_break.address, sizeof(m_result)); + R_DISCARD(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(m_result)), m_debug_handle, d.info.exception.specific.user_break.address, sizeof(m_result))); } break; case svc::DebugException_UndefinedSystemCall: @@ -289,7 +289,7 @@ namespace ams::creport { } /* Read the dying message. */ - svc::ReadDebugProcessMemory(reinterpret_cast(m_dying_message), m_debug_handle, m_dying_message_address, m_dying_message_size); + R_DISCARD(svc::ReadDebugProcessMemory(reinterpret_cast(m_dying_message), m_debug_handle, m_dying_message_address, m_dying_message_size)); } void CrashReport::SaveReport(bool enable_screenshot) { diff --git a/stratosphere/creport/source/creport_crash_report.hpp b/stratosphere/creport/source/creport_crash_report.hpp index 36aee6b11..79080d93a 100644 --- a/stratosphere/creport/source/creport_crash_report.hpp +++ b/stratosphere/creport/source/creport_crash_report.hpp @@ -67,11 +67,11 @@ namespace ams::creport { } bool IsApplication() const { - return (m_process_info.flags & svc::CreateProcessFlag_IsApplication) != 0; + return (m_process_info.flags & svc::CreateProcessParameterFlag_IsApplication) != 0; } bool Is64Bit() const { - return (m_process_info.flags & svc::CreateProcessFlag_Is64Bit) != 0; + return (m_process_info.flags & svc::CreateProcessParameterFlag_64Bit) != 0; } bool IsUserBreak() const { diff --git a/stratosphere/creport/source/creport_main.cpp b/stratosphere/creport/source/creport_main.cpp index 5e5d38e09..8bcfccec7 100644 --- a/stratosphere/creport/source/creport_main.cpp +++ b/stratosphere/creport/source/creport_main.cpp @@ -123,7 +123,7 @@ namespace ams { if (R_SUCCEEDED(pgl::Initialize())) { ON_SCOPE_EXIT { pgl::Finalize(); }; - pgl::TerminateProcess(crashed_pid); + R_DISCARD(pgl::TerminateProcess(crashed_pid)); } } else { /* Use ns to terminate. */ diff --git a/stratosphere/creport/source/creport_scoped_file.hpp b/stratosphere/creport/source/creport_scoped_file.hpp index 5adcbeb09..dcdd1d773 100644 --- a/stratosphere/creport/source/creport_scoped_file.hpp +++ b/stratosphere/creport/source/creport_scoped_file.hpp @@ -38,9 +38,9 @@ namespace ams::creport { ~ScopedFile() { if (m_opened) { if (m_cache != nullptr) { - this->TryWriteCache(); + R_DISCARD(this->TryWriteCache()); } - fs::FlushFile(m_file); + R_DISCARD(fs::FlushFile(m_file)); fs::CloseFile(m_file); } } diff --git a/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp b/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp index 956226448..99dc434d4 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp @@ -29,7 +29,7 @@ namespace ams::dmnt { for (size_t i = 0; (bp = static_cast(this->GetBreakPoint(i))) != nullptr; ++i) { if (bp->m_in_use && bp->m_is_step) { AMS_DMNT2_GDB_LOG_DEBUG("BreakPointManager::ClearStep %p 0x%lx (idx=%zu)\n", bp, bp->m_address, i); - bp->Clear(m_debug_process); + R_DISCARD(bp->Clear(m_debug_process)); } } } diff --git a/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager_base.cpp b/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager_base.cpp index 0819798e3..43022b8b0 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager_base.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager_base.cpp @@ -28,7 +28,7 @@ namespace ams::dmnt { BreakPointBase *bp = nullptr; for (size_t i = 0; (bp = static_cast(this->GetBreakPoint(i))) != nullptr; ++i) { if (bp->m_in_use) { - bp->Clear(m_debug_process); + R_DISCARD(bp->Clear(m_debug_process)); } } } diff --git a/stratosphere/dmnt.gen2/source/dmnt2_debug_process.cpp b/stratosphere/dmnt.gen2/source/dmnt2_debug_process.cpp index 90505a4a9..e94ca9731 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_debug_process.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_debug_process.cpp @@ -44,7 +44,7 @@ namespace ams::dmnt { /* Get our process id. */ u64 pid_value = 0; - svc::GetProcessId(std::addressof(pid_value), m_debug_handle); + R_DISCARD(svc::GetProcessId(std::addressof(pid_value), m_debug_handle)); m_process_id = { pid_value }; @@ -88,8 +88,8 @@ namespace ams::dmnt { m_create_process_info = d.info.create_process; /* Cache our bools. */ - m_is_64_bit = (m_create_process_info.flags & svc::CreateProcessFlag_Is64Bit); - m_is_64_bit_address_space = (m_create_process_info.flags & svc::CreateProcessFlag_AddressSpaceMask) == svc::CreateProcessFlag_AddressSpace64Bit; + m_is_64_bit = (m_create_process_info.flags & svc::CreateProcessParameterFlag_64Bit); + m_is_64_bit_address_space = (m_create_process_info.flags & svc::CreateProcessParameterFlag_AddressSpaceMask) == svc::CreateProcessParameterFlag_AddressSpace64Bit39; } break; case svc::DebugEvent_CreateThread: @@ -413,7 +413,7 @@ namespace ams::dmnt { /* Get the instruction where we were. */ u32 insn = 0; - this->ReadMemory(std::addressof(insn), pc, sizeof(insn)); + R_DISCARD(this->ReadMemory(std::addressof(insn), pc, sizeof(insn))); /* Handle by architecture. */ bool is_call = false; @@ -471,7 +471,7 @@ namespace ams::dmnt { } Result DebugProcess::ClearBreakPoint(uintptr_t address, size_t size) { - m_software_breakpoints.ClearBreakPoint(address, size); + R_DISCARD(m_software_breakpoints.ClearBreakPoint(address, size)); R_SUCCEED(); } @@ -480,7 +480,7 @@ namespace ams::dmnt { } Result DebugProcess::ClearHardwareBreakPoint(uintptr_t address, size_t size) { - m_hardware_breakpoints.ClearBreakPoint(address, size); + R_DISCARD(m_hardware_breakpoints.ClearBreakPoint(address, size)); R_SUCCEED(); } @@ -522,8 +522,8 @@ namespace ams::dmnt { m_create_process_info = out->info.create_process; /* Cache our bools. */ - m_is_64_bit = (m_create_process_info.flags & svc::CreateProcessFlag_Is64Bit); - m_is_64_bit_address_space = (m_create_process_info.flags & svc::CreateProcessFlag_AddressSpaceMask) == svc::CreateProcessFlag_AddressSpace64Bit; + m_is_64_bit = (m_create_process_info.flags & svc::CreateProcessParameterFlag_64Bit); + m_is_64_bit_address_space = (m_create_process_info.flags & svc::CreateProcessParameterFlag_AddressSpaceMask) == svc::CreateProcessParameterFlag_AddressSpace64Bit39; } break; case svc::DebugEvent_CreateThread: diff --git a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp index 757a237a8..83c2489cb 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp @@ -1030,7 +1030,7 @@ namespace ams::dmnt { const auto reason = info.break_reason & ~svc::BreakReason_NotificationOnlyFlag; if (reason == svc::BreakReason_PostLoadDll || reason == svc::BreakReason_PostUnloadDll) { /* Re-collect the process's modules. */ - m_debug_process.CollectModules(); + R_DISCARD(m_debug_process.CollectModules()); } if (m_debug_process.GetOverrideStatus().IsHbl() && reason == svc::BreakReason_PostLoadDll) { @@ -1049,7 +1049,7 @@ namespace ams::dmnt { } /* This was just a notification, so we should continue. */ - m_debug_process.Continue(); + R_DISCARD(m_debug_process.Continue()); continue; } @@ -1064,7 +1064,7 @@ namespace ams::dmnt { if (!is_svc_break) { AMS_DMNT2_GDB_LOG_ERROR("UserBreak from non-SvcBreak (%08x)\n", insn); - m_debug_process.Continue(); + R_DISCARD(m_debug_process.Continue()); continue; } } @@ -1194,7 +1194,7 @@ namespace ams::dmnt { AMS_DMNT2_GDB_LOG_DEBUG("CreateThread %lx\n", thread_id); if (m_debug_process.IsValid()) { - m_debug_process.Continue(); + R_DISCARD(m_debug_process.Continue()); } else { AppendReplyFormat(reply_cur, reply_end, "W00"); } @@ -1205,7 +1205,7 @@ namespace ams::dmnt { AMS_DMNT2_GDB_LOG_DEBUG("ExitThread %lx\n", thread_id); if (m_debug_process.IsValid()) { - m_debug_process.Continue(); + R_DISCARD(m_debug_process.Continue()); } else { AppendReplyFormat(reply_cur, reply_end, "W00"); } @@ -1227,7 +1227,7 @@ namespace ams::dmnt { break; default: AMS_DMNT2_GDB_LOG_DEBUG("Unhandled ProcessEvent %u %lx\n", static_cast(d.type), thread_id); - m_debug_process.Continue(); + R_DISCARD(m_debug_process.Continue()); break; } @@ -1235,7 +1235,7 @@ namespace ams::dmnt { bool do_break; this->SendPacket(std::addressof(do_break), send_buffer); if (do_break) { - m_debug_process.Break(); + R_DISCARD(m_debug_process.Break()); } } } @@ -1250,7 +1250,7 @@ namespace ams::dmnt { /* Get the thread context. */ svc::ThreadContext thread_context = {}; - m_debug_process.GetThreadContext(std::addressof(thread_context), thread_id, svc::ThreadContextFlag_General | svc::ThreadContextFlag_Control); + R_DISCARD(m_debug_process.GetThreadContext(std::addressof(thread_context), thread_id, svc::ThreadContextFlag_General | svc::ThreadContextFlag_Control)); /* Add important registers. */ /* TODO: aarch32 */ @@ -1280,7 +1280,7 @@ namespace ams::dmnt { /* Add the thread core. */ { u32 core = 0; - m_debug_process.GetThreadCurrentCore(std::addressof(core), thread_id); + R_DISCARD(m_debug_process.GetThreadCurrentCore(std::addressof(core), thread_id)); AppendReplyFormat(m_reply_cur, m_reply_end, ";core:%u;", core); } @@ -1305,7 +1305,7 @@ namespace ams::dmnt { /* If we should, break the process. */ if (do_break) { - m_debug_process.Break(); + R_DISCARD(m_debug_process.Break()); } } } @@ -1721,7 +1721,7 @@ namespace ams::dmnt { } void GdbServerImpl::k() { - m_debug_process.Terminate(); + R_DISCARD(m_debug_process.Terminate()); m_killed = true; } @@ -2369,7 +2369,7 @@ namespace ams::dmnt { /* Get the thread core. */ u32 core = 0; - m_debug_process.GetThreadCurrentCore(std::addressof(core), thread_ids[i]); + R_DISCARD(m_debug_process.GetThreadCurrentCore(std::addressof(core), thread_ids[i])); /* Get the thread name. */ char name[os::ThreadNameLengthMax + 1]; diff --git a/stratosphere/dmnt.gen2/source/dmnt2_hardware_breakpoint.cpp b/stratosphere/dmnt.gen2/source/dmnt2_hardware_breakpoint.cpp index 563918825..5d9079b4c 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_hardware_breakpoint.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_hardware_breakpoint.cpp @@ -197,7 +197,7 @@ namespace ams::dmnt { g_last_bp_ctx_register = g_last_bp_register; for (int i = g_last_bp_ctx_register; i >= static_cast(svc::HardwareBreakPointRegisterName_I0); --i) { const Result result = svc::SetHardwareBreakPoint(static_cast(i), dbgbcr, svc::PseudoHandle::CurrentProcess); - svc::SetHardwareBreakPoint(static_cast(i), 0, 0); + R_DISCARD(svc::SetHardwareBreakPoint(static_cast(i), 0, 0)); if (R_FAILED(result)) { if (!svc::ResultInvalidHandle::Includes(result)) { diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp index 627c56bdd..521461c89 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp @@ -346,7 +346,7 @@ namespace ams::dmnt::cheat::impl { Result ResumeCheatProcessUnsafe() { m_broken_unsafe = false; m_unsafe_break_event.Signal(); - dmnt::cheat::impl::ContinueCheatProcess(this->GetCheatProcessHandle()); + R_DISCARD(dmnt::cheat::impl::ContinueCheatProcess(this->GetCheatProcessHandle())); R_SUCCEED(); } @@ -682,7 +682,7 @@ namespace ams::dmnt::cheat::impl { while (true) { eventLoadRemote(std::addressof(hook), manager->HookToCreateApplicationProcess(), true); if (R_SUCCEEDED(eventWait(std::addressof(hook), std::numeric_limits::max()))) { - manager->AttachToApplicationProcess(true); + R_DISCARD(manager->AttachToApplicationProcess(true)); } eventClose(std::addressof(hook)); } @@ -760,7 +760,7 @@ namespace ams::dmnt::cheat::impl { const auto &value = entry.GetValue(); /* Use Write SVC directly, to avoid the usual frozen address update logic. */ - svc::WriteDebugProcessMemory(manager->GetCheatProcessHandle(), reinterpret_cast(std::addressof(value.value)), address, value.width); + R_DISCARD(svc::WriteDebugProcessMemory(manager->GetCheatProcessHandle(), reinterpret_cast(std::addressof(value.value)), address, value.width)); } } } @@ -1146,8 +1146,8 @@ namespace ams::dmnt::cheat::impl { { char path[fs::EntryNameLengthMax + 1]; util::SNPrintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/cheats/toggles.txt", program_id.value); - fs::DeleteFile(path); - fs::CreateFile(path, 0); + R_DISCARD(fs::DeleteFile(path)); + R_DISCARD(fs::CreateFile(path, 0)); if (R_FAILED(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend))) { return; } diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index c1ecfb675..11b25b3a2 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -21,7 +21,7 @@ namespace ams::dmnt::cheat::impl { void CheatVirtualMachine::DebugLog(u32 log_id, u64 value) { /* Just unconditionally try to create the log folder. */ - fs::EnsureDirectory("sdmc:/atmosphere/cheat_vm_logs"); + R_DISCARD(fs::EnsureDirectory("sdmc:/atmosphere/cheat_vm_logs")); fs::FileHandle log_file; { @@ -40,7 +40,7 @@ namespace ams::dmnt::cheat::impl { char log_value[18]; util::SNPrintf(log_value, sizeof(log_value), "%016lx\n", value); - fs::WriteFile(log_file, log_offset, log_value, std::strlen(log_value), fs::WriteOption::Flush); + R_DISCARD(fs::WriteFile(log_file, log_offset, log_value, std::strlen(log_value), fs::WriteOption::Flush)); } void CheatVirtualMachine::OpenDebugLogFile() { @@ -796,7 +796,7 @@ namespace ams::dmnt::cheat::impl { u64 kHeld = 0; /* Get Keys held. */ - hid::GetKeysHeld(std::addressof(kHeld)); + R_DISCARD(hid::GetKeysHeld(std::addressof(kHeld))); this->OpenDebugLogFile(); ON_SCOPE_EXIT { this->CloseDebugLogFile(); }; @@ -838,7 +838,7 @@ namespace ams::dmnt::cheat::impl { case 2: case 4: case 8: - dmnt::cheat::impl::WriteCheatProcessMemoryUnsafe(dst_address, std::addressof(dst_value), cur_opcode.store_static.bit_width); + R_DISCARD(dmnt::cheat::impl::WriteCheatProcessMemoryUnsafe(dst_address, std::addressof(dst_value), cur_opcode.store_static.bit_width)); break; } } @@ -853,7 +853,7 @@ namespace ams::dmnt::cheat::impl { case 2: case 4: case 8: - dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(src_address, std::addressof(src_value), cur_opcode.begin_cond.bit_width); + R_DISCARD(dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(src_address, std::addressof(src_value), cur_opcode.begin_cond.bit_width)); break; } /* Check against condition. */ @@ -933,7 +933,7 @@ namespace ams::dmnt::cheat::impl { case 2: case 4: case 8: - dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(src_address, std::addressof(m_registers[cur_opcode.ldr_memory.reg_index]), cur_opcode.ldr_memory.bit_width); + R_DISCARD(dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(src_address, std::addressof(m_registers[cur_opcode.ldr_memory.reg_index]), cur_opcode.ldr_memory.bit_width)); break; } } @@ -952,7 +952,7 @@ namespace ams::dmnt::cheat::impl { case 2: case 4: case 8: - dmnt::cheat::impl::WriteCheatProcessMemoryUnsafe(dst_address, std::addressof(dst_value), cur_opcode.str_static.bit_width); + R_DISCARD(dmnt::cheat::impl::WriteCheatProcessMemoryUnsafe(dst_address, std::addressof(dst_value), cur_opcode.str_static.bit_width)); break; } /* Increment register if relevant. */ @@ -1143,7 +1143,7 @@ namespace ams::dmnt::cheat::impl { case 2: case 4: case 8: - dmnt::cheat::impl::WriteCheatProcessMemoryUnsafe(dst_address, std::addressof(dst_value), cur_opcode.str_register.bit_width); + R_DISCARD(dmnt::cheat::impl::WriteCheatProcessMemoryUnsafe(dst_address, std::addressof(dst_value), cur_opcode.str_register.bit_width)); break; } @@ -1214,7 +1214,7 @@ namespace ams::dmnt::cheat::impl { case 2: case 4: case 8: - dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(cond_address, std::addressof(cond_value), cur_opcode.begin_reg_cond.bit_width); + R_DISCARD(dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(cond_address, std::addressof(cond_value), cur_opcode.begin_reg_cond.bit_width)); break; } } @@ -1309,10 +1309,10 @@ namespace ams::dmnt::cheat::impl { } break; case CheatVmOpcodeType_PauseProcess: - dmnt::cheat::impl::PauseCheatProcessUnsafe(); + R_DISCARD(dmnt::cheat::impl::PauseCheatProcessUnsafe()); break; case CheatVmOpcodeType_ResumeProcess: - dmnt::cheat::impl::ResumeCheatProcessUnsafe(); + R_DISCARD(dmnt::cheat::impl::ResumeCheatProcessUnsafe()); break; case CheatVmOpcodeType_DebugLog: { @@ -1356,7 +1356,7 @@ namespace ams::dmnt::cheat::impl { case 2: case 4: case 8: - dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(val_address, std::addressof(log_value), cur_opcode.debug_log.bit_width); + R_DISCARD(dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(val_address, std::addressof(log_value), cur_opcode.debug_log.bit_width)); break; } } diff --git a/stratosphere/erpt/source/erpt_main.cpp b/stratosphere/erpt/source/erpt_main.cpp index 93096dbcb..9e9f289ad 100644 --- a/stratosphere/erpt/source/erpt_main.cpp +++ b/stratosphere/erpt/source/erpt_main.cpp @@ -62,9 +62,9 @@ namespace ams { { u8 disable_report_cleanup = 0; if (settings::fwdbg::GetSettingsItemValue(std::addressof(disable_report_cleanup), sizeof(disable_report_cleanup), "erpt", "disable_automatic_report_cleanup") == sizeof(disable_report_cleanup)) { - erpt::srv::SetEnabledAutomaticReportCleanup(disable_report_cleanup == 0); + R_DISCARD(erpt::srv::SetEnabledAutomaticReportCleanup(disable_report_cleanup == 0)); } else { - erpt::srv::SetEnabledAutomaticReportCleanup(true); + R_DISCARD(erpt::srv::SetEnabledAutomaticReportCleanup(true)); } } @@ -72,7 +72,7 @@ namespace ams { R_ABORT_UNLESS(erpt::srv::Initialize(erpt::g_memory_heap, erpt::MemoryHeapSize)); /* Atmosphere always wants to redirect new reports to the SD card, to prevent them from being logged. */ - erpt::srv::SetRedirectNewReportsToSdCard(true); + R_DISCARD(erpt::srv::SetRedirectNewReportsToSdCard(true)); /* Configure the serial number, OS version, product model, and region. */ { diff --git a/stratosphere/fatal/source/fatal_repair.cpp b/stratosphere/fatal/source/fatal_repair.cpp index 201ec4ba4..f2054b421 100644 --- a/stratosphere/fatal/source/fatal_repair.cpp +++ b/stratosphere/fatal/source/fatal_repair.cpp @@ -105,11 +105,11 @@ namespace ams::fatal::srv { void CheckRepairStatus() { if (IsInRepairWithoutVolHeld()) { - ThrowFatalForSelf(ResultInRepairWithoutVolHeld()); + R_DISCARD(ThrowFatalForSelf(ResultInRepairWithoutVolHeld())); } if (IsInRepairWithoutTimeReviserCartridge()) { - ThrowFatalForSelf(ResultInRepairWithoutTimeReviserCartridge()); + R_DISCARD(ThrowFatalForSelf(ResultInRepairWithoutTimeReviserCartridge())); } } diff --git a/stratosphere/fatal/source/fatal_task_error_report.cpp b/stratosphere/fatal/source/fatal_task_error_report.cpp index cac9db288..9e69c79f3 100644 --- a/stratosphere/fatal/source/fatal_task_error_report.cpp +++ b/stratosphere/fatal/source/fatal_task_error_report.cpp @@ -24,7 +24,7 @@ namespace ams::fatal::srv { /* Helpers. */ void TryEnsureReportDirectories() { - fs::EnsureDirectory("sdmc:/atmosphere/fatal_reports/dumps"); + R_DISCARD(fs::EnsureDirectory("sdmc:/atmosphere/fatal_reports/dumps")); } bool TryGetCurrentTimestamp(u64 *out) { diff --git a/stratosphere/htc/source/htc_main.cpp b/stratosphere/htc/source/htc_main.cpp index 5477bc113..5c54d5f3e 100644 --- a/stratosphere/htc/source/htc_main.cpp +++ b/stratosphere/htc/source/htc_main.cpp @@ -177,7 +177,7 @@ namespace ams { /* Create the htc misc ipc thread. */ os::ThreadType htc_ipc_thread; - os::CreateThread(std::addressof(htc_ipc_thread), htc::HtcIpcThreadFunction, nullptr, htc::g_htc_ipc_thread_stack, sizeof(htc::g_htc_ipc_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcIpc)); + R_DISCARD(os::CreateThread(std::addressof(htc_ipc_thread), htc::HtcIpcThreadFunction, nullptr, htc::g_htc_ipc_thread_stack, sizeof(htc::g_htc_ipc_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcIpc))); os::SetThreadNamePointer(std::addressof(htc_ipc_thread), AMS_GET_SYSTEM_THREAD_NAME(htc, HtcIpc)); /* Initialize the htcfs server. */ @@ -186,7 +186,7 @@ namespace ams { /* Create the htcfs ipc thread. */ os::ThreadType htcfs_ipc_thread; - os::CreateThread(std::addressof(htcfs_ipc_thread), htc::HtcfsIpcThreadFunction, nullptr, htc::g_htcfs_ipc_thread_stack, sizeof(htc::g_htcfs_ipc_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcfsIpc)); + R_DISCARD(os::CreateThread(std::addressof(htcfs_ipc_thread), htc::HtcfsIpcThreadFunction, nullptr, htc::g_htcfs_ipc_thread_stack, sizeof(htc::g_htcfs_ipc_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcfsIpc))); os::SetThreadNamePointer(std::addressof(htcfs_ipc_thread), AMS_GET_SYSTEM_THREAD_NAME(htc, HtcfsIpc)); /* Initialize the htcs server. */ @@ -196,7 +196,7 @@ namespace ams { /* Create the htcs ipc threads. */ os::ThreadType htcs_ipc_threads[htc::NumHtcsIpcThreads]; for (size_t i = 0; i < htc::NumHtcsIpcThreads; ++i) { - os::CreateThread(std::addressof(htcs_ipc_threads[i]), htc::HtcsIpcThreadFunction, nullptr, htc::g_htcs_ipc_thread_stack[i], sizeof(htc::g_htcs_ipc_thread_stack[i]), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcsIpc)); + R_DISCARD(os::CreateThread(std::addressof(htcs_ipc_threads[i]), htc::HtcsIpcThreadFunction, nullptr, htc::g_htcs_ipc_thread_stack[i], sizeof(htc::g_htcs_ipc_thread_stack[i]), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcsIpc))); os::SetThreadNamePointer(std::addressof(htcs_ipc_threads[i]), AMS_GET_SYSTEM_THREAD_NAME(htc, HtcsIpc)); } diff --git a/stratosphere/loader/source/ldr_argument_store.hpp b/stratosphere/loader/source/ldr_argument_store.hpp index cc7bee4b8..6a417971c 100644 --- a/stratosphere/loader/source/ldr_argument_store.hpp +++ b/stratosphere/loader/source/ldr_argument_store.hpp @@ -33,7 +33,7 @@ namespace ams::ldr { Entry m_argument_map[ArgumentMapCount]; public: constexpr ArgumentStore() : m_argument_map{} { - this->Flush(); + R_DISCARD(this->Flush()); } public: const Entry *Get(ncm::ProgramId program_id); diff --git a/stratosphere/loader/source/ldr_embedded_usb_patches.inc b/stratosphere/loader/source/ldr_embedded_usb_patches.inc index 0ac5bc23c..1ed107817 100644 --- a/stratosphere/loader/source/ldr_embedded_usb_patches.inc +++ b/stratosphere/loader/source/ldr_embedded_usb_patches.inc @@ -102,4 +102,5 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("766D0C2277207B40AD9B8DE309396D50CCE94885"), util::size(Usb30ForceEnablePatches_21_0_0), Usb30ForceEnablePatches_21_0_0 }, /* 21.0.0 */ { ParseModuleId("B734339F2280170AF0200573F9B943242CEF8C15"), util::size(Usb30ForceEnablePatches_22_0_0), Usb30ForceEnablePatches_22_0_0 }, /* 22.0.0 - 22.1.0 */ { ParseModuleId("AD8D36F2029822A4C498F055ADBDAA789EB913C6"), util::size(Usb30ForceEnablePatches_22_0_0), Usb30ForceEnablePatches_22_0_0 }, /* 22.5.0 */ + { ParseModuleId("760E48C572F8192C9BC6DC8FEB3D6213F0551505"), util::size(Usb30ForceEnablePatches_22_0_0), Usb30ForceEnablePatches_22_0_0 }, /* 23.0.0 */ }; diff --git a/stratosphere/loader/source/ldr_embedded_web_patches.inc b/stratosphere/loader/source/ldr_embedded_web_patches.inc new file mode 100644 index 000000000..825123005 --- /dev/null +++ b/stratosphere/loader/source/ldr_embedded_web_patches.inc @@ -0,0 +1,61 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Breakdown of each patch in order: */ +/* #1 - Patch the 0xDEEF000 size check branch to NOP. */ +/* #2 - Change the root heap "Reserved" region allocation size from 0x43E000 to 0. */ +/* #3 - Change the root heap "Scene" size from 0x4580000 to 0x4040000. */ +/* #4 - Change the scene heap "ReservedTbd" region allocation size from 0x540000 to 0. */ +/* #5 - Patch the linking of "ReservedTbd" to the parent heap with a NOP. */ +/* #6 - Patch the initial memory block allocation size from 0xB400000 to 0xAC00000. */ +/* #7 - Patch the initial memory block initialization size from 0xB400000 to 0xAC00000. */ +constexpr inline const EmbeddedPatchEntry SystemWebMemoryPatches_23_0_0[] = { + { 0x861DD4, "\x1F\x20\x03\xD5", 4 }, + { 0x861E80, "\x02\x00\x80\x52", 4 }, + { 0x861E6C, "\x82\x80\xA0\x52", 4 }, + { 0x8C1718, "\x02\x00\x80\x52", 4 }, + { 0x8C172C, "\x1F\x20\x03\xD5", 4 }, + { 0x861D44, "\x01\x58\xA1\x52", 4 }, + { 0x861D5C, "\x03\x58\xA1\x52", 4 }, +}; + +constexpr inline const EmbeddedPatchEntry OpenWebMemoryPatches_23_0_0[] = { + { 0x828DBC, "\x1F\x20\x03\xD5", 4 }, + { 0x828E68, "\x02\x00\x80\x52", 4 }, + { 0x828E54, "\x82\x80\xA0\x52", 4 }, + { 0x74C564, "\x02\x00\x80\x52", 4 }, + { 0x74C578, "\x1F\x20\x03\xD5", 4 }, + { 0x828D2C, "\x01\x58\xA1\x52", 4 }, + { 0x828D44, "\x03\x58\xA1\x52", 4 }, +}; + +constexpr inline const EmbeddedPatchEntry OfflineWebMemoryPatches_23_0_0[] = { + { 0x130698, "\x1F\x20\x03\xD5", 4 }, + { 0x130744, "\x02\x00\x80\x52", 4 }, + { 0x130730, "\x82\x80\xA0\x52", 4 }, + { 0x4D728, "\x02\x00\x80\x52", 4 }, + { 0x4D738, "\x1F\x20\x03\xD5", 4 }, + { 0x130614, "\x01\x58\xA1\x52", 4 }, + { 0x130624, "\x02\x58\xA1\x52", 4 }, +}; + +constexpr inline const EmbeddedPatch WebMemoryPatches[] = { + { ParseModuleId("97BF9C2D43EB002FB5B3578E7714F428104ED596"), util::size(SystemWebMemoryPatches_23_0_0), SystemWebMemoryPatches_23_0_0 }, /* 23.0.0 */ + + { ParseModuleId("1470453424A9CDE689BE6DA86457ED1C79F5F403"), util::size(OpenWebMemoryPatches_23_0_0), OpenWebMemoryPatches_23_0_0 }, /* 23.0.0 */ + + { ParseModuleId("86DAFFA68DA38660317018ADC7AD415BCCDDC583"), util::size(OfflineWebMemoryPatches_23_0_0), OfflineWebMemoryPatches_23_0_0 }, /* 23.0.0 */ +}; diff --git a/stratosphere/loader/source/ldr_meta.cpp b/stratosphere/loader/source/ldr_meta.cpp index d6b6d7852..87475196f 100644 --- a/stratosphere/loader/source/ldr_meta.cpp +++ b/stratosphere/loader/source/ldr_meta.cpp @@ -88,8 +88,8 @@ namespace ams::ldr { R_UNLESS(npdm->magic == Npdm::Magic, ldr::ResultInvalidMeta()); /* Validate flags. */ - constexpr u32 InvalidMetaFlagMask = 0x80000000; - R_UNLESS(!(npdm->flags & InvalidMetaFlagMask), ldr::ResultInvalidMeta()); + constexpr u32 InvalidMetaFlag0Mask = 0x80000000; + R_UNLESS(!(npdm->flags0 & InvalidMetaFlag0Mask), ldr::ResultInvalidMeta()); /* Validate Acid extents. */ R_TRY(ValidateSubregion(sizeof(Npdm), size, npdm->acid_offset, npdm->acid_size, sizeof(Acid))); @@ -262,14 +262,15 @@ namespace ams::ldr { /* Perform address space override. */ if (status.HasOverrideAddressSpace()) { /* Clear the existing address space. */ - meta->npdm->flags &= ~Npdm::MetaFlag_AddressSpaceTypeMask; + meta->npdm->flags0 &= ~Npdm::MetaFlag0_ProcessAddressSpaceMask; /* Set the new address space flag. */ switch (status.GetOverrideAddressSpaceFlags()) { - case cfg::impl::OverrideStatusFlag_AddressSpace32Bit: meta->npdm->flags |= (Npdm::AddressSpaceType_32Bit) << Npdm::MetaFlag_AddressSpaceTypeShift; break; - case cfg::impl::OverrideStatusFlag_AddressSpace64BitDeprecated: meta->npdm->flags |= (Npdm::AddressSpaceType_64BitDeprecated) << Npdm::MetaFlag_AddressSpaceTypeShift; break; - case cfg::impl::OverrideStatusFlag_AddressSpace32BitWithoutAlias: meta->npdm->flags |= (Npdm::AddressSpaceType_32BitWithoutAlias) << Npdm::MetaFlag_AddressSpaceTypeShift; break; - case cfg::impl::OverrideStatusFlag_AddressSpace64Bit: meta->npdm->flags |= (Npdm::AddressSpaceType_64Bit) << Npdm::MetaFlag_AddressSpaceTypeShift; break; + case cfg::impl::OverrideStatusFlag_AddressSpace32Bit: meta->npdm->flags0 |= (Npdm::ProcessAddressSpace_32Bit) << Npdm::MetaFlag0_ProcessAddressSpaceShift; break; + case cfg::impl::OverrideStatusFlag_AddressSpace64Bit36: meta->npdm->flags0 |= (Npdm::ProcessAddressSpace_64Bit36) << Npdm::MetaFlag0_ProcessAddressSpaceShift; break; + case cfg::impl::OverrideStatusFlag_AddressSpace32BitNoReserved: meta->npdm->flags0 |= (Npdm::ProcessAddressSpace_32BitNoReserved) << Npdm::MetaFlag0_ProcessAddressSpaceShift; break; + case cfg::impl::OverrideStatusFlag_AddressSpace64Bit39: meta->npdm->flags0 |= (Npdm::ProcessAddressSpace_64Bit39) << Npdm::MetaFlag0_ProcessAddressSpaceShift; break; + case cfg::impl::OverrideStatusFlag_AddressSpace64Bit42: meta->npdm->flags0 |= (Npdm::ProcessAddressSpace_64Bit42) << Npdm::MetaFlag0_ProcessAddressSpaceShift; break; AMS_UNREACHABLE_DEFAULT_CASE(); } } diff --git a/stratosphere/loader/source/ldr_patcher.cpp b/stratosphere/loader/source/ldr_patcher.cpp index c78b3919b..a6776b691 100644 --- a/stratosphere/loader/source/ldr_patcher.cpp +++ b/stratosphere/loader/source/ldr_patcher.cpp @@ -109,6 +109,7 @@ namespace ams::ldr { #include "ldr_embedded_usb_patches.inc" #include "ldr_embedded_am_patches.inc" + #include "ldr_embedded_web_patches.inc" } @@ -153,6 +154,18 @@ namespace ams::ldr { } } } + + /* TODO: Remove this if/when a cleaner solution is figured out. */ + for (const auto &patch : WebMemoryPatches) { + if (std::memcmp(std::addressof(patch.module_id), std::addressof(module_id), sizeof(module_id)) == 0) { + for (size_t i = 0; i < patch.num_entries; ++i) { + const auto &entry = patch.entries[i]; + if (entry.offset + entry.size <= mapped_size) { + std::memcpy(reinterpret_cast(mapped_nso + entry.offset), entry.data, entry.size); + } + } + } + } } } \ No newline at end of file diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index bea773f44..8ba4fac2a 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -175,8 +175,8 @@ namespace ams::ldr { return (MakeProgramInfoFlag(static_cast(meta->aci_kac), meta->aci->kac_size / sizeof(util::BitPack32)) & ProgramInfoFlag_ApplicationTypeMask) == ProgramInfoFlag_Application; } - Npdm::AddressSpaceType GetAddressSpaceType(const Meta *meta) { - return static_cast((meta->npdm->flags & Npdm::MetaFlag_AddressSpaceTypeMask) >> Npdm::MetaFlag_AddressSpaceTypeShift); + Npdm::ProcessAddressSpace GetProcessAddressSpace(const Meta *meta) { + return static_cast((meta->npdm->flags0 & Npdm::MetaFlag0_ProcessAddressSpaceMask) >> Npdm::MetaFlag0_ProcessAddressSpaceShift); } Acid::PoolPartition GetPoolPartition(const Meta *meta) { @@ -399,52 +399,56 @@ namespace ams::ldr { R_SUCCEED(); } - Result GetCreateProcessFlags(u32 *out, const Meta *meta, const u32 ldr_flags) { - const u8 meta_flags = meta->npdm->flags; + Result GetCreateProcessParameterFlags(u32 *out, const Meta *meta, const u32 ldr_flags) { + const u8 meta_flags0 = meta->npdm->flags0; + const u8 meta_flags1 = meta->npdm->flags1; u32 flags = 0; /* Set Is64Bit. */ - if (meta_flags & Npdm::MetaFlag_Is64Bit) { - flags |= svc::CreateProcessFlag_Is64Bit; + if (meta_flags0 & Npdm::MetaFlag0_Is64BitInstruction) { + flags |= svc::CreateProcessParameterFlag_64Bit; } - /* Set AddressSpaceType. */ - switch (GetAddressSpaceType(meta)) { - case Npdm::AddressSpaceType_32Bit: - flags |= svc::CreateProcessFlag_AddressSpace32Bit; + /* Set ProcessAddressSpace. */ + switch (GetProcessAddressSpace(meta)) { + case Npdm::ProcessAddressSpace_32Bit: + flags |= svc::CreateProcessParameterFlag_AddressSpace32Bit; break; - case Npdm::AddressSpaceType_64BitDeprecated: - flags |= svc::CreateProcessFlag_AddressSpace64BitDeprecated; + case Npdm::ProcessAddressSpace_64Bit36: + flags |= svc::CreateProcessParameterFlag_AddressSpace64Bit36; break; - case Npdm::AddressSpaceType_32BitWithoutAlias: - flags |= svc::CreateProcessFlag_AddressSpace32BitWithoutAlias; + case Npdm::ProcessAddressSpace_32BitNoReserved: + flags |= svc::CreateProcessParameterFlag_AddressSpace32BitNoReserved; break; - case Npdm::AddressSpaceType_64Bit: - flags |= svc::CreateProcessFlag_AddressSpace64Bit; + case Npdm::ProcessAddressSpace_64Bit39: + flags |= svc::CreateProcessParameterFlag_AddressSpace64Bit39; + break; + case Npdm::ProcessAddressSpace_64Bit42: + flags |= svc::CreateProcessParameterFlag_AddressSpace64Bit42; break; default: R_THROW(ldr::ResultInvalidMeta()); } /* Set Enable Debug. */ - if (ldr_flags & CreateProcessFlag_EnableDebug) { - flags |= svc::CreateProcessFlag_EnableDebug; + if (ldr_flags & CreateProcessParameterFlag_EnableJitDebug) { + flags |= svc::CreateProcessParameterFlag_EnableJitDebug; } /* Set Enable ASLR. */ - if (!(ldr_flags & CreateProcessFlag_DisableAslr)) { - flags |= svc::CreateProcessFlag_EnableAslr; + if (!(ldr_flags & CreateProcessParameterFlag_DisableAslr)) { + flags |= svc::CreateProcessParameterFlag_EnableAslr; } /* Set Is Application. */ if (IsApplication(meta)) { - flags |= svc::CreateProcessFlag_IsApplication; + flags |= svc::CreateProcessParameterFlag_IsApplication; /* 7.0.0+: Set OptimizeMemoryAllocation if relevant. */ if (hos::GetVersion() >= hos::Version_7_0_0) { - if (meta_flags & Npdm::MetaFlag_OptimizeMemoryAllocation) { - flags |= svc::CreateProcessFlag_OptimizeMemoryAllocation; + if (meta_flags0 & Npdm::MetaFlag0_OptimizeMemoryAllocation) { + flags |= svc::CreateProcessParameterFlag_OptimizeMemoryAllocation; } } } @@ -456,19 +460,19 @@ namespace ams::ldr { switch (GetPoolPartition(meta)) { case Acid::PoolPartition_Application: if (IsApplet(meta)) { - flags |= svc::CreateProcessFlag_PoolPartitionApplet; + flags |= svc::CreateProcessParameterFlag_PoolPartitionApplet; } else { - flags |= svc::CreateProcessFlag_PoolPartitionApplication; + flags |= svc::CreateProcessParameterFlag_PoolPartitionApplication; } break; case Acid::PoolPartition_Applet: - flags |= svc::CreateProcessFlag_PoolPartitionApplet; + flags |= svc::CreateProcessParameterFlag_PoolPartitionApplet; break; case Acid::PoolPartition_System: - flags |= svc::CreateProcessFlag_PoolPartitionSystem; + flags |= svc::CreateProcessParameterFlag_PoolPartitionSystem; break; case Acid::PoolPartition_SystemNonSecure: - flags |= svc::CreateProcessFlag_PoolPartitionSystemNonSecure; + flags |= svc::CreateProcessParameterFlag_PoolPartitionSystemNonSecure; break; default: R_THROW(ldr::ResultInvalidMeta()); @@ -476,18 +480,23 @@ namespace ams::ldr { } else if (hos::GetVersion() >= hos::Version_4_0_0) { /* On 4.0.0+, the corresponding bit was simply "UseSecureMemory". */ if (meta->acid->flags & Acid::AcidFlag_DeprecatedUseSecureMemory) { - flags |= svc::CreateProcessFlag_DeprecatedUseSecureMemory; + flags |= svc::CreateProcessParameterFlag_DeprecatedUseSecureMemory; } } - /* 11.0.0+/meso Set Disable DAS merge. */ - if (meta_flags & Npdm::MetaFlag_DisableDeviceAddressSpaceMerge) { - flags |= svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge; + /* 11.0.0+/meso Set Disable DAS Merge. */ + if (meta_flags0 & Npdm::MetaFlag0_DisableDeviceAddressSpaceMerge) { + flags |= svc::CreateProcessParameterFlag_DisableDeviceAddressSpaceMerge; } - /* 18.0.0+/meso Set Alias region extra size. */ - if (meta_flags & Npdm::MetaFlag_EnableAliasRegionExtraSize) { - flags |= svc::CreateProcessFlag_EnableAliasRegionExtraSize; + /* 18.0.0+/meso Set Enable Address Sanitizer . */ + if (meta_flags0 & Npdm::MetaFlag0_EnableAddressSanitizer) { + flags |= svc::CreateProcessParameterFlag_EnableAddressSanitizer; + } + + /* 23.0.0+/meso Set Enable Shadow Stack. */ + if (meta_flags1 & Npdm::MetaFlag1_EnableShadowStack) { + flags |= svc::CreateProcessParameterFlag_EnableShadowStack; } *out = flags; @@ -505,7 +514,7 @@ namespace ams::ldr { out->reslimit = resource_limit; /* Set flags. */ - R_TRY(GetCreateProcessFlags(std::addressof(out->flags), meta, flags)); + R_TRY(GetCreateProcessParameterFlags(std::addressof(out->flags), meta, flags)); /* 3.0.0+ System Resource Size. */ if (hos::GetVersion() >= hos::Version_3_0_0) { @@ -515,7 +524,7 @@ namespace ams::ldr { /* Validate system resource usage. */ if (meta->npdm->system_resource_size) { /* Process must be 64-bit. */ - R_UNLESS((out->flags & svc::CreateProcessFlag_AddressSpace64Bit), ldr::ResultInvalidMeta()); + R_UNLESS((out->flags & svc::CreateProcessParameterFlag_AddressSpace64Bit39), ldr::ResultInvalidMeta()); /* Process must be application or applet. */ R_UNLESS(IsApplication(meta) || IsApplet(meta), ldr::ResultInvalidMeta()); @@ -583,25 +592,29 @@ namespace ams::ldr { uintptr_t aslr_start = 0; size_t aslr_size = 0; if (hos::GetVersion() >= hos::Version_2_0_0) { - switch (out_param->flags & svc::CreateProcessFlag_AddressSpaceMask) { - case svc::CreateProcessFlag_AddressSpace32Bit: - case svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: + switch (out_param->flags & svc::CreateProcessParameterFlag_AddressSpaceMask) { + case svc::CreateProcessParameterFlag_AddressSpace32Bit: + case svc::CreateProcessParameterFlag_AddressSpace32BitNoReserved: aslr_start = svc::AddressSmallMap32Start; aslr_size = svc::AddressSmallMap32Size; break; - case svc::CreateProcessFlag_AddressSpace64BitDeprecated: + case svc::CreateProcessParameterFlag_AddressSpace64Bit36: aslr_start = svc::AddressSmallMap36Start; aslr_size = svc::AddressSmallMap36Size; break; - case svc::CreateProcessFlag_AddressSpace64Bit: + case svc::CreateProcessParameterFlag_AddressSpace64Bit39: aslr_start = svc::AddressMap39Start; aslr_size = svc::AddressMap39Size; break; + case svc::CreateProcessParameterFlag_AddressSpace64Bit42: + aslr_start = svc::AddressMap42Start; + aslr_size = svc::AddressMap42Size; + break; AMS_UNREACHABLE_DEFAULT_CASE(); } } else { /* On 1.0.0, only 2 address space types existed. */ - if (out_param->flags & svc::CreateProcessFlag_AddressSpace64BitDeprecated) { + if (out_param->flags & svc::CreateProcessParameterFlag_AddressSpace64Bit36) { aslr_start = svc::AddressSmallMap36Start; aslr_size = svc::AddressSmallMap36Size; } else { @@ -614,7 +627,7 @@ namespace ams::ldr { /* Set Create Process output. */ uintptr_t aslr_slide = 0; size_t free_size = (aslr_size - total_size); - if (out_param->flags & svc::CreateProcessFlag_EnableAslr) { + if (out_param->flags & svc::CreateProcessParameterFlag_EnableAslr) { aslr_slide = GenerateSecureRandom(free_size / os::MemoryBlockUnitSize) * os::MemoryBlockUnitSize; } @@ -799,7 +812,7 @@ namespace ams::ldr { /* Set the output handle, and ensure that if we fail after this point we clean it up. */ out->process_handle = process_handle; out->code_address = param.code_address; - ON_RESULT_FAILURE { svc::CloseHandle(process_handle); }; + ON_RESULT_FAILURE { R_DISCARD(svc::CloseHandle(process_handle)); }; /* Load all auto load modules. */ R_RETURN(LoadAutoLoadModules(out, ctx, argument)); @@ -857,8 +870,8 @@ namespace ams::ldr { os::ProcessId process_id = os::GetProcessId(info.process_handle); /* Register new process. */ - const auto as_type = GetAddressSpaceType(std::addressof(meta)); - RoManager::GetInstance().RegisterProcess(pin_id, process_id, meta.aci->program_id, as_type == Npdm::AddressSpaceType_64Bit || as_type == Npdm::AddressSpaceType_64BitDeprecated); + const auto as_type = GetProcessAddressSpace(std::addressof(meta)); + RoManager::GetInstance().RegisterProcess(pin_id, process_id, meta.aci->program_id, as_type == Npdm::ProcessAddressSpace_64Bit39 || as_type == Npdm::ProcessAddressSpace_64Bit36); /* Register all NSOs. */ for (int i = 0; i < ctx.nso_count; i++) { @@ -869,7 +882,7 @@ namespace ams::ldr { /* If we're overriding for HBL, perform HTML document redirection. */ if (override_status.IsHbl()) { /* Don't validate result, failure is okay. */ - RedirectHtmlDocumentPathForHbl(loc); + R_DISCARD(RedirectHtmlDocumentPathForHbl(loc)); } /* Clear the external code for the program. */ diff --git a/stratosphere/pm/source/impl/pm_process_info.cpp b/stratosphere/pm/source/impl/pm_process_info.cpp index d472803dc..1c51e3f10 100644 --- a/stratosphere/pm/source/impl/pm_process_info.cpp +++ b/stratosphere/pm/source/impl/pm_process_info.cpp @@ -89,8 +89,8 @@ namespace ams::pm::impl { if (m_handle != os::InvalidNativeHandle) { /* Unregister the process. */ fsprUnregisterProgram(m_process_id.value); - sm::manager::UnregisterProcess(m_process_id); - ldr::pm::UnpinProgram(m_pin_id); + R_DISCARD(sm::manager::UnregisterProcess(m_process_id)); + R_DISCARD(ldr::pm::UnpinProgram(m_pin_id)); /* Close the process's handle. */ os::CloseNativeHandle(m_handle); diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 8a4d7ba16..5bd14732c 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -86,14 +86,14 @@ namespace ams::pm::impl { R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_application_process_event), os::EventClearMode_AutoClear, true)); } - inline u32 GetLoaderCreateProcessFlags(u32 launch_flags) { + inline u32 GetLoaderCreateProcessParameterFlags(u32 launch_flags) { u32 ldr_flags = 0; if (ShouldSignalOnException(launch_flags) || (hos::GetVersion() >= hos::Version_2_0_0 && !ShouldStartSuspended(launch_flags))) { - ldr_flags |= ldr::CreateProcessFlag_EnableDebug; + ldr_flags |= ldr::CreateProcessParameterFlag_EnableJitDebug; } if (ShouldDisableAslr(launch_flags)) { - ldr_flags |= ldr::CreateProcessFlag_DisableAslr; + ldr_flags |= ldr::CreateProcessParameterFlag_DisableAslr; } return ldr_flags; @@ -142,7 +142,7 @@ namespace ams::pm::impl { R_TRY(ldr::pm::AtmospherePinProgram(std::addressof(pin_id), fixed_location, override_status)); /* If we fail after now, unpin. */ - ON_RESULT_FAILURE { ldr::pm::UnpinProgram(pin_id); }; + ON_RESULT_FAILURE { R_DISCARD(ldr::pm::UnpinProgram(pin_id)); }; /* Ensure we can talk to mitm services. */ { @@ -166,7 +166,7 @@ namespace ams::pm::impl { WaitResourceAvailable(std::addressof(program_info)); /* Actually create the process. */ - R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(flags), GetResourceLimitHandle(std::addressof(program_info)), attrs.program_attrs)); + R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessParameterFlags(flags), GetResourceLimitHandle(std::addressof(program_info)), attrs.program_attrs)); } /* Get the process id. */ @@ -480,13 +480,16 @@ namespace ams::pm::impl { Result NotifyBootFinished() { AMS_FUNCTION_LOCAL_STATIC_CONSTINIT(bool, s_has_boot_finished, false); if (!s_has_boot_finished) { - /* Set program verification disabled, if we should. */ - /* NOTE: Nintendo does not check the result of this. */ - if (spl::IsDisabledProgramVerification()) { - if (hos::GetVersion() >= hos::Version_10_0_0) { - ldr::pm::SetEnabledProgramVerification(false); - } else { - fsprSetEnabledProgramVerification(false); + /* 23.0.0+ removed this and all usage of spl from the pm sysmodule, both in normal and safe mode FIRM. */ + if (hos::GetVersion() < hos::Version_23_0_0) { + /* Set program verification disabled, if we should. */ + /* NOTE: Nintendo does not check the result of this. */ + if (spl::IsDisabledProgramVerification()) { + if (hos::GetVersion() >= hos::Version_10_0_0) { + R_DISCARD(ldr::pm::SetEnabledProgramVerification(false)); + } else { + fsprSetEnabledProgramVerification(false); + } } } diff --git a/stratosphere/pm/source/impl/pm_process_tracker.cpp b/stratosphere/pm/source/impl/pm_process_tracker.cpp index 5d1c3b418..8f436f00f 100644 --- a/stratosphere/pm/source/impl/pm_process_tracker.cpp +++ b/stratosphere/pm/source/impl/pm_process_tracker.cpp @@ -94,7 +94,7 @@ namespace ams::pm::impl { auto list = GetProcessList(); /* Reset the process's signal. */ - svc::ResetSignal(process_info->GetHandle()); + R_DISCARD(svc::ResetSignal(process_info->GetHandle())); /* Update the process's state. */ const svc::ProcessState old_state = process_info->GetState(); diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index 5bef871c7..a4925ef67 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -54,8 +54,8 @@ namespace ams { void RegisterPrivilegedProcess(os::ProcessId process_id, ncm::ProgramId program_id) { fsprUnregisterProgram(process_id.value); fsprRegisterProgram(process_id.value, process_id.value, NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl), 0); - sm::manager::UnregisterProcess(process_id); - sm::manager::RegisterProcess(process_id, program_id, cfg::OverrideStatus{}, PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl)); + R_DISCARD(sm::manager::UnregisterProcess(process_id)); + R_DISCARD(sm::manager::RegisterProcess(process_id, program_id, cfg::OverrideStatus{}, PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl))); } void RegisterPrivilegedProcesses() { diff --git a/stratosphere/ro/source/impl/ro_service_impl.cpp b/stratosphere/ro/source/impl/ro_service_impl.cpp index 0eee275eb..e8c0b45c7 100644 --- a/stratosphere/ro/source/impl/ro_service_impl.cpp +++ b/stratosphere/ro/source/impl/ro_service_impl.cpp @@ -47,7 +47,7 @@ namespace ams::ro::impl { } }; static_assert(sizeof(Sha256Hash) == sizeof(Sha256Hash::hash)); - + struct NroInfo { u64 base_address; u64 nro_heap_address; @@ -55,8 +55,10 @@ namespace ams::ro::impl { u64 bss_heap_address; u64 bss_heap_size; u64 code_size; + u64 ro_size; /* 23.0.0+ */ u64 rw_size; ModuleId module_id; + bool is_compress; /* 23.0.0+ */ }; struct NrrInfo { @@ -72,7 +74,17 @@ namespace ams::ro::impl { u8 cached_signed_area[sizeof(NrrHeader) - NrrHeader::GetSignedAreaOffset()]; Sha256Hash signed_area_hash; }; - + + struct AdditionalNroHeaderInfo { + u32 signature; + u8 reserved_04[0xC]; + u32 compressed_size; + u32 reserved_14; + u32 hash_size; + u32 hash_offset; + u8 reserved_20[0x40]; + }; + struct ProcessContext { private: bool m_nro_in_use[MaxNroInfos]{}; @@ -82,6 +94,8 @@ namespace ams::ro::impl { os::NativeHandle m_process_handle = os::InvalidNativeHandle; os::ProcessId m_process_id = os::InvalidProcessId; bool m_in_use{}; + u8 m_decompression_src_work_buffer[0x10000]{}; + u8 m_decompression_dst_work_buffer[0x10000]{}; public: constexpr ProcessContext() = default; @@ -96,6 +110,9 @@ namespace ams::ro::impl { m_process_handle = process_handle; m_process_id = process_id; m_in_use = true; + + std::memset(m_decompression_src_work_buffer, 0, sizeof(m_decompression_src_work_buffer)); + std::memset(m_decompression_dst_work_buffer, 0, sizeof(m_decompression_dst_work_buffer)); } void Finalize() { @@ -104,7 +121,7 @@ namespace ams::ro::impl { if (m_process_handle != os::InvalidNativeHandle) { for (size_t i = 0; i < MaxNrrInfos; i++) { if (m_nrr_in_use[i]) { - UnmapNrr(m_process_handle, m_nrr_infos[i].mapped_header, m_nrr_infos[i].nrr_heap_address, m_nrr_infos[i].nrr_heap_size, m_nrr_infos[i].mapped_code_address); + R_DISCARD(UnmapNrr(m_process_handle, m_nrr_infos[i].mapped_header, m_nrr_infos[i].nrr_heap_address, m_nrr_infos[i].nrr_heap_size, m_nrr_infos[i].mapped_code_address)); } } os::CloseNativeHandle(m_process_handle); @@ -117,8 +134,11 @@ namespace ams::ro::impl { m_process_handle = os::InvalidNativeHandle; m_process_id = os::InvalidProcessId; - + m_in_use = false; + + std::memset(m_decompression_src_work_buffer, 0, sizeof(m_decompression_src_work_buffer)); + std::memset(m_decompression_dst_work_buffer, 0, sizeof(m_decompression_dst_work_buffer)); } os::NativeHandle GetProcessHandle() const { @@ -246,21 +266,12 @@ namespace ams::ro::impl { R_THROW(ro::ResultNotAuthorized()); } - - Result ValidateNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, bool *out_aligned_header, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) { - /* Map the NRO. */ - void *mapped_memory = nullptr; - R_TRY_CATCH(os::MapProcessMemory(std::addressof(mapped_memory), m_process_handle, base_address, expected_nro_size, ro::impl::GenerateSecureRandom)) { - R_CONVERT(os::ResultOutOfAddressSpace, ro::ResultOutOfAddressSpace()) - } R_END_TRY_CATCH; - - /* When we're done, unmap the memory. */ - ON_SCOPE_EXIT { os::UnmapProcessMemory(mapped_memory, m_process_handle, base_address, expected_nro_size); }; - + + Result ValidateNro(NroHeader **out_header, AdditionalNroHeaderInfo *out_additional_header_info, void *out_additional_header_hash, u8 *mapped_memory, u64 expected_nro_size, u64 expected_bss_size) { /* Validate header. */ - const NroHeader *header = static_cast(mapped_memory); + NroHeader *header = reinterpret_cast(mapped_memory); R_UNLESS(header->IsMagicValid(), ro::ResultInvalidNro()); - + /* Read sizes from header. */ const u64 nro_size = header->GetSize(); const u64 text_ofs = header->GetTextOffset(); @@ -270,17 +281,28 @@ namespace ams::ro::impl { const u64 rw_ofs = header->GetRwOffset(); const u64 rw_size = header->GetRwSize(); const u64 bss_size = header->GetBssSize(); - - /* Validate sizes meet expected. */ - R_UNLESS(nro_size == expected_nro_size, ro::ResultInvalidNro()); - R_UNLESS(bss_size == expected_bss_size, ro::ResultInvalidNro()); - + /* Validate all sizes are aligned. */ R_UNLESS(util::IsAligned(text_size, os::MemoryPageSize), ro::ResultInvalidNro()); R_UNLESS(util::IsAligned(ro_size, os::MemoryPageSize), ro::ResultInvalidNro()); R_UNLESS(util::IsAligned(rw_size, os::MemoryPageSize), ro::ResultInvalidNro()); R_UNLESS(util::IsAligned(bss_size, os::MemoryPageSize), ro::ResultInvalidNro()); + /* Validate sizes meet expected. */ + R_UNLESS(nro_size == expected_nro_size, ro::ResultInvalidNro()); + + /* Account for compression when checking bss size. */ + if (header->IsCompress()) { + R_UNLESS((bss_size - expected_nro_size + (rw_ofs + rw_size)) == expected_bss_size, ro::ResultInvalidBssSize()); + } else { + /* 23.0.0+ uses the new error code here too. */ + if (hos::GetVersion() >= hos::Version_23_0_0) { + R_UNLESS(bss_size == expected_bss_size, ro::ResultInvalidBssSize()); + } else { + R_UNLESS(bss_size == expected_bss_size, ro::ResultInvalidNro()); + } + } + /* Validate sections are in order. */ R_UNLESS(text_ofs <= ro_ofs, ro::ResultInvalidNro()); R_UNLESS(ro_ofs <= rw_ofs, ro::ResultInvalidNro()); @@ -289,24 +311,160 @@ namespace ams::ro::impl { R_UNLESS(text_ofs == 0, ro::ResultInvalidNro()); R_UNLESS(text_ofs + text_size == ro_ofs, ro::ResultInvalidNro()); R_UNLESS(ro_ofs + ro_size == rw_ofs, ro::ResultInvalidNro()); - R_UNLESS(rw_ofs + rw_size == nro_size, ro::ResultInvalidNro()); - + + /* Only check data section if not using compression. */ + if (!header->IsCompress()) { + R_UNLESS(rw_ofs + rw_size == nro_size, ro::ResultInvalidNro()); + } + /* Verify NRO hash. */ R_TRY(this->ValidateHasNroHash(header)); /* Check if NRO has already been loaded. */ const ModuleId *module_id = header->GetModuleId(); R_UNLESS(R_FAILED(this->GetNroInfoByModuleId(nullptr, module_id)), ro::ResultAlreadyLoaded()); + + /* Validate compression related fields. */ + if (header->IsCompress()) { + const u64 additional_header_offset = header->GetAdditionalHeaderOffset(); + + /* Compression must have aligned header as well. */ + R_UNLESS(header->IsAlignedHeader(), ro::ResultInvalidNro()); + + /* Validate additional header offset. */ + R_UNLESS(additional_header_offset == 0x80, ro::ResultInvalidNro()); + + /* Validate additional header. */ + AdditionalNroHeader *additional_header = reinterpret_cast(mapped_memory + additional_header_offset); + R_UNLESS(additional_header->IsMagicValid(), ro::ResultInvalidNro()); + + /* Read sizes from header. */ + const u64 hash_size = additional_header->GetHashSize(); + const u64 hash_offset = additional_header->GetHashOffset(); + const u64 compressed_size = additional_header->GetCompressedSize(); + + /* Validate additional header hash size and offset. */ + R_UNLESS(hash_size == 0x20, ro::ResultInvalidNro()); + R_UNLESS(hash_offset == 0xE0, ro::ResultInvalidNro()); + + /* Copy the additional header hash to output. */ + std::memcpy(out_additional_header_hash, additional_header->GetHash(), hash_size); + + /* Validate compressed size. */ + R_UNLESS(rw_ofs + rw_size > nro_size, ro::ResultInvalidNro()); + R_UNLESS(compressed_size >= 0x1000, ro::ResultInvalidNro()); + R_UNLESS(util::AlignUp(compressed_size, os::MemoryPageSize) == expected_nro_size, ro::ResultInvalidNro()); + + /* Copy the additional header info to output. This is AdditionalNroHeader minus the hash. */ + std::memcpy(reinterpret_cast(out_additional_header_info), additional_header, sizeof(AdditionalNroHeader) - hash_size); + } else { + /* Explicitly clear additional header hash and info. */ + std::memset(out_additional_header_hash, 0, crypto::Sha256Generator::HashSize); + std::memset(reinterpret_cast(out_additional_header_info), 0, sizeof(AdditionalNroHeaderInfo)); + } + + /* Copy the header to output. */ + *out_header = header; + R_SUCCEED(); + } + + Result DecompressNro(u8 *mapped_nro, u64 total_size, const NroHeader *nro_header, u32 compressed_size) { + /* Read sizes from header. */ + const u64 rw_ofs = nro_header->GetRwOffset(); + const u64 rw_size = nro_header->GetRwSize(); + const u64 bss_size = nro_header->GetBssSize(); + + /* Divide the mapped NRO into regions devised for the decompression. */ + u8 *nro_aligned_start = static_cast(mapped_nro + 0x1000); + const u8 *nro_expected_end = static_cast(mapped_nro + total_size); + const u64 nro_src_buffer_size = compressed_size - 0x1000; + u8 *nro_src_buffer = static_cast(mapped_nro + total_size - nro_src_buffer_size); + const u64 nro_dst_buffer_size = total_size - 0xC00; + u8 *nro_dst_buffer = static_cast(mapped_nro + 0xC00); + + /* Copy to source buffer. */ + std::memmove(nro_src_buffer, nro_aligned_start, nro_src_buffer_size); + + /* Decompress. */ + u64 decompressed_size = 0; + R_UNLESS(util::DecompressLZ4Frame(std::addressof(decompressed_size), nro_dst_buffer, nro_dst_buffer_size, nro_src_buffer, nro_src_buffer_size, m_decompression_src_work_buffer, sizeof(m_decompression_src_work_buffer), m_decompression_dst_work_buffer, sizeof(m_decompression_dst_work_buffer)) == 0, ro::ResultInvalidNro()); + + /* Find the BSS. */ + u8 *nro_expected_bss_start = static_cast(mapped_nro + rw_ofs + rw_size); + const u8 *nro_expected_bss_end = static_cast(nro_expected_bss_start + bss_size); + const u8 *nro_bss_start = static_cast(nro_expected_bss_start - 0x400); + const u8 *nro_decompressed_end = static_cast(nro_dst_buffer + decompressed_size); + + /* The decompressed data must end at the expected BSS start. */ + if (nro_decompressed_end == nro_bss_start) { + /* Copy the decompressed data back to the mapped NRO memory. */ + std::memmove(nro_aligned_start, nro_dst_buffer, decompressed_size); + std::memset(nro_dst_buffer, 0, 0x400); + + /* Check the BSS ends where it's supposed, initialize it and then succeed. */ + if (nro_expected_bss_end == nro_expected_end) { + std::memset(nro_expected_bss_start, 0, bss_size); + R_SUCCEED(); + } + } + + /* Clear the decompressed data buffer in case of error. */ + std::memset(nro_dst_buffer, 0, nro_dst_buffer_size); + R_THROW(ro::ResultInvalidNro()); + } + + Result CheckAdditionalHeaderHash(const u8 *mapped_nro, const void *additional_nro_header_hash, size_t additional_nro_header_hash_size, u64 rw_ofs, u64 rw_size) { + /* Calculate hash. */ + Sha256Hash nro_rw_hash; + crypto::GenerateSha256(std::addressof(nro_rw_hash), additional_nro_header_hash_size, mapped_nro + 0x1000, (rw_ofs + rw_size) - 0x1000); + + /* Compare the hashes. */ + const Sha256Hash *expected_hash = reinterpret_cast(additional_nro_header_hash); + if (*expected_hash != nro_rw_hash) { + R_THROW(ro::ResultInvalidNro()); + } + R_SUCCEED(); + } + Result ParseNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, u64 *out_bss_size, bool *out_aligned_header, bool *out_is_compress, u64 base_address, u64 total_size, u64 expected_nro_size, u64 expected_bss_size) { + /* Map the NRO. */ + void *mapped_memory = nullptr; + R_TRY_CATCH(os::MapProcessMemory(std::addressof(mapped_memory), m_process_handle, base_address, total_size, ro::impl::GenerateSecureRandom)) { + R_CONVERT(os::ResultOutOfAddressSpace, ro::ResultOutOfAddressSpace()) + } R_END_TRY_CATCH; + + /* When we're done, unmap the memory. */ + ON_SCOPE_EXIT { os::UnmapProcessMemory(mapped_memory, m_process_handle, base_address, total_size); }; + + /* ValidateNro */ + NroHeader *nro_header = nullptr; + AdditionalNroHeaderInfo additional_nro_header_info; + u8 additional_nro_header_hash[crypto::Sha256Generator::HashSize]; + R_TRY(this->ValidateNro(std::addressof(nro_header), std::addressof(additional_nro_header_info), std::addressof(additional_nro_header_hash), static_cast(mapped_memory), expected_nro_size, expected_bss_size)); + + /* DecompressNro */ + if (nro_header->IsCompress()) { + R_TRY(this->DecompressNro(static_cast(mapped_memory), total_size, nro_header, additional_nro_header_info.compressed_size)); + + /* CheckAdditionalHeaderHash */ + if (nro_header->GetAdditionalHeaderOffset() != 0) { + R_TRY(this->CheckAdditionalHeaderHash(static_cast(mapped_memory), std::addressof(additional_nro_header_hash), sizeof(additional_nro_header_hash), nro_header->GetRwOffset(), nro_header->GetRwSize())); + ON_RESULT_FAILURE { std::memset(static_cast(mapped_memory) + 0x1000, 0, total_size - 0x1000); }; + } + } + /* Apply patches to NRO. */ - LocateAndApplyIpsPatchesToModule(module_id, static_cast(mapped_memory), nro_size); + const ModuleId *module_id = nro_header->GetModuleId(); + LocateAndApplyIpsPatchesToModule(module_id, static_cast(mapped_memory), nro_header->GetSize()); /* Copy to output. */ *out_module_id = *module_id; - *out_rx_size = text_size; - *out_ro_size = ro_size; - *out_rw_size = rw_size; - *out_aligned_header = header->IsAlignedHeader(); + *out_rx_size = nro_header->GetTextSize(); + *out_ro_size = nro_header->GetRoSize(); + *out_rw_size = nro_header->GetRwSize(); + *out_bss_size = nro_header->GetBssSize(); + *out_aligned_header = nro_header->IsAlignedHeader(); + *out_is_compress = nro_header->IsCompress(); R_SUCCEED(); } @@ -547,26 +705,35 @@ namespace ams::ro::impl { /* Check we have space for a new NRO. */ NroInfo *nro_info = nullptr; R_TRY(context->GetFreeNroInfo(std::addressof(nro_info))); + + /* Map the NRO. */ + R_TRY(MapNro(std::addressof(nro_info->base_address), context->GetProcessHandle(), nro_address, nro_size, bss_address, bss_size)); + + /* Parse the NRO. */ + u64 nro_rx_size = 0, nro_ro_size = 0, nro_rw_size = 0, nro_bss_size = 0; + bool nro_aligned_header = false; + bool nro_is_compress = false; + R_TRY(context->ParseNro(std::addressof(nro_info->module_id), std::addressof(nro_rx_size), std::addressof(nro_ro_size), std::addressof(nro_rw_size), std::addressof(nro_bss_size), std::addressof(nro_aligned_header), std::addressof(nro_is_compress), nro_info->base_address, total_size, nro_size, bss_size)); + ON_RESULT_FAILURE { R_DISCARD(UnmapNro(context->GetProcessHandle(), nro_info->base_address, nro_address, nro_size, bss_address, bss_size)); }; + + /* Set NRO perms. */ + R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, nro_rx_size, nro_ro_size, nro_rw_size + nro_bss_size, nro_aligned_header)); + ON_RESULT_FAILURE_2 { if (!nro_is_compress) { R_DISCARD(UnmapNro(context->GetProcessHandle(), nro_info->base_address, nro_address, nro_size, bss_address, bss_size)); } }; + + context->SetNroInfoInUse(nro_info, true); nro_info->nro_heap_address = nro_address; nro_info->nro_heap_size = nro_size; nro_info->bss_heap_address = bss_address; nro_info->bss_heap_size = bss_size; - - /* Map the NRO. */ - R_TRY(MapNro(std::addressof(nro_info->base_address), context->GetProcessHandle(), nro_address, nro_size, bss_address, bss_size)); - ON_RESULT_FAILURE { UnmapNro(context->GetProcessHandle(), nro_info->base_address, nro_address, nro_size, bss_address, bss_size); }; - - /* Validate the NRO (parsing region extents). */ - u64 rx_size = 0, ro_size = 0, rw_size = 0; - bool aligned_header = false; - R_TRY(context->ValidateNro(std::addressof(nro_info->module_id), std::addressof(rx_size), std::addressof(ro_size), std::addressof(rw_size), std::addressof(aligned_header), nro_info->base_address, nro_size, bss_size)); - - /* Set NRO perms. */ - R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, rx_size, ro_size, rw_size + bss_size, aligned_header)); - - context->SetNroInfoInUse(nro_info, true); - nro_info->code_size = rx_size + ro_size; - nro_info->rw_size = rw_size; + if (hos::GetVersion() >= hos::Version_23_0_0) { + nro_info->code_size = nro_rx_size; + nro_info->ro_size = nro_ro_size; + } else { + nro_info->code_size = nro_rx_size + nro_ro_size; + nro_info->ro_size = 0; + } + nro_info->rw_size = nro_rw_size; + nro_info->is_compress = nro_is_compress; *out_address = nro_info->base_address; R_SUCCEED(); } @@ -582,6 +749,25 @@ namespace ams::ro::impl { /* Check the NRO is loaded. */ NroInfo *nro_info = nullptr; R_TRY(context->GetNroInfoByAddress(std::addressof(nro_info), nro_address)); + + /* Handle compression related mappings. */ + if (nro_info->is_compress) { + const u64 code_address = nro_info->base_address + 0x1000; + const u64 code_size = nro_info->code_size - 0x1000; + + /* Remove code region permissions. */ + R_TRY(os::SetProcessMemoryPermission(context->GetProcessHandle(), code_address, code_size, os::MemoryPermission_None)); + + /* Map the code region. */ + void *mapped_memory = nullptr; + R_TRY(os::MapProcessMemory(std::addressof(mapped_memory), context->GetProcessHandle(), code_address, code_size, ro::impl::GenerateSecureRandom)); + + /* Clear the memory. */ + std::memset(mapped_memory, 0, code_size); + + /* Unmap the code region. */ + os::UnmapProcessMemory(mapped_memory, context->GetProcessHandle(), code_address, code_size); + } /* Unmap. */ const NroInfo nro_backup = *nro_info; @@ -590,7 +776,11 @@ namespace ams::ro::impl { context->SetNroInfoInUse(nro_info, false); std::memset(nro_info, 0, sizeof(*nro_info)); } - R_RETURN(UnmapNro(context->GetProcessHandle(), nro_backup.base_address, nro_backup.nro_heap_address, nro_backup.code_size + nro_backup.rw_size, nro_backup.bss_heap_address, nro_backup.bss_heap_size)); + if (hos::GetVersion() >= hos::Version_23_0_0) { + R_RETURN(UnmapNro(context->GetProcessHandle(), nro_backup.base_address, nro_backup.nro_heap_address, nro_backup.nro_heap_size, nro_backup.bss_heap_address, nro_backup.bss_heap_size)); + } else { + R_RETURN(UnmapNro(context->GetProcessHandle(), nro_backup.base_address, nro_backup.nro_heap_address, nro_backup.code_size + nro_backup.rw_size, nro_backup.bss_heap_address, nro_backup.bss_heap_size)); + } } /* Debug service implementations. */ diff --git a/stratosphere/ro/source/ro_ro_service.cpp b/stratosphere/ro/source/ro_ro_service.cpp index ec309fb63..e25c326da 100644 --- a/stratosphere/ro/source/ro_ro_service.cpp +++ b/stratosphere/ro/source/ro_ro_service.cpp @@ -60,7 +60,7 @@ namespace ams::ro { R_RETURN(impl::RegisterProcess(std::addressof(m_context_id), std::move(process_h), client_pid.GetValue())); } - Result RoService::RegisterProcessModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle &&process_h) { + Result RoService::RegisterModuleInfoWithUserProcessHandle(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle &&process_h) { /* Validate the process. */ R_TRY(impl::ValidateProcess(m_context_id, client_pid.GetValue())); diff --git a/stratosphere/ro/source/ro_ro_service.hpp b/stratosphere/ro/source/ro_ro_service.hpp index a97a9fe15..db5d2f24b 100644 --- a/stratosphere/ro/source/ro_ro_service.hpp +++ b/stratosphere/ro/source/ro_ro_service.hpp @@ -38,7 +38,7 @@ namespace ams::ro { Result RegisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size); Result UnregisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address); Result RegisterProcessHandle(const sf::ClientProcessId &client_pid, sf::CopyHandle &&process_h); - Result RegisterProcessModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle &&process_h); + Result RegisterModuleInfoWithUserProcessHandle(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle &&process_h); }; static_assert(ro::impl::IsIRoInterface); diff --git a/stratosphere/spl/source/spl_main.cpp b/stratosphere/spl/source/spl_main.cpp index a6e1134a1..b9d2491d5 100644 --- a/stratosphere/spl/source/spl_main.cpp +++ b/stratosphere/spl/source/spl_main.cpp @@ -147,7 +147,7 @@ namespace ams { R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_Ssl, SslServiceName, SslMaxSessions)); R_ABORT_UNLESS(g_server_manager.RegisterServer(PortIndex_Es, EsServiceName, EsMaxSessions)); if (fw_ver >= hos::Version_5_0_0) { - g_server_manager.RegisterServer(PortIndex_Manu, ManuServiceName, ManuMaxSessions); + R_DISCARD(g_server_manager.RegisterServer(PortIndex_Manu, ManuServiceName, ManuMaxSessions)); } } diff --git a/stratosphere/spl/source/spl_secure_monitor_manager.cpp b/stratosphere/spl/source/spl_secure_monitor_manager.cpp index c31bae8bf..39ed37b3e 100644 --- a/stratosphere/spl/source/spl_secure_monitor_manager.cpp +++ b/stratosphere/spl/source/spl_secure_monitor_manager.cpp @@ -164,7 +164,7 @@ namespace ams::spl { for (auto i = 0; i < impl::AesKeySlotCount; ++i) { if (m_aes_keyslot_owners[i] == owner) { m_aes_keyslot_owners[i] = nullptr; - impl::DeallocateAesKeySlot(impl::AesKeySlotMin + i); + R_DISCARD(impl::DeallocateAesKeySlot(impl::AesKeySlotMin + i)); } } } diff --git a/troposphere/haze/include/haze/console_main_loop.hpp b/troposphere/haze/include/haze/console_main_loop.hpp index 184c36fc6..ce54bad69 100644 --- a/troposphere/haze/include/haze/console_main_loop.hpp +++ b/troposphere/haze/include/haze/console_main_loop.hpp @@ -214,8 +214,8 @@ namespace haze { event_reactor.SetResult(ResultSuccess()); /* Configure the PTP responder and console main loop. */ - ptp_responder.Initialize(std::addressof(event_reactor), std::addressof(ptp_object_heap)); - console_main_loop.Initialize(std::addressof(event_reactor), std::addressof(ptp_object_heap)); + R_DISCARD(ptp_responder.Initialize(std::addressof(event_reactor), std::addressof(ptp_object_heap))); + R_DISCARD(console_main_loop.Initialize(std::addressof(event_reactor), std::addressof(ptp_object_heap))); /* Ensure we maintain a clean state on exit. */ ON_SCOPE_EXIT { diff --git a/utilities/erpt.py b/utilities/erpt.py index 7f23d7fb4..1c0e719f4 100644 --- a/utilities/erpt.py +++ b/utilities/erpt.py @@ -253,6 +253,8 @@ CATEGORIES = { 154 : 'PscTransitionStateInfo', 155 : 'FsProxyErrorInfo3', 156 : 'BluetoothErrorInfo', + 157 : 'SystemConfigInfo', + 158 : 'ClockContextInfo', 1000 : 'TestNx', 1001 : 'NANDTypeInfo', 1002 : 'NANDExtendedCsd',