Compare commits

...

11 Commits

Author SHA1 Message Date
Michael Scire
3dbc79dd5c ams: bump version to 0.19.4 2021-06-08 08:09:05 -07:00
Michael Scire
90b54c03b3 git subrepo pull emummc
subrepo:
  subdir:   "emummc"
  merged:   "219c723c"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "219c723c"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-06-08 07:50:35 -07:00
Michael Scire
7821241356 kern: fix enormous whoops 2021-05-31 04:20:59 -07:00
Michael Scire
8fea8d9b2e sm: lighten abort restrictions on mitm handle acquisition (closes #1528) 2021-05-30 22:53:32 -07:00
Michael Scire
dcdf46f576 kern: slightly improve genericity of debugger break event 2021-05-30 21:13:42 -07:00
Michael Scire
df5537b748 mem: actually fully fix the heap bug, add comments for future self 2021-05-26 23:21:08 -07:00
Michael Scire
0f2855ada8 mem: fix rare crash/logic error in heap allocation code 2021-05-26 20:43:03 -07:00
Michael Scire
c790d03693 libstrat: fix override operator new to be noexcept (closes #1494) 2021-05-16 23:10:13 -07:00
Michael Scire
25be7c5b1b git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "b5b55f60"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "b5b55f60"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-05-12 22:47:42 -07:00
Michael Scire
7e05e12b83 sf/tipc: treat min/max as true min/max, rather than numeric 2021-05-12 22:43:39 -07:00
Michael Scire
99d7f72c51 warmboot: remove superfluous firmware version check 2021-05-12 16:57:10 -07:00
26 changed files with 208 additions and 47 deletions

View File

@@ -1,4 +1,11 @@
# Changelog # Changelog
## 0.19.4
+ Support was added for 12.0.3.
+ A number of minor issues were fixed, including:
+ An issue was fixed that could cause heap memory corruption when allocation was highly contended.
+ An issue was fixed that could cause sleep to fail under certain conditions.
+ An issue was fixed that could cause a scheduler slow path to be taken more often than necessary.
+ General system stability improvements to enhance the user's experience.
## 0.19.3 ## 0.19.3
+ Support was added for 12.0.2. + Support was added for 12.0.2.
+ A number of minor issues were fixed, including: + A number of minor issues were fixed, including:

View File

@@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/m4xw/emuMMC remote = https://github.com/m4xw/emuMMC
branch = develop branch = develop
commit = c6717b9320247d3ec81b372adae5e5623be7d16b commit = 219c723c3001fbc33d47840ceceb83cf39a1d218
parent = bf8de39e694dc64431180bc513ce110f07fc3531 parent = 7821241356c2f6b159945babf657ffd921957918
method = rebase method = rebase
cmdver = 0.4.1 cmdver = 0.4.1

View File

@@ -53,6 +53,8 @@
#include "offsets/1100_exfat.h" #include "offsets/1100_exfat.h"
#include "offsets/1200.h" #include "offsets/1200.h"
#include "offsets/1200_exfat.h" #include "offsets/1200_exfat.h"
#include "offsets/1203.h"
#include "offsets/1203_exfat.h"
#include "../utils/fatal.h" #include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@@ -117,6 +119,8 @@ DEFINE_OFFSET_STRUCT(_1100);
DEFINE_OFFSET_STRUCT(_1100_EXFAT); DEFINE_OFFSET_STRUCT(_1100_EXFAT);
DEFINE_OFFSET_STRUCT(_1200); DEFINE_OFFSET_STRUCT(_1200);
DEFINE_OFFSET_STRUCT(_1200_EXFAT); DEFINE_OFFSET_STRUCT(_1200_EXFAT);
DEFINE_OFFSET_STRUCT(_1203);
DEFINE_OFFSET_STRUCT(_1203_EXFAT);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) { const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) { switch (version) {
@@ -194,6 +198,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_1200)); return &(GET_OFFSET_STRUCT_NAME(_1200));
case FS_VER_12_0_0_EXFAT: case FS_VER_12_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1200_EXFAT)); return &(GET_OFFSET_STRUCT_NAME(_1200_EXFAT));
case FS_VER_12_0_3:
return &(GET_OFFSET_STRUCT_NAME(_1203));
case FS_VER_12_0_3_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1203_EXFAT));
default: default:
fatal_abort(Fatal_UnknownVersion); fatal_abort(Fatal_UnknownVersion);
} }

View File

@@ -77,6 +77,9 @@ enum FS_VER
FS_VER_12_0_0, FS_VER_12_0_0,
FS_VER_12_0_0_EXFAT, FS_VER_12_0_0_EXFAT,
FS_VER_12_0_3,
FS_VER_12_0_3_EXFAT,
FS_VER_MAX, FS_VER_MAX,
}; };

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* Copyright (c) 2021 CTCaer
*
* 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_1203_H__
#define __FS_1203_H__
// Accessor vtable getters
#define FS_OFFSET_1203_SDMMC_ACCESSOR_GC 0x1550E0
#define FS_OFFSET_1203_SDMMC_ACCESSOR_SD 0x156EF0
#define FS_OFFSET_1203_SDMMC_ACCESSOR_NAND 0x155610
// Hooks
#define FS_OFFSET_1203_SDMMC_WRAPPER_READ 0x150A80
#define FS_OFFSET_1203_SDMMC_WRAPPER_WRITE 0x150B40
#define FS_OFFSET_1203_RTLD 0x688
#define FS_OFFSET_1203_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1203_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
// Misc funcs
#define FS_OFFSET_1203_LOCK_MUTEX 0x29350
#define FS_OFFSET_1203_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
// Misc Data
#define FS_OFFSET_1203_SD_MUTEX 0xE3D3E8
#define FS_OFFSET_1203_NAND_MUTEX 0xE38768
#define FS_OFFSET_1203_ACTIVE_PARTITION 0xE387A8
#define FS_OFFSET_1203_SDMMC_DAS_HANDLE 0xE20DB0
// NOPs
#define FS_OFFSET_1203_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1203_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1203_H__

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* Copyright (c) 2021 CTCaer
*
* 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_1203_EXFAT_H__
#define __FS_1203_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_GC 0x1550E0
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_SD 0x156EF0
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_NAND 0x155610
// Hooks
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_READ 0x150A80
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_WRITE 0x150B40
#define FS_OFFSET_1203_EXFAT_RTLD 0x688
#define FS_OFFSET_1203_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1203_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
// Misc funcs
#define FS_OFFSET_1203_EXFAT_LOCK_MUTEX 0x29350
#define FS_OFFSET_1203_EXFAT_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
// Misc Data
#define FS_OFFSET_1203_EXFAT_SD_MUTEX 0xE4B3E8
#define FS_OFFSET_1203_EXFAT_NAND_MUTEX 0xE46768
#define FS_OFFSET_1203_EXFAT_ACTIVE_PARTITION 0xE467A8
#define FS_OFFSET_1203_EXFAT_SDMMC_DAS_HANDLE 0xE2EDB0
// NOPs
#define FS_OFFSET_1203_EXFAT_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1203_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1203_EXFAT_H__

View File

@@ -36,7 +36,6 @@ namespace ams::warmboot {
void Main(const Metadata *metadata) { void Main(const Metadata *metadata) {
/* Ensure that we're running under vaguely sane conditions. */ /* Ensure that we're running under vaguely sane conditions. */
AMS_ABORT_UNLESS(metadata->magic == Metadata::Magic); AMS_ABORT_UNLESS(metadata->magic == Metadata::Magic);
AMS_ABORT_UNLESS(metadata->target_firmware <= ams::TargetFirmware_Max);
/* Restrict the bpmp's access to dram. */ /* Restrict the bpmp's access to dram. */
if (metadata->target_firmware >= TargetFirmware_4_0_0) { if (metadata->target_firmware >= TargetFirmware_4_0_0) {

View File

@@ -94,6 +94,9 @@ typedef enum {
FS_VER_12_0_0, FS_VER_12_0_0,
FS_VER_12_0_0_EXFAT, FS_VER_12_0_0_EXFAT,
FS_VER_12_0_3,
FS_VER_12_0_3_EXFAT,
FS_VER_MAX, FS_VER_MAX,
} emummc_fs_ver_t; } emummc_fs_ver_t;

View File

@@ -429,6 +429,9 @@ static const uint8_t g_fs_hashes[FS_VER_MAX][0x8] = {
"\xDC\x2A\x08\x49\x96\xBB\x3C\x01", /* FS_VER_12_0_0 */ "\xDC\x2A\x08\x49\x96\xBB\x3C\x01", /* FS_VER_12_0_0 */
"\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", /* FS_VER_12_0_0_EXFAT */ "\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", /* FS_VER_12_0_0_EXFAT */
"\xC8\x67\x62\xBE\x19\xA5\x1F\xA0", /* FS_VER_12_0_3 */
"\xE1\xE8\xD3\xD6\xA2\xFE\x0B\x10", /* FS_VER_12_0_3_EXFAT */
}; };
kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) { kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) {

View File

@@ -285,8 +285,10 @@ static bool is_nca_present(const char *nca_name) {
static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){ static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){
#define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0) #define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0)
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_0) { if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_2) {
CHECK_NCA("a1863a5c0e1cedd442f5e60b0422dc15", 12_0_3);
CHECK_NCA("63d928b5a3016fe8cc0e76d2f06f4e98", 12_0_2); CHECK_NCA("63d928b5a3016fe8cc0e76d2f06f4e98", 12_0_2);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_0) {
CHECK_NCA("e65114b456f9d0b566a80e53bade2d89", 12_0_1); CHECK_NCA("e65114b456f9d0b566a80e53bade2d89", 12_0_1);
CHECK_NCA("bd4185843550fbba125b20787005d1d2", 12_0_0); CHECK_NCA("bd4185843550fbba125b20787005d1d2", 12_0_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) { } else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) {

View File

@@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master branch = master
commit = 9ac6f527e2a48ba97636ba8f65538f960870cd8a commit = b5b55f60d8567ea4608163abc299e5e238381d44
parent = 269d4496b2365785c87545b0337f89078cb76c3e parent = 7e05e12b833e19333ffac02e4fec72250c8b17fa
method = merge method = merge
cmdver = 0.4.1 cmdver = 0.4.1

View File

@@ -308,8 +308,11 @@ namespace ams::kern {
} }
/* Send an exception event to represent our breaking the process. */ /* Send an exception event to represent our breaking the process. */
static_assert(util::size(thread_ids) >= 4); /* TODO: How should this be handled in the case of more than 4 physical cores? */
this->PushDebugEvent(ams::svc::DebugEvent_Exception, ams::svc::DebugException_DebuggerBreak, thread_ids[0], thread_ids[1], thread_ids[2], thread_ids[3]); static_assert(util::size(thread_ids) <= 4);
[&]<size_t... Ix>(std::index_sequence<Ix...>) ALWAYS_INLINE_LAMBDA {
this->PushDebugEvent(ams::svc::DebugEvent_Exception, ams::svc::DebugException_DebuggerBreak, thread_ids[Ix]...);
}(std::make_index_sequence<util::size(thread_ids)>());
/* Signal. */ /* Signal. */
this->NotifyAvailable(); this->NotifyAvailable();

View File

@@ -231,6 +231,10 @@ namespace ams::kern {
next_thread = m_idle_thread; next_thread = m_idle_thread;
} }
if (next_thread->GetCurrentCore() != m_core_id) {
next_thread->SetCurrentCore(m_core_id);
}
/* If we're not actually switching thread, there's nothing to do. */ /* If we're not actually switching thread, there's nothing to do. */
if (next_thread == cur_thread) { if (next_thread == cur_thread) {
return; return;
@@ -263,10 +267,6 @@ namespace ams::kern {
MESOSPHERE_KTRACE_THREAD_SWITCH(next_thread); MESOSPHERE_KTRACE_THREAD_SWITCH(next_thread);
if (next_thread->GetCurrentCore() != m_core_id) {
next_thread->SetCurrentCore(m_core_id);
}
/* Switch the current process, if we're switching processes. */ /* Switch the current process, if we're switching processes. */
if (KProcess *next_process = next_thread->GetOwnerProcess(); next_process != cur_process) { if (KProcess *next_process = next_thread->GetOwnerProcess(); next_process != cur_process) {
KProcess::Switch(cur_process, next_process); KProcess::Switch(cur_process, next_process);

View File

@@ -20,23 +20,23 @@ namespace ams::fs::impl {
class Newable { class Newable {
public: public:
static void *operator new(size_t size) { static ALWAYS_INLINE void *operator new(size_t size) noexcept {
return ::ams::fs::impl::Allocate(size); return ::ams::fs::impl::Allocate(size);
} }
static void *operator new(size_t size, Newable *placement) { static ALWAYS_INLINE void *operator new(size_t size, Newable *placement) noexcept {
return placement; return placement;
} }
static void *operator new[](size_t size) { static ALWAYS_INLINE void *operator new[](size_t size) noexcept {
return ::ams::fs::impl::Allocate(size); return ::ams::fs::impl::Allocate(size);
} }
static void operator delete(void *ptr, size_t size) { static ALWAYS_INLINE void operator delete(void *ptr, size_t size) noexcept {
return ::ams::fs::impl::Deallocate(ptr, size); return ::ams::fs::impl::Deallocate(ptr, size);
} }
static void operator delete[](void *ptr, size_t size) { static ALWAYS_INLINE void operator delete[](void *ptr, size_t size) noexcept {
return ::ams::fs::impl::Deallocate(ptr, size); return ::ams::fs::impl::Deallocate(ptr, size);
} }
}; };

View File

@@ -106,11 +106,9 @@ namespace ams::fssystem {
using Newable::operator new; using Newable::operator new;
using Newable::operator delete; using Newable::operator delete;
static void *operator new(size_t, void *p) {
return p;
}
static void operator delete(void *, size_t, void*) { /* ... */ } static ALWAYS_INLINE void *operator new(size_t, void *p) noexcept { return p; }
static ALWAYS_INLINE void operator delete(void *, size_t, void*) noexcept { /* ... */ }
}; };
using AttrListTraits = util::IntrusiveListBaseTraits<AttrInfo>; using AttrListTraits = util::IntrusiveListBaseTraits<AttrInfo>;

View File

@@ -63,6 +63,7 @@ namespace ams::hos {
Version_12_0_0 = ::ams::TargetFirmware_12_0_0, Version_12_0_0 = ::ams::TargetFirmware_12_0_0,
Version_12_0_1 = ::ams::TargetFirmware_12_0_1, Version_12_0_1 = ::ams::TargetFirmware_12_0_1,
Version_12_0_2 = ::ams::TargetFirmware_12_0_2, Version_12_0_2 = ::ams::TargetFirmware_12_0_2,
Version_12_0_3 = ::ams::TargetFirmware_12_0_3,
Version_Current = ::ams::TargetFirmware_Current, Version_Current = ::ams::TargetFirmware_Current,

View File

@@ -54,7 +54,10 @@ namespace ams::sf::cmif {
Result (*handler)(CmifOutHeader **out_header_ptr, ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data); Result (*handler)(CmifOutHeader **out_header_ptr, ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data);
constexpr inline bool Matches(u32 cmd_id, hos::Version hosver) const { constexpr inline bool Matches(u32 cmd_id, hos::Version hosver) const {
return this->cmd_id == cmd_id && this->hosver_low <= hosver && hosver <= this->hosver_high; const bool min_valid = this->hosver_low == hos::Version_Min;
const bool max_valid = this->hosver_high == hos::Version_Max;
return this->cmd_id == cmd_id && (min_valid || this->hosver_low <= hosver) && (max_valid || hosver <= this->hosver_high);
} }
constexpr inline decltype(handler) GetHandler() const { constexpr inline decltype(handler) GetHandler() const {

View File

@@ -79,8 +79,9 @@ namespace ams::tipc::impl {
#define AMS_TIPC_IMPL_PROCESS_METHOD_REQUEST_BY_ID(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, ARGNAMES, VERSION_MIN, VERSION_MAX) \ #define AMS_TIPC_IMPL_PROCESS_METHOD_REQUEST_BY_ID(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, ARGNAMES, VERSION_MIN, VERSION_MAX) \
if constexpr (constexpr u16 TipcCommandId = CMD_ID + 0x10; CommandId == TipcCommandId) { \ if constexpr (constexpr u16 TipcCommandId = CMD_ID + 0x10; CommandId == TipcCommandId) { \
constexpr bool AlwaysValid = VERSION_MIN == hos::Version_Min && VERSION_MAX == hos::Version_Max; \ constexpr bool MinValid = VERSION_MIN == hos::Version_Min; \
if (AlwaysValid || (VERSION_MIN <= fw_ver && fw_ver <= VERSION_MAX)) { \ constexpr bool MaxValid = VERSION_MAX == hos::Version_Max; \
if ((MinValid || VERSION_MIN <= fw_ver) && (MaxValid || fw_ver <= VERSION_MAX)) { \
return ::ams::tipc::impl::InvokeServiceCommandImpl<TipcCommandId, &ImplType::NAME, ImplType>(impl, message_buffer); \ return ::ams::tipc::impl::InvokeServiceCommandImpl<TipcCommandId, &ImplType::NAME, ImplType>(impl, message_buffer); \
} \ } \
} }

View File

@@ -22,13 +22,13 @@ namespace ams::erpt::srv {
class Allocator { class Allocator {
public: public:
void *operator new(size_t sz) { return lmem::AllocateFromExpHeap(g_heap_handle, sz); } void *operator new(size_t sz) noexcept { return lmem::AllocateFromExpHeap(g_heap_handle, sz); }
void *operator new(size_t sz, size_t algn) { return lmem::AllocateFromExpHeap(g_heap_handle, sz, static_cast<s32>(algn)); } void *operator new(size_t sz, size_t algn) noexcept { return lmem::AllocateFromExpHeap(g_heap_handle, sz, static_cast<s32>(algn)); }
void *operator new[](size_t sz) { return lmem::AllocateFromExpHeap(g_heap_handle, sz); } void *operator new[](size_t sz) noexcept { return lmem::AllocateFromExpHeap(g_heap_handle, sz); }
void *operator new[](size_t sz, size_t algn) { return lmem::AllocateFromExpHeap(g_heap_handle, sz, static_cast<s32>(algn)); } void *operator new[](size_t sz, size_t algn) noexcept { return lmem::AllocateFromExpHeap(g_heap_handle, sz, static_cast<s32>(algn)); }
void operator delete(void *p) { lmem::FreeToExpHeap(g_heap_handle, p); } void operator delete(void *p) noexcept { lmem::FreeToExpHeap(g_heap_handle, p); }
void operator delete[](void *p) { lmem::FreeToExpHeap(g_heap_handle, p); } void operator delete[](void *p) noexcept { lmem::FreeToExpHeap(g_heap_handle, p); }
}; };
inline void *Allocate(size_t sz) { inline void *Allocate(size_t sz) {

View File

@@ -976,26 +976,35 @@ namespace ams::mem::impl::heap {
return span; return span;
} }
} else { } else {
/* Save the extents of the free span we found. */
auto * const prev_ptr = span->start.p;
const size_t prev_pages = span->num_pages;
/* Allocate a new span struct. */
Span *new_span = this->AllocateSpanStruct(); Span *new_span = this->AllocateSpanStruct();
if (new_span == nullptr) { if (new_span == nullptr) {
return nullptr; return nullptr;
} }
auto new_span_guard = SCOPE_GUARD { this->FreeSpanToSpanPage(new_span); }; auto new_span_guard = SCOPE_GUARD { this->FreeSpanToSpanPage(new_span); };
const size_t prev_pages = span->num_pages; /* Allocating the new span potentially invalidates the span we were looking at, so find the span for it in the table. */
span = GetSpanFromPointer(std::addressof(this->span_table), span->start.p); span = GetSpanFromPointer(std::addressof(this->span_table), prev_ptr);
const size_t found_pages = span->num_pages; const size_t cur_pages = span->num_pages;
/* If the span was partially allocated, we need to find a new one that's big enough. */
if (found_pages != prev_pages) { if (cur_pages != prev_pages) {
span = this->SearchFreeSpan(num_pages); span = this->SearchFreeSpan(num_pages);
if (span == nullptr) { if (span == nullptr) {
return nullptr; return nullptr;
} }
} }
if (found_pages == prev_pages || num_pages != span->num_pages) { /* If the span is big enough to split (span->num_pages > num_pages), we want to split it. */
/* We're going to use the new span. */ /* span->num_pages > num_pages is true if the span wasn't partially allocated (cur_pages == prev_pages) */
/* OR if the new free span we found has num_pages > num_pages. Note that we know span->num_pages >= num_pages */
/* so this > condition can be expressed as span->num_pages != num_pages. */
if (cur_pages == prev_pages || num_pages != span->num_pages) {
/* We're going to use the new span for our split. */
new_span_guard.Cancel(); new_span_guard.Cancel();
return this->SplitSpan(span, num_pages, new_span); return this->SplitSpan(span, num_pages, new_span);

View File

@@ -17,10 +17,10 @@
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0 #define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
#define ATMOSPHERE_RELEASE_VERSION_MINOR 19 #define ATMOSPHERE_RELEASE_VERSION_MINOR 19
#define ATMOSPHERE_RELEASE_VERSION_MICRO 3 #define ATMOSPHERE_RELEASE_VERSION_MICRO 4
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 12 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 12
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 2 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 3

View File

@@ -61,8 +61,9 @@
#define ATMOSPHERE_TARGET_FIRMWARE_12_0_0 ATMOSPHERE_TARGET_FIRMWARE(12, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_12_0_0 ATMOSPHERE_TARGET_FIRMWARE(12, 0, 0)
#define ATMOSPHERE_TARGET_FIRMWARE_12_0_1 ATMOSPHERE_TARGET_FIRMWARE(12, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_12_0_1 ATMOSPHERE_TARGET_FIRMWARE(12, 0, 1)
#define ATMOSPHERE_TARGET_FIRMWARE_12_0_2 ATMOSPHERE_TARGET_FIRMWARE(12, 0, 2) #define ATMOSPHERE_TARGET_FIRMWARE_12_0_2 ATMOSPHERE_TARGET_FIRMWARE(12, 0, 2)
#define ATMOSPHERE_TARGET_FIRMWARE_12_0_3 ATMOSPHERE_TARGET_FIRMWARE(12, 0, 3)
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_12_0_2 #define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_12_0_3
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
@@ -116,6 +117,7 @@ namespace ams {
TargetFirmware_12_0_0 = ATMOSPHERE_TARGET_FIRMWARE_12_0_0, TargetFirmware_12_0_0 = ATMOSPHERE_TARGET_FIRMWARE_12_0_0,
TargetFirmware_12_0_1 = ATMOSPHERE_TARGET_FIRMWARE_12_0_1, TargetFirmware_12_0_1 = ATMOSPHERE_TARGET_FIRMWARE_12_0_1,
TargetFirmware_12_0_2 = ATMOSPHERE_TARGET_FIRMWARE_12_0_2, TargetFirmware_12_0_2 = ATMOSPHERE_TARGET_FIRMWARE_12_0_2,
TargetFirmware_12_0_3 = ATMOSPHERE_TARGET_FIRMWARE_12_0_3,
TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,

View File

@@ -136,8 +136,7 @@ _ZN3ams4kern10KScheduler12ScheduleImplEv:
/* Check if the highest priority thread is the same as the current thread. */ /* Check if the highest priority thread is the same as the current thread. */
ldr x7, [x1, #(KSCHEDULER_HIGHEST_PRIORITY_THREAD)] ldr x7, [x1, #(KSCHEDULER_HIGHEST_PRIORITY_THREAD)]
ldr x2, [x18] cmp x7, x18
cmp x7, x2
b.ne 1f b.ne 1f
/* If they're the same, then we can just return as there's nothing to do. */ /* If they're the same, then we can just return as there's nothing to do. */

View File

@@ -367,7 +367,7 @@ namespace ams::sm::impl {
{ {
/* TODO: Convert mitm internal messaging to use tipc? */ /* TODO: Convert mitm internal messaging to use tipc? */
::Service srv { .session = service_info->mitm_query_h }; ::Service srv { .session = service_info->mitm_query_h };
R_TRY(::serviceDispatchInOut(std::addressof(srv), 65000, client_info, should_mitm)); R_ABORT_UNLESS(::serviceDispatchInOut(std::addressof(srv), 65000, client_info, should_mitm));
} }
/* If we shouldn't mitm, give normal session. */ /* If we shouldn't mitm, give normal session. */
@@ -383,8 +383,9 @@ namespace ams::sm::impl {
auto fwd_guard = SCOPE_GUARD { R_ABORT_UNLESS(svc::CloseHandle(fwd_hnd)); }; auto fwd_guard = SCOPE_GUARD { R_ABORT_UNLESS(svc::CloseHandle(fwd_hnd)); };
/* Get the mitm handle. */ /* Get the mitm handle. */
/* This should be guaranteed to succeed, since we got a forward handle. */
svc::Handle hnd; svc::Handle hnd;
R_TRY(svc::ConnectToPort(std::addressof(hnd), service_info->mitm_port_h)); R_ABORT_UNLESS(svc::ConnectToPort(std::addressof(hnd), service_info->mitm_port_h));
/* We got both handles, so we no longer need to clean up the forward handle. */ /* We got both handles, so we no longer need to clean up the forward handle. */
fwd_guard.Cancel(); fwd_guard.Cancel();
@@ -410,9 +411,8 @@ namespace ams::sm::impl {
MitmProcessInfo client_info; MitmProcessInfo client_info;
GetMitmProcessInfo(std::addressof(client_info), process_id); GetMitmProcessInfo(std::addressof(client_info), process_id);
if (!IsMitmDisallowed(client_info.program_id)) { if (!IsMitmDisallowed(client_info.program_id)) {
/* We're mitm'd. Assert, because mitm service host dead is an error state. */ /* Get a mitm service handle. */
R_ABORT_UNLESS(GetMitmServiceHandleImpl(out, service_info, client_info)); return GetMitmServiceHandleImpl(out, service_info, client_info);
return ResultSuccess();
} }
} }