Compare commits
22 Commits
1.7.1
...
1800_suppo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cd3d29770 | ||
|
|
f860590d5f | ||
|
|
e6cf70a18a | ||
|
|
b4d453882d | ||
|
|
05df389d30 | ||
|
|
23d6014f91 | ||
|
|
496f8bf45e | ||
|
|
4974a98ec6 | ||
|
|
1f44a9c4bf | ||
|
|
6113ffa191 | ||
|
|
48e86f0406 | ||
|
|
bf3203da0f | ||
|
|
af7a200865 | ||
|
|
cfb12deb51 | ||
|
|
4aac5f0082 | ||
|
|
f5a9d1d6e8 | ||
|
|
5e63792a67 | ||
|
|
8cacb07d5f | ||
|
|
4301e948cc | ||
|
|
c331216f99 | ||
|
|
b12e89d0a9 | ||
|
|
83b3b09e73 |
@@ -3,7 +3,7 @@
|
||||
=====
|
||||
|
||||

|
||||
[](https://discordapp.com/invite/ZdqEhed)
|
||||
[](https://discordapp.com/invite/ZdqEhed)
|
||||
|
||||
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
|
||||
|
||||
|
||||
@@ -1,32 +1,4 @@
|
||||
# Changelog
|
||||
## 1.7.1
|
||||
+ Support was added for 18.1.0.
|
||||
+ Atmosphère was updated to use GCC 14/newlib (latest devkitA64/devkitARM releases).
|
||||
+ Further changes were for 18.0.0:
|
||||
+ `loader` was updated to reflect the latest official behavior.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.7.0
|
||||
+ Basic support was added for 18.0.0.
|
||||
+ The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes.
|
||||
+ There shouldn't be anything user visible resulting from this, but it will be addressed in a future atmosphère update, once I am not traveling so much.
|
||||
+ `exosphère` was updated to reflect the latest official secure monitor behavior.
|
||||
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||
+ `spl` was updated to reflect the latest official behavior.
|
||||
+ `fusee`'s no longer supports applying IPS patches to KIPs.
|
||||
+ The only KIPs that are ever present are a) atmosphère modules, b) custom system modules, or c) FS.
|
||||
+ The IPS subsystem was originally designed to make nogc patches work for FS, but these are now internal, and it appears the literal only kip patches that exist are for piracy.
|
||||
+ I could not find any kip patches posted anywhere made for any other purpose.
|
||||
+ It fundamentally does not make sense to slow down boot for every normal user for a feature that has no actual use-case, especially when `fusee` seeks to be a minimal bootloader.
|
||||
+ Minor improvements were made to atmosphere's gdbstub, including:
|
||||
+ Support was added for QStartNoAckMode.
|
||||
+ An issue was fixed that could cause a fatal error when creating too many breakpoints.
|
||||
+ A number of minor issues were fixed and improvements were made, including:
|
||||
+ `pt-BR` (`PortugueseBr`) is now accepted as a valid language when overriding game locales.
|
||||
+ A bug was fixed that could cause atmosphere to incorrectly serialize output object IDs over IPC when using domain objects.
|
||||
+ A bug was fixed in `pm`'s resource limit boost logic that could potentially cause legitimate boosts to fail in certain circumstances.
|
||||
+ `loader`/`ro` will now throw a fatal error when using invalid IPS patches that go out of bounds, instead of corrupting memory.
|
||||
+ Support was fixed for booting using a memory configuration of half of the true available memory (e.g. forcing a 4GB configuration on an 8GB board).
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 1.6.2
|
||||
+ Support was finished for 17.0.0.
|
||||
+ `erpt` was updated to support the latest official behavior.
|
||||
|
||||
4
emummc/.gitrepo
vendored
4
emummc/.gitrepo
vendored
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/m4xw/emummc
|
||||
branch = develop
|
||||
commit = f23f943d4092ca9490dbcebbdd117abc3740abcf
|
||||
parent = 1e3349e99a023517269b3fc1bc32fd84e5b3caa9
|
||||
commit = 9513a5412057b1f1bc44ed8e717c57c726763a88
|
||||
parent = e4d08ae0c5342cdb0875d164522a63ec9d233052
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
2
emummc/README.md
vendored
2
emummc/README.md
vendored
@@ -2,7 +2,7 @@
|
||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||
|
||||
### Supported Horizon Versions
|
||||
**1.0.0 - 18.1.0**
|
||||
**1.0.0 - 18.0.0**
|
||||
|
||||
## Features
|
||||
* Arbitrary SDMMC backend selection
|
||||
|
||||
8
emummc/source/FS/FS_offsets.c
vendored
8
emummc/source/FS/FS_offsets.c
vendored
@@ -71,8 +71,6 @@
|
||||
#include "offsets/1700_exfat.h"
|
||||
#include "offsets/1800.h"
|
||||
#include "offsets/1800_exfat.h"
|
||||
#include "offsets/1810.h"
|
||||
#include "offsets/1810_exfat.h"
|
||||
#include "../utils/fatal.h"
|
||||
|
||||
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
|
||||
@@ -155,8 +153,6 @@ DEFINE_OFFSET_STRUCT(_1700);
|
||||
DEFINE_OFFSET_STRUCT(_1700_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1800);
|
||||
DEFINE_OFFSET_STRUCT(_1800_EXFAT);
|
||||
DEFINE_OFFSET_STRUCT(_1810);
|
||||
DEFINE_OFFSET_STRUCT(_1810_EXFAT);
|
||||
|
||||
const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
switch (version) {
|
||||
@@ -270,10 +266,6 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1800));
|
||||
case FS_VER_18_0_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1800_EXFAT));
|
||||
case FS_VER_18_1_0:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1810));
|
||||
case FS_VER_18_1_0_EXFAT:
|
||||
return &(GET_OFFSET_STRUCT_NAME(_1810_EXFAT));
|
||||
default:
|
||||
fatal_abort(Fatal_UnknownVersion);
|
||||
}
|
||||
|
||||
3
emummc/source/FS/FS_versions.h
vendored
3
emummc/source/FS/FS_versions.h
vendored
@@ -104,9 +104,6 @@ enum FS_VER
|
||||
FS_VER_18_0_0,
|
||||
FS_VER_18_0_0_EXFAT,
|
||||
|
||||
FS_VER_18_1_0,
|
||||
FS_VER_18_1_0_EXFAT,
|
||||
|
||||
FS_VER_MAX,
|
||||
};
|
||||
|
||||
|
||||
59
emummc/source/FS/offsets/1810.h
vendored
59
emummc/source/FS/offsets/1810.h
vendored
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1810_H__
|
||||
#define __FS_1810_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1810_SDMMC_ACCESSOR_GC 0x18AB00
|
||||
#define FS_OFFSET_1810_SDMMC_ACCESSOR_SD 0x18C800
|
||||
#define FS_OFFSET_1810_SDMMC_ACCESSOR_NAND 0x18AFE0
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1810_SDMMC_WRAPPER_READ 0x186A50
|
||||
#define FS_OFFSET_1810_SDMMC_WRAPPER_WRITE 0x186AB0
|
||||
#define FS_OFFSET_1810_RTLD 0x2A3A4
|
||||
#define FS_OFFSET_1810_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44)))
|
||||
|
||||
#define FS_OFFSET_1810_CLKRST_SET_MIN_V_CLK_RATE 0x1A77D0
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1810_LOCK_MUTEX 0x17FCC0
|
||||
#define FS_OFFSET_1810_UNLOCK_MUTEX 0x17FD10
|
||||
|
||||
#define FS_OFFSET_1810_SDMMC_WRAPPER_CONTROLLER_OPEN 0x186A10
|
||||
#define FS_OFFSET_1810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x186A30
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1810_SD_MUTEX 0xFD13F0
|
||||
#define FS_OFFSET_1810_NAND_MUTEX 0xFCCB28
|
||||
#define FS_OFFSET_1810_ACTIVE_PARTITION 0xFCCB68
|
||||
#define FS_OFFSET_1810_SDMMC_DAS_HANDLE 0xFB1950
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1810_SD_DAS_INIT 0x28F24
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1810_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1810_H__
|
||||
59
emummc/source/FS/offsets/1810_exfat.h
vendored
59
emummc/source/FS/offsets/1810_exfat.h
vendored
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FS_1810_EXFAT_H__
|
||||
#define __FS_1810_EXFAT_H__
|
||||
|
||||
// Accessor vtable getters
|
||||
#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_GC 0x195B90
|
||||
#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_SD 0x197890
|
||||
#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_NAND 0x196070
|
||||
|
||||
// Hooks
|
||||
#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_READ 0x191AE0
|
||||
#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_WRITE 0x191B40
|
||||
#define FS_OFFSET_1810_EXFAT_RTLD 0x2A3A4
|
||||
#define FS_OFFSET_1810_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44)))
|
||||
|
||||
#define FS_OFFSET_1810_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1B2860
|
||||
|
||||
// Misc funcs
|
||||
#define FS_OFFSET_1810_EXFAT_LOCK_MUTEX 0x18AD50
|
||||
#define FS_OFFSET_1810_EXFAT_UNLOCK_MUTEX 0x18ADA0
|
||||
|
||||
#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x191AA0
|
||||
#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191AC0
|
||||
|
||||
// Misc Data
|
||||
#define FS_OFFSET_1810_EXFAT_SD_MUTEX 0xFE33F0
|
||||
#define FS_OFFSET_1810_EXFAT_NAND_MUTEX 0xFDEB28
|
||||
#define FS_OFFSET_1810_EXFAT_ACTIVE_PARTITION 0xFDEB68
|
||||
#define FS_OFFSET_1810_EXFAT_SDMMC_DAS_HANDLE 0xFBE950
|
||||
|
||||
// NOPs
|
||||
#define FS_OFFSET_1810_EXFAT_SD_DAS_INIT 0x28F24
|
||||
|
||||
// Nintendo Paths
|
||||
#define FS_OFFSET_1810_EXFAT_NINTENDO_PATHS \
|
||||
{ \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \
|
||||
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
|
||||
}
|
||||
|
||||
#endif // __FS_1810_EXFAT_H__
|
||||
@@ -174,9 +174,6 @@ namespace ams::nxboot {
|
||||
FsVersion_18_0_0,
|
||||
FsVersion_18_0_0_Exfat,
|
||||
|
||||
FsVersion_18_1_0,
|
||||
FsVersion_18_1_0_Exfat,
|
||||
|
||||
FsVersion_Count,
|
||||
};
|
||||
|
||||
@@ -263,9 +260,6 @@ namespace ams::nxboot {
|
||||
|
||||
{ 0x79, 0x5F, 0x5A, 0x5E, 0xB0, 0xC6, 0x77, 0x9E }, /* FsVersion_18_0_0 */
|
||||
{ 0x1E, 0x2C, 0x64, 0xB1, 0xCC, 0xE2, 0x78, 0x24 }, /* FsVersion_18_0_0_Exfat */
|
||||
|
||||
{ 0xA3, 0x39, 0xF0, 0x1C, 0x95, 0xBF, 0xA7, 0x68 }, /* FsVersion_18_1_0 */
|
||||
{ 0x20, 0x4C, 0xBA, 0x86, 0xDE, 0x08, 0x44, 0x6A }, /* FsVersion_18_1_0_Exfat */
|
||||
};
|
||||
|
||||
const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) {
|
||||
|
||||
@@ -1002,16 +1002,14 @@ namespace ams::nxboot {
|
||||
\
|
||||
constexpr u32 SrcLow = RANGE_LOW(SRC_RANGE); \
|
||||
constexpr u32 DstLow = RANGE_LOW(DST_RANGE); \
|
||||
constexpr auto Shift = (SrcLow < DstLow) ? (DstLow - SrcLow) \
|
||||
: (SrcLow - DstLow); \
|
||||
\
|
||||
cur_reg_value &= ~Mask; \
|
||||
if constexpr (SrcLow == DstLow) { \
|
||||
cur_reg_value |= (src_value & Mask); \
|
||||
} else if constexpr (SrcLow < DstLow) { \
|
||||
cur_reg_value |= ((src_value << Shift) & Mask); \
|
||||
cur_reg_value |= ((src_value << (DstLow - SrcLow)) & Mask); \
|
||||
} else { \
|
||||
cur_reg_value |= ((src_value >> Shift) & Mask); \
|
||||
cur_reg_value |= ((src_value >> (SrcLow - DstLow)) & Mask); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[subrepo]
|
||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||
branch = master
|
||||
commit = bb767869105d0eb5c38425f54bf20614639a078d
|
||||
parent = ab5cc7568430e2c1b3fa1be6be104b7c5f71eb32
|
||||
commit = bfc55834869fe24f8d94550bc6909a65ae7d35c2
|
||||
parent = 742fd16080bce8cd664d6244304a771f82e8aa04
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
|
||||
@@ -44,7 +44,7 @@ else ifeq ($(strip $(ATMOSPHERE_COMPILER_NAME)),clang)
|
||||
export ATMOSPHERE_CFLAGS += -Wno-c99-designator -Wno-gnu-alignof-expression -Wno-unused-private-field
|
||||
endif
|
||||
|
||||
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++23 -Wno-invalid-offsetof
|
||||
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++20 -Wno-invalid-offsetof
|
||||
export ATMOSPHERE_ASFLAGS :=
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace ams::kern {
|
||||
KPhysicalAddress KSystemControlBase::Init::GetKernelPhysicalBaseAddress(KPhysicalAddress base_address) {
|
||||
const size_t real_dram_size = KSystemControl::Init::GetRealMemorySize();
|
||||
const size_t intended_dram_size = KSystemControl::Init::GetIntendedMemorySize();
|
||||
if (intended_dram_size * 2 <= real_dram_size) {
|
||||
if (intended_dram_size * 2 < real_dram_size) {
|
||||
return base_address;
|
||||
} else {
|
||||
return base_address + ((real_dram_size - intended_dram_size) / 2);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/fssystem/fssystem_nca_file_system_driver.hpp>
|
||||
#include <stratosphere/ldr/ldr_platform_id.hpp>
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
@@ -26,13 +25,10 @@ namespace ams::fssystem {
|
||||
|
||||
void InvalidateHardwareAesKey();
|
||||
|
||||
bool IsValidSignatureKeyGeneration(ldr::PlatformId platform, size_t key_generation);
|
||||
|
||||
const u8 *GetAcidSignatureKeyModulus(ldr::PlatformId platform, bool prod, size_t key_generation, bool unk_unused);
|
||||
size_t GetAcidSignatureKeyModulusSize(ldr::PlatformId platform, bool unk_unused);
|
||||
|
||||
const u8 *GetAcidSignatureKeyModulus(bool prod, size_t key_generation);
|
||||
const u8 *GetAcidSignatureKeyPublicExponent();
|
||||
|
||||
constexpr inline size_t AcidSignatureKeyModulusSize = NcaCryptoConfiguration::Rsa2048KeyModulusSize;
|
||||
constexpr inline size_t AcidSignatureKeyPublicExponentSize = NcaCryptoConfiguration::Rsa2048KeyPublicExponentSize;
|
||||
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ namespace ams::hos {
|
||||
Version_17_0_0 = ::ams::TargetFirmware_17_0_0,
|
||||
Version_17_0_1 = ::ams::TargetFirmware_17_0_1,
|
||||
Version_18_0_0 = ::ams::TargetFirmware_18_0_0,
|
||||
Version_18_1_0 = ::ams::TargetFirmware_18_1_0,
|
||||
|
||||
Version_Current = ::ams::TargetFirmware_Current,
|
||||
|
||||
|
||||
@@ -1,27 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
/* TODO: Is this really a FS type? What namespace does this actually live inside? */
|
||||
enum PlatformId {
|
||||
PlatformId_Nx = 0,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
#include <stratosphere/ncm/ncm_program_location.hpp>
|
||||
#include <stratosphere/sf/sf_buffer_tags.hpp>
|
||||
#include <stratosphere/ldr/ldr_platform_id.hpp>
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
@@ -225,7 +224,6 @@ namespace ams::ldr {
|
||||
|
||||
MetaFlag_OptimizeMemoryAllocation = (1 << 4),
|
||||
MetaFlag_DisableDeviceAddressSpaceMerge = (1 << 5),
|
||||
MetaFlag_EnableAliasRegionExtraSize = (1 << 6),
|
||||
};
|
||||
|
||||
enum AddressSpaceType {
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace ams::sf {
|
||||
} else if constexpr(TransferMode == BufferTransferMode::AutoSelect) {
|
||||
return SfBufferAttr_HipcAutoSelect;
|
||||
} else {
|
||||
static_assert(false, "Invalid BufferTransferMode");
|
||||
static_assert(TransferMode != TransferMode, "Invalid BufferTransferMode");
|
||||
}
|
||||
}();
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace ams::sf {
|
||||
private:
|
||||
struct Holder {
|
||||
MemoryResource *allocator;
|
||||
alignas(alignof(T)) std::byte storage[sizeof(T)];
|
||||
typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;
|
||||
};
|
||||
public:
|
||||
void *Allocate(size_t size) {
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace ams::sf {
|
||||
|
||||
struct Globals {
|
||||
ExpHeapAllocator allocator;
|
||||
alignas(0x10) std::byte buffer[Size == 0 ? 1 : Size];
|
||||
typename std::aligned_storage<Size == 0 ? 1 : Size>::type buffer;
|
||||
};
|
||||
|
||||
static constinit inline Globals _globals = {};
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace ams::emummc {
|
||||
/* Retrieve and cache values. */
|
||||
{
|
||||
|
||||
alignas(os::MemoryPageSize) std::byte path_storage[2 * (MaxDirLen + 1)];
|
||||
typename std::aligned_storage<2 * (MaxDirLen + 1), os::MemoryPageSize>::type path_storage;
|
||||
|
||||
struct {
|
||||
char file_path[MaxDirLen + 1];
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace ams::fs {
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
namespace {
|
||||
|
||||
alignas(0x10) constinit std::byte g_fsp_service_object_buffer[0x80] = {};
|
||||
alignas(0x10) constinit std::byte g_fsp_ldr_service_object_buffer[0x80] = {};
|
||||
constinit std::aligned_storage_t<0x80> g_fsp_service_object_buffer;
|
||||
constinit std::aligned_storage_t<0x80> g_fsp_ldr_service_object_buffer;
|
||||
constinit bool g_use_static_fsp_service_object_buffer = false;
|
||||
constinit bool g_use_static_fsp_ldr_service_object_buffer = false;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace ams::fssrv::impl {
|
||||
|
||||
namespace {
|
||||
|
||||
alignas(0x10) constinit std::byte g_static_buffer_for_program_info_for_initial_process[0x80] = {};
|
||||
constinit std::aligned_storage<0x80>::type g_static_buffer_for_program_info_for_initial_process = {};
|
||||
|
||||
template<typename T>
|
||||
class StaticAllocatorForProgramInfoForInitialProcess : public std::allocator<T> {
|
||||
|
||||
@@ -22,11 +22,9 @@ namespace ams::fssystem {
|
||||
|
||||
constexpr inline const size_t KeySize = crypto::AesDecryptor128::KeySize;
|
||||
|
||||
constexpr inline const size_t NxAcidSignatureKeyGenerationMax = 1;
|
||||
constexpr inline const size_t AcidSignatureKeyGenerationMax = 1;
|
||||
|
||||
constexpr inline const size_t NxAcidSignatureKeyModulusSize = NcaCryptoConfiguration::Rsa2048KeyModulusSize;
|
||||
|
||||
constexpr inline const u8 NxAcidSignatureKeyModulusDev[NxAcidSignatureKeyGenerationMax + 1][NxAcidSignatureKeyModulusSize] = {
|
||||
constexpr inline const u8 AcidSignatureKeyModulusDev[AcidSignatureKeyGenerationMax + 1][AcidSignatureKeyModulusSize] = {
|
||||
{
|
||||
0xD6, 0x34, 0xA5, 0x78, 0x6C, 0x68, 0xCE, 0x5A, 0xC2, 0x37, 0x17, 0xF3, 0x82, 0x45, 0xC6, 0x89,
|
||||
0xE1, 0x2D, 0x06, 0x67, 0xBF, 0xB4, 0x06, 0x19, 0x55, 0x6B, 0x27, 0x66, 0x0C, 0xA4, 0xB5, 0x87,
|
||||
@@ -65,7 +63,7 @@ namespace ams::fssystem {
|
||||
}
|
||||
};
|
||||
|
||||
constexpr inline const u8 NxAcidSignatureKeyModulusProd[NxAcidSignatureKeyGenerationMax + 1][NxAcidSignatureKeyModulusSize] = {
|
||||
constexpr inline const u8 AcidSignatureKeyModulusProd[AcidSignatureKeyGenerationMax + 1][AcidSignatureKeyModulusSize] = {
|
||||
{
|
||||
0xDD, 0xC8, 0xDD, 0xF2, 0x4E, 0x6D, 0xF0, 0xCA, 0x9E, 0xC7, 0x5D, 0xC7, 0x7B, 0xAD, 0xFE, 0x7D,
|
||||
0x23, 0x89, 0x69, 0xB6, 0xF2, 0x06, 0xA2, 0x02, 0x88, 0xE1, 0x55, 0x91, 0xAB, 0xCB, 0x4D, 0x50,
|
||||
@@ -104,7 +102,7 @@ namespace ams::fssystem {
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(NxAcidSignatureKeyModulusProd) == sizeof(NxAcidSignatureKeyModulusDev));
|
||||
static_assert(sizeof(AcidSignatureKeyModulusProd) == sizeof(AcidSignatureKeyModulusDev));
|
||||
|
||||
constexpr inline const u8 AcidSignatureKeyPublicExponent[] = {
|
||||
0x01, 0x00, 0x01
|
||||
@@ -297,36 +295,10 @@ namespace ams::fssystem {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidSignatureKeyGeneration(ldr::PlatformId platform, size_t key_generation) {
|
||||
switch (platform) {
|
||||
case ldr::PlatformId_Nx:
|
||||
return key_generation <= NxAcidSignatureKeyGenerationMax;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
const u8 *GetAcidSignatureKeyModulus(ldr::PlatformId platform, bool prod, size_t key_generation, bool unk_unused) {
|
||||
AMS_ASSERT(IsValidSignatureKeyGeneration(platform, key_generation));
|
||||
AMS_UNUSED(unk_unused);
|
||||
|
||||
switch (platform) {
|
||||
case ldr::PlatformId_Nx:
|
||||
{
|
||||
const size_t used_keygen = (key_generation % (NxAcidSignatureKeyGenerationMax + 1));
|
||||
return prod ? NxAcidSignatureKeyModulusProd[used_keygen] : NxAcidSignatureKeyModulusDev[used_keygen];
|
||||
}
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
size_t GetAcidSignatureKeyModulusSize(ldr::PlatformId platform, bool unk_unused) {
|
||||
AMS_UNUSED(unk_unused);
|
||||
|
||||
switch (platform) {
|
||||
case ldr::PlatformId_Nx:
|
||||
return NxAcidSignatureKeyModulusSize;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
const u8 *GetAcidSignatureKeyModulus(bool prod, size_t key_generation) {
|
||||
AMS_ASSERT(key_generation <= AcidSignatureKeyGenerationMax);
|
||||
const size_t used_keygen = (key_generation % (AcidSignatureKeyGenerationMax + 1));
|
||||
return prod ? AcidSignatureKeyModulusProd[used_keygen] : AcidSignatureKeyModulusDev[used_keygen];
|
||||
}
|
||||
|
||||
const u8 *GetAcidSignatureKeyPublicExponent() {
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace ams::htc::server::rpc {
|
||||
#else
|
||||
static constexpr size_t MaxTaskSize = 0xE1D8;
|
||||
#endif
|
||||
struct TaskStorage { alignas(alignof(void *)) std::byte _storage[MaxTaskSize]; };
|
||||
using TaskStorage = typename std::aligned_storage<MaxTaskSize, alignof(void *)>::type;
|
||||
private:
|
||||
bool m_valid[MaxRpcCount]{};
|
||||
TaskStorage m_storages[MaxRpcCount]{};
|
||||
|
||||
@@ -19,13 +19,9 @@
|
||||
namespace ams::osdbg::impl {
|
||||
|
||||
template<size_t Size, int NumPointers, size_t Alignment>
|
||||
struct AlignedStorageIlp32 {
|
||||
alignas(Alignment) std::byte _storage[Size + NumPointers * sizeof(u32)];
|
||||
};
|
||||
using AlignedStorageIlp32 = typename std::aligned_storage<Size + NumPointers * sizeof(u32), Alignment>::type;
|
||||
|
||||
template<size_t Size, int NumPointers, size_t Alignment>
|
||||
struct AlignedStorageLp64 {
|
||||
alignas(Alignment) std::byte _storage[Size + NumPointers * sizeof(u64)];
|
||||
};
|
||||
using AlignedStorageLp64 = typename std::aligned_storage<Size + NumPointers * sizeof(u64), Alignment>::type;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 7
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 1
|
||||
#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 18
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0
|
||||
|
||||
@@ -81,9 +81,8 @@
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_17_0_0 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_17_0_1 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 1)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_18_0_0 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_18_1_0 ATMOSPHERE_TARGET_FIRMWARE(18, 1, 0)
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_18_1_0
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_18_0_0
|
||||
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
|
||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
||||
@@ -157,7 +156,6 @@ namespace ams {
|
||||
TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0,
|
||||
TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1,
|
||||
TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0,
|
||||
TargetFirmware_18_1_0 = ATMOSPHERE_TARGET_FIRMWARE_18_1_0,
|
||||
|
||||
TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ namespace ams::ldr {
|
||||
R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidPlatformId, 14);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 51);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNroImage, 52);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrrImage, 53);
|
||||
|
||||
@@ -85,13 +85,14 @@ namespace ams {
|
||||
};
|
||||
|
||||
/* Use CRTP for Results. */
|
||||
template<typename Self>
|
||||
class ResultBase {
|
||||
public:
|
||||
using BaseType = typename ResultTraits::BaseType;
|
||||
static constexpr BaseType SuccessValue = ResultTraits::SuccessValue;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE BaseType GetModule(this auto const &self) { return ResultTraits::GetModuleFromValue(self.GetValue()); }
|
||||
constexpr ALWAYS_INLINE BaseType GetDescription(this auto const &self) { return ResultTraits::GetDescriptionFromValue(self.GetValue()); }
|
||||
constexpr ALWAYS_INLINE BaseType GetModule() const { return ResultTraits::GetModuleFromValue(static_cast<const Self *>(this)->GetValue()); }
|
||||
constexpr ALWAYS_INLINE BaseType GetDescription() const { return ResultTraits::GetDescriptionFromValue(static_cast<const Self *>(this)->GetValue()); }
|
||||
};
|
||||
|
||||
class ResultInternalAccessor;
|
||||
@@ -100,10 +101,10 @@ namespace ams {
|
||||
|
||||
class ResultSuccess;
|
||||
|
||||
class Result final : public result::impl::ResultBase {
|
||||
class Result final : public result::impl::ResultBase<Result> {
|
||||
friend class result::impl::ResultInternalAccessor;
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase;
|
||||
using Base = typename result::impl::ResultBase<Result>;
|
||||
private:
|
||||
typename Base::BaseType m_value;
|
||||
private:
|
||||
@@ -156,9 +157,9 @@ namespace ams {
|
||||
|
||||
}
|
||||
|
||||
class ResultSuccess final : public result::impl::ResultBase {
|
||||
class ResultSuccess final : public result::impl::ResultBase<ResultSuccess> {
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase;
|
||||
using Base = typename result::impl::ResultBase<ResultSuccess>;
|
||||
public:
|
||||
constexpr ALWAYS_INLINE operator Result() const { return result::impl::MakeResult(Base::SuccessValue); }
|
||||
static constexpr ALWAYS_INLINE bool CanAccept(Result result) { return result.IsSuccess(); }
|
||||
@@ -188,9 +189,9 @@ namespace ams {
|
||||
namespace result::impl {
|
||||
|
||||
template<ResultTraits::BaseType _Module, ResultTraits::BaseType _Description>
|
||||
class ResultErrorBase : public ResultBase {
|
||||
class ResultErrorBase : public ResultBase<ResultErrorBase<_Module, _Description>> {
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase;
|
||||
using Base = typename result::impl::ResultBase<ResultErrorBase<_Module, _Description>>;
|
||||
static constexpr typename Base::BaseType Module = _Module;
|
||||
static constexpr typename Base::BaseType Description = _Description;
|
||||
static constexpr typename Base::BaseType Value = ResultTraits::MakeStaticValue<Module, Description>::value;
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace ams::svc::codegen::impl {
|
||||
} else if constexpr (Size == 8) {
|
||||
__asm__ __volatile__("ldr x%c[r], [sp, %c[offset]]" :: [r]"i"(Reg), [offset]"i"(Offset) : "memory");
|
||||
} else {
|
||||
static_assert(false, "Invalid Size");
|
||||
static_assert(Size != Size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace ams::svc::codegen::impl {
|
||||
} else if constexpr (Size == 8) {
|
||||
__asm__ __volatile__("ldp x%c[r0], x%c[r1], [sp, %c[offset]]" :: [r0]"i"(Reg0), [r1]"i"(Reg1), [offset]"i"(Offset) : "memory");
|
||||
} else {
|
||||
static_assert(false, "Invalid Size");
|
||||
static_assert(Size != Size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace ams::svc::codegen::impl {
|
||||
} else if constexpr (Size == 8) {
|
||||
__asm__ __volatile__("str x%c[r], [sp, %c[offset]]" :: [r]"i"(Reg), [offset]"i"(Offset) : "memory");
|
||||
} else {
|
||||
static_assert(false, "Invalid Size");
|
||||
static_assert(Size != Size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace ams::svc::codegen::impl {
|
||||
} else if constexpr (Size == 8) {
|
||||
__asm__ __volatile__("stp x%c[r0], x%c[r1], [sp, %c[offset]]" :: [r0]"i"(Reg0), [r1]"i"(Reg1), [offset]"i"(Offset) : "memory");
|
||||
} else {
|
||||
static_assert(false, "Invalid Size");
|
||||
static_assert(Size != Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -461,7 +461,7 @@ namespace ams::svc::codegen::impl {
|
||||
if constexpr (CodeGenKind == CodeGenerationKind::SvcInvocationToKernelProcedure) {
|
||||
return Operation::ImplType::template CanGenerateCodeForSvcInvocationToKernelProcedure<Operation>(allocator);
|
||||
} else {
|
||||
static_assert(false, "Invalid CodeGenerationKind");
|
||||
static_assert(CodeGenKind != CodeGenKind, "Invalid CodeGenerationKind");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +474,7 @@ namespace ams::svc::codegen::impl {
|
||||
} else if constexpr (CodeGenKind == CodeGenerationKind::KernelProcedureToSvcInvocation) {
|
||||
Operation::ImplType::template GenerateCodeForKernelProcedureToSvcInvocation<Operation>(mcg);
|
||||
} else {
|
||||
static_assert(false, "Invalid CodeGenerationKind");
|
||||
static_assert(CodeGenKind != CodeGenKind, "Invalid CodeGenerationKind");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace ams::svc::codegen::impl {
|
||||
META_CODE_OPERATION_KIND_GENERATE_CODE(Pack)
|
||||
META_CODE_OPERATION_KIND_GENERATE_CODE(Unpack)
|
||||
META_CODE_OPERATION_KIND_GENERATE_CODE(LoadStackAddress)
|
||||
else { static_assert(false, "Unknown MetaOperationKind"); }
|
||||
else { static_assert(Kind != Kind, "Unknown MetaOperationKind"); }
|
||||
#undef META_CODE_OPERATION_KIND_GENERATE_CODE
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace ams::util {
|
||||
} else if constexpr (Order == std::memory_order_acq_rel || Order == std::memory_order_seq_cst) {
|
||||
return ::ams::util::impl::LoadAcquireExclusiveForAtomic(p);
|
||||
} else {
|
||||
static_assert(false, "Invalid memory order");
|
||||
static_assert(Order != Order, "Invalid memory order");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace ams::util {
|
||||
} else if constexpr (Order == std::memory_order_acq_rel || Order == std::memory_order_seq_cst) {
|
||||
return ::ams::util::impl::StoreReleaseExclusiveForAtomic(p, s);
|
||||
} else {
|
||||
static_assert(false, "Invalid memory order");
|
||||
static_assert(Order != Order, "Invalid memory order");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace ams::util {
|
||||
|
||||
template<typename T, size_t Size = sizeof(T), size_t Align = alignof(T)>
|
||||
struct TypedStorage {
|
||||
alignas(Align) std::byte _storage[Size];
|
||||
typename std::aligned_storage<Size, Align>::type _storage;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* ScopedCodeMount functionality. */
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, PlatformId platform) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
|
||||
m_result = this->Initialize(loc, platform);
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
|
||||
m_result = this->Initialize(loc);
|
||||
}
|
||||
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, PlatformId platform) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
|
||||
m_result = this->Initialize(loc, platform);
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
|
||||
m_result = this->Initialize(loc);
|
||||
}
|
||||
|
||||
ScopedCodeMount::~ScopedCodeMount() {
|
||||
@@ -46,28 +46,25 @@ namespace ams::ldr {
|
||||
}
|
||||
}
|
||||
|
||||
Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, PlatformId platform) {
|
||||
Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc) {
|
||||
/* Capture override status, if necessary. */
|
||||
this->EnsureOverrideStatus(loc);
|
||||
AMS_ABORT_UNLESS(m_has_status);
|
||||
|
||||
/* Get the content path. */
|
||||
char content_path[fs::EntryNameLengthMax + 1];
|
||||
R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, platform));
|
||||
|
||||
/* Get the content attributes. */
|
||||
const auto content_attributes = GetPlatformContentAttributes(platform);
|
||||
R_TRY(GetProgramPath(content_path, sizeof(content_path), loc));
|
||||
|
||||
/* Mount the atmosphere code file system. */
|
||||
R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, m_override_status.IsHbl(), m_override_status.IsProgramSpecific()));
|
||||
R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, fs::ContentAttributes_None, loc.program_id, m_override_status.IsHbl(), m_override_status.IsProgramSpecific()));
|
||||
m_mounted_ams = true;
|
||||
|
||||
/* Mount the sd or base code file system. */
|
||||
R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, content_attributes, loc.program_id));
|
||||
R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, fs::ContentAttributes_None, loc.program_id));
|
||||
m_mounted_sd_or_code = true;
|
||||
|
||||
/* Mount the base code file system. */
|
||||
if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, content_attributes, loc.program_id))) {
|
||||
if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, fs::ContentAttributes_None, loc.program_id))) {
|
||||
m_mounted_code = true;
|
||||
}
|
||||
|
||||
@@ -83,7 +80,7 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* Redirection API. */
|
||||
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, PlatformId platform) {
|
||||
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc) {
|
||||
/* Check for storage id none. */
|
||||
if (static_cast<ncm::StorageId>(loc.storage_id) == ncm::StorageId::None) {
|
||||
std::memset(out_path, 0, out_size);
|
||||
@@ -91,10 +88,6 @@ namespace ams::ldr {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Get the content attributes. */
|
||||
const auto content_attributes = GetPlatformContentAttributes(platform);
|
||||
AMS_UNUSED(content_attributes);
|
||||
|
||||
lr::Path path;
|
||||
|
||||
/* Check that path registration is allowable. */
|
||||
@@ -166,12 +159,4 @@ namespace ams::ldr {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
fs::ContentAttributes GetPlatformContentAttributes(PlatformId platform) {
|
||||
switch (platform) {
|
||||
case PlatformId_Nx:
|
||||
return fs::ContentAttributes_None;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace ams::ldr {
|
||||
bool m_mounted_sd_or_code;
|
||||
bool m_mounted_code;
|
||||
public:
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc, PlatformId platform);
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, PlatformId platform);
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc);
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status);
|
||||
~ScopedCodeMount();
|
||||
|
||||
Result GetResult() const {
|
||||
@@ -59,27 +59,21 @@ namespace ams::ldr {
|
||||
return m_base_code_verification_data;
|
||||
}
|
||||
private:
|
||||
Result Initialize(const ncm::ProgramLocation &loc, PlatformId platform);
|
||||
Result Initialize(const ncm::ProgramLocation &loc);
|
||||
void EnsureOverrideStatus(const ncm::ProgramLocation &loc);
|
||||
};
|
||||
|
||||
constexpr inline const char * const AtmosphereCodeMountName = "ams-code";
|
||||
constexpr inline const char * const AtmosphereCompatMountName = "ams-cmpt";
|
||||
constexpr inline const char * const SdOrCodeMountName = "sd-code";
|
||||
constexpr inline const char * const CodeMountName = "code";
|
||||
constexpr inline const char * const CompatMountName = "cmpt";
|
||||
constexpr inline const char * const AtmosphereCodeMountName = "ams-code";
|
||||
constexpr inline const char * const SdOrCodeMountName = "sd-code";
|
||||
constexpr inline const char * const CodeMountName = "code";
|
||||
|
||||
#define ENCODE_ATMOSPHERE_CODE_PATH(relative) "ams-code:" relative
|
||||
#define ENCODE_ATMOSPHERE_CMPT_PATH(relative) "ams-cmpt:" relative
|
||||
#define ENCODE_SD_OR_CODE_PATH(relative) "sd-code:" relative
|
||||
#define ENCODE_CODE_PATH(relative) "code:" relative
|
||||
#define ENCODE_CMPT_PATH(relative) "cmpt:" relative
|
||||
|
||||
/* Redirection API. */
|
||||
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, PlatformId platform);
|
||||
Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc);
|
||||
Result RedirectProgramPath(const char *path, size_t size, const ncm::ProgramLocation &loc);
|
||||
Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc);
|
||||
|
||||
fs::ContentAttributes GetPlatformContentAttributes(PlatformId platform);
|
||||
|
||||
}
|
||||
|
||||
@@ -27,72 +27,56 @@ namespace ams::ldr {
|
||||
|
||||
constinit ArgumentStore g_argument_store;
|
||||
|
||||
bool IsValidPlatform(PlatformId platform) {
|
||||
return platform == PlatformId_Nx;
|
||||
}
|
||||
|
||||
Result CreateProcessByPlatform(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, PlatformId platform) {
|
||||
/* Check that the platform is valid. */
|
||||
R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId());
|
||||
|
||||
/* Get the location and override status. */
|
||||
ncm::ProgramLocation loc;
|
||||
cfg::OverrideStatus override_status;
|
||||
R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id));
|
||||
|
||||
/* Get the program path. */
|
||||
char path[fs::EntryNameLengthMax];
|
||||
R_TRY(GetProgramPath(path, sizeof(path), loc, platform));
|
||||
path[sizeof(path) - 1] = '\x00';
|
||||
|
||||
/* Create the process. */
|
||||
R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, platform));
|
||||
}
|
||||
|
||||
Result GetProgramInfoByPlatform(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, PlatformId platform) {
|
||||
/* Check that the platform is valid. */
|
||||
R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId());
|
||||
|
||||
/* Zero output. */
|
||||
std::memset(out, 0, sizeof(*out));
|
||||
|
||||
/* Get the program path. */
|
||||
char path[fs::EntryNameLengthMax];
|
||||
R_TRY(GetProgramPath(path, sizeof(path), loc, platform));
|
||||
path[sizeof(path) - 1] = '\x00';
|
||||
|
||||
/* Get the program info. */
|
||||
cfg::OverrideStatus status;
|
||||
R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, platform));
|
||||
|
||||
if (loc.program_id != out->program_id) {
|
||||
/* Redirect the program path. */
|
||||
const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast<ncm::StorageId>(loc.storage_id));
|
||||
R_TRY(RedirectProgramPath(path, sizeof(path), new_loc));
|
||||
|
||||
/* Update the arguments, as needed. */
|
||||
if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) {
|
||||
R_TRY(g_argument_store.Set(new_loc.program_id, entry->argument, entry->argument_size));
|
||||
}
|
||||
}
|
||||
|
||||
/* If we should, set the output status. */
|
||||
if (out_status != nullptr) {
|
||||
*out_status = status;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit) {
|
||||
R_RETURN(CreateProcessByPlatform(out, pin_id, flags, resource_limit, PlatformId_Nx));
|
||||
/* Declare program path, which we'll need later. */
|
||||
|
||||
/* Get the location and override status. */
|
||||
ncm::ProgramLocation loc;
|
||||
cfg::OverrideStatus override_status;
|
||||
R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id));
|
||||
|
||||
/* Get the program path. */
|
||||
char path[fs::EntryNameLengthMax];
|
||||
R_TRY(GetProgramPath(path, sizeof(path), loc));
|
||||
path[sizeof(path) - 1] = '\x00';
|
||||
|
||||
/* Create the process. */
|
||||
R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit));
|
||||
}
|
||||
|
||||
Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) {
|
||||
R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, PlatformId_Nx));
|
||||
/* Zero output. */
|
||||
std::memset(out, 0, sizeof(*out));
|
||||
|
||||
/* Get the program path. */
|
||||
char path[fs::EntryNameLengthMax];
|
||||
R_TRY(GetProgramPath(path, sizeof(path), loc));
|
||||
path[sizeof(path) - 1] = '\x00';
|
||||
|
||||
/* Get the program info. */
|
||||
cfg::OverrideStatus status;
|
||||
R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path));
|
||||
|
||||
if (loc.program_id != out->program_id) {
|
||||
/* Redirect the program path. */
|
||||
const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast<ncm::StorageId>(loc.storage_id));
|
||||
R_TRY(RedirectProgramPath(path, sizeof(path), new_loc));
|
||||
|
||||
/* Update the arguments, as needed. */
|
||||
if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) {
|
||||
R_TRY(this->SetProgramArgument(new_loc.program_id, entry->argument, entry->argument_size));
|
||||
}
|
||||
}
|
||||
|
||||
/* If we should, set the output status. */
|
||||
if (out_status != nullptr) {
|
||||
*out_status = status;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result LoaderService::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
|
||||
|
||||
@@ -55,8 +55,21 @@ namespace ams::ldr {
|
||||
R_UNLESS(npdm->magic == Npdm::Magic, ldr::ResultInvalidMeta());
|
||||
|
||||
/* Validate flags. */
|
||||
constexpr u32 InvalidMetaFlagMask = 0x80000000;
|
||||
R_UNLESS(!(npdm->flags & InvalidMetaFlagMask), ldr::ResultInvalidMeta());
|
||||
u32 mask;
|
||||
if (hos::GetVersion() >= hos::Version_11_0_0) {
|
||||
/* 11.0.0 added bit 5 = "DisableDeviceAddressSpaceMerge". */
|
||||
mask = ~0x3F;
|
||||
} else if (hos::GetVersion() >= hos::Version_7_0_0) {
|
||||
/* 7.0.0 added bit 4 = "UseOptimizedMemory" */
|
||||
mask = ~0x1F;
|
||||
} else {
|
||||
mask = ~0xF;
|
||||
}
|
||||
|
||||
/* We set the "DisableDeviceAddressSpaceMerge" bit on all versions, so be permissive with it. */
|
||||
mask &= ~0x20;
|
||||
|
||||
R_UNLESS(!(npdm->flags & mask), ldr::ResultInvalidMeta());
|
||||
|
||||
/* Validate Acid extents. */
|
||||
R_TRY(ValidateSubregion(sizeof(Npdm), size, npdm->acid_offset, npdm->acid_size, sizeof(Acid)));
|
||||
@@ -77,8 +90,8 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* Validate that the acid version is correct. */
|
||||
constexpr u8 SupportedSdkMajorVersion = ams::svc::ConvertToSdkMajorVersion(ams::svc::SupportedKernelMajorVersion);
|
||||
if (acid->unknown_209 < SupportedSdkMajorVersion) {
|
||||
constexpr u8 MinimumValueForAcid209 = 14; /* TODO: What is the actual meaning of this value? */
|
||||
if (acid->unknown_209 < MinimumValueForAcid209) {
|
||||
R_UNLESS(acid->version == 0, ldr::ResultInvalidMeta());
|
||||
R_UNLESS(acid->unknown_209 == 0, ldr::ResultInvalidMeta());
|
||||
}
|
||||
@@ -103,30 +116,22 @@ namespace ams::ldr {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
const u8 *GetAcidSignatureModulus(PlatformId platform, u8 key_generation, bool unk_unused) {
|
||||
return fssystem::GetAcidSignatureKeyModulus(platform, !IsDevelopmentForAcidSignatureCheck(), key_generation, unk_unused);
|
||||
const u8 *GetAcidSignatureModulus(u32 key_generation) {
|
||||
return fssystem::GetAcidSignatureKeyModulus(!IsDevelopmentForAcidSignatureCheck(), key_generation);
|
||||
}
|
||||
|
||||
size_t GetAcidSignatureModulusSize(PlatformId platform, bool unk_unused) {
|
||||
return fssystem::GetAcidSignatureKeyModulusSize(platform, unk_unused);
|
||||
}
|
||||
|
||||
Result ValidateAcidSignature(Meta *meta, PlatformId platform, bool unk_unused) {
|
||||
Result ValidateAcidSignature(Meta *meta) {
|
||||
/* Loader did not check signatures prior to 10.0.0. */
|
||||
if (hos::GetVersion() < hos::Version_10_0_0) {
|
||||
meta->check_verification_data = false;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Get the signature key generation. */
|
||||
const auto signature_key_generation = meta->npdm->signature_key_generation;
|
||||
R_UNLESS(fssystem::IsValidSignatureKeyGeneration(platform, signature_key_generation), ldr::ResultInvalidMeta());
|
||||
|
||||
/* Verify the signature. */
|
||||
const u8 *sig = meta->acid->signature;
|
||||
const size_t sig_size = sizeof(meta->acid->signature);
|
||||
const u8 *mod = GetAcidSignatureModulus(platform, signature_key_generation, unk_unused);
|
||||
const size_t mod_size = GetAcidSignatureModulusSize(platform, unk_unused);
|
||||
const u8 *mod = GetAcidSignatureModulus(meta->npdm->signature_key_generation);
|
||||
const size_t mod_size = fssystem::AcidSignatureKeyModulusSize;
|
||||
const u8 *exp = fssystem::GetAcidSignatureKeyPublicExponent();
|
||||
const size_t exp_size = fssystem::AcidSignatureKeyPublicExponentSize;
|
||||
const u8 *msg = meta->acid->modulus;
|
||||
@@ -190,10 +195,7 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* API. */
|
||||
Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused) {
|
||||
/* Set the cached program id back to zero. */
|
||||
g_cached_program_id = {};
|
||||
|
||||
Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
|
||||
/* Try to load meta from file. */
|
||||
fs::FileHandle file;
|
||||
R_TRY(fs::OpenFile(std::addressof(file), AtmosphereMetaPath, fs::OpenMode_Read));
|
||||
@@ -259,7 +261,7 @@ namespace ams::ldr {
|
||||
R_TRY(fs::OpenFile(std::addressof(file), BaseMetaPath, fs::OpenMode_Read));
|
||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||
R_TRY(LoadMetaFromFile(file, std::addressof(g_original_meta_cache)));
|
||||
R_TRY(ValidateAcidSignature(std::addressof(g_original_meta_cache.meta), platform, unk_unused));
|
||||
R_TRY(ValidateAcidSignature(std::addressof(g_original_meta_cache.meta)));
|
||||
meta->modulus = g_original_meta_cache.meta.modulus;
|
||||
meta->check_verification_data = g_original_meta_cache.meta.check_verification_data;
|
||||
}
|
||||
@@ -278,9 +280,9 @@ namespace ams::ldr {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform) {
|
||||
Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) {
|
||||
if (g_cached_program_id != loc.program_id || g_cached_override_status != status) {
|
||||
R_RETURN(LoadMeta(out_meta, loc, status, platform, false));
|
||||
R_RETURN(LoadMeta(out_meta, loc, status));
|
||||
}
|
||||
*out_meta = g_meta_cache.meta;
|
||||
R_SUCCEED();
|
||||
|
||||
@@ -36,8 +36,8 @@ namespace ams::ldr {
|
||||
};
|
||||
|
||||
/* Meta API. */
|
||||
Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused);
|
||||
Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform);
|
||||
Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
|
||||
Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status);
|
||||
void InvalidateMetaCache();
|
||||
|
||||
}
|
||||
|
||||
@@ -34,43 +34,23 @@ namespace ams::ldr {
|
||||
enum NsoIndex {
|
||||
Nso_Rtld = 0,
|
||||
Nso_Main = 1,
|
||||
Nso_Compat0 = 2,
|
||||
Nso_Compat1 = 3,
|
||||
Nso_Compat2 = 4,
|
||||
Nso_Compat3 = 5,
|
||||
Nso_Compat4 = 6,
|
||||
Nso_Compat5 = 7,
|
||||
Nso_Compat6 = 8,
|
||||
Nso_Compat7 = 9,
|
||||
Nso_Compat8 = 10,
|
||||
Nso_Compat9 = 11,
|
||||
Nso_SubSdk0 = 12,
|
||||
Nso_SubSdk1 = 13,
|
||||
Nso_SubSdk2 = 14,
|
||||
Nso_SubSdk3 = 15,
|
||||
Nso_SubSdk4 = 16,
|
||||
Nso_SubSdk5 = 17,
|
||||
Nso_SubSdk6 = 18,
|
||||
Nso_SubSdk7 = 19,
|
||||
Nso_SubSdk8 = 20,
|
||||
Nso_SubSdk9 = 21,
|
||||
Nso_Sdk = 22,
|
||||
Nso_SubSdk0 = 2,
|
||||
Nso_SubSdk1 = 3,
|
||||
Nso_SubSdk2 = 4,
|
||||
Nso_SubSdk3 = 5,
|
||||
Nso_SubSdk4 = 6,
|
||||
Nso_SubSdk5 = 7,
|
||||
Nso_SubSdk6 = 8,
|
||||
Nso_SubSdk7 = 9,
|
||||
Nso_SubSdk8 = 10,
|
||||
Nso_SubSdk9 = 11,
|
||||
Nso_Sdk = 12,
|
||||
Nso_Count,
|
||||
};
|
||||
|
||||
constexpr inline const char *NsoPaths[Nso_Count] = {
|
||||
ENCODE_ATMOSPHERE_CODE_PATH("/rtld"),
|
||||
ENCODE_ATMOSPHERE_CODE_PATH("/main"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat0"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat1"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat2"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat3"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat4"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat5"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat6"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat7"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat8"),
|
||||
ENCODE_ATMOSPHERE_CMPT_PATH("/compat9"),
|
||||
ENCODE_ATMOSPHERE_CODE_PATH("/subsdk0"),
|
||||
ENCODE_ATMOSPHERE_CODE_PATH("/subsdk1"),
|
||||
ENCODE_ATMOSPHERE_CODE_PATH("/subsdk2"),
|
||||
@@ -380,11 +360,6 @@ namespace ams::ldr {
|
||||
flags |= svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge;
|
||||
}
|
||||
|
||||
/* 18.0.0+/meso Set Alias region extra size. */
|
||||
if (meta_flags & Npdm::MetaFlag_EnableAliasRegionExtraSize) {
|
||||
flags |= svc::CreateProcessFlag_EnableAliasRegionExtraSize;
|
||||
}
|
||||
|
||||
*out = flags;
|
||||
R_SUCCEED();
|
||||
}
|
||||
@@ -664,15 +639,15 @@ namespace ams::ldr {
|
||||
}
|
||||
|
||||
/* Process Creation API. */
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, PlatformId platform) {
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit) {
|
||||
/* Mount code. */
|
||||
AMS_UNUSED(path);
|
||||
ScopedCodeMount mount(loc, override_status, platform);
|
||||
ScopedCodeMount mount(loc, override_status);
|
||||
R_TRY(mount.GetResult());
|
||||
|
||||
/* Load meta, possibly from cache. */
|
||||
Meta meta;
|
||||
R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, platform));
|
||||
R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status));
|
||||
|
||||
/* Validate meta. */
|
||||
R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData()));
|
||||
@@ -720,16 +695,16 @@ namespace ams::ldr {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, PlatformId platform) {
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path) {
|
||||
Meta meta;
|
||||
|
||||
/* Load Meta. */
|
||||
{
|
||||
AMS_UNUSED(path);
|
||||
|
||||
ScopedCodeMount mount(loc, platform);
|
||||
ScopedCodeMount mount(loc);
|
||||
R_TRY(mount.GetResult());
|
||||
R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), platform, false));
|
||||
R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus()));
|
||||
if (out_status != nullptr) {
|
||||
*out_status = mount.GetOverrideStatus();
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
namespace ams::ldr {
|
||||
|
||||
/* Process Creation API. */
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, PlatformId platform);
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, PlatformId platform);
|
||||
Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit);
|
||||
Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path);
|
||||
|
||||
Result PinProgram(PinId *out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status);
|
||||
Result UnpinProgram(PinId id);
|
||||
|
||||
@@ -61,7 +61,7 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++23 -fno-exceptions -fno-rtti
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++20 -fno-exceptions -fno-rtti
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
@@ -61,7 +61,7 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++23
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++20
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
Reference in New Issue
Block a user