Compare commits
46 Commits
0.17.1
...
mariko_fus
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fa8325f74 | ||
|
|
6baf1d6593 | ||
|
|
95b49294df | ||
|
|
557903cfa7 | ||
|
|
c06f0440fd | ||
|
|
23cb37d6be | ||
|
|
a2535c7330 | ||
|
|
e43a960b5d | ||
|
|
feed7550f5 | ||
|
|
be897d728d | ||
|
|
0dc6bcb180 | ||
|
|
45bae80f18 | ||
|
|
6e9675916c | ||
|
|
b74742e0a1 | ||
|
|
d153a8fa5a | ||
|
|
fa53d11cae | ||
|
|
200da4c2da | ||
|
|
539dbf0800 | ||
|
|
c3bf204627 | ||
|
|
2920c042e1 | ||
|
|
a968d0be32 | ||
|
|
52c7932f1f | ||
|
|
ec398dc612 | ||
|
|
a35a30efcd | ||
|
|
8402ea7e93 | ||
|
|
c356e1ab36 | ||
|
|
4d4fc19cba | ||
|
|
0a0cc52846 | ||
|
|
f40fa150d8 | ||
|
|
db8a367834 | ||
|
|
d083384f2f | ||
|
|
83fa9983bf | ||
|
|
b9428dd2f3 | ||
|
|
dc52610bd8 | ||
|
|
7ed9bdd374 | ||
|
|
1107d4858c | ||
|
|
eb1b624219 | ||
|
|
5012782237 | ||
|
|
736360e965 | ||
|
|
4111aa0a83 | ||
|
|
6671d46c8d | ||
|
|
b14dd4fd5f | ||
|
|
b917d7c886 | ||
|
|
6263a54be5 | ||
|
|
a266e9b11a | ||
|
|
b5d866f5a0 |
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace ams::kern {
|
||||
|
||||
void Dump();
|
||||
private:
|
||||
ALWAYS_INLINE bool IsSignaledImpl() const;
|
||||
bool IsSignaledImpl() const;
|
||||
void CleanupRequests();
|
||||
};
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); })
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
SECTIONS
|
||||
{
|
||||
/* Discard .eh_frame section */
|
||||
/DISCARD/ : { *(.group .comment .note .interp)
|
||||
EXCLUDE_FILE(*crtbegin.o) *(.eh_frame_hdr .eh_frame)
|
||||
}
|
||||
}
|
||||
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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(); }
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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] = '/';
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
%rename link pre_old_link
|
||||
|
||||
*link:
|
||||
%(pre_old_link) -T %:getenv(ATMOSPHERE_LIBRARIES_DIR /libstratosphere/discard-ehframe.ld)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user