Compare commits

..

46 Commits

Author SHA1 Message Date
Michael Scire
4fa8325f74 ams: update Makefile to build zips with new names 2021-01-05 09:43:09 -08:00
Michael Scire
6baf1d6593 fusee: pass along lcd vendor to exosphere (needed for mariko fatal) 2021-01-05 09:32:57 -08:00
Michael Scire
95b49294df docs/changelog: don't let dreams remain memes 2021-01-05 09:28:08 -08:00
Michael Scire
557903cfa7 fusee: perform only pmic reboots on mariko 2021-01-05 00:57:37 -08:00
Michael Scire
c06f0440fd ams: provisional changelog for 0.17.0, release sometime this week 2021-01-05 00:45:32 -08:00
Michael Scire
23cb37d6be pmic: use correct shutdown impl for erista power-off 2021-01-05 00:30:28 -08:00
Michael Scire
a2535c7330 sept: fix sdram parameter scratch save 2021-01-05 00:22:38 -08:00
Michael Scire
e43a960b5d ams: mariko support implies 0.17.0 2021-01-04 17:20:54 -08:00
Michael Scire
feed7550f5 sept: fixes to work with new hwinit/etc 2021-01-04 17:18:13 -08:00
Michael Scire
be897d728d sept is erista-only, and doesn't need mariko sdram (space saving measure) 2021-01-04 14:10:59 -08:00
Michael Scire
0dc6bcb180 fusee: fix overcorrection for boot reason address 2021-01-04 11:33:27 -08:00
Michael Scire
45bae80f18 fusee: sdram scratch fixes 2021-01-04 02:37:05 -08:00
Michael Scire
6e9675916c fusee: implement mariko warmboot firmware cache 2021-01-04 00:55:52 -08:00
Michael Scire
b74742e0a1 fusee/exo: fixes to allow booting (sleep broken until warmboot cache implemented) 2021-01-03 23:46:13 -08:00
Michael Scire
d153a8fa5a fusee: commit pre-rendered splash binary 2021-01-03 22:47:24 -08:00
hexkyz
fa53d11cae fusee: fix regulator configuration 2021-01-03 16:24:54 +00:00
Michael Scire
200da4c2da fusee: execute more ccplex boot code out of iram 2021-01-01 16:44:43 -08:00
Michael Scire
539dbf0800 fusee: use pre-rendered splash screen instead of bmp 2021-01-01 16:26:00 -08:00
Michael Scire
c3bf204627 fusee: minor hwinit fixes 2021-01-01 16:03:57 -08:00
hexkyz
2920c042e1 fusee: fix cluster bringup for mariko 2021-01-01 16:37:16 +00:00
Michael Scire
a968d0be32 fusee: fix support for mariko key derivation/package1 parsing 2020-12-31 23:29:00 -08:00
Michael Scire
52c7932f1f fusee: add special log level for sd card debug 2020-12-31 18:35:26 -08:00
Michael Scire
ec398dc612 fusee/sept: build fixes 2020-12-31 18:07:11 -08:00
hexkyz
a35a30efcd fusee: fix mariko master key derivation 2020-12-31 16:02:49 -08:00
hexkyz
8402ea7e93 fusee: cleanup code and start fleshing out mariko keygen 2020-12-31 16:02:49 -08:00
hexkyz
c356e1ab36 fusee: start fleshing out nxboot for Mariko 2020-12-31 16:02:49 -08:00
hexkyz
4d4fc19cba fusee: accurately match Mariko pk1ldr 2020-12-31 16:02:49 -08:00
hexkyz
0a0cc52846 fusee: 11.0.0 support 2020-12-31 16:02:49 -08:00
hexkyz
f40fa150d8 fusee/sept: delegate SoC selection to individual components and keep common code SoC-agnostic 2020-12-31 16:02:48 -08:00
hexkyz
db8a367834 fusee: artificially raise main length to avoid elf compilation issues (final size will be much smaller) 2020-12-31 16:02:48 -08:00
hexkyz
d083384f2f fusee: move dsi register write to the proper configuration list 2020-12-31 16:02:48 -08:00
hexkyz
83fa9983bf fusee: update display code for mariko 2020-12-31 16:02:48 -08:00
Michael Scire
b9428dd2f3 fusee: fixup extents for chainloader/stack 2020-12-31 16:02:48 -08:00
Michael Scire
dc52610bd8 fusee-primary: fix reboot-to-self for decompressed code 2020-12-31 16:02:48 -08:00
Michael Scire
7ed9bdd374 fusee/sept: fix fuse driver to not infinitely recurse on get_soc_type() 2020-12-31 16:02:48 -08:00
Michael Scire
1107d4858c fusee: fixup common for primary 2020-12-31 16:02:48 -08:00
Michael Scire
eb1b624219 fusee: uncompress fusee-primary, which is now getting pretty big. 2020-12-31 16:02:48 -08:00
hexkyz
5012782237 fusee: implement mariko sdram params saving 2020-12-31 16:02:47 -08:00
hexkyz
736360e965 fusee: mariko sdram initialization 2020-12-31 16:02:47 -08:00
hexkyz
4111aa0a83 fusee: initial mariko hwinit 2020-12-31 16:02:47 -08:00
hexkyz
6671d46c8d fusee: support mariko in sdmmc 2020-12-31 16:02:47 -08:00
hexkyz
b14dd4fd5f fusee/sept: support mariko fuses 2020-12-31 16:02:47 -08:00
hexkyz
b917d7c886 fusee/sept: update fuse driver code 2020-12-31 16:02:47 -08:00
hexkyz
6263a54be5 fusee: fix sdmmc speed modes 2020-12-31 16:02:46 -08:00
hexkyz
a266e9b11a fusee: update FatFs to R0.14 2020-12-31 16:02:46 -08:00
hexkyz
b5d866f5a0 fusee/sept: isolate common code for mariko preparation (to be revised during C++ rewrite) 2020-12-31 16:02:46 -08:00
93 changed files with 331 additions and 664 deletions

View File

@@ -1,12 +1,4 @@
# Changelog
## 0.17.1
+ A number of atmosphère's modules were using more memory than their Nintendo equivalent's in 0.17.0; a number of code generatio tweaks have been applied to fix this across the board.
+ A detailed comparison of atmosphère module memory usage versus Nintendo's was made and can be found [here](https://github.com/Atmosphere-NX/Atmosphere/wiki/Memory-Comparisons).
+ Several minor bugs were fixed, including:
+ A bug was fixed in mesosphère that caused games which attempt to map more memory than the Switch has to fail.
+ This affected "Piczle Lines DX 500 More Puzzles!", and possibly other games.
+ Enabling configuration to "blank" PRODINFO no longer causes a hang on Mariko devices (or any devices with newer format).
+ Several issues were fixed, and usability and stability were improved.
## 0.17.0
+ fusee was heavily rewritten in order to add support for Mariko hardware.
+ **Please Note**: Mariko hardware currently has no (and may not ever have any) software exploits; fusee works when loaded from bootloader context with the right keys in the security engine. No means of getting the system into this state is provided.

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master
commit = 6c11c07e2a7f03952a4e70eb89b47bf528de39c6
parent = 9e104bb83f1302e9f126542fbf57c7f666aae953
commit = b05ba02f044beb03b3e228a660c0c28d0b1efe0d
parent = f2a6a4a6e60bfe0dea11ba3a0ff56c95a5871a6c
method = merge
cmdver = 0.4.1

View File

@@ -36,7 +36,7 @@ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(SETTINGS) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
export LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs $(SETTINGS) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
export LIBS = -lstratosphere -lnx

View File

@@ -85,7 +85,7 @@ namespace ams::kern {
virtual KProcess *GetOwner() const { return nullptr; }
u32 GetReferenceCount() const {
return m_ref_count.load();
return m_ref_count;
}
ALWAYS_INLINE bool IsDerivedFrom(const TypeObj &rhs) const {

View File

@@ -49,9 +49,9 @@ namespace ams::kern {
constexpr KVirtualAddress GetAddress() const { return m_address; }
constexpr size_t GetSize() const { return m_size; }
constexpr size_t GetUsed() const { return m_used.load(); }
constexpr size_t GetPeak() const { return m_peak.load(); }
constexpr size_t GetCount() const { return m_count.load(); }
constexpr size_t GetUsed() const { return m_used; }
constexpr size_t GetPeak() const { return m_peak; }
constexpr size_t GetCount() const { return m_count; }
constexpr bool IsInRange(KVirtualAddress addr) const {
return this->GetAddress() <= addr && addr <= this->GetAddress() + this->GetSize() - 1;
@@ -65,7 +65,7 @@ namespace ams::kern {
/* Free blocks to memory. */
u8 *cur = GetPointer<u8>(m_address + m_size);
for (size_t i = 0; i < sz / sizeof(T); i++) {
for (size_t i = 0; i < m_count; i++) {
cur -= sizeof(T);
this->GetImpl()->Free(cur);
}
@@ -84,13 +84,13 @@ namespace ams::kern {
this->Initialize(page_allocator);
/* Allocate until we have the correct number of objects. */
while (m_count.load() < num_objects) {
while (m_count < num_objects) {
auto *allocated = reinterpret_cast<T *>(m_page_allocator->Allocate());
MESOSPHERE_ABORT_UNLESS(allocated != nullptr);
for (size_t i = 0; i < sizeof(PageBuffer) / sizeof(T); i++) {
this->GetImpl()->Free(allocated + i);
}
m_count.fetch_add(sizeof(PageBuffer) / sizeof(T));
m_count += sizeof(PageBuffer) / sizeof(T);
}
}
@@ -106,7 +106,7 @@ namespace ams::kern {
for (size_t i = 1; i < sizeof(PageBuffer) / sizeof(T); i++) {
this->GetImpl()->Free(allocated + i);
}
m_count.fetch_add(sizeof(PageBuffer) / sizeof(T));
m_count += sizeof(PageBuffer) / sizeof(T);
}
}
}
@@ -116,8 +116,8 @@ namespace ams::kern {
new (allocated) T();
/* Update our tracking. */
size_t used = m_used.fetch_add(1) + 1;
size_t peak = m_peak.load();
size_t used = ++m_used;
size_t peak = m_peak;
while (peak < used) {
if (m_peak.compare_exchange_weak(peak, used, std::memory_order_relaxed)) {
break;
@@ -130,7 +130,7 @@ namespace ams::kern {
void Free(T *t) {
this->GetImpl()->Free(t);
m_used.fetch_sub(1);
--m_used;
}
};

View File

@@ -303,7 +303,6 @@ namespace ams::kern {
const auto linear_id = handle_pack.Get<HandleLinearId>();
const auto reserved = handle_pack.Get<HandleReserved>();
MESOSPHERE_ASSERT(reserved == 0);
MESOSPHERE_UNUSED(reserved);
/* Validate our indexing information. */
if (raw_value == 0) {

View File

@@ -50,7 +50,7 @@ namespace ams::kern {
}
}
ALWAYS_INLINE void Unlock() {
void Unlock() {
MESOSPHERE_ASSERT_THIS();
const uintptr_t cur_thread = reinterpret_cast<uintptr_t>(GetCurrentThreadPointer());
@@ -65,8 +65,8 @@ namespace ams::kern {
void LockSlowPath(uintptr_t owner, uintptr_t cur_thread);
void UnlockSlowPath(uintptr_t cur_thread);
ALWAYS_INLINE bool IsLocked() const { return m_tag.load() != 0; }
ALWAYS_INLINE bool IsLockedByCurrentThread() const { return (m_tag.load() | 0x1ul) == (reinterpret_cast<uintptr_t>(GetCurrentThreadPointer()) | 0x1ul); }
bool IsLocked() const { return m_tag != 0; }
bool IsLockedByCurrentThread() const { return (m_tag | 0x1ul) == (reinterpret_cast<uintptr_t>(GetCurrentThreadPointer()) | 0x1ul); }
};
using KScopedLightLock = KScopedLock<KLightLock>;

View File

@@ -203,54 +203,54 @@ namespace ams::kern {
virtual Result Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, const KPageGroup &page_group, const KPageProperties properties, OperationType operation, bool reuse_ll) = 0;
virtual void FinalizeUpdate(PageLinkedList *page_list) = 0;
ALWAYS_INLINE KPageTableImpl &GetImpl() { return m_impl; }
ALWAYS_INLINE const KPageTableImpl &GetImpl() const { return m_impl; }
KPageTableImpl &GetImpl() { return m_impl; }
const KPageTableImpl &GetImpl() const { return m_impl; }
ALWAYS_INLINE bool IsLockedByCurrentThread() const { return m_general_lock.IsLockedByCurrentThread(); }
bool IsLockedByCurrentThread() const { return m_general_lock.IsLockedByCurrentThread(); }
ALWAYS_INLINE bool IsLinearMappedPhysicalAddress(KPhysicalAddress phys_addr) {
bool IsLinearMappedPhysicalAddress(KPhysicalAddress phys_addr) {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
return KMemoryLayout::IsLinearMappedPhysicalAddress(m_cached_physical_linear_region, phys_addr);
}
ALWAYS_INLINE bool IsLinearMappedPhysicalAddress(KPhysicalAddress phys_addr, size_t size) {
bool IsLinearMappedPhysicalAddress(KPhysicalAddress phys_addr, size_t size) {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
return KMemoryLayout::IsLinearMappedPhysicalAddress(m_cached_physical_linear_region, phys_addr, size);
}
ALWAYS_INLINE bool IsHeapPhysicalAddress(KPhysicalAddress phys_addr) {
bool IsHeapPhysicalAddress(KPhysicalAddress phys_addr) {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
return KMemoryLayout::IsHeapPhysicalAddress(m_cached_physical_heap_region, phys_addr);
}
ALWAYS_INLINE bool IsHeapPhysicalAddress(KPhysicalAddress phys_addr, size_t size) {
bool IsHeapPhysicalAddress(KPhysicalAddress phys_addr, size_t size) {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
return KMemoryLayout::IsHeapPhysicalAddress(m_cached_physical_heap_region, phys_addr, size);
}
ALWAYS_INLINE bool IsHeapPhysicalAddressForFinalize(KPhysicalAddress phys_addr) {
bool IsHeapPhysicalAddressForFinalize(KPhysicalAddress phys_addr) {
MESOSPHERE_ASSERT(!this->IsLockedByCurrentThread());
return KMemoryLayout::IsHeapPhysicalAddress(m_cached_physical_heap_region, phys_addr);
}
ALWAYS_INLINE bool IsHeapVirtualAddress(KVirtualAddress virt_addr) {
bool IsHeapVirtualAddress(KVirtualAddress virt_addr) {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
return KMemoryLayout::IsHeapVirtualAddress(m_cached_virtual_heap_region, virt_addr);
}
ALWAYS_INLINE bool IsHeapVirtualAddress(KVirtualAddress virt_addr, size_t size) {
bool IsHeapVirtualAddress(KVirtualAddress virt_addr, size_t size) {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
return KMemoryLayout::IsHeapVirtualAddress(m_cached_virtual_heap_region, virt_addr, size);
}
ALWAYS_INLINE bool ContainsPages(KProcessAddress addr, size_t num_pages) const {
bool ContainsPages(KProcessAddress addr, size_t num_pages) const {
return (m_address_space_start <= addr) && (num_pages <= (m_address_space_end - m_address_space_start) / PageSize) && (addr + num_pages * PageSize - 1 <= m_address_space_end - 1);
}
private:

View File

@@ -135,7 +135,6 @@ namespace ams::kern {
}
void UnpinThread(s32 core_id, KThread *thread) {
MESOSPHERE_UNUSED(thread);
MESOSPHERE_ASSERT(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores));
MESOSPHERE_ASSERT(thread != nullptr);
MESOSPHERE_ASSERT(m_pinned_threads[core_id] == thread);

View File

@@ -38,7 +38,7 @@ namespace ams::kern {
static_assert(ams::svc::HighestThreadPriority <= HighestCoreMigrationAllowedPriority);
struct SchedulingState {
std::atomic<u8> needs_scheduling;
std::atomic<bool> needs_scheduling;
bool interrupt_task_thread_runnable;
bool should_count_idle;
u64 idle_count;
@@ -181,7 +181,7 @@ namespace ams::kern {
KScopedInterruptDisable intr_disable;
ON_SCOPE_EXIT { GetCurrentThread().EnableDispatch(); };
if (m_state.needs_scheduling.load()) {
if (m_state.needs_scheduling) {
Schedule();
}
}

View File

@@ -53,7 +53,7 @@ namespace ams::kern {
void Dump();
private:
ALWAYS_INLINE bool IsSignaledImpl() const;
bool IsSignaledImpl() const;
void CleanupRequests();
};

View File

@@ -36,8 +36,8 @@ namespace ams::kern {
}
constexpr void Open() {
++m_reference_count;
MESOSPHERE_ASSERT(m_reference_count > 0);
const size_t ref_count = ++m_reference_count;
MESOSPHERE_ASSERT(ref_count > 0);
}
constexpr bool Close() {

View File

@@ -207,7 +207,7 @@ namespace ams::kern {
s32 m_original_physical_ideal_core_id{};
s32 m_num_core_migration_disables{};
ThreadState m_thread_state{};
std::atomic<u8> m_termination_requested{};
std::atomic<bool> m_termination_requested{};
bool m_wait_cancelled{};
bool m_cancellable{};
bool m_signaled{};
@@ -486,7 +486,7 @@ namespace ams::kern {
MESOSPHERE_UNUSED(core_id);
}
s64 GetCpuTime() const { return m_cpu_time.load(); }
s64 GetCpuTime() const { return m_cpu_time; }
s64 GetCpuTime(s32 core_id) const {
MESOSPHERE_ABORT_UNLESS(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores));
@@ -530,7 +530,7 @@ namespace ams::kern {
ALWAYS_INLINE void *GetKernelStackTop() const { return m_kernel_stack_top; }
ALWAYS_INLINE bool IsTerminationRequested() const {
return m_termination_requested.load() || this->GetRawState() == ThreadState_Terminated;
return m_termination_requested || this->GetRawState() == ThreadState_Terminated;
}
size_t GetKernelStackUsage() const;

View File

@@ -40,10 +40,8 @@ namespace ams::kern {
MESOSPHERE_PANIC(__VA_ARGS__); \
} \
})
#elif defined(MESOSPHERE_PRESERVE_ASSERTION_EXPRESSIONS)
#define MESOSPHERE_ASSERT_IMPL(expr, ...) do { static_cast<void>(expr); } while (0)
#else
#define MESOSPHERE_ASSERT_IMPL(expr, ...) static_cast<void>(0)
#define MESOSPHERE_ASSERT_IMPL(expr, ...) do { static_cast<void>(expr); } while (0)
#endif
#define MESOSPHERE_ASSERT(expr) MESOSPHERE_ASSERT_IMPL(expr, "Assertion failed: %s\n", #expr)
@@ -58,10 +56,8 @@ namespace ams::kern {
#ifdef MESOSPHERE_BUILD_FOR_AUDITING
#define MESOSPHERE_AUDIT(expr) MESOSPHERE_ASSERT(expr)
#elif defined(MESOSPHERE_PRESERVE_AUDIT_EXPRESSIONS)
#define MESOSPHERE_AUDIT(expr) do { static_cast<void>(expr); } while (0)
#else
#define MESOSPHERE_AUDIT(expr) static_cast<void>(0)
#define MESOSPHERE_AUDIT(expr) do { static_cast<void>(expr); } while (0)
#endif
#define MESOSPHERE_TODO(arg) ({ constexpr const char *__mesosphere_todo = arg; static_cast<void>(__mesosphere_todo); MESOSPHERE_PANIC("TODO (%s): %s\n", __PRETTY_FUNCTION__, __mesosphere_todo); })

View File

@@ -54,12 +54,12 @@ namespace ams::kern::svc {
public:
using T = typename std::remove_const<typename std::remove_pointer<_T>::type>::type;
public:
static ALWAYS_INLINE Result CopyFromUserspace(void *dst, const void *src, size_t size) {
static Result CopyFromUserspace(void *dst, const void *src, size_t size) {
R_UNLESS(UserspaceAccess::CopyMemoryFromUser(dst, src, size), svc::ResultInvalidPointer());
return ResultSuccess();
}
static ALWAYS_INLINE Result CopyToUserspace(void *dst, const void *src, size_t size) {
static Result CopyToUserspace(void *dst, const void *src, size_t size) {
R_UNLESS(UserspaceAccess::CopyMemoryToUser(dst, src, size), svc::ResultInvalidPointer());
return ResultSuccess();
}
@@ -70,12 +70,12 @@ namespace ams::kern::svc {
public:
using T = typename std::remove_const<typename std::remove_pointer<_T>::type>::type;
public:
static ALWAYS_INLINE Result CopyFromUserspace(void *dst, const void *src, size_t size) {
static Result CopyFromUserspace(void *dst, const void *src, size_t size) {
R_UNLESS(UserspaceAccess::CopyMemoryFromUserAligned32Bit(dst, src, size), svc::ResultInvalidPointer());
return ResultSuccess();
}
static ALWAYS_INLINE Result CopyToUserspace(void *dst, const void *src, size_t size) {
static Result CopyToUserspace(void *dst, const void *src, size_t size) {
R_UNLESS(UserspaceAccess::CopyMemoryToUserAligned32Bit(dst, src, size), svc::ResultInvalidPointer());
return ResultSuccess();
}
@@ -86,12 +86,12 @@ namespace ams::kern::svc {
public:
using T = typename std::remove_const<typename std::remove_pointer<_T>::type>::type;
public:
static ALWAYS_INLINE Result CopyFromUserspace(void *dst, const void *src, size_t size) {
static Result CopyFromUserspace(void *dst, const void *src, size_t size) {
R_UNLESS(UserspaceAccess::CopyMemoryFromUserAligned64Bit(dst, src, size), svc::ResultInvalidPointer());
return ResultSuccess();
}
static ALWAYS_INLINE Result CopyToUserspace(void *dst, const void *src, size_t size) {
static Result CopyToUserspace(void *dst, const void *src, size_t size) {
R_UNLESS(UserspaceAccess::CopyMemoryToUserAligned64Bit(dst, src, size), svc::ResultInvalidPointer());
return ResultSuccess();
}
@@ -110,26 +110,26 @@ namespace ams::kern::svc {
private:
CT *m_ptr;
private:
ALWAYS_INLINE Result CopyToImpl(void *p, size_t size) const {
Result CopyToImpl(void *p, size_t size) const {
return Traits::CopyFromUserspace(p, m_ptr, size);
}
ALWAYS_INLINE Result CopyFromImpl(const void *p, size_t size) const {
Result CopyFromImpl(const void *p, size_t size) const {
return Traits::CopyToUserspace(m_ptr, p, size);
}
protected:
ALWAYS_INLINE Result CopyTo(T *p) const { return this->CopyToImpl(p, sizeof(*p)); }
ALWAYS_INLINE Result CopyFrom(const T *p) const { return this->CopyFromImpl(p, sizeof(*p)); }
Result CopyTo(T *p) const { return this->CopyToImpl(p, sizeof(*p)); }
Result CopyFrom(const T *p) const { return this->CopyFromImpl(p, sizeof(*p)); }
ALWAYS_INLINE Result CopyArrayElementTo(T *p, size_t index) const { return Traits::CopyFromUserspace(p, m_ptr + index, sizeof(*p)); }
ALWAYS_INLINE Result CopyArrayElementFrom(const T *p, size_t index) const { return Traits::CopyToUserspace(m_ptr + index, p, sizeof(*p)); }
Result CopyArrayElementTo(T *p, size_t index) const { return Traits::CopyFromUserspace(p, m_ptr + index, sizeof(*p)); }
Result CopyArrayElementFrom(const T *p, size_t index) const { return Traits::CopyToUserspace(m_ptr + index, p, sizeof(*p)); }
ALWAYS_INLINE Result CopyArrayTo(T *arr, size_t count) const { return this->CopyToImpl(arr, sizeof(*arr) * count); }
ALWAYS_INLINE Result CopyArrayFrom(const T *arr, size_t count) const { return this->CopyFromImpl(arr, sizeof(*arr) * count); }
Result CopyArrayTo(T *arr, size_t count) const { return this->CopyToImpl(arr, sizeof(*arr) * count); }
Result CopyArrayFrom(const T *arr, size_t count) const { return this->CopyFromImpl(arr, sizeof(*arr) * count); }
constexpr ALWAYS_INLINE bool IsNull() const { return m_ptr == nullptr; }
constexpr bool IsNull() const { return m_ptr == nullptr; }
constexpr ALWAYS_INLINE CT *GetUnsafePointer() const { return m_ptr; }
constexpr CT *GetUnsafePointer() const { return m_ptr; }
};
template<>
@@ -142,19 +142,19 @@ namespace ams::kern::svc {
private:
const char *ptr;
protected:
ALWAYS_INLINE Result CopyStringTo(char *dst, size_t size) const {
Result CopyStringTo(char *dst, size_t size) const {
static_assert(sizeof(char) == 1);
R_UNLESS(UserspaceAccess::CopyStringFromUser(dst, this->ptr, size) > 0, svc::ResultInvalidPointer());
return ResultSuccess();
}
ALWAYS_INLINE Result CopyArrayElementTo(char *dst, size_t index) const {
Result CopyArrayElementTo(char *dst, size_t index) const {
return Traits::CopyFromUserspace(dst, this->ptr + index, sizeof(*dst));
}
constexpr ALWAYS_INLINE bool IsNull() const { return this->ptr == nullptr; }
constexpr bool IsNull() const { return this->ptr == nullptr; }
constexpr ALWAYS_INLINE const char *GetUnsafePointer() const { return this->ptr; }
constexpr const char *GetUnsafePointer() const { return this->ptr; }
};
}

View File

@@ -109,7 +109,7 @@ namespace ams::kern::arch::arm64::cpu {
/* Wait for a request to come in. */
{
KScopedLightLock lk(m_cv_lock);
while ((m_target_cores.load() & (1ul << core_id)) == 0) {
while ((m_target_cores & (1ul << core_id)) == 0) {
m_cv.Wait(std::addressof(m_cv_lock));
}
}
@@ -120,7 +120,7 @@ namespace ams::kern::arch::arm64::cpu {
/* Broadcast, if there's nothing pending. */
{
KScopedLightLock lk(m_cv_lock);
if (m_target_cores.load() == 0) {
if (m_target_cores == 0) {
m_cv.Broadcast();
}
}
@@ -163,7 +163,7 @@ namespace ams::kern::arch::arm64::cpu {
if ((op == Operation::InstructionMemoryBarrier) || (Kernel::GetState() == Kernel::State::Initializing)) {
/* Check that there's no on-going operation. */
MESOSPHERE_ABORT_UNLESS(m_operation == Operation::Idle);
MESOSPHERE_ABORT_UNLESS(m_target_cores.load() == 0);
MESOSPHERE_ABORT_UNLESS(m_target_cores == 0);
/* Set operation. */
m_operation = op;
@@ -171,13 +171,12 @@ namespace ams::kern::arch::arm64::cpu {
/* For certain operations, we want to send an interrupt. */
m_target_cores = other_cores_mask;
const u64 target_mask = m_target_cores.load();
const u64 target_mask = m_target_cores;
DataSynchronizationBarrier();
Kernel::GetInterruptManager().SendInterProcessorInterrupt(KInterruptName_CacheOperation, target_mask);
this->ProcessOperation();
while (m_target_cores.load() != 0) {
while (m_target_cores != 0) {
cpu::Yield();
}
@@ -189,7 +188,7 @@ namespace ams::kern::arch::arm64::cpu {
/* Check that there's no on-going operation. */
MESOSPHERE_ABORT_UNLESS(m_operation == Operation::Idle);
MESOSPHERE_ABORT_UNLESS(m_target_cores.load() == 0);
MESOSPHERE_ABORT_UNLESS(m_target_cores == 0);
/* Set operation. */
m_operation = op;
@@ -199,7 +198,7 @@ namespace ams::kern::arch::arm64::cpu {
/* Use the condvar. */
m_cv.Broadcast();
while (m_target_cores.load() != 0) {
while (m_target_cores != 0) {
m_cv.Wait(std::addressof(m_cv_lock));
}

View File

@@ -208,8 +208,6 @@ namespace ams::kern::arch::arm64 {
}
Result KInterruptManager::BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level) {
MESOSPHERE_UNUSED(core_id);
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
KScopedInterruptDisable di;
@@ -224,8 +222,6 @@ namespace ams::kern::arch::arm64 {
}
Result KInterruptManager::UnbindHandler(s32 irq, s32 core_id) {
MESOSPHERE_UNUSED(core_id);
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
KScopedInterruptDisable di;
@@ -248,8 +244,6 @@ namespace ams::kern::arch::arm64 {
}
Result KInterruptManager::ClearInterrupt(s32 irq, s32 core_id) {
MESOSPHERE_UNUSED(core_id);
R_UNLESS(KInterruptController::IsGlobal(irq) || KInterruptController::IsLocal(irq), svc::ResultOutOfRange());
KScopedInterruptDisable di;

View File

@@ -583,15 +583,15 @@ namespace ams::kern::board::nintendo::nx {
constinit KMemoryControllerInterruptTask g_mc_interrupt_task;
/* Memory controller utilities. */
ALWAYS_INLINE void SmmuSynchronizationBarrier() {
void SmmuSynchronizationBarrier() {
ReadMcRegister(MC_SMMU_CONFIG);
}
ALWAYS_INLINE void InvalidatePtc() {
void InvalidatePtc() {
WriteMcRegister(MC_SMMU_PTC_FLUSH_0, 0);
}
ALWAYS_INLINE void InvalidatePtc(KPhysicalAddress address) {
void InvalidatePtc(KPhysicalAddress address) {
WriteMcRegister(MC_SMMU_PTC_FLUSH_1, (static_cast<u64>(GetInteger(address)) >> 32));
WriteMcRegister(MC_SMMU_PTC_FLUSH_0, (GetInteger(address) & 0xFFFFFFF0u) | 1u);
}
@@ -606,15 +606,15 @@ namespace ams::kern::board::nintendo::nx {
return ((match_asid ? 1u : 0u) << 31) | ((asid & 0x7F) << 24) | (((address & 0xFFC00000u) >> DevicePageBits)) | (match);
}
ALWAYS_INLINE void InvalidateTlb() {
void InvalidateTlb() {
return WriteMcRegister(MC_SMMU_TLB_FLUSH, EncodeTlbFlushValue(false, 0, 0, TlbFlushVaMatch_All));
}
ALWAYS_INLINE void InvalidateTlb(u8 asid) {
void InvalidateTlb(u8 asid) {
return WriteMcRegister(MC_SMMU_TLB_FLUSH, EncodeTlbFlushValue(true, asid, 0, TlbFlushVaMatch_All));
}
ALWAYS_INLINE void InvalidateTlbSection(u8 asid, KDeviceVirtualAddress address) {
void InvalidateTlbSection(u8 asid, KDeviceVirtualAddress address) {
return WriteMcRegister(MC_SMMU_TLB_FLUSH, EncodeTlbFlushValue(true, asid, address, TlbFlushVaMatch_Section));
}
@@ -1163,7 +1163,6 @@ namespace ams::kern::board::nintendo::nx {
}
void KDevicePageTable::UnmapImpl(KDeviceVirtualAddress address, u64 size, bool force) {
MESOSPHERE_UNUSED(force);
MESOSPHERE_ASSERT((address & ~DeviceVirtualAddressMask) == 0);
MESOSPHERE_ASSERT(((address + size - 1) & ~DeviceVirtualAddressMask) == 0);

View File

@@ -84,7 +84,6 @@ namespace ams::kern::board::nintendo::nx {
do {
bool res = smc::ReadWriteRegister(std::addressof(value), PmcPhysicalAddress + APBDEV_PMC_PWRGATE_STATUS, 0, 0);
MESOSPHERE_ASSERT(res);
MESOSPHERE_UNUSED(res);
} while ((value & PWRGATE_STATUS_CE123_MASK) != 0);
}

View File

@@ -121,7 +121,6 @@ namespace ams::kern {
MESOSPHERE_ASSERT(reserved == 0);
MESOSPHERE_ASSERT(linear_id != 0);
MESOSPHERE_ASSERT(index < m_table_size);
MESOSPHERE_UNUSED(linear_id, reserved);
/* Free the entry. */
/* NOTE: This code does not check the linear id. */
@@ -144,7 +143,6 @@ namespace ams::kern {
MESOSPHERE_ASSERT(reserved == 0);
MESOSPHERE_ASSERT(linear_id != 0);
MESOSPHERE_ASSERT(index < m_table_size);
MESOSPHERE_UNUSED(reserved);
/* Set the entry. */
Entry *entry = std::addressof(m_table[index]);

View File

@@ -16,6 +16,9 @@
#include <mesosphere.hpp>
#include <mesosphere/kern_select_page_table.hpp>
#undef ALWAYS_INLINE_LAMBDA
#define ALWAYS_INLINE_LAMBDA
namespace ams::kern {
Result KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) {
@@ -3285,7 +3288,6 @@ namespace ams::kern {
TraversalEntry next_entry;
bool traverse_valid = src_impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), aligned_src_start);
MESOSPHERE_ASSERT(traverse_valid);
MESOSPHERE_UNUSED(traverse_valid);
/* Prepare tracking variables. */
KPhysicalAddress cur_block_addr = next_entry.phys_addr;

View File

@@ -17,9 +17,6 @@
namespace ams::kern {
#pragma GCC push_options
#pragma GCC optimize ("-O3")
bool KScheduler::s_scheduler_update_needed;
KScheduler::LockType KScheduler::s_scheduler_lock;
KSchedulerPriorityQueue KScheduler::s_priority_queue;
@@ -610,6 +607,4 @@ namespace ams::kern {
}
}
#pragma GCC pop_options
}

View File

@@ -37,7 +37,7 @@ namespace ams::kern {
uintptr_t m_msg_buffer_end;
uintptr_t m_msg_buffer_space_end;
public:
static constexpr ALWAYS_INLINE int GetEntryCount(const ipc::MessageBuffer::MessageHeader &header) {
static constexpr int GetEntryCount(const ipc::MessageBuffer::MessageHeader &header) {
const auto count = header.GetReceiveListCount();
switch (count) {
case ipc::MessageBuffer::MessageHeader::ReceiveListCountType_None:
@@ -82,7 +82,7 @@ namespace ams::kern {
}
}
constexpr ALWAYS_INLINE bool IsIndex() const {
constexpr bool IsIndex() const {
return m_recv_list_count > ipc::MessageBuffer::MessageHeader::ReceiveListCountType_CountOffset;
}

View File

@@ -63,7 +63,6 @@ namespace ams::kern {
m_tls_address = Null<KProcessAddress>;
const uintptr_t kern_stack_top_address = reinterpret_cast<uintptr_t>(kern_stack_top);
MESOSPHERE_UNUSED(kern_stack_top_address);
/* Next, assert things based on the type. */
switch (type) {
@@ -1162,7 +1161,7 @@ namespace ams::kern {
/* Determine if this is the first termination request. */
const bool first_request = [&] ALWAYS_INLINE_LAMBDA () -> bool {
/* Perform an atomic compare-and-swap from false to true. */
u8 expected = false;
bool expected = false;
return m_termination_requested.compare_exchange_strong(expected, true);
}();

View File

@@ -24,7 +24,7 @@ namespace ams::kern::svc {
Result SetHeapSize(uintptr_t *out_address, size_t size) {
/* Validate size. */
R_UNLESS(util::IsAligned(size, ams::svc::HeapSizeAlignment), svc::ResultInvalidSize());
R_UNLESS(size < ams::kern::MainMemorySizeMax, svc::ResultInvalidSize());
R_UNLESS(size < ams::kern::MainMemorySize, svc::ResultInvalidSize());
/* Set the heap size. */
KProcessAddress address;

View File

@@ -175,9 +175,9 @@ namespace ams::kern::svc {
R_UNLESS(params.code_address + code_size - 1 <= map_end - 1, svc::ResultInvalidMemoryRegion());
/* Check that the number of pages is valid for the kernel address space. */
R_UNLESS(code_num_pages < (kern::MainMemorySizeMax / PageSize), svc::ResultOutOfMemory());
R_UNLESS(system_resource_num_pages < (kern::MainMemorySizeMax / PageSize), svc::ResultOutOfMemory());
R_UNLESS(total_pages < (kern::MainMemorySizeMax / PageSize), svc::ResultOutOfMemory());
R_UNLESS(code_num_pages < (kern::MainMemorySize / PageSize), svc::ResultOutOfMemory());
R_UNLESS(system_resource_num_pages < (kern::MainMemorySize / PageSize), svc::ResultOutOfMemory());
R_UNLESS(total_pages < (kern::MainMemorySize / PageSize), svc::ResultOutOfMemory());
/* Check that optimized memory allocation is used only for applications. */
const bool optimize_allocs = (params.flags & ams::svc::CreateProcessFlag_OptimizeMemoryAllocation) != 0;

View File

@@ -99,8 +99,8 @@ namespace ams::kern::svc {
Result CreateSharedMemory(ams::svc::Handle *out, size_t size, ams::svc::MemoryPermission owner_perm, ams::svc::MemoryPermission remote_perm) {
/* Validate the size. */
R_UNLESS(0 < size && size < kern::MainMemorySizeMax, svc::ResultInvalidSize());
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
R_UNLESS(0 < size && size < kern::MainMemorySize, svc::ResultInvalidSize());
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
/* Validate the permissions. */
R_UNLESS(IsValidSharedMemoryPermission(owner_perm), svc::ResultInvalidNewMemoryPermission());

View File

@@ -1,7 +0,0 @@
SECTIONS
{
/* Discard .eh_frame section */
/DISCARD/ : { *(.group .comment .note .interp)
EXCLUDE_FILE(*crtbegin.o) *(.eh_frame_hdr .eh_frame)
}
}

View File

@@ -75,7 +75,7 @@ namespace ams::fs {
/* Format the path. */
std::va_list va_list;
va_start(va_list, format);
const size_t len = util::VSNPrintf(dst->str, sizeof(dst->str), format, va_list);
const size_t len = std::vsnprintf(dst->str, sizeof(dst->str), format, va_list);
va_end(va_list);
/* Validate length. */

View File

@@ -49,7 +49,7 @@ namespace ams::kvdb {
std::va_list args;
va_start(args, format);
CheckLength(util::VSNPrintf(string.buffer, N, format, args));
CheckLength(std::vsnprintf(string.buffer, N, format, args));
string.buffer[N - 1] = 0;
va_end(args);
@@ -81,7 +81,7 @@ namespace ams::kvdb {
/* Format into the buffer, abort if too large. */
std::va_list args;
va_start(args, format);
CheckLength(util::VSNPrintf(this->buffer, N, format, args));
CheckLength(std::vsnprintf(this->buffer, N, format, args));
va_end(args);
}
@@ -103,7 +103,7 @@ namespace ams::kvdb {
const size_t length = GetLength();
std::va_list args;
va_start(args, format);
CheckLength(util::VSNPrintf(this->buffer + length, N - length, format, args) + length);
CheckLength(std::vsnprintf(this->buffer + length, N - length, format, args) + length);
va_end(args);
}

View File

@@ -19,7 +19,6 @@
#include <stratosphere/os/os_common_types.hpp>
#include <stratosphere/os/os_tick.hpp>
#include <stratosphere/os/os_memory_common.hpp>
#include <stratosphere/os/os_memory_fence.hpp>
#include <stratosphere/os/os_memory_permission.hpp>
#include <stratosphere/os/os_memory_heap_api.hpp>
#include <stratosphere/os/os_memory_virtual_address_api.hpp>
@@ -39,7 +38,6 @@
#include <stratosphere/os/os_timer_event.hpp>
#include <stratosphere/os/os_thread_local_storage.hpp>
#include <stratosphere/os/os_sdk_thread_local_storage.hpp>
#include <stratosphere/os/os_sdk_reply_and_receive.hpp>
#include <stratosphere/os/os_thread.hpp>
#include <stratosphere/os/os_message_queue.hpp>
#include <stratosphere/os/os_waitable.hpp>

View File

@@ -1,41 +0,0 @@
/*
* Copyright (c) 2018-2020 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::os::impl {
#if defined(ATMOSPHERE_ARCH_ARM64)
ALWAYS_INLINE void FenceMemoryStoreStore() { __asm__ __volatile__("dmb ishst" ::: "memory"); }
ALWAYS_INLINE void FenceMemoryStoreLoad() { __asm__ __volatile__("dmb ish" ::: "memory"); }
ALWAYS_INLINE void FenceMemoryStoreAny() { __asm__ __volatile__("dmb ish" ::: "memory"); }
ALWAYS_INLINE void FenceMemoryLoadStore() { __asm__ __volatile__("dmb ishld" ::: "memory"); }
ALWAYS_INLINE void FenceMemoryLoadLoad() { __asm__ __volatile__("dmb ishld" ::: "memory"); }
ALWAYS_INLINE void FenceMemoryLoadAny() { __asm__ __volatile__("dmb ishld" ::: "memory"); }
ALWAYS_INLINE void FenceMemoryAnyStore() { __asm__ __volatile__("dmb ish" ::: "memory"); }
ALWAYS_INLINE void FenceMemoryAnyLoad() { __asm__ __volatile__("dmb ish" ::: "memory"); }
ALWAYS_INLINE void FenceMemoryAnyAny() { __asm__ __volatile__("dmb ish" ::: "memory"); }
#else
#error "Unknown architecture for os::impl::FenceMemory* (Horizon)"
#endif
}

View File

@@ -1,17 +0,0 @@
/*
* Copyright (c) 2018-2020 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 <stratosphere/os/os_memory_fence_api.hpp>

View File

@@ -1,39 +0,0 @@
/*
* Copyright (c) 2018-2020 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>
#if defined(ATMOSPHERE_OS_HORIZON)
#include <stratosphere/os/impl/os_memory_fence_api.os.horizon.hpp>
#else
#error "Unknown os for os::MemoryFence*"
#endif
namespace ams::os {
ALWAYS_INLINE void FenceMemoryStoreStore() { return impl::FenceMemoryStoreStore(); }
ALWAYS_INLINE void FenceMemoryStoreLoad() { return impl::FenceMemoryStoreLoad(); }
ALWAYS_INLINE void FenceMemoryStoreAny() { return impl::FenceMemoryStoreAny(); }
ALWAYS_INLINE void FenceMemoryLoadStore() { return impl::FenceMemoryLoadStore(); }
ALWAYS_INLINE void FenceMemoryLoadLoad() { return impl::FenceMemoryLoadLoad(); }
ALWAYS_INLINE void FenceMemoryLoadAny() { return impl::FenceMemoryLoadAny(); }
ALWAYS_INLINE void FenceMemoryAnyStore() { return impl::FenceMemoryLoadStore(); }
ALWAYS_INLINE void FenceMemoryAnyLoad() { return impl::FenceMemoryLoadLoad(); }
ALWAYS_INLINE void FenceMemoryAnyAny() { return impl::FenceMemoryLoadAny(); }
}

View File

@@ -1,26 +0,0 @@
/*
* Copyright (c) 2018-2020 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::os {
struct WaitableHolderType;
struct WaitableManagerType;
Result SdkReplyAndReceive(os::WaitableHolderType **out, Handle reply_target, WaitableManagerType *manager);
}

View File

@@ -368,11 +368,18 @@ namespace ams::sf::impl {
size_t out_object_index;
};
template<typename... Arguments>
template<auto MemberFunction, typename Return, typename Class, typename... Arguments>
struct CommandMetaInfo {
public:
using ReturnType = Return;
using ClassType = Class;
using ClassTypePointer = ClassType *;
using ArgsType = std::tuple<typename std::decay<Arguments>::type...>;
static constexpr bool ReturnsResult = std::is_same<ReturnType, Result>::value;
static constexpr bool ReturnsVoid = std::is_same<ReturnType, void>::value;
static_assert(ReturnsResult || ReturnsVoid, "Service Commands must return Result or void.");
using InDatas = TupleFilter<InDataFilter>::FilteredType<ArgsType>;
using OutDatas = TupleFilter<OutDataFilter>::FilteredType<ArgsType>;
using Buffers = TupleFilter<BufferFilter>::FilteredType<ArgsType>;
@@ -1029,13 +1036,15 @@ namespace ams::sf::impl {
return ResultSuccess();
}
template<typename CommandMeta, typename... Arguments>
constexpr Result InvokeServiceCommandImplCommon(CmifOutHeader **out_header_ptr, cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, Result (*invoke_impl)(sf::IServiceObject *, Arguments &&...)) {
template<auto ServiceCommandImpl, typename Return, typename ClassType, typename... Arguments>
constexpr Result InvokeServiceCommandImpl(CmifOutHeader **out_header_ptr, cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) {
using CommandMeta = CommandMetaInfo<ServiceCommandImpl, Return, ClassType, Arguments...>;
using ImplProcessorType = HipcCommandProcessor<CommandMeta>;
using BufferArrayType = std::array<cmif::PointerAndSize, CommandMeta::NumBuffers>;
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
using InOutObjectHolderType = InOutObjectHolder<CommandMeta::NumInObjects, CommandMeta::NumOutObjects>;
static_assert(std::is_base_of<sf::IServiceObject, typename CommandMeta::ClassType>::value, "InvokeServiceCommandImpl: Service Commands must be ServiceObject member functions");
/* Create a processor for us to work with. */
ImplProcessorType impl_processor;
@@ -1067,6 +1076,7 @@ namespace ams::sf::impl {
/* Decoding/Invocation. */
{
typename CommandMeta::ClassTypePointer this_ptr = static_cast<typename CommandMeta::ClassTypePointer>(ctx.srv_obj);
typename CommandMeta::ArgsType args_tuple = ImplProcessorType::DeserializeArguments(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder);
/* Handle in process ID holder if relevant. */
@@ -1093,18 +1103,16 @@ namespace ams::sf::impl {
#undef _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID
}
using TrueArgumentsTuple = std::tuple<Arguments...>;
sf::IServiceObject * const this_ptr = ctx.srv_obj;
const auto command_result = [this_ptr, invoke_impl, &args_tuple]<size_t ...Ix>(std::index_sequence<Ix...>) ALWAYS_INLINE_LAMBDA {
return invoke_impl(this_ptr, std::forward<typename std::tuple_element<Ix, TrueArgumentsTuple>::type>(std::get<Ix>(args_tuple))...);
}(std::make_index_sequence<std::tuple_size<typename CommandMeta::ArgsType>::value>());
if (R_FAILED(command_result)) {
cmif::PointerAndSize out_raw_data;
ctx.processor->PrepareForErrorReply(ctx, out_raw_data, runtime_metadata);
R_TRY(GetCmifOutHeaderPointer(out_header_ptr, out_raw_data));
return command_result;
if constexpr (CommandMeta::ReturnsResult) {
const auto command_result = std::apply([=](auto&&... args) { return (this_ptr->*ServiceCommandImpl)(std::forward<Arguments>(args)...); }, args_tuple);
if (R_FAILED(command_result)) {
cmif::PointerAndSize out_raw_data;
ctx.processor->PrepareForErrorReply(ctx, out_raw_data, runtime_metadata);
R_TRY(GetCmifOutHeaderPointer(out_header_ptr, out_raw_data));
return command_result;
}
} else {
std::apply([=](auto&&... args) { (this_ptr->*ServiceCommandImpl)(std::forward<Arguments>(args)...); }, args_tuple);
}
}
@@ -1129,26 +1137,6 @@ namespace ams::sf::impl {
return ResultSuccess();
}
template<auto ServiceCommandImpl, typename Return, typename ClassType, typename... Arguments>
constexpr Result InvokeServiceCommandImpl(CmifOutHeader **out_header_ptr, cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) {
using CommandMeta = CommandMetaInfo<Arguments...>;
static_assert(std::is_base_of<sf::IServiceObject, ClassType>::value, "InvokeServiceCommandImpl: Service Commands must be ServiceObject member functions");
constexpr bool ReturnsResult = std::is_same<Return, Result>::value;
constexpr bool ReturnsVoid = std::is_same<Return, void>::value;
static_assert(ReturnsResult || ReturnsVoid, "Service Commands must return Result or void.");
return InvokeServiceCommandImplCommon<CommandMeta, Arguments...>(out_header_ptr, ctx, in_raw_data, +[](sf::IServiceObject *srv_obj, Arguments &&... args) -> Result {
if constexpr (ReturnsResult) {
return (static_cast<ClassType *>(srv_obj)->*ServiceCommandImpl)(std::forward<Arguments>(args)...);
} else {
(static_cast<ClassType *>(srv_obj)->*ServiceCommandImpl)(std::forward<Arguments>(args)...);
return ResultSuccess();
}
});
}
}
namespace ams::sf::impl {

View File

@@ -88,14 +88,14 @@ namespace ams::emummc {
/* Format paths. */
if (storage == Storage_SdFile) {
util::SNPrintf(g_exo_config.file_cfg.path, sizeof(g_exo_config.file_cfg.path), "/%s", paths->file_path);
std::snprintf(g_exo_config.file_cfg.path, sizeof(g_exo_config.file_cfg.path), "/%s", paths->file_path);
}
util::SNPrintf(g_exo_config.emu_dir_path, sizeof(g_exo_config.emu_dir_path), "/%s", paths->nintendo_path);
std::snprintf(g_exo_config.emu_dir_path, sizeof(g_exo_config.emu_dir_path), "/%s", paths->nintendo_path);
/* If we're emummc, implement default nintendo redirection path. */
if (g_is_emummc && std::strcmp(g_exo_config.emu_dir_path, "/") == 0) {
util::SNPrintf(g_exo_config.emu_dir_path, sizeof(g_exo_config.emu_dir_path), "/emummc/Nintendo_%04x", g_exo_config.base_cfg.id);
std::snprintf(g_exo_config.emu_dir_path, sizeof(g_exo_config.emu_dir_path), "/emummc/Nintendo_%04x", g_exo_config.base_cfg.id);
}
}

View File

@@ -197,15 +197,10 @@ extern "C" {
}
namespace {
constinit ams::os::Mutex g_abort_lock(true);
}
/* Custom abort handler, so that std::abort will trigger these. */
void abort() {
std::scoped_lock lk(g_abort_lock);
static ams::os::Mutex abort_lock(true);
std::scoped_lock lk(abort_lock);
ams::AbortImpl();
__builtin_unreachable();

View File

@@ -238,7 +238,7 @@ namespace ams::boot2 {
/* Read the mitm list off the SD card. */
{
char path[fs::EntryNameLengthMax];
util::SNPrintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/mitm.lst", static_cast<u64>(program_id));
std::snprintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/mitm.lst", static_cast<u64>(program_id));
fs::FileHandle f;
if (R_FAILED(fs::OpenFile(&f, path, fs::OpenMode_Read))) {

View File

@@ -23,7 +23,7 @@ namespace ams::cfg {
/* Helper. */
void GetFlagMountName(char *dst) {
util::SNPrintf(dst, fs::MountNameLengthMax + 1, "#flag%08x", g_flag_mount_count.fetch_add(1));
std::snprintf(dst, fs::MountNameLengthMax + 1, "#flag%08x", g_flag_mount_count.fetch_add(1));
}
bool HasFlagFile(const char *flag_path) {
@@ -42,7 +42,7 @@ namespace ams::cfg {
/* Check if the entry exists. */
char full_path[fs::EntryNameLengthMax + 1];
util::SNPrintf(full_path, sizeof(full_path), "%s:/%s", mount_name, flag_path[0] == '/' ? flag_path + 1 : flag_path);
std::snprintf(full_path, sizeof(full_path), "%s:/%s", mount_name, flag_path[0] == '/' ? flag_path + 1 : flag_path);
bool has_file;
if (R_FAILED(fs::HasFile(std::addressof(has_file), full_path))) {
@@ -61,19 +61,19 @@ namespace ams::cfg {
bool HasContentSpecificFlag(ncm::ProgramId program_id, const char *flag) {
char content_flag[fs::EntryNameLengthMax + 1];
util::SNPrintf(content_flag, sizeof(content_flag) - 1, "/atmosphere/contents/%016lx/flags/%s.flag", static_cast<u64>(program_id), flag);
std::snprintf(content_flag, sizeof(content_flag) - 1, "/atmosphere/contents/%016lx/flags/%s.flag", static_cast<u64>(program_id), flag);
return HasFlagFile(content_flag);
}
bool HasGlobalFlag(const char *flag) {
char global_flag[fs::EntryNameLengthMax + 1];
util::SNPrintf(global_flag, sizeof(global_flag) - 1, "/atmosphere/flags/%s.flag", flag);
std::snprintf(global_flag, sizeof(global_flag) - 1, "/atmosphere/flags/%s.flag", flag);
return HasFlagFile(global_flag);
}
bool HasHblFlag(const char *flag) {
char hbl_flag[0x100];
util::SNPrintf(hbl_flag, sizeof(hbl_flag) - 1, "hbl_%s", flag);
std::snprintf(hbl_flag, sizeof(hbl_flag) - 1, "hbl_%s", flag);
return HasGlobalFlag(hbl_flag);
}

View File

@@ -252,7 +252,7 @@ namespace ams::cfg {
while (*value == '/' || *value == '\\') {
value++;
}
util::SNPrintf(g_hbl_sd_path, sizeof(g_hbl_sd_path) - 1, "/%s", value);
std::snprintf(g_hbl_sd_path, sizeof(g_hbl_sd_path) - 1, "/%s", value);
g_hbl_sd_path[sizeof(g_hbl_sd_path) - 1] = '\0';
for (size_t i = 0; i < sizeof(g_hbl_sd_path); i++) {
@@ -332,7 +332,7 @@ namespace ams::cfg {
std::atomic<u32> g_ini_mount_count;
void GetIniMountName(char *dst) {
util::SNPrintf(dst, fs::MountNameLengthMax + 1, "#ini%08x", g_ini_mount_count.fetch_add(1));
std::snprintf(dst, fs::MountNameLengthMax + 1, "#ini%08x", g_ini_mount_count.fetch_add(1));
}
void ParseIniFile(util::ini::Handler handler, const char *path, void *user_ctx) {
@@ -348,7 +348,7 @@ namespace ams::cfg {
fs::FileHandle file;
{
char full_path[fs::EntryNameLengthMax + 1];
util::SNPrintf(full_path, sizeof(full_path), "%s:/%s", mount_name, path[0] == '/' ? path + 1 : path);
std::snprintf(full_path, sizeof(full_path), "%s:/%s", mount_name, path[0] == '/' ? path + 1 : path);
if (R_FAILED(fs::OpenFile(std::addressof(file), full_path, fs::OpenMode_Read))) {
return;
}
@@ -365,7 +365,7 @@ namespace ams::cfg {
ContentSpecificOverrideConfig GetContentOverrideConfig(ncm::ProgramId program_id) {
char path[fs::EntryNameLengthMax + 1];
util::SNPrintf(path, sizeof(path), "/atmosphere/contents/%016lx/config.ini", static_cast<u64>(program_id));
std::snprintf(path, sizeof(path), "/atmosphere/contents/%016lx/config.ini", static_cast<u64>(program_id));
ContentSpecificOverrideConfig config = {
.override_key = g_default_override_key,

View File

@@ -50,7 +50,7 @@ namespace ams::diag {
void DebugLogImpl(const char *format, ::std::va_list vl) {
std::scoped_lock lk(g_debug_log_lock);
util::VSNPrintf(g_debug_buffer, sizeof(g_debug_buffer), format, vl);
std::vsnprintf(g_debug_buffer, sizeof(g_debug_buffer), format, vl);
svc::OutputDebugString(g_debug_buffer, strlen(g_debug_buffer));
}

View File

@@ -24,7 +24,7 @@ namespace ams::erpt::srv {
attachment_id.uuid.ToString(uuid_str, sizeof(uuid_str));
AttachmentFileName attachment_name;
util::SNPrintf(attachment_name.name, sizeof(attachment_name.name), "%s:/%s.att", ReportStoragePath, uuid_str);
std::snprintf(attachment_name.name, sizeof(attachment_name.name), "%s:/%s.att", ReportStoragePath, uuid_str);
return attachment_name;
}

View File

@@ -21,7 +21,7 @@ namespace ams::erpt::srv {
ReportFileName Report::FileName(ReportId report_id, bool redirect_to_sd) {
ReportFileName report_name;
util::SNPrintf(report_name.name, sizeof(report_name.name),
std::snprintf(report_name.name, sizeof(report_name.name),
"%s:/%08x-%04x-%04x-%02x%02x-%04x%08x",
(redirect_to_sd ? ReportOnSdStoragePath : ReportStoragePath),
report_id.uuid_data.time_low,

View File

@@ -80,7 +80,7 @@ namespace ams::fs {
namespace ams::fs::impl {
const char *IdString::ToValueString(int id) {
const int len = util::SNPrintf(this->buffer, sizeof(this->buffer), "%d", id);
const int len = std::snprintf(this->buffer, sizeof(this->buffer), "%d", id);
AMS_ASSERT(static_cast<size_t>(len) < sizeof(this->buffer));
return this->buffer;
}
@@ -202,7 +202,7 @@ namespace ams::fs::impl {
return;
}
const auto size = util::VSNPrintf(log_buffer.get(), log_buffer_size, format, vl);
const auto size = std::vsnprintf(log_buffer.get(), log_buffer_size, format, vl);
if (size < log_buffer_size) {
break;
}
@@ -233,7 +233,7 @@ namespace ams::fs::impl {
return;
}
const auto size = util::VSNPrintf(str_buffer.get(), str_buffer_size, format, vl);
const auto size = std::vsnprintf(str_buffer.get(), str_buffer_size, format, vl);
if (size < str_buffer_size) {
break;
}
@@ -269,7 +269,7 @@ namespace ams::fs::impl {
return;
}
log_buffer_size = 1 + util::SNPrintf(log_buffer.get(), try_size, FormatString, start_ms, end_ms, result.GetValue(), handle, priority, name, str_buffer.get());
log_buffer_size = 1 + std::snprintf(log_buffer.get(), try_size, FormatString, start_ms, end_ms, result.GetValue(), handle, priority, name, str_buffer.get());
if (log_buffer_size <= try_size) {
break;
}
@@ -312,7 +312,7 @@ namespace ams::fs::impl {
" }\n";
char log_buffer[0x80];
const int len = 1 + util::SNPrintf(log_buffer, sizeof(log_buffer), StartLog, static_cast<int>(program_index));
const int len = 1 + std::snprintf(log_buffer, sizeof(log_buffer), StartLog, static_cast<int>(program_index));
if (static_cast<size_t>(len) <= sizeof(log_buffer)) {
OutputAccessLogImpl(log_buffer, len);
}

View File

@@ -33,7 +33,7 @@ namespace ams::fs {
AMS_ABORT_UNLESS(dst_size >= needed_size);
/* Generate the name. */
auto size = util::SNPrintf(dst, dst_size, "%s:", bis_mount_name);
auto size = std::snprintf(dst, dst_size, "%s:", bis_mount_name);
AMS_ASSERT(static_cast<size_t>(size) == needed_size - 1);
return ResultSuccess();

View File

@@ -172,7 +172,7 @@ namespace ams::fs {
/* Create a redirection filesystem to the relevant content folder. */
char path[fs::EntryNameLengthMax + 1];
util::SNPrintf(path, sizeof(path), "/atmosphere/contents/%016lx/exefs", program_id.value);
std::snprintf(path, sizeof(path), "/atmosphere/contents/%016lx/exefs", program_id.value);
auto subdir_fs = std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_fs), path);
if (subdir_fs == nullptr) {
@@ -190,7 +190,7 @@ namespace ams::fs {
/* Create a path representing the stub. */
char stub_path[fs::EntryNameLengthMax + 1];
util::SNPrintf(stub_path, sizeof(stub_path), "%s.stub", path);
std::snprintf(stub_path, sizeof(stub_path), "%s.stub", path);
/* Query whether we have the file. */
bool has_file;

View File

@@ -32,7 +32,7 @@ namespace ams::fs {
AMS_ABORT_UNLESS(dst_size >= needed_size);
/* Generate the name. */
auto size = util::SNPrintf(dst, dst_size, "%s:", GetContentStorageMountName(id));
auto size = std::snprintf(dst, dst_size, "%s:", GetContentStorageMountName(id));
AMS_ASSERT(static_cast<size_t>(size) == needed_size - 1);
return ResultSuccess();

View File

@@ -42,7 +42,7 @@ namespace ams::fs {
AMS_ABORT_UNLESS(dst_size >= needed_size);
/* Generate the name. */
auto size = util::SNPrintf(dst, dst_size, "%s%s%08x:", impl::GameCardFileSystemMountName, GetGameCardMountNameSuffix(this->partition), this->handle);
auto size = std::snprintf(dst, dst_size, "%s%s%08x:", impl::GameCardFileSystemMountName, GetGameCardMountNameSuffix(this->partition), this->handle);
AMS_ASSERT(static_cast<size_t>(size) == needed_size - 1);
return ResultSuccess();

View File

@@ -34,7 +34,7 @@ namespace ams::fs {
AMS_ABORT_UNLESS(dst_size >= needed_size);
/* Generate the name. */
auto size = util::SNPrintf(dst, dst_size, "%s:", impl::SdCardFileSystemMountName);
auto size = std::snprintf(dst, dst_size, "%s:", impl::SdCardFileSystemMountName);
AMS_ASSERT(static_cast<size_t>(size) == needed_size - 1);
return ResultSuccess();

View File

@@ -151,7 +151,7 @@ namespace ams::fs {
AMS_FS_R_TRY(accessor->GetCommonMountName(dst, dst_size));
const auto mount_name_len = strnlen(dst, dst_size);
const auto common_path_len = util::SNPrintf(dst + mount_name_len, dst_size - mount_name_len, "%s", sub_path);
const auto common_path_len = std::snprintf(dst + mount_name_len, dst_size - mount_name_len, "%s", sub_path);
AMS_FS_R_UNLESS(static_cast<size_t>(common_path_len) < dst_size - mount_name_len, fs::ResultTooLongPath());
return ResultSuccess();

View File

@@ -78,7 +78,7 @@ namespace ams::fssystem {
std::unique_ptr<fs::fsa::IFile> dst_file;
{
char dst_path[fs::EntryNameLengthMax + 1];
const size_t original_size = static_cast<size_t>(util::SNPrintf(dst_path, sizeof(dst_path), "%s%s", dst_parent_path, entry->name));
const size_t original_size = static_cast<size_t>(std::snprintf(dst_path, sizeof(dst_path), "%s%s", dst_parent_path, entry->name));
/* TODO: Error code? N aborts here. */
AMS_ABORT_UNLESS(original_size < sizeof(dst_path));
@@ -103,7 +103,7 @@ namespace ams::fssystem {
Result CopyDirectoryRecursively(fs::fsa::IFileSystem *dst_fs, fs::fsa::IFileSystem *src_fs, const char *dst_path, const char *src_path, void *work_buf, size_t work_buf_size) {
char dst_path_buf[fs::EntryNameLengthMax + 1];
const size_t original_size = static_cast<size_t>(util::SNPrintf(dst_path_buf, sizeof(dst_path_buf), "%s", dst_path));
const size_t original_size = static_cast<size_t>(std::snprintf(dst_path_buf, sizeof(dst_path_buf), "%s", dst_path));
AMS_ABORT_UNLESS(original_size < sizeof(dst_path_buf));
return IterateDirectoryRecursively(src_fs, src_path,

View File

@@ -21,7 +21,7 @@ namespace ams::ncm {
void GetStringFromBytes(char *dst, const void *src, size_t count) {
for (size_t i = 0; i < count; i++) {
util::SNPrintf(dst + 2 * i, 3, "%02x", static_cast<const u8 *>(src)[i]);
std::snprintf(dst + 2 * i, 3, "%02x", static_cast<const u8 *>(src)[i]);
}
}
@@ -68,14 +68,14 @@ namespace ams::ncm {
AMS_ABORT_UNLESS(dst_size > TicketFileStringLength);
ContentIdString str;
GetStringFromRightsId(str.data, sizeof(str), id);
util::SNPrintf(dst, dst_size, "%s.tik", str.data);
std::snprintf(dst, dst_size, "%s.tik", str.data);
}
void GetCertificateFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id) {
AMS_ABORT_UNLESS(dst_size > CertFileStringLength);
ContentIdString str;
GetStringFromRightsId(str.data, sizeof(str), id);
util::SNPrintf(dst, dst_size, "%s.cert", str.data);
std::snprintf(dst, dst_size, "%s.cert", str.data);
}
std::optional<ContentId> GetContentIdFromString(const char *str, size_t len) {

View File

@@ -25,7 +25,7 @@ namespace ams::ncm {
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *package_root_path, const char *entry_path) {
char package_path[MaxPackagePathLength];
const size_t path_len = util::SNPrintf(package_path, sizeof(package_path), "%s%s", package_root_path, entry_path);
const size_t path_len = std::snprintf(package_path, sizeof(package_path), "%s%s", package_root_path, entry_path);
AMS_ABORT_UNLESS(path_len < MaxPackagePathLength);
return fs::ConvertToFsCommonPath(dst, dst_size, package_path);

View File

@@ -122,7 +122,7 @@ namespace ams::ncm {
/* This also works on < 4.0.0 (though the system partition will never be on-sd there), */
/* and so this will always return false. */
char path[fs::MountNameLengthMax + 2 /* :/ */ + 1];
util::SNPrintf(path, sizeof(path), "%s:/", bis_mount_name);
std::snprintf(path, sizeof(path), "%s:/", bis_mount_name);
return fs::IsSignedSystemPartitionOnSdCardValid(path);
} else {
/* On 4.0.0-7.0.1, use the remote command to validate the system partition. */
@@ -203,7 +203,7 @@ namespace ams::ncm {
/* Create a new mount name and copy it to out. */
std::strcpy(out->mount_name, impl::CreateUniqueMountName().str);
util::SNPrintf(out->path, sizeof(out->path), "%s:/", out->mount_name);
std::snprintf(out->path, sizeof(out->path), "%s:/", out->mount_name);
return ResultSuccess();
}
@@ -214,7 +214,7 @@ namespace ams::ncm {
/* Create a new mount name and copy it to out. */
std::strcpy(out->mount_name, impl::CreateUniqueMountName().str);
util::SNPrintf(out->path, sizeof(out->path), "%s:/", out->mount_name);
std::snprintf(out->path, sizeof(out->path), "%s:/", out->mount_name);
return ResultSuccess();
}
@@ -230,7 +230,7 @@ namespace ams::ncm {
/* Create a new mount name and copy it to out. */
std::strcpy(out->mount_name, impl::CreateUniqueMountName().str);
out->mount_name[0] = '#';
util::SNPrintf(out->path, sizeof(out->path), "%s:/meta", out->mount_name);
std::snprintf(out->path, sizeof(out->path), "%s:/meta", out->mount_name);
return ResultSuccess();
}

View File

@@ -39,13 +39,13 @@ namespace ams::ncm::impl {
MountName CreateUniqueMountName() {
MountName name = {};
util::SNPrintf(name.str, sizeof(name.str), "@ncm%08x", g_mount_name_count.fetch_add(1));
std::snprintf(name.str, sizeof(name.str), "@ncm%08x", g_mount_name_count.fetch_add(1));
return name;
}
RootDirectoryPath GetRootDirectoryPath(const MountName &mount_name) {
RootDirectoryPath path = {};
util::SNPrintf(path.str, sizeof(path.str), "%s:/", mount_name.str);
std::snprintf(path.str, sizeof(path.str), "%s:/", mount_name.str);
return path;
}

View File

@@ -29,7 +29,7 @@ namespace ams::ncm {
/* Create a hex string from bytes. */
for (size_t i = 0; i < sizeof(bytes); i++) {
util::SNPrintf(tmp, util::size(tmp), "%02x", bytes[i]);
std::snprintf(tmp, util::size(tmp), "%02x", bytes[i]);
out->Append(tmp);
}

View File

@@ -55,14 +55,14 @@ namespace ams::os::impl {
manager.NotifyThreadNameChanged(thread);
{
GetReference(thread->cs_thread).Lock();
std::unique_lock lk(GetReference(thread->cs_thread));
while (thread->state == ThreadType::State_Initialized) {
GetReference(thread->cv_thread).Wait(GetPointer(thread->cs_thread));
}
const auto new_state = thread->state;
GetReference(thread->cs_thread).Unlock();
if (new_state == ThreadType::State_Started) {
if (thread->state == ThreadType::State_Started) {
lk.unlock();
thread->function(thread->argument);
}
}
@@ -220,7 +220,7 @@ namespace ams::os::impl {
constexpr size_t ThreadNamePrefixSize = sizeof(ThreadNamePrefix) - 1;
const u64 func = reinterpret_cast<u64>(thread->function);
static_assert(ThreadNamePrefixSize + sizeof(func) * 2 + 1 <= sizeof(thread->name_buffer));
util::SNPrintf(thread->name_buffer, sizeof(thread->name_buffer), "%s%016lX", ThreadNamePrefix, func);
std::snprintf(thread->name_buffer, sizeof(thread->name_buffer), "%s%016lX", ThreadNamePrefix, func);
}
thread->name_pointer = thread->name_buffer;

View File

@@ -20,32 +20,23 @@
namespace ams::os::impl {
Result WaitableManagerImpl::WaitAnyImpl(WaitableHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target) {
WaitableHolderBase *WaitableManagerImpl::WaitAnyImpl(bool infinite, TimeSpan timeout) {
/* Prepare for processing. */
this->signaled_holder = nullptr;
this->target_impl.SetCurrentThreadHandleForCancelWait();
WaitableHolderBase *holder = this->LinkHoldersToObjectList();
WaitableHolderBase *result = this->LinkHoldersToObjectList();
/* Check if we've been signaled. */
{
std::scoped_lock lk(this->cs_wait);
if (this->signaled_holder != nullptr) {
holder = this->signaled_holder;
result = this->signaled_holder;
}
}
/* Process object array. */
Result wait_result = ResultSuccess();
if (holder != nullptr) {
if (reply && reply_target != svc::InvalidHandle) {
s32 index;
wait_result = this->target_impl.TimedReplyAndReceive(std::addressof(index), nullptr, 0, 0, reply_target, TimeSpan::FromNanoSeconds(0));
if (R_FAILED(wait_result)) {
holder = nullptr;
}
}
} else {
wait_result = this->WaitAnyHandleImpl(std::addressof(holder), infinite, timeout, reply, reply_target);
if (result == nullptr) {
result = this->WaitAnyHandleImpl(infinite, timeout);
}
/* Unlink holders from the current object list. */
@@ -53,13 +44,10 @@ namespace ams::os::impl {
this->target_impl.ClearCurrentThreadHandleForCancelWait();
/* Set output holder. */
*out = holder;
return wait_result;
return result;
}
Result WaitableManagerImpl::WaitAnyHandleImpl(WaitableHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target) {
WaitableHolderBase *WaitableManagerImpl::WaitAnyHandleImpl(bool infinite, TimeSpan timeout) {
Handle object_handles[MaximumHandleCount];
WaitableHolderBase *objects[MaximumHandleCount];
@@ -72,30 +60,18 @@ namespace ams::os::impl {
TimeSpan min_timeout = 0;
WaitableHolderBase *min_timeout_object = this->RecalculateNextTimeout(&min_timeout, end_time);
s32 index = WaitInvalid;
Result wait_result = ResultSuccess();
if (reply) {
if (infinite && min_timeout_object == nullptr) {
wait_result = this->target_impl.ReplyAndReceive(std::addressof(index), object_handles, MaximumHandleCount, count, reply_target);
} else {
wait_result = this->target_impl.TimedReplyAndReceive(std::addressof(index), object_handles, MaximumHandleCount, count, reply_target, min_timeout);
}
} else if (infinite && min_timeout_object == nullptr) {
wait_result = this->target_impl.WaitAny(std::addressof(index), object_handles, MaximumHandleCount, count);
s32 index;
if (infinite && min_timeout_object == nullptr) {
index = this->target_impl.WaitAny(object_handles, MaximumHandleCount, count);
} else {
if (count == 0 && min_timeout == 0) {
index = WaitTimedOut;
} else {
wait_result = this->target_impl.TimedWaitAny(std::addressof(index), object_handles, MaximumHandleCount, count, min_timeout);
index = this->target_impl.TimedWaitAny(object_handles, MaximumHandleCount, count, min_timeout);
AMS_ABORT_UNLESS(index != WaitInvalid);
}
}
if (index == WaitInvalid) {
*out = nullptr;
return wait_result;
}
switch (index) {
case WaitTimedOut:
if (min_timeout_object) {
@@ -103,35 +79,23 @@ namespace ams::os::impl {
if (min_timeout_object->IsSignaled() == TriBool::True) {
std::scoped_lock lk(this->cs_wait);
this->signaled_holder = min_timeout_object;
*out = min_timeout_object;
return wait_result;
return this->signaled_holder;
}
} else {
*out = nullptr;
return wait_result;
continue;
}
break;
return nullptr;
case WaitCancelled:
{
std::scoped_lock lk(this->cs_wait);
if (this->signaled_holder) {
*out = this->signaled_holder;
return wait_result;
}
if (this->signaled_holder) {
return this->signaled_holder;
}
break;
continue;
default: /* 0 - 0x3F, valid. */
{
AMS_ASSERT(0 <= index && index < static_cast<s32>(MaximumHandleCount));
std::scoped_lock lk(this->cs_wait);
this->signaled_holder = objects[index];
*out = objects[index];
return wait_result;
return this->signaled_holder;
}
}
reply_target = svc::InvalidHandle;
}
}

View File

@@ -38,21 +38,14 @@ namespace ams::os::impl {
InternalCriticalSection cs_wait;
WaitableManagerTargetImpl target_impl;
private:
Result WaitAnyImpl(WaitableHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target);
Result WaitAnyHandleImpl(WaitableHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target);
WaitableHolderBase *WaitAnyImpl(bool infinite, TimeSpan timeout);
WaitableHolderBase *WaitAnyHandleImpl(bool infinite, TimeSpan timeout);
s32 BuildHandleArray(Handle out_handles[], WaitableHolderBase *out_objects[], s32 num);
WaitableHolderBase *LinkHoldersToObjectList();
void UnlinkHoldersFromObjectList();
WaitableHolderBase *RecalculateNextTimeout(TimeSpan *out_min_timeout, TimeSpan end_time);
WaitableHolderBase *WaitAnyImpl(bool infinite, TimeSpan timeout) {
WaitableHolderBase *holder = nullptr;
const Result wait_result = this->WaitAnyImpl(std::addressof(holder), infinite, timeout, false, svc::InvalidHandle);
AMS_ASSERT(R_SUCCEEDED(wait_result));
return holder;
}
public:
/* Wait. */
WaitableHolderBase *WaitAny() {
@@ -67,10 +60,6 @@ namespace ams::os::impl {
return this->WaitAnyImpl(false, ts);
}
Result ReplyAndReceive(WaitableHolderBase **out, Handle reply_target) {
return this->WaitAnyImpl(out, true, TimeSpan::FromNanoSeconds(std::numeric_limits<s64>::max()), true, reply_target);
}
/* List management. */
bool IsEmpty() const {
return this->waitable_list.empty();

View File

@@ -19,13 +19,13 @@
namespace ams::os::impl {
Result WaitableManagerHorizonImpl::WaitSynchronizationN(s32 *out_index, s32 num, Handle arr[], s32 array_size, s64 ns) {
s32 WaitableManagerHorizonImpl::WaitSynchronizationN(s32 num, Handle arr[], s32 array_size, s64 ns) {
AMS_ASSERT(!(num == 0 && ns == 0));
s32 index = WaitableManagerImpl::WaitInvalid;
R_TRY_CATCH(svc::WaitSynchronization(std::addressof(index), static_cast<const svc::Handle *>(arr), num, ns)) {
R_CATCH(svc::ResultTimedOut) { index = WaitableManagerImpl::WaitTimedOut; }
R_CATCH(svc::ResultCancelled) { index = WaitableManagerImpl::WaitCancelled; }
R_CATCH(svc::ResultTimedOut) { return WaitableManagerImpl::WaitTimedOut; }
R_CATCH(svc::ResultCancelled) { return WaitableManagerImpl::WaitCancelled; }
/* All other results are critical errors. */
/* svc::ResultThreadTerminating */
/* svc::ResultInvalidHandle. */
@@ -33,34 +33,7 @@ namespace ams::os::impl {
/* svc::ResultOutOfRange */
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
*out_index = index;
return ResultSuccess();
}
Result ReplyAndReceiveN(s32 *out_index, s32 num, Handle arr[], s32 array_size, s64 ns, Handle reply_target) {
/* NOTE: Nintendo does not initialize this value, which seems like it can cause incorrect behavior. */
s32 index = WaitableManagerImpl::WaitInvalid;
static_assert(WaitableManagerImpl::WaitInvalid != -1);
R_TRY_CATCH(svc::ReplyAndReceive(std::addressof(index), arr, num, ns, reply_target)) {
R_CATCH(svc::ResultTimedOut) { *out_index = WaitableManagerImpl::WaitTimedOut; return R_CURRENT_RESULT; }
R_CATCH(svc::ResultCancelled) { *out_index = WaitableManagerImpl::WaitCancelled; return R_CURRENT_RESULT; }
R_CATCH(svc::ResultSessionClosed) {
if (index == -1) {
*out_index = WaitableManagerImpl::WaitInvalid;
return os::ResultSessionClosedForReply();
} else {
*out_index = index;
return os::ResultSessionClosedForReceive();
}
}
R_CATCH(svc::ResultReceiveListBroken) {
*out_index = index;
return os::ResultReceiveListBroken();
}
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
return ResultSuccess();
return index;
}
void WaitableManagerHorizonImpl::CancelWait() {

View File

@@ -25,33 +25,24 @@ namespace ams::os::impl {
private:
Handle handle;
private:
Result WaitSynchronizationN(s32 *out_index, s32 num, Handle arr[], s32 array_size, s64 ns);
Result ReplyAndReceiveN(s32 *out_index, s32 num, Handle arr[], s32 array_size, s64 ns, Handle reply_target);
s32 WaitSynchronizationN(s32 num, Handle arr[], s32 array_size, s64 ns);
public:
void CancelWait();
Result WaitAny(s32 *out_index, Handle arr[], s32 array_size, s32 num) {
return this->WaitSynchronizationN(out_index, num, arr, array_size, svc::WaitInfinite);
s32 WaitAny(Handle arr[], s32 array_size, s32 num) {
return this->WaitSynchronizationN(num, arr, array_size, svc::WaitInfinite);
}
Result TryWaitAny(s32 *out_index, Handle arr[], s32 array_size, s32 num) {
return this->WaitSynchronizationN(out_index, num, arr, array_size, 0);
s32 TryWaitAny(Handle arr[], s32 array_size, s32 num) {
return this->WaitSynchronizationN(num, arr, array_size, 0);
}
Result TimedWaitAny(s32 *out_index, Handle arr[], s32 array_size, s32 num, TimeSpan ts) {
s32 TimedWaitAny(Handle arr[], s32 array_size, s32 num, TimeSpan ts) {
s64 timeout = ts.GetNanoSeconds();
if (timeout < 0) {
timeout = 0;
}
return this->WaitSynchronizationN(out_index, num, arr, array_size, timeout);
}
Result ReplyAndReceive(s32 *out_index, Handle arr[], s32 array_size, s32 num, Handle reply_target) {
return this->ReplyAndReceiveN(out_index, num, arr, array_size, std::numeric_limits<s64>::max(), reply_target);
}
Result TimedReplyAndReceive(s32 *out_index, Handle arr[], s32 array_size, s32 num, Handle reply_target, TimeSpan ts) {
return this->ReplyAndReceiveN(out_index, num, arr, array_size, ts.GetNanoSeconds(), reply_target);
return this->WaitSynchronizationN(num, arr, array_size, timeout);
}
void SetCurrentThreadHandleForCancelWait() {

View File

@@ -1,47 +0,0 @@
/*
* Copyright (c) 2018-2020 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/>.
*/
#include <stratosphere.hpp>
#include "impl/os_waitable_manager_impl.hpp"
#include "impl/os_waitable_holder_base.hpp"
#include "impl/os_waitable_holder_impl.hpp"
namespace ams::os {
namespace {
ALWAYS_INLINE impl::WaitableManagerImpl &GetWaitableManagerImpl(WaitableManagerType *manager) {
return GetReference(manager->impl_storage);
}
ALWAYS_INLINE WaitableHolderType *CastToWaitableHolder(impl::WaitableHolderBase *base) {
return reinterpret_cast<WaitableHolderType *>(base);
}
}
Result SdkReplyAndReceive(os::WaitableHolderType **out, Handle reply_target, WaitableManagerType *manager) {
auto &impl = GetWaitableManagerImpl(manager);
AMS_ASSERT(manager->state == WaitableManagerType::State_Initialized);
AMS_ASSERT(!impl.IsEmpty());
impl::WaitableHolderBase *holder_base;
ON_SCOPE_EXIT { *out = CastToWaitableHolder(holder_base); };
return impl.ReplyAndReceive(std::addressof(holder_base), reply_target);
}
}

View File

@@ -26,7 +26,7 @@ namespace ams::os {
return GetReference(manager->impl_storage);
}
ALWAYS_INLINE WaitableHolderType *CastToWaitableHolder(impl::WaitableHolderBase *base) {
ALWAYS_INLINE WaitableHolderType *ReinterpretAsWaitableHolder(impl::WaitableHolderBase *base) {
return reinterpret_cast<WaitableHolderType *>(base);
}
@@ -59,7 +59,7 @@ namespace ams::os {
AMS_ASSERT(manager->state == WaitableManagerType::State_Initialized);
AMS_ASSERT(!impl.IsEmpty());
auto *holder = CastToWaitableHolder(impl.WaitAny());
auto *holder = ReinterpretAsWaitableHolder(impl.WaitAny());
AMS_ASSERT(holder != nullptr);
return holder;
}
@@ -70,7 +70,7 @@ namespace ams::os {
AMS_ASSERT(manager->state == WaitableManagerType::State_Initialized);
AMS_ASSERT(!impl.IsEmpty());
auto *holder = CastToWaitableHolder(impl.TryWaitAny());
auto *holder = ReinterpretAsWaitableHolder(impl.TryWaitAny());
return holder;
}
@@ -81,7 +81,7 @@ namespace ams::os {
AMS_ASSERT(!impl.IsEmpty());
AMS_ASSERT(timeout.GetNanoSeconds() >= 0);
auto *holder = CastToWaitableHolder(impl.TimedWaitAny(timeout));
auto *holder = ReinterpretAsWaitableHolder(impl.TimedWaitAny(timeout));
return holder;
}

View File

@@ -217,7 +217,7 @@ namespace ams::patcher {
/* Inspect all patches from /atmosphere/<patch_dir>/<*>/<*>.ips */
char path[fs::EntryNameLengthMax + 1];
util::SNPrintf(path, sizeof(path), "%s:/atmosphere/%s", mount_name, patch_dir_name);
std::snprintf(path, sizeof(path), "%s:/atmosphere/%s", mount_name, patch_dir_name);
const size_t patches_dir_path_len = std::strlen(path);
/* Open the patch directory. */
@@ -237,7 +237,7 @@ namespace ams::patcher {
}
/* Print the path for this directory. */
util::SNPrintf(path + patches_dir_path_len, sizeof(path) - patches_dir_path_len, "/%s", entry.name);
std::snprintf(path + patches_dir_path_len, sizeof(path) - patches_dir_path_len, "/%s", entry.name);
const size_t patch_dir_path_len = patches_dir_path_len + 1 + std::strlen(entry.name);
/* Open the patch directory. */
@@ -259,7 +259,7 @@ namespace ams::patcher {
}
/* Print the path for this file. */
util::SNPrintf(path + patch_dir_path_len, sizeof(path) - patch_dir_path_len, "/%s", entry.name);
std::snprintf(path + patch_dir_path_len, sizeof(path) - patch_dir_path_len, "/%s", entry.name);
/* Open the file. */
fs::FileHandle file;

View File

@@ -124,9 +124,9 @@ namespace ams::pgl::srv {
const s32 dump_arg = ConvertDumpTypeToArgument(dump_type);
const s32 log_arg = GetSnapShotDumpOutputAllLog(process_id) ? 1 : 0;
if (str_arg != nullptr) {
return util::SNPrintf(dst, dst_size, "D %010llu \"%s\" -log %d -dump %d", static_cast<unsigned long long>(static_cast<u64>(process_id)), str_arg, log_arg, dump_arg);
return std::snprintf(dst, dst_size, "D %010llu \"%s\" -log %d -dump %d", static_cast<unsigned long long>(static_cast<u64>(process_id)), str_arg, log_arg, dump_arg);
} else {
return util::SNPrintf(dst, dst_size, "D %010llu -log %d -dump %d", static_cast<unsigned long long>(static_cast<u64>(process_id)), log_arg, dump_arg);
return std::snprintf(dst, dst_size, "D %010llu -log %d -dump %d", static_cast<unsigned long long>(static_cast<u64>(process_id)), log_arg, dump_arg);
}
}
@@ -215,7 +215,7 @@ namespace ams::pgl::srv {
/* Generate arguments. */
char arguments[0x40];
const size_t len = util::SNPrintf(arguments, sizeof(arguments), "%ld %d %d %d", static_cast<s64>(static_cast<u64>(process_id)), GetCrashReportDetailedArgument(data_flags), GetCrashReportScreenShotArgument(data_flags), g_enable_jit_debug);
const size_t len = std::snprintf(arguments, sizeof(arguments), "%ld %d %d %d", static_cast<s64>(static_cast<u64>(process_id)), GetCrashReportDetailedArgument(data_flags), GetCrashReportScreenShotArgument(data_flags), g_enable_jit_debug);
if (R_FAILED(ldr::SetProgramArgument(ncm::SystemProgramId::Creport, arguments, len + 1))) {
return;
}

View File

@@ -174,7 +174,7 @@ namespace ams::pgl::srv {
/* Get the file name. */
char file_name[ncm::ContentIdStringLength + 5];
const size_t len = util::SNPrintf(file_name, sizeof(file_name), "%s.nca", id_str.data);
const size_t len = std::snprintf(file_name, sizeof(file_name), "%s.nca", id_str.data);
R_UNLESS(len + 1 == sizeof(file_name), pgl::ResultBufferNotEnough());
/* Ensure we have the content. */
@@ -199,7 +199,7 @@ namespace ams::pgl::srv {
/* Get the file name. */
/* NSPD does not support indexed content, so we always use 0 as the index. */
char file_name[0x20];
const size_t len = util::SNPrintf(file_name, sizeof(file_name), "%s%d.ncd", content_name, 0);
const size_t len = std::snprintf(file_name, sizeof(file_name), "%s%d.ncd", content_name, 0);
R_UNLESS(len + 1 <= sizeof(file_name), pgl::ResultBufferNotEnough());
/* Ensure we have the content. */
@@ -267,7 +267,7 @@ namespace ams::pgl::srv {
Result SearchContent(bool *out, lr::Path *out_path, const char *extension, fs::OpenDirectoryMode mode) const {
/* Generate the root directory path. */
char root_dir[sizeof(this->mount_name) + 2];
util::SNPrintf(root_dir, sizeof(root_dir), "%s:/", this->mount_name);
std::snprintf(root_dir, sizeof(root_dir), "%s:/", this->mount_name);
/* Open the root directory. */
fs::DirectoryHandle dir;
@@ -287,7 +287,7 @@ namespace ams::pgl::srv {
if (HasSuffix(entry.name, extension)) {
*out = true;
if (out_path) {
const size_t len = util::SNPrintf(out_path->str, sizeof(out_path->str), "%s/%s", this->content_path, entry.name);
const size_t len = std::snprintf(out_path->str, sizeof(out_path->str), "%s/%s", this->content_path, entry.name);
R_UNLESS(len + 1 < sizeof(out_path->str), pgl::ResultBufferNotEnough());
if (entry.type == fs::DirectoryEntryType_Directory) {
out_path->str[len] = '/';

View File

@@ -1,4 +0,0 @@
%rename link pre_old_link
*link:
%(pre_old_link) -T %:getenv(ATMOSPHERE_LIBRARIES_DIR /libstratosphere/discard-ehframe.ld)

View File

@@ -17,7 +17,7 @@
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
#define ATMOSPHERE_RELEASE_VERSION_MINOR 17
#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

View File

@@ -37,8 +37,4 @@ namespace ams::os {
R_DEFINE_ERROR_RESULT(OutOfTransferMemory, 505);
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 506);
R_DEFINE_ERROR_RESULT(SessionClosedForReceive, 510);
R_DEFINE_ERROR_RESULT(SessionClosedForReply, 511);
R_DEFINE_ERROR_RESULT(ReceiveListBroken, 512);
}

View File

@@ -375,8 +375,8 @@ namespace ams::svc::ipc {
u32 *buffer;
size_t size;
public:
constexpr ALWAYS_INLINE MessageBuffer(u32 *b, size_t sz) : buffer(b), size(sz) { /* ... */ }
constexpr explicit ALWAYS_INLINE MessageBuffer(u32 *b) : buffer(b), size(sizeof(::ams::svc::ThreadLocalRegion::message_buffer)) { /* ... */ }
constexpr MessageBuffer(u32 *b, size_t sz) : buffer(b), size(sz) { /* ... */ }
constexpr explicit MessageBuffer(u32 *b) : buffer(b), size(sizeof(::ams::svc::ThreadLocalRegion::message_buffer)) { /* ... */ }
constexpr ALWAYS_INLINE size_t GetBufferSize() const {
return this->size;

View File

@@ -27,7 +27,7 @@ namespace ams::svc {
private:
s64 tick;
private:
static constexpr s64 NanoSecondsPerSecond = TimeSpan::FromSeconds(1).GetNanoSeconds();
static constexpr s64 NanoSecondsPerSecond = INT64_C(1'000'000'000);
static constexpr void DivNs(s64 &out, const s64 value) {
out = value / NanoSecondsPerSecond;

View File

@@ -39,7 +39,7 @@ namespace ams::util {
IntrusiveListNode *prev;
IntrusiveListNode *next;
public:
constexpr ALWAYS_INLINE IntrusiveListNode() : prev(this), next(this) { /* ... */ }
constexpr IntrusiveListNode() : prev(this), next(this) { /* ... */ }
constexpr ALWAYS_INLINE bool IsLinked() const {
return this->next != this;

View File

@@ -41,7 +41,7 @@ namespace ams::util {
template<class, class, class>
friend class IntrusiveRedBlackTree;
public:
constexpr ALWAYS_INLINE IntrusiveRedBlackTreeNode() : entry() { /* ... */}
constexpr IntrusiveRedBlackTreeNode() : entry() { /* ... */}
};
static_assert(std::is_literal_type<IntrusiveRedBlackTreeNode>::value);
@@ -355,11 +355,11 @@ namespace ams::util {
/* Generate static implementations for comparison operations for IntrusiveRedBlackTreeRoot. */
RB_GENERATE_WITH_COMPARE_STATIC(IntrusiveRedBlackTreeRootWithCompare, IntrusiveRedBlackTreeNode, entry, CompareImpl, LightCompareImpl);
private:
static ALWAYS_INLINE int CompareImpl(const IntrusiveRedBlackTreeNode *lhs, const IntrusiveRedBlackTreeNode *rhs) {
static int CompareImpl(const IntrusiveRedBlackTreeNode *lhs, const IntrusiveRedBlackTreeNode *rhs) {
return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
}
static ALWAYS_INLINE int LightCompareImpl(const void *elm, const IntrusiveRedBlackTreeNode *rhs) {
static int LightCompareImpl(const void *elm, const IntrusiveRedBlackTreeNode *rhs) {
return Comparator::Compare(*static_cast<const_light_pointer>(elm), *Traits::GetParent(rhs));
}

View File

@@ -23,101 +23,83 @@ namespace ams::util {
namespace impl {
#define AMS_UTIL_OFFSET_OF_STANDARD_COMPLIANT 0
template<size_t MaxDepth>
struct OffsetOfUnionHolder {
template<typename ParentType, typename MemberType, size_t Offset>
union UnionImpl {
using PaddingMember = char;
static constexpr size_t GetOffset() { return Offset; }
#if AMS_UTIL_OFFSET_OF_STANDARD_COMPLIANT
template<size_t MaxDepth>
struct OffsetOfUnionHolder {
template<typename ParentType, typename MemberType, size_t Offset>
union UnionImpl {
using PaddingMember = char;
static constexpr size_t GetOffset() { return Offset; }
#pragma pack(push, 1)
struct {
PaddingMember padding[Offset];
MemberType members[(sizeof(ParentType) / sizeof(MemberType)) + 1];
} data;
#pragma pack(pop)
UnionImpl<ParentType, MemberType, Offset + 1> next_union;
};
template<typename ParentType, typename MemberType>
union UnionImpl<ParentType, MemberType, 0> {
static constexpr size_t GetOffset() { return 0; }
struct {
MemberType members[(sizeof(ParentType) / sizeof(MemberType)) + 1];
} data;
UnionImpl<ParentType, MemberType, 1> next_union;
};
template<typename ParentType, typename MemberType>
union UnionImpl<ParentType, MemberType, MaxDepth> { /* Empty ... */ };
#pragma pack(push, 1)
struct {
PaddingMember padding[Offset];
MemberType members[(sizeof(ParentType) / sizeof(MemberType)) + 1];
} data;
#pragma pack(pop)
UnionImpl<ParentType, MemberType, Offset + 1> next_union;
};
template<typename ParentType, typename MemberType>
struct OffsetOfCalculator {
using UnionHolder = typename OffsetOfUnionHolder<sizeof(MemberType)>::template UnionImpl<ParentType, MemberType, 0>;
union Union {
char c;
UnionHolder first_union;
TYPED_STORAGE(ParentType) parent;
union UnionImpl<ParentType, MemberType, 0> {
static constexpr size_t GetOffset() { return 0; }
/* This coerces the active member to be c. */
constexpr Union() : c() { /* ... */ }
};
static constexpr Union U = {};
static constexpr const MemberType *GetNextAddress(const MemberType *start, const MemberType *target) {
while (start < target) {
start++;
}
return start;
}
static constexpr std::ptrdiff_t GetDifference(const MemberType *start, const MemberType *target) {
return (target - start) * sizeof(MemberType);
}
template<typename CurUnion>
static constexpr std::ptrdiff_t OffsetOfImpl(MemberType ParentType::*member, CurUnion &cur_union) {
constexpr size_t Offset = CurUnion::GetOffset();
const auto target = std::addressof(GetPointer(U.parent)->*member);
const auto start = std::addressof(cur_union.data.members[0]);
const auto next = GetNextAddress(start, target);
if (next != target) {
if constexpr (Offset < sizeof(MemberType) - 1) {
return OffsetOfImpl(member, cur_union.next_union);
} else {
__builtin_unreachable();
}
}
return (next - start) * sizeof(MemberType) + Offset;
}
static constexpr std::ptrdiff_t OffsetOf(MemberType ParentType::*member) {
return OffsetOfImpl(member, U.first_union);
}
struct {
MemberType members[(sizeof(ParentType) / sizeof(MemberType)) + 1];
} data;
UnionImpl<ParentType, MemberType, 1> next_union;
};
#else
template<typename ParentType, typename MemberType>
struct OffsetOfCalculator {
static constexpr std::ptrdiff_t OffsetOf(MemberType ParentType::*member) {
constexpr TYPED_STORAGE(ParentType) Holder = {};
const auto *parent = GetPointer(Holder);
const auto *target = std::addressof(parent->*member);
return static_cast<const uint8_t *>(static_cast<const void *>(target)) - static_cast<const uint8_t *>(static_cast<const void *>(parent));
}
};
union UnionImpl<ParentType, MemberType, MaxDepth> { /* Empty ... */ };
};
#endif
template<typename ParentType, typename MemberType>
struct OffsetOfCalculator {
using UnionHolder = typename OffsetOfUnionHolder<sizeof(MemberType)>::template UnionImpl<ParentType, MemberType, 0>;
union Union {
char c;
UnionHolder first_union;
TYPED_STORAGE(ParentType) parent;
/* This coerces the active member to be c. */
constexpr Union() : c() { /* ... */ }
};
static constexpr Union U = {};
static constexpr const MemberType *GetNextAddress(const MemberType *start, const MemberType *target) {
while (start < target) {
start++;
}
return start;
}
static constexpr std::ptrdiff_t GetDifference(const MemberType *start, const MemberType *target) {
return (target - start) * sizeof(MemberType);
}
template<typename CurUnion>
static constexpr std::ptrdiff_t OffsetOfImpl(MemberType ParentType::*member, CurUnion &cur_union) {
constexpr size_t Offset = CurUnion::GetOffset();
const auto target = std::addressof(GetPointer(U.parent)->*member);
const auto start = std::addressof(cur_union.data.members[0]);
const auto next = GetNextAddress(start, target);
if (next != target) {
if constexpr (Offset < sizeof(MemberType) - 1) {
return OffsetOfImpl(member, cur_union.next_union);
} else {
__builtin_unreachable();
}
}
return (next - start) * sizeof(MemberType) + Offset;
}
static constexpr std::ptrdiff_t OffsetOf(MemberType ParentType::*member) {
return OffsetOfImpl(member, U.first_union);
}
};
template<typename T>
struct GetMemberPointerTraits;

View File

@@ -17,7 +17,6 @@
#pragma once
#include <vapours/common.hpp>
#include <vapours/assert.hpp>
#include <vapours/util/util_format_string.hpp>
namespace ams::util {
@@ -36,7 +35,7 @@ namespace ams::util {
}
const char *ToString(char *dst, size_t dst_size) const {
util::SNPrintf(dst, dst_size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
std::snprintf(dst, dst_size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
this->data[ 0], this->data[ 1], this->data[ 2], this->data[ 3], this->data[ 4], this->data[ 5], this->data[ 6], this->data[ 7],
this->data[ 8], this->data[ 9], this->data[10], this->data[11], this->data[12], this->data[13], this->data[14], this->data[15]);

View File

@@ -174,7 +174,7 @@ SECTIONS
================== */
/* Discard sections that difficult post-processing */
/DISCARD/ : { *(.group .comment .note .interp .fini_array .fini_array.* .text._ZSt23__cmpexch_failure_orderSt12memory_order) }
/DISCARD/ : { *(.group .comment .note .interp .fini_array .fini_array.*) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }

View File

@@ -124,33 +124,33 @@ namespace ams::mitm::fs {
void FormatAtmosphereSdPath(char *dst_path, size_t dst_path_size, const char *src_path) {
if (src_path[0] == '/') {
util::SNPrintf(dst_path, dst_path_size, "/atmosphere%s", src_path);
std::snprintf(dst_path, dst_path_size, "/atmosphere%s", src_path);
} else {
util::SNPrintf(dst_path, dst_path_size, "/atmosphere/%s", src_path);
std::snprintf(dst_path, dst_path_size, "/atmosphere/%s", src_path);
}
}
void FormatAtmosphereSdPath(char *dst_path, size_t dst_path_size, const char *subdir, const char *src_path) {
if (src_path[0] == '/') {
util::SNPrintf(dst_path, dst_path_size, "/atmosphere/%s%s", subdir, src_path);
std::snprintf(dst_path, dst_path_size, "/atmosphere/%s%s", subdir, src_path);
} else {
util::SNPrintf(dst_path, dst_path_size, "/atmosphere/%s/%s", subdir, src_path);
std::snprintf(dst_path, dst_path_size, "/atmosphere/%s/%s", subdir, src_path);
}
}
void FormatAtmosphereSdPath(char *dst_path, size_t dst_path_size, ncm::ProgramId program_id, const char *src_path) {
if (src_path[0] == '/') {
util::SNPrintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx%s", static_cast<u64>(program_id), src_path);
std::snprintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx%s", static_cast<u64>(program_id), src_path);
} else {
util::SNPrintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx/%s", static_cast<u64>(program_id), src_path);
std::snprintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx/%s", static_cast<u64>(program_id), src_path);
}
}
void FormatAtmosphereSdPath(char *dst_path, size_t dst_path_size, ncm::ProgramId program_id, const char *subdir, const char *src_path) {
if (src_path[0] == '/') {
util::SNPrintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx/%s%s", static_cast<u64>(program_id), subdir, src_path);
std::snprintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx/%s%s", static_cast<u64>(program_id), subdir, src_path);
} else {
util::SNPrintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx/%s/%s", static_cast<u64>(program_id), subdir, src_path);
std::snprintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx/%s/%s", static_cast<u64>(program_id), subdir, src_path);
}
}

View File

@@ -81,9 +81,9 @@ namespace ams::mitm {
void GetBackupFileName(char *dst, size_t dst_size, const char *serial_number, const char *fn) {
if (strlen(serial_number) > 0) {
util::SNPrintf(dst, dst_size, "automatic_backups/%s_%s", serial_number, fn);
std::snprintf(dst, dst_size, "automatic_backups/%s_%s", serial_number, fn);
} else {
util::SNPrintf(dst, dst_size, "automatic_backups/%s", fn);
std::snprintf(dst, dst_size, "automatic_backups/%s", fn);
}
}
@@ -166,7 +166,7 @@ namespace ams::mitm {
if (emummc::IsActive()) {
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);
std::snprintf(emummc_path, sizeof(emummc_path), "%s/eMMC", emummc_file_path);
mitm::fs::OpenSdFile(&g_emummc_file, emummc_path, ams::fs::OpenMode_Read);
}
}

View File

@@ -222,6 +222,8 @@ namespace ams::mitm {
Blank(info.GetBlock<EcqvEcdsaAmiiboRootCertificateBlock>());
Blank(info.GetBlock<EcqvBlsAmiiboRootCertificateBlock>());
Blank(info.GetBlock<ExtendedSslKeyBlock>());
if (IsValid(info.GetBlock<Rsa2048DeviceKeyBlock>()) && !IsBlank(info.GetBlock<Rsa2048DeviceKeyBlock>())) Blank(info.GetBlock<Rsa2048DeviceKeyBlock>());
if (IsValid(info.GetBlock<Rsa2048DeviceCertificateBlock>()) && !IsBlank(info.GetBlock<Rsa2048DeviceCertificateBlock>())) Blank(info.GetBlock<Rsa2048DeviceCertificateBlock>());
/* Set header hash. */
crypto::GenerateSha256Hash(std::addressof(info.header.body_hash), sizeof(info.header.body_hash), std::addressof(info.body), sizeof(info.body));
@@ -404,7 +406,7 @@ namespace ams::mitm {
if (IsValidForSecureBackup(info)) {
GetSerialNumber(sn, info);
util::SNPrintf(dst, dst_size, "automatic_backups/%s_PRODINFO.bin", sn);
std::snprintf(dst, dst_size, "automatic_backups/%s_PRODINFO.bin", sn);
} else {
Sha256Hash hash;
crypto::GenerateSha256Hash(std::addressof(hash), sizeof(hash), std::addressof(info), sizeof(info));
@@ -412,13 +414,13 @@ namespace ams::mitm {
if (IsValid(info)) {
if (IsBlank(info)) {
util::SNPrintf(dst, dst_size, "automatic_backups/BLANK_PRODINFO_%02X%02X%02X%02X.bin", hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
std::snprintf(dst, dst_size, "automatic_backups/BLANK_PRODINFO_%02X%02X%02X%02X.bin", hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
} else {
GetSerialNumber(sn, info);
util::SNPrintf(dst, dst_size, "automatic_backups/%s_PRODINFO_%02X%02X%02X%02X.bin", sn, hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
std::snprintf(dst, dst_size, "automatic_backups/%s_PRODINFO_%02X%02X%02X%02X.bin", sn, hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
}
} else {
util::SNPrintf(dst, dst_size, "automatic_backups/INVALID_PRODINFO_%02X%02X%02X%02X.bin", hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
std::snprintf(dst, dst_size, "automatic_backups/INVALID_PRODINFO_%02X%02X%02X%02X.bin", hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
}
}
}
@@ -581,7 +583,7 @@ namespace ams::mitm {
ON_SCOPE_EXIT { crypto::ClearMemory(std::addressof(hash), sizeof(hash)); };
crypto::GenerateSha256Hash(std::addressof(hash), sizeof(hash), std::addressof(g_calibration_info), sizeof(g_calibration_info));
util::SNPrintf(out_name, out_name_size, "%02X%02X%02X%02X", hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
std::snprintf(out_name, out_name_size, "%02X%02X%02X%02X", hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
}
SaveProdInfoBackup(std::addressof(g_prodinfo_backup_file), g_calibration_info);
}

View File

@@ -101,9 +101,9 @@ namespace ams::mitm::fs {
const bool is_system = attribute.system_save_data_id != InvalidSystemSaveDataId && IsEmptyAccountId(attribute.user_id);
size_t out_path_len;
if (is_system) {
out_path_len = static_cast<size_t>(util::SNPrintf(dst, dst_size, "/atmosphere/saves/%s/%s/%s/%016lx", emummc_str, space_id_str, save_type_str, attribute.system_save_data_id));
out_path_len = static_cast<size_t>(std::snprintf(dst, dst_size, "/atmosphere/saves/%s/%s/%s/%016lx", emummc_str, space_id_str, save_type_str, attribute.system_save_data_id));
} else {
out_path_len = static_cast<size_t>(util::SNPrintf(dst, dst_size, "/atmosphere/saves/%s/%s/%s/%016lx/%016lx%016lx", emummc_str, space_id_str, save_type_str, static_cast<u64>(program_id), attribute.user_id.data[1], attribute.user_id.data[0]));
out_path_len = static_cast<size_t>(std::snprintf(dst, dst_size, "/atmosphere/saves/%s/%s/%s/%016lx/%016lx%016lx", emummc_str, space_id_str, save_type_str, static_cast<u64>(program_id), attribute.user_id.data[1], attribute.user_id.data[0]));
}
R_UNLESS(out_path_len < dst_size, fs::ResultTooLongPath());

View File

@@ -66,7 +66,7 @@ namespace ams::mitm::settings {
/* No truncation occurs assuming two-digits for all version number components. */
char display_version[sizeof(g_ams_firmware_version.display_version)];
util::SNPrintf(display_version, sizeof(display_version), "%s|AMS %c.%u.%u|%c", g_ams_firmware_version.display_version, mesosphere_char, api_info.GetMinorVersion(), api_info.GetMicroVersion(), emummc_char);
std::snprintf(display_version, sizeof(display_version), "%s|AMS %c.%u.%u|%c", g_ams_firmware_version.display_version, mesosphere_char, api_info.GetMinorVersion(), api_info.GetMicroVersion(), emummc_char);
std::memcpy(g_ams_firmware_version.display_version, display_version, sizeof(display_version));
}

View File

@@ -57,7 +57,7 @@ namespace ams::mitm::sysupdater {
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *package_root_path, const char *entry_path) {
char package_path[ams::fs::EntryNameLengthMax];
const size_t path_len = util::SNPrintf(package_path, sizeof(package_path), "%s%s", package_root_path, entry_path);
const size_t path_len = std::snprintf(package_path, sizeof(package_path), "%s%s", package_root_path, entry_path);
AMS_ABORT_UNLESS(path_len < ams::fs::EntryNameLengthMax);
return ams::fs::ConvertToFsCommonPath(dst, dst_size, package_path);
@@ -209,7 +209,7 @@ namespace ams::mitm::sysupdater {
fs::FileHandle file;
{
char path[fs::EntryNameLengthMax];
util::SNPrintf(path, sizeof(path), "%s%s%s", package_root, content_id_str.data, content_info->GetType() == ncm::ContentType::Meta ? ".cnmt.nca" : ".nca");
std::snprintf(path, sizeof(path), "%s%s%s", package_root, content_id_str.data, content_info->GetType() == ncm::ContentType::Meta ? ".cnmt.nca" : ".nca");
if (R_FAILED(ValidateResult(fs::OpenFile(std::addressof(file), path, ams::fs::OpenMode_Read)))) {
*done = true;
return ResultSuccess();
@@ -292,7 +292,7 @@ namespace ams::mitm::sysupdater {
R_UNLESS(user_path.str[0] == '/', fs::ResultInvalidPath());
/* Print as @Sdcard:<user_path>/ */
util::SNPrintf(out->str, sizeof(out->str), "%s:%s/", ams::fs::impl::SdCardFileSystemMountName, user_path.str);
std::snprintf(out->str, sizeof(out->str), "%s:%s/", ams::fs::impl::SdCardFileSystemMountName, user_path.str);
/* Normalize, if the user provided an ending / */
const size_t len = std::strlen(out->str);

View File

@@ -303,7 +303,7 @@ namespace ams::creport {
char file_path[fs::EntryNameLengthMax + 1];
/* Save crash report. */
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.log", timestamp, this->process_info.program_id);
std::snprintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.log", timestamp, this->process_info.program_id);
{
ScopedFile file(file_path);
if (file.IsOpen()) {
@@ -312,7 +312,7 @@ namespace ams::creport {
}
/* Dump threads. */
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/dumps/%011lu_%016lx_thread_info.bin", timestamp, this->process_info.program_id);
std::snprintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/dumps/%011lu_%016lx_thread_info.bin", timestamp, this->process_info.program_id);
{
ScopedFile file(file_path);
if (file.IsOpen()) {
@@ -341,7 +341,7 @@ namespace ams::creport {
if (capssc_holder) {
u64 jpeg_size;
if (R_SUCCEEDED(capsrv::CaptureJpegScreenshot(std::addressof(jpeg_size), this->heap_storage, sizeof(this->heap_storage), vi::LayerStack_ApplicationForDebug, TimeSpan::FromSeconds(10)))) {
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.jpg", timestamp, this->process_info.program_id);
std::snprintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.jpg", timestamp, this->process_info.program_id);
ScopedFile file(file_path);
if (file.IsOpen()) {
file.Write(this->heap_storage, jpeg_size);

View File

@@ -107,7 +107,7 @@ namespace ams::creport {
GetModuleBuildId(module.build_id, module.end_address);
/* Some homebrew won't have a name. Add a fake one for readability. */
if (std::strcmp(module.name, "") == 0) {
util::SNPrintf(module.name, sizeof(module.name), "[%02x%02x%02x%02x]", module.build_id[0], module.build_id[1], module.build_id[2], module.build_id[3]);
std::snprintf(module.name, sizeof(module.name), "[%02x%02x%02x%02x]", module.build_id[0], module.build_id[1], module.build_id[2], module.build_id[3]);
}
}
@@ -249,13 +249,13 @@ namespace ams::creport {
const char *ModuleList::GetFormattedAddressString(uintptr_t address) {
/* Print default formatted string. */
util::SNPrintf(this->address_str_buf, sizeof(this->address_str_buf), "%016lx", address);
std::snprintf(this->address_str_buf, sizeof(this->address_str_buf), "%016lx", address);
/* See if the address is inside a module, for pretty-printing. */
for (size_t i = 0; i < this->num_modules; i++) {
const auto& module = this->modules[i];
if (module.start_address <= address && address < module.end_address) {
util::SNPrintf(this->address_str_buf, sizeof(this->address_str_buf), "%016lx (%s + 0x%lx)", address, module.name, address - module.start_address);
std::snprintf(this->address_str_buf, sizeof(this->address_str_buf), "%016lx (%s + 0x%lx)", address, module.name, address - module.start_address);
break;
}
}

View File

@@ -40,7 +40,7 @@ namespace ams::creport {
{
std::va_list vl;
va_start(vl, fmt);
util::VSNPrintf(g_format_buffer, sizeof(g_format_buffer), fmt, vl);
std::vsnprintf(g_format_buffer, sizeof(g_format_buffer), fmt, vl);
va_end(vl);
}
@@ -70,7 +70,7 @@ namespace ams::creport {
{
char hex[MaximumLineLength * 2 + 2] = {};
for (size_t i = 0; i < cur_size; i++) {
util::SNPrintf(hex + i * 2, 3, "%02X", data_u8[data_ofs++]);
std::snprintf(hex + i * 2, 3, "%02X", data_u8[data_ofs++]);
}
hex[cur_size * 2 + 0] = '\n';
hex[cur_size * 2 + 1] = '\x00';

View File

@@ -970,7 +970,7 @@ namespace ams::dmnt::cheat::impl {
fs::FileHandle file;
{
char path[fs::EntryNameLengthMax + 1];
util::SNPrintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/cheats/%02x%02x%02x%02x%02x%02x%02x%02x.txt", program_id.value,
std::snprintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/cheats/%02x%02x%02x%02x%02x%02x%02x%02x.txt", program_id.value,
build_id[0], build_id[1], build_id[2], build_id[3], build_id[4], build_id[5], build_id[6], build_id[7]);
if (R_FAILED(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read))) {
return false;
@@ -1009,7 +1009,7 @@ namespace ams::dmnt::cheat::impl {
fs::FileHandle file;
{
char path[fs::EntryNameLengthMax + 1];
util::SNPrintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/cheats/toggles.txt", program_id.value);
std::snprintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/cheats/toggles.txt", program_id.value);
if (R_FAILED(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read))) {
/* No file presence is allowed. */
return true;
@@ -1046,7 +1046,7 @@ namespace ams::dmnt::cheat::impl {
fs::FileHandle file;
{
char path[fs::EntryNameLengthMax + 1];
util::SNPrintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/cheats/toggles.txt", program_id.value);
std::snprintf(path, sizeof(path), "sdmc:/atmosphere/contents/%016lx/cheats/toggles.txt", program_id.value);
fs::DeleteFile(path);
fs::CreateFile(path, 0);
if (R_FAILED(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend))) {
@@ -1061,7 +1061,7 @@ namespace ams::dmnt::cheat::impl {
/* Save all non-master cheats. */
for (size_t i = 1; i < MaxCheatCount; i++) {
if (this->cheat_entries[i].definition.num_opcodes != 0) {
util::SNPrintf(buf, sizeof(buf), "[%s]\n", this->cheat_entries[i].definition.readable_name);
std::snprintf(buf, sizeof(buf), "[%s]\n", this->cheat_entries[i].definition.readable_name);
const size_t name_len = std::strlen(buf);
if (R_SUCCEEDED(fs::WriteFile(file, offset, buf, name_len, fs::WriteOption::Flush))) {
offset += name_len;

View File

@@ -26,7 +26,7 @@ namespace ams::dmnt::cheat::impl {
fs::FileHandle log_file;
{
char log_path[fs::EntryNameLengthMax + 1];
util::SNPrintf(log_path, sizeof(log_path), "sdmc:/atmosphere/cheat_vm_logs/%08x.log", log_id);
std::snprintf(log_path, sizeof(log_path), "sdmc:/atmosphere/cheat_vm_logs/%08x.log", log_id);
if (R_FAILED(fs::OpenFile(std::addressof(log_file), log_path, fs::OpenMode_Write | fs::OpenMode_AllowAppend))) {
return;
}
@@ -39,7 +39,7 @@ namespace ams::dmnt::cheat::impl {
}
char log_value[18];
util::SNPrintf(log_value, sizeof(log_value), "%016lx\n", value);
std::snprintf(log_value, sizeof(log_value), "%016lx\n", value);
fs::WriteFile(log_file, log_offset, log_value, std::strlen(log_value), fs::WriteOption::Flush);
}
@@ -69,7 +69,7 @@ namespace ams::dmnt::cheat::impl {
{
std::va_list vl;
va_start(vl, format);
util::VSNPrintf(this->debug_log_format_buf, sizeof(this->debug_log_format_buf) - 1, format, vl);
std::vsnprintf(this->debug_log_format_buf, sizeof(this->debug_log_format_buf) - 1, format, vl);
va_end(vl);
}

View File

@@ -103,7 +103,7 @@ namespace ams::erpt {
switch (model) {
case settings::system::ProductModel_Invalid: return util::Strlcpy(dst, "Invalid", static_cast<int>(dst_size));
case settings::system::ProductModel_Nx: return util::Strlcpy(dst, "NX", static_cast<int>(dst_size));
default: return util::SNPrintf(dst, dst_size, "%d", static_cast<int>(model));
default: return std::snprintf(dst, dst_size, "%d", static_cast<int>(model));
}
}
@@ -141,7 +141,7 @@ int main(int argc, char **argv)
settings::system::GetSerialNumber(std::addressof(serial_number));
char os_private[0x60];
const auto os_priv_len = util::SNPrintf(os_private, sizeof(os_private), "%s (%.8s)", firmware_version.display_name, firmware_version.revision);
const auto os_priv_len = std::snprintf(os_private, sizeof(os_private), "%s (%.8s)", firmware_version.display_name, firmware_version.revision);
AMS_ASSERT(static_cast<size_t>(os_priv_len) < sizeof(os_private));
R_ABORT_UNLESS(erpt::srv::SetSerialNumberAndOsVersion(serial_number.str,

View File

@@ -135,7 +135,7 @@ namespace ams::fatal::srv::font {
std::va_list va_arg;
va_start(va_arg, format);
util::VSNPrintf(char_buf, sizeof(char_buf), format, va_arg);
std::vsnprintf(char_buf, sizeof(char_buf), format, va_arg);
va_end(va_arg);
PrintLine(char_buf);
@@ -150,7 +150,7 @@ namespace ams::fatal::srv::font {
std::va_list va_arg;
va_start(va_arg, format);
util::VSNPrintf(char_buf, sizeof(char_buf), format, va_arg);
std::vsnprintf(char_buf, sizeof(char_buf), format, va_arg);
va_end(va_arg);
Print(char_buf);
@@ -158,14 +158,14 @@ namespace ams::fatal::srv::font {
void PrintMonospaceU64(u64 x) {
char char_buf[0x400];
util::SNPrintf(char_buf, sizeof(char_buf), "%016lX", x);
std::snprintf(char_buf, sizeof(char_buf), "%016lX", x);
DrawString(char_buf, false, true);
}
void PrintMonospaceU32(u32 x) {
char char_buf[0x400];
util::SNPrintf(char_buf, sizeof(char_buf), "%08X", x);
std::snprintf(char_buf, sizeof(char_buf), "%08X", x);
DrawString(char_buf, false, true);
}

View File

@@ -40,7 +40,7 @@ namespace ams::fatal::srv {
{
std::va_list vl;
va_start(vl, fmt);
util::VSNPrintf(g_format_buffer, sizeof(g_format_buffer), fmt, vl);
std::vsnprintf(g_format_buffer, sizeof(g_format_buffer), fmt, vl);
va_end(vl);
}
@@ -70,7 +70,7 @@ namespace ams::fatal::srv {
{
char hex[MaximumLineLength * 2 + 2] = {};
for (size_t i = 0; i < cur_size; i++) {
util::SNPrintf(hex + i * 2, 3, "%02X", data_u8[data_ofs++]);
std::snprintf(hex + i * 2, 3, "%02X", data_u8[data_ofs++]);
}
hex[cur_size * 2 + 0] = '\n';
hex[cur_size * 2 + 1] = '\x00';

View File

@@ -75,7 +75,7 @@ namespace ams::fatal::srv {
/* Open report file. */
{
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/%011lu_%016lx.log", timestamp, static_cast<u64>(this->context->program_id));
std::snprintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/%011lu_%016lx.log", timestamp, static_cast<u64>(this->context->program_id));
ScopedFile file(file_path);
if (file.IsOpen()) {
file.WriteFormat("Atmosphère Fatal Report (v1.1):\n");
@@ -137,7 +137,7 @@ namespace ams::fatal::srv {
/* Dump data to file. */
{
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/dumps/%011lu_%016lx.bin", timestamp, static_cast<u64>(this->context->program_id));
std::snprintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/dumps/%011lu_%016lx.bin", timestamp, static_cast<u64>(this->context->program_id));
ScopedFile file(file_path);
if (file.IsOpen()) {
file.Write(this->context->tls_dump, sizeof(this->context->tls_dump));

View File

@@ -31,7 +31,7 @@ extern "C" {
u32 __nx_applet_type = AppletType_None;
#define INNER_HEAP_SIZE 0x2000
#define INNER_HEAP_SIZE 0x4000
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];