ams: update to build with gcc10/c++20

This commit is contained in:
Michael Scire 2020-05-05 18:16:13 -07:00
parent 17b6bcfd37
commit 492a9e1849
87 changed files with 361 additions and 322 deletions

View file

@ -33,7 +33,7 @@ INCLUDES := include ../libraries/libvapours/include
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ARCH := -march=armv8-a -mtune=cortex-a57 -mgeneral-regs-only #<- important ARCH := -march=armv8-a -mtune=cortex-a57 -mgeneral-regs-only -mno-outline-atomics #<- important
DEFINES := -D__CCPLEX__ -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" -DATMOSPHERE_RELEASE_VERSION_HASH="0x$(AMSHASH)" DEFINES := -D__CCPLEX__ -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" -DATMOSPHERE_RELEASE_VERSION_HASH="0x$(AMSHASH)"
CFLAGS := \ CFLAGS := \
-g \ -g \
@ -156,6 +156,8 @@ $(OUTPUT).bin : $(OUTPUT).elf
$(OUTPUT).elf : $(OFILES) $(OUTPUT).elf : $(OFILES)
my_libc.o: CFLAGS += -fno-builtin
%.elf: %.elf:
@echo linking $(notdir $@) @echo linking $(notdir $@)
$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ $(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@

View file

@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef EXOSPHERE_MMU_H #ifndef EXOSPHERE_MMU_H
#define EXOSPHERE_MMU_H #define EXOSPHERE_MMU_H
@ -134,7 +134,7 @@
#define TCR_EL2_RSVD (BIT(31) | BIT(23)) #define TCR_EL2_RSVD (BIT(31) | BIT(23))
#define TCR_EL3_RSVD (BIT(31) | BIT(23)) #define TCR_EL3_RSVD (BIT(31) | BIT(23))
static inline void mmu_init_table(uintptr_t *tbl, size_t num_entries) { static inline void mmu_init_table(volatile uintptr_t *tbl, size_t num_entries) {
for(size_t i = 0; i < num_entries / 8; i++) { for(size_t i = 0; i < num_entries / 8; i++) {
tbl[i] = MMU_PTE_TYPE_FAULT; tbl[i] = MMU_PTE_TYPE_FAULT;
} }

View file

@ -75,7 +75,7 @@ __libc_fini_array (void)
{ {
size_t count; size_t count;
size_t i; size_t i;
count = __fini_array_end - __fini_array_start; count = __fini_array_end - __fini_array_start;
for (i = count; i > 0; i--) for (i = count; i > 0; i--)
__fini_array_start[i-1] (); __fini_array_start[i-1] ();
@ -170,7 +170,7 @@ memmove (void *dst_void,
} }
else else
{ {
/* Use optimizing algorithm for a non-destructive copy to closely /* Use optimizing algorithm for a non-destructive copy to closely
match memcpy. If the size is small or either SRC or DST is unaligned, match memcpy. If the size is small or either SRC or DST is unaligned,
then punt into the byte copy loop. This should be rare. */ then punt into the byte copy loop. This should be rare. */
if (!TOO_SMALL(length) && !UNALIGNED (src, dst)) if (!TOO_SMALL(length) && !UNALIGNED (src, dst))
@ -561,7 +561,7 @@ memcmp (const void *m1,
s2++; s2++;
} }
return 0; return 0;
#else #else
unsigned char *s1 = (unsigned char *) m1; unsigned char *s1 = (unsigned char *) m1;
unsigned char *s2 = (unsigned char *) m2; unsigned char *s2 = (unsigned char *) m2;
unsigned long *a1; unsigned long *a1;
@ -572,13 +572,13 @@ memcmp (const void *m1,
not turn up in inner loops. */ not turn up in inner loops. */
if (!TOO_SMALL(n) && !UNALIGNED(s1,s2)) if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
{ {
/* Otherwise, load and compare the blocks of memory one /* Otherwise, load and compare the blocks of memory one
word at a time. */ word at a time. */
a1 = (unsigned long*) s1; a1 = (unsigned long*) s1;
a2 = (unsigned long*) s2; a2 = (unsigned long*) s2;
while (n >= LBLOCKSIZE) while (n >= LBLOCKSIZE)
{ {
if (*a1 != *a2) if (*a1 != *a2)
break; break;
a1++; a1++;
a2++; a2++;
@ -703,7 +703,7 @@ strchr (const char *s1,
/* /*
FUNCTION FUNCTION
<<strcmp>>---character string compare <<strcmp>>---character string compare
INDEX INDEX
strcmp strcmp
SYNOPSIS SYNOPSIS
@ -736,7 +736,7 @@ QUICKREF
int int
strcmp (const char *s1, strcmp (const char *s1,
const char *s2) const char *s2)
{ {
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
while (*s1 != '\0' && *s1 == *s2) while (*s1 != '\0' && *s1 == *s2)
{ {
@ -751,7 +751,7 @@ strcmp (const char *s1,
/* If s1 or s2 are unaligned, then compare bytes. */ /* If s1 or s2 are unaligned, then compare bytes. */
if (!UNALIGNED (s1, s2)) if (!UNALIGNED (s1, s2))
{ {
/* If s1 and s2 are word-aligned, compare them a word at a time. */ /* If s1 and s2 are word-aligned, compare them a word at a time. */
a1 = (unsigned long*)s1; a1 = (unsigned long*)s1;
a2 = (unsigned long*)s2; a2 = (unsigned long*)s2;
@ -915,7 +915,7 @@ strlen (const char *str)
/* /*
FUNCTION FUNCTION
<<strncmp>>---character string compare <<strncmp>>---character string compare
INDEX INDEX
strncmp strncmp
SYNOPSIS SYNOPSIS
@ -944,7 +944,7 @@ QUICKREF
#define UNALIGNED(X, Y) \ #define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
int int
strncmp (const char *s1, strncmp (const char *s1,
const char *s2, const char *s2,
size_t n) size_t n)
@ -1103,10 +1103,10 @@ strncpy (char *__restrict dst0,
#endif /* not PREFER_SIZE_OVER_SPEED */ #endif /* not PREFER_SIZE_OVER_SPEED */
} }
/* /*
FUNCTION FUNCTION
<<strnlen>>---character string length <<strnlen>>---character string length
INDEX INDEX
strnlen strnlen
SYNOPSIS SYNOPSIS

View file

@ -5,7 +5,7 @@ endif
include $(DEVKITPRO)/devkitA64/base_rules include $(DEVKITPRO)/devkitA64/base_rules
export ATMOSPHERE_DEFINES += -DATMOSPHERE_ARCH_ARM64 export ATMOSPHERE_DEFINES += -DATMOSPHERE_ARCH_ARM64
export ATMOSPHERE_SETTINGS += -march=armv8-a+crc+crypto -mtp=soft export ATMOSPHERE_SETTINGS += -march=armv8-a+crc+crypto -mno-outline-atomics -mtp=soft
export ATMOSPHERE_CFLAGS += export ATMOSPHERE_CFLAGS +=
export ATMOSPHERE_CXXFLAGS += export ATMOSPHERE_CXXFLAGS +=
export ATMOSPHERE_ASFLAGS += export ATMOSPHERE_ASFLAGS +=

View file

@ -18,7 +18,7 @@ export ATMOSPHERE_DEFINES := -DATMOSPHERE
export ATMOSPHERE_SETTINGS := -fPIE -g export ATMOSPHERE_SETTINGS := -fPIE -g
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \ export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++17 export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++2a
export ATMOSPHERE_ASFLAGS := export ATMOSPHERE_ASFLAGS :=

View file

@ -122,6 +122,8 @@ $(filter-out kern_svc_tables.o, $(OFILES)) : $(GCH_FILES)
$(OFILES_SRC) : $(HFILES_BIN) $(OFILES_SRC) : $(HFILES_BIN)
kern_libc_generic.o: CFLAGS += -fno-builtin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin %_bin.h %.bin.o : %.bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View file

@ -72,7 +72,7 @@ namespace ams::kern::arch::arm64 {
SgirTargetListFilter_Reserved = (3 << 24), SgirTargetListFilter_Reserved = (3 << 24),
}; };
}; };
static_assert(std::is_pod<GicDistributor>::value); static_assert(util::is_pod<GicDistributor>::value);
static_assert(sizeof(GicDistributor) == 0x1000); static_assert(sizeof(GicDistributor) == 0x1000);
struct GicCpuInterface { struct GicCpuInterface {
@ -98,7 +98,7 @@ namespace ams::kern::arch::arm64 {
u32 dir; u32 dir;
u32 _0x1004[1023]; u32 _0x1004[1023];
}; };
static_assert(std::is_pod<GicCpuInterface>::value); static_assert(util::is_pod<GicCpuInterface>::value);
static_assert(sizeof(GicCpuInterface) == 0x2000); static_assert(sizeof(GicCpuInterface) == 0x2000);
struct KInterruptController { struct KInterruptController {
@ -164,11 +164,11 @@ namespace ams::kern::arch::arm64 {
} }
void SetTarget(s32 irq, s32 core_id) const { void SetTarget(s32 irq, s32 core_id) const {
this->gicd->itargetsr.bytes[irq] |= GetGicMask(core_id); this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] | GetGicMask(core_id);
} }
void ClearTarget(s32 irq, s32 core_id) const { void ClearTarget(s32 irq, s32 core_id) const {
this->gicd->itargetsr.bytes[irq] &= ~GetGicMask(core_id); this->gicd->itargetsr.bytes[irq] = this->gicd->itargetsr.bytes[irq] & ~GetGicMask(core_id);
} }
void SetPriorityLevel(s32 irq, s32 level) const { void SetPriorityLevel(s32 irq, s32 level) const {

View file

@ -32,7 +32,7 @@ namespace ams::kern::init {
u32 init_array_offset; u32 init_array_offset;
u32 init_array_end_offset; u32 init_array_end_offset;
}; };
static_assert(std::is_pod<KernelLayout>::value); static_assert(util::is_pod<KernelLayout>::value);
static_assert(sizeof(KernelLayout) == 0x30); static_assert(sizeof(KernelLayout) == 0x30);
} }

View file

@ -31,8 +31,10 @@ namespace ams::kern {
s32 core_id; s32 core_id;
void *exception_stack_top; void *exception_stack_top;
}; };
static_assert(std::is_pod<KCurrentContext>::value); static_assert(std::is_standard_layout<KCurrentContext>::value && std::is_trivially_destructible<KCurrentContext>::value);
static_assert(sizeof(KCurrentContext) <= cpu::DataCacheLineSize); static_assert(sizeof(KCurrentContext) <= cpu::DataCacheLineSize);
static_assert(sizeof(std::atomic<KThread *>) == sizeof(KThread *));
static_assert(sizeof(std::atomic<KProcess *>) == sizeof(KProcess *));
namespace impl { namespace impl {

View file

@ -65,7 +65,7 @@ namespace ams::kern {
Node *next; Node *next;
u8 buffer[PageSize - sizeof(Node *)]; u8 buffer[PageSize - sizeof(Node *)];
}; };
static_assert(std::is_pod<Node>::value); static_assert(util::is_pod<Node>::value);
private: private:
Node *root; Node *root;
public: public:

View file

@ -22,19 +22,19 @@ namespace ams::kern {
constexpr uintptr_t Invalid = std::numeric_limits<uintptr_t>::max(); constexpr uintptr_t Invalid = std::numeric_limits<uintptr_t>::max();
constexpr KAddressSpaceInfo AddressSpaceInfos[] = { constexpr KAddressSpaceInfo AddressSpaceInfos[] = {
{ .bit_width = 32, .address = 2_MB, .size = 1_GB - 2_MB, KAddressSpaceInfo::Type_32Bit, }, { .bit_width = 32, .address = 2_MB, .size = 1_GB - 2_MB, .type = KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 32, .address = 1_GB, .size = 4_GB - 1_GB, KAddressSpaceInfo::Type_Small64Bit, }, { .bit_width = 32, .address = 1_GB, .size = 4_GB - 1_GB, .type = KAddressSpaceInfo::Type_Small64Bit, },
{ .bit_width = 32, .address = Invalid, .size = 1_GB, KAddressSpaceInfo::Type_Heap, }, { .bit_width = 32, .address = Invalid, .size = 1_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 32, .address = Invalid, .size = 1_GB, KAddressSpaceInfo::Type_Alias, }, { .bit_width = 32, .address = Invalid, .size = 1_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 36, .address = 128_MB, .size = 2_GB - 128_MB, KAddressSpaceInfo::Type_32Bit, }, { .bit_width = 36, .address = 128_MB, .size = 2_GB - 128_MB, .type = KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 36, .address = 2_GB, .size = 64_GB - 2_GB, KAddressSpaceInfo::Type_Small64Bit, }, { .bit_width = 36, .address = 2_GB, .size = 64_GB - 2_GB, .type = KAddressSpaceInfo::Type_Small64Bit, },
{ .bit_width = 36, .address = Invalid, .size = 6_GB, KAddressSpaceInfo::Type_Heap, }, { .bit_width = 36, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 36, .address = Invalid, .size = 6_GB, KAddressSpaceInfo::Type_Alias, }, { .bit_width = 36, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 39, .address = 128_MB, .size = 512_GB - 128_MB, KAddressSpaceInfo::Type_Large64Bit, }, { .bit_width = 39, .address = 128_MB, .size = 512_GB - 128_MB, .type = KAddressSpaceInfo::Type_Large64Bit, },
{ .bit_width = 39, .address = Invalid, .size = 64_GB, KAddressSpaceInfo::Type_32Bit, }, { .bit_width = 39, .address = Invalid, .size = 64_GB, .type = KAddressSpaceInfo::Type_32Bit, },
{ .bit_width = 39, .address = Invalid, .size = 6_GB, KAddressSpaceInfo::Type_Heap, }, { .bit_width = 39, .address = Invalid, .size = 6_GB, .type = KAddressSpaceInfo::Type_Heap, },
{ .bit_width = 39, .address = Invalid, .size = 64_GB, KAddressSpaceInfo::Type_Alias, }, { .bit_width = 39, .address = Invalid, .size = 64_GB, .type = KAddressSpaceInfo::Type_Alias, },
{ .bit_width = 39, .address = Invalid, .size = 2_GB, KAddressSpaceInfo::Type_Stack, }, { .bit_width = 39, .address = Invalid, .size = 2_GB, .type = KAddressSpaceInfo::Type_Stack, },
}; };
constexpr bool IsAllowedIndexForAddress(size_t index) { constexpr bool IsAllowedIndexForAddress(size_t index) {

View file

@ -104,7 +104,7 @@ namespace ams {
}; };
static_assert(sizeof(FatalErrorContext) == 0x450, "sizeof(FatalErrorContext)"); static_assert(sizeof(FatalErrorContext) == 0x450, "sizeof(FatalErrorContext)");
static_assert(std::is_pod<FatalErrorContext>::value, "FatalErrorContext"); static_assert(util::is_pod<FatalErrorContext>::value, "FatalErrorContext");
#ifdef ATMOSPHERE_GIT_BRANCH #ifdef ATMOSPHERE_GIT_BRANCH
NX_CONSTEXPR const char *GetGitBranch() { NX_CONSTEXPR const char *GetGitBranch() {

View file

@ -41,6 +41,6 @@ namespace ams::capsrv {
}; };
static_assert(sizeof(ScreenShotDecodeOption) == 0x20); static_assert(sizeof(ScreenShotDecodeOption) == 0x20);
static_assert(sizeof(ScreenShotDecodeOption) == sizeof(::CapsScreenShotDecodeOption)); static_assert(sizeof(ScreenShotDecodeOption) == sizeof(::CapsScreenShotDecodeOption));
static_assert(std::is_pod<ScreenShotDecodeOption>::value); static_assert(util::is_pod<ScreenShotDecodeOption>::value);
} }

View file

@ -49,7 +49,7 @@ namespace ams::cfg {
}; };
static_assert(sizeof(OverrideStatus) == 0x10, "sizeof(OverrideStatus)"); static_assert(sizeof(OverrideStatus) == 0x10, "sizeof(OverrideStatus)");
static_assert(std::is_pod<OverrideStatus>::value, "std::is_pod<OverrideStatus>::value"); static_assert(util::is_pod<OverrideStatus>::value, "util::is_pod<OverrideStatus>::value");
constexpr inline bool operator==(const OverrideStatus &lhs, const OverrideStatus &rhs) { constexpr inline bool operator==(const OverrideStatus &lhs, const OverrideStatus &rhs) {
return std::memcmp(&lhs, &rhs, sizeof(lhs)) == 0; return std::memcmp(&lhs, &rhs, sizeof(lhs)) == 0;

View file

@ -36,7 +36,7 @@ namespace ams::dmnt::cheat {
u8 main_nso_build_id[0x20]; u8 main_nso_build_id[0x20];
}; };
static_assert(std::is_pod<CheatProcessMetadata>::value && sizeof(CheatProcessMetadata) == 0x70, "CheatProcessMetadata definition!"); static_assert(util::is_pod<CheatProcessMetadata>::value && sizeof(CheatProcessMetadata) == 0x70, "CheatProcessMetadata definition!");
struct CheatDefinition : sf::LargeData, sf::PrefersMapAliasTransferMode { struct CheatDefinition : sf::LargeData, sf::PrefersMapAliasTransferMode {
char readable_name[0x40]; char readable_name[0x40];
@ -50,8 +50,8 @@ namespace ams::dmnt::cheat {
CheatDefinition definition; CheatDefinition definition;
}; };
static_assert(std::is_pod<CheatDefinition>::value, "CheatDefinition"); static_assert(util::is_pod<CheatDefinition>::value, "CheatDefinition");
static_assert(std::is_pod<CheatEntry>::value, "CheatEntry"); static_assert(util::is_pod<CheatEntry>::value, "CheatEntry");
struct FrozenAddressValue { struct FrozenAddressValue {
u64 value; u64 value;

View file

@ -108,7 +108,7 @@ namespace ams::erpt {
}; };
using ReportFlagSet = util::BitFlagSet<BITSIZEOF(u32), ReportFlag>; using ReportFlagSet = util::BitFlagSet<BITSIZEOF(u32), ReportFlag>;
static_assert(std::is_pod<ReportFlagSet>::value); static_assert(util::is_pod<ReportFlagSet>::value);
static_assert(sizeof(ReportFlagSet) == sizeof(u32)); static_assert(sizeof(ReportFlagSet) == sizeof(u32));
struct ReportInfo { struct ReportInfo {
@ -149,7 +149,7 @@ namespace ams::erpt {
}; };
using AttachmentFlagSet = util::BitFlagSet<BITSIZEOF(u32), AttachmentFlag>; using AttachmentFlagSet = util::BitFlagSet<BITSIZEOF(u32), AttachmentFlag>;
static_assert(std::is_pod<AttachmentFlagSet>::value); static_assert(util::is_pod<AttachmentFlagSet>::value);
static_assert(sizeof(AttachmentFlagSet) == sizeof(u32)); static_assert(sizeof(AttachmentFlagSet) == sizeof(u32));
constexpr inline u32 AttachmentNameSizeMax = 0x20; constexpr inline u32 AttachmentNameSizeMax = 0x20;

View file

@ -75,44 +75,44 @@ namespace ams::fatal {
static constexpr size_t MaxStackTraceDepth = 0x20; static constexpr size_t MaxStackTraceDepth = 0x20;
static constexpr const char *RegisterNameStrings[RegisterName_Count] = { static constexpr const char *RegisterNameStrings[RegisterName_Count] = {
u8"X0", "X0",
u8"X1", "X1",
u8"X2", "X2",
u8"X3", "X3",
u8"X4", "X4",
u8"X5", "X5",
u8"X6", "X6",
u8"X7", "X7",
u8"X8", "X8",
u8"X9", "X9",
u8"X10", "X10",
u8"X11", "X11",
u8"X12", "X12",
u8"X13", "X13",
u8"X14", "X14",
u8"X15", "X15",
u8"X16", "X16",
u8"X17", "X17",
u8"X18", "X18",
u8"X19", "X19",
u8"X20", "X20",
u8"X21", "X21",
u8"X22", "X22",
u8"X23", "X23",
u8"X24", "X24",
u8"X25", "X25",
u8"X26", "X26",
u8"X27", "X27",
u8"X28", "X28",
u8"FP", "FP",
u8"LR", "LR",
u8"SP", "SP",
u8"PC", "PC",
u8"PState", "PState",
u8"Afsr0", "Afsr0",
u8"Afsr1", "Afsr1",
u8"Esr", "Esr",
u8"Far", "Far",
}; };
/* Registers, exception context. N left names for these fields in fatal .rodata. */ /* Registers, exception context. N left names for these fields in fatal .rodata. */
@ -209,27 +209,27 @@ namespace ams::fatal {
static constexpr size_t MaxStackTraceDepth = 0x20; static constexpr size_t MaxStackTraceDepth = 0x20;
static constexpr const char *RegisterNameStrings[RegisterName_Count] = { static constexpr const char *RegisterNameStrings[RegisterName_Count] = {
u8"R0", "R0",
u8"R1", "R1",
u8"R2", "R2",
u8"R3", "R3",
u8"R4", "R4",
u8"R5", "R5",
u8"R6", "R6",
u8"R7", "R7",
u8"R8", "R8",
u8"R9", "R9",
u8"R10", "R10",
u8"FP", "FP",
u8"IP", "IP",
u8"LR", "LR",
u8"SP", "SP",
u8"PC", "PC",
u8"PState", "PState",
u8"Afsr0", "Afsr0",
u8"Afsr1", "Afsr1",
u8"Esr", "Esr",
u8"Far", "Far",
}; };
/* Registers, exception context. N left names for these fields in fatal .rodata. */ /* Registers, exception context. N left names for these fields in fatal .rodata. */
@ -311,9 +311,9 @@ namespace ams::fatal {
} }
}; };
static_assert(std::is_pod<aarch64::CpuContext>::value && sizeof(aarch64::CpuContext) == 0x248, "aarch64::CpuContext definition!"); static_assert(util::is_pod<aarch64::CpuContext>::value && sizeof(aarch64::CpuContext) == 0x248, "aarch64::CpuContext definition!");
static_assert(std::is_pod<aarch32::CpuContext>::value && sizeof(aarch32::CpuContext) == 0xE0, "aarch32::CpuContext definition!"); static_assert(util::is_pod<aarch32::CpuContext>::value && sizeof(aarch32::CpuContext) == 0xE0, "aarch32::CpuContext definition!");
static_assert(std::is_pod<CpuContext>::value && sizeof(CpuContext) == 0x250, "CpuContext definition!"); static_assert(util::is_pod<CpuContext>::value && sizeof(CpuContext) == 0x250, "CpuContext definition!");
namespace srv { namespace srv {

View file

@ -43,6 +43,6 @@ namespace ams::fs {
return this->Get(); return this->Get();
} }
}; };
static_assert(std::is_pod<Int64>::value); static_assert(util::is_pod<Int64>::value);
} }

View file

@ -28,7 +28,7 @@ namespace ams::fs {
Position next_dir; Position next_dir;
Position next_file; Position next_file;
}; };
static_assert(std::is_pod<FindPosition>::value); static_assert(util::is_pod<FindPosition>::value);
using DirectoryInfo = RomDirectoryInfo; using DirectoryInfo = RomDirectoryInfo;
using FileInfo = RomFileInfo; using FileInfo = RomFileInfo;
@ -56,13 +56,13 @@ namespace ams::fs {
Position dir; Position dir;
Position file; Position file;
}; };
static_assert(std::is_pod<RomDirectoryEntry>::value); static_assert(util::is_pod<RomDirectoryEntry>::value);
struct RomFileEntry { struct RomFileEntry {
Position next; Position next;
FileInfo info; FileInfo info;
}; };
static_assert(std::is_pod<RomFileEntry>::value); static_assert(util::is_pod<RomFileEntry>::value);
static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength; static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength;
@ -109,7 +109,7 @@ namespace ams::fs {
return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar)); return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar));
} }
}; };
static_assert(std::is_pod<RomEntryKey>::value); static_assert(util::is_pod<RomEntryKey>::value);
struct EntryKey { struct EntryKey {
RomEntryKey key; RomEntryKey key;
@ -126,7 +126,7 @@ namespace ams::fs {
return hash; return hash;
} }
}; };
static_assert(std::is_pod<EntryKey>::value); static_assert(util::is_pod<EntryKey>::value);
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>; using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>; using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;

View file

@ -31,7 +31,7 @@ namespace ams::fs {
BucketIndex ind; BucketIndex ind;
Position pos; Position pos;
}; };
static_assert(std::is_pod<FindIndex>::value); static_assert(util::is_pod<FindIndex>::value);
private: private:
static constexpr inline Position InvalidPosition = ~Position(); static constexpr inline Position InvalidPosition = ~Position();
@ -41,7 +41,7 @@ namespace ams::fs {
Position next; Position next;
u32 size; u32 size;
}; };
static_assert(std::is_pod<Element>::value); static_assert(util::is_pod<Element>::value);
private: private:
s64 bucket_count; s64 bucket_count;
SubStorage bucket_storage; SubStorage bucket_storage;

View file

@ -26,7 +26,7 @@ namespace ams::fs {
size_t length; size_t length;
const RomPathChar *path; const RomPathChar *path;
}; };
static_assert(std::is_pod<RomEntryName>::value); static_assert(util::is_pod<RomEntryName>::value);
constexpr void InitializeRomEntryName(RomEntryName *entry) { constexpr void InitializeRomEntryName(RomEntryName *entry) {
AMS_ABORT_UNLESS(entry != nullptr); AMS_ABORT_UNLESS(entry != nullptr);

View file

@ -34,19 +34,19 @@ namespace ams::fs {
s64 file_entry_size; s64 file_entry_size;
s64 body_offset; s64 body_offset;
}; };
static_assert(std::is_pod<RomFileSystemInformation>::value); static_assert(util::is_pod<RomFileSystemInformation>::value);
static_assert(sizeof(RomFileSystemInformation) == 0x50); static_assert(sizeof(RomFileSystemInformation) == 0x50);
struct RomDirectoryInfo { struct RomDirectoryInfo {
/* ... */ /* ... */
}; };
static_assert(std::is_pod<RomDirectoryInfo>::value); static_assert(util::is_pod<RomDirectoryInfo>::value);
struct RomFileInfo { struct RomFileInfo {
Int64 offset; Int64 offset;
Int64 size; Int64 size;
}; };
static_assert(std::is_pod<RomFileInfo>::value); static_assert(util::is_pod<RomFileInfo>::value);
namespace RomStringTraits { namespace RomStringTraits {

View file

@ -34,7 +34,7 @@ namespace ams::fs {
return !(lhs == rhs); return !(lhs == rhs);
} }
static_assert(std::is_pod<ReadOption>::value && sizeof(ReadOption) == sizeof(u32)); static_assert(util::is_pod<ReadOption>::value && sizeof(ReadOption) == sizeof(u32));
struct WriteOption { struct WriteOption {
u32 value; u32 value;
@ -58,7 +58,7 @@ namespace ams::fs {
return !(lhs == rhs); return !(lhs == rhs);
} }
static_assert(std::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32)); static_assert(util::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32));
struct FileHandle { struct FileHandle {
void *handle; void *handle;

View file

@ -42,7 +42,7 @@ namespace ams::fs {
template<typename T> template<typename T>
std::unique_ptr<T, Deleter> MakeUnique() { std::unique_ptr<T, Deleter> MakeUnique() {
static_assert(std::is_pod<T>::value); static_assert(util::is_pod<T>::value);
return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T))); return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T)));
} }

View file

@ -36,7 +36,7 @@ namespace ams::fs {
} }
}; };
static_assert(std::is_pod<QueryRangeInfo>::value); static_assert(util::is_pod<QueryRangeInfo>::value);
static_assert(sizeof(QueryRangeInfo) == 0x40); static_assert(sizeof(QueryRangeInfo) == 0x40);
static_assert(sizeof(QueryRangeInfo) == sizeof(::FsRangeInfo)); static_assert(sizeof(QueryRangeInfo) == sizeof(::FsRangeInfo));

View file

@ -23,7 +23,7 @@ namespace ams::fs {
u64 data64[2]; u64 data64[2];
}; };
static_assert(sizeof(RightsId) == 0x10); static_assert(sizeof(RightsId) == 0x10);
static_assert(std::is_pod<RightsId>::value); static_assert(util::is_pod<RightsId>::value);
inline bool operator==(const RightsId &lhs, const RightsId &rhs) { inline bool operator==(const RightsId &lhs, const RightsId &rhs) {
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) == 0; return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) == 0;

View file

@ -51,7 +51,7 @@ namespace ams::fs {
struct UserId { struct UserId {
u64 data[2]; u64 data[2];
}; };
static_assert(std::is_pod<UserId>::value); static_assert(util::is_pod<UserId>::value);
constexpr inline bool operator<(const UserId &lhs, const UserId &rhs) { constexpr inline bool operator<(const UserId &lhs, const UserId &rhs) {
if (lhs.data[0] < rhs.data[0]) { if (lhs.data[0] < rhs.data[0]) {
@ -92,7 +92,7 @@ namespace ams::fs {
bool pseudo; bool pseudo;
u8 reserved[0x1A]; u8 reserved[0x1A];
}; };
static_assert(std::is_pod<SaveDataCreationInfo>::value); static_assert(util::is_pod<SaveDataCreationInfo>::value);
static_assert(sizeof(SaveDataCreationInfo) == 0x40); static_assert(sizeof(SaveDataCreationInfo) == 0x40);
struct SaveDataAttribute { struct SaveDataAttribute {
@ -154,6 +154,6 @@ namespace ams::fs {
u8 unused[0x190]; u8 unused[0x190];
}; };
static_assert(sizeof(SaveDataExtraData) == 0x200); static_assert(sizeof(SaveDataExtraData) == 0x200);
static_assert(std::is_pod<SaveDataExtraData>::value); static_assert(util::is_pod<SaveDataExtraData>::value);
} }

View file

@ -43,7 +43,7 @@ namespace ams::fssrv::sf {
} }
}; };
static_assert(std::is_pod<Path>::value && sizeof(Path) == FS_MAX_PATH); static_assert(util::is_pod<Path>::value && sizeof(Path) == FS_MAX_PATH);
using FspPath = Path; using FspPath = Path;

View file

@ -30,7 +30,7 @@ namespace ams::fssystem {
class PageList; class PageList;
struct PageEntry { PageEntry *next; }; struct PageEntry { PageEntry *next; };
static_assert(std::is_pod<PageEntry>::value); static_assert(util::is_pod<PageEntry>::value);
static_assert(sizeof(PageEntry) <= BlockSizeMin); static_assert(sizeof(PageEntry) <= BlockSizeMin);
class PageList : public ::ams::fs::impl::Newable { class PageList : public ::ams::fs::impl::Newable {

View file

@ -35,7 +35,7 @@ namespace ams::fssystem {
Position next_dir; Position next_dir;
Position next_file; Position next_file;
}; };
static_assert(std::is_pod<FindPosition>::value); static_assert(util::is_pod<FindPosition>::value);
using DirectoryInfo = RomDirectoryInfo; using DirectoryInfo = RomDirectoryInfo;
using FileInfo = RomFileInfo; using FileInfo = RomFileInfo;
@ -63,13 +63,13 @@ namespace ams::fssystem {
Position dir; Position dir;
Position file; Position file;
}; };
static_assert(std::is_pod<RomDirectoryEntry>::value); static_assert(util::is_pod<RomDirectoryEntry>::value);
struct RomFileEntry { struct RomFileEntry {
Position next; Position next;
FileInfo info; FileInfo info;
}; };
static_assert(std::is_pod<RomFileEntry>::value); static_assert(util::is_pod<RomFileEntry>::value);
static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength; static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength;
@ -115,7 +115,7 @@ namespace ams::fssystem {
return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar)); return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar));
} }
}; };
static_assert(std::is_pod<RomEntryKey>::value); static_assert(util::is_pod<RomEntryKey>::value);
struct EntryKey { struct EntryKey {
RomEntryKey key; RomEntryKey key;
@ -132,7 +132,7 @@ namespace ams::fssystem {
return hash; return hash;
} }
}; };
static_assert(std::is_pod<EntryKey>::value); static_assert(util::is_pod<EntryKey>::value);
using DirectoryEntryMapTable = EntryMapTable<DirectoryBucketStorage, DirectoryEntryStorage, RomEntryKey, EntryKey, RomDirectoryEntry>; using DirectoryEntryMapTable = EntryMapTable<DirectoryBucketStorage, DirectoryEntryStorage, RomEntryKey, EntryKey, RomDirectoryEntry>;
using FileEntryMapTable = EntryMapTable<FileBucketStorage, FileEntryStorage, RomEntryKey, EntryKey, RomFileEntry>; using FileEntryMapTable = EntryMapTable<FileBucketStorage, FileEntryStorage, RomEntryKey, EntryKey, RomFileEntry>;

View file

@ -37,7 +37,7 @@ namespace ams::fssystem {
BucketIndex ind; BucketIndex ind;
Position pos; Position pos;
}; };
static_assert(std::is_pod<FindIndex>::value); static_assert(util::is_pod<FindIndex>::value);
private: private:
static constexpr inline Position InvalidPosition = ~Position(); static constexpr inline Position InvalidPosition = ~Position();
@ -47,7 +47,7 @@ namespace ams::fssystem {
Position next; Position next;
u32 size; u32 size;
}; };
static_assert(std::is_pod<Element>::value); static_assert(util::is_pod<Element>::value);
private: private:
s64 bucket_offset; s64 bucket_offset;
u32 bucket_count; u32 bucket_count;

View file

@ -26,7 +26,7 @@ namespace ams::fssystem {
size_t length; size_t length;
const RomPathChar *path; const RomPathChar *path;
}; };
static_assert(std::is_pod<RomEntryName>::value); static_assert(util::is_pod<RomEntryName>::value);
constexpr void InitializeRomEntryName(RomEntryName *entry) { constexpr void InitializeRomEntryName(RomEntryName *entry) {
entry->length = 0; entry->length = 0;

View file

@ -34,19 +34,19 @@ namespace ams::fssystem {
s64 file_entry_size; s64 file_entry_size;
s64 body_offset; s64 body_offset;
}; };
static_assert(std::is_pod<RomFileSystemInformation>::value); static_assert(util::is_pod<RomFileSystemInformation>::value);
static_assert(sizeof(RomFileSystemInformation) == 0x50); static_assert(sizeof(RomFileSystemInformation) == 0x50);
struct RomDirectoryInfo { struct RomDirectoryInfo {
/* ... */ /* ... */
}; };
static_assert(std::is_pod<RomDirectoryInfo>::value); static_assert(util::is_pod<RomDirectoryInfo>::value);
struct RomFileInfo { struct RomFileInfo {
fs::Int64 offset; fs::Int64 offset;
fs::Int64 size; fs::Int64 size;
}; };
static_assert(std::is_pod<RomFileInfo>::value); static_assert(util::is_pod<RomFileInfo>::value);
namespace RomStringTraits { namespace RomStringTraits {

View file

@ -29,7 +29,7 @@ namespace ams::fssystem {
u32 name_offset; u32 name_offset;
u32 reserved; u32 reserved;
}; };
static_assert(std::is_pod<PartitionEntry>::value); static_assert(util::is_pod<PartitionEntry>::value);
#pragma pack(pop) #pragma pack(pop)
static constexpr const char VersionSignature[] = { 'P', 'F', 'S', '0' }; static constexpr const char VersionSignature[] = { 'P', 'F', 'S', '0' };
@ -52,7 +52,7 @@ namespace ams::fssystem {
u64 hash_target_offset; u64 hash_target_offset;
char hash[HashSize]; char hash[HashSize];
}; };
static_assert(std::is_pod<PartitionEntry>::value); static_assert(util::is_pod<PartitionEntry>::value);
#pragma pack(pop) #pragma pack(pop)
static constexpr const char VersionSignature[] = { 'H', 'F', 'S', '0' }; static constexpr const char VersionSignature[] = { 'H', 'F', 'S', '0' };

View file

@ -186,7 +186,7 @@ namespace ams::kvdb {
template<class Key, size_t Capacity> template<class Key, size_t Capacity>
class FileKeyValueCache { class FileKeyValueCache {
static_assert(std::is_pod<Key>::value, "FileKeyValueCache Key must be pod!"); static_assert(util::is_pod<Key>::value, "FileKeyValueCache Key must be pod!");
static_assert(sizeof(Key) <= FileKeyValueStore::MaxKeySize, "FileKeyValueCache Key is too big!"); static_assert(sizeof(Key) <= FileKeyValueStore::MaxKeySize, "FileKeyValueCache Key is too big!");
public: public:
using LeastRecentlyUsedList = impl::LruList<Key, Capacity>; using LeastRecentlyUsedList = impl::LruList<Key, Capacity>;

View file

@ -38,7 +38,7 @@ namespace ams::kvdb {
size_t key_size; size_t key_size;
size_t value_size; size_t value_size;
}; };
static_assert(std::is_pod<Entry>::value, "FileKeyValueStore::Entry definition!"); static_assert(util::is_pod<Entry>::value, "FileKeyValueStore::Entry definition!");
class Cache { class Cache {
private: private:
@ -83,13 +83,13 @@ namespace ams::kvdb {
/* Niceties. */ /* Niceties. */
template<typename Key> template<typename Key>
Result Get(size_t *out_size, void *out_value, size_t max_out_size, const Key &key) { Result Get(size_t *out_size, void *out_value, size_t max_out_size, const Key &key) {
static_assert(std::is_pod<Key>::value && sizeof(Key) <= MaxKeySize, "Invalid FileKeyValueStore Key!"); static_assert(util::is_pod<Key>::value && sizeof(Key) <= MaxKeySize, "Invalid FileKeyValueStore Key!");
return this->Get(out_size, out_value, max_out_size, &key, sizeof(Key)); return this->Get(out_size, out_value, max_out_size, &key, sizeof(Key));
} }
template<typename Key, typename Value> template<typename Key, typename Value>
Result Get(Value *out_value, const Key &key) { Result Get(Value *out_value, const Key &key) {
static_assert(std::is_pod<Value>::value && !std::is_pointer<Value>::value, "Invalid FileKeyValueStore Value!"); static_assert(util::is_pod<Value>::value && !std::is_pointer<Value>::value, "Invalid FileKeyValueStore Value!");
size_t size = 0; size_t size = 0;
R_TRY(this->Get(&size, out_value, sizeof(Value), key)); R_TRY(this->Get(&size, out_value, sizeof(Value), key));
AMS_ABORT_UNLESS(size >= sizeof(Value)); AMS_ABORT_UNLESS(size >= sizeof(Value));
@ -103,13 +103,13 @@ namespace ams::kvdb {
template<typename Key> template<typename Key>
Result Set(const Key &key, const void *value, size_t value_size) { Result Set(const Key &key, const void *value, size_t value_size) {
static_assert(std::is_pod<Key>::value && sizeof(Key) <= MaxKeySize, "Invalid FileKeyValueStore Key!"); static_assert(util::is_pod<Key>::value && sizeof(Key) <= MaxKeySize, "Invalid FileKeyValueStore Key!");
return this->Set(&key, sizeof(Key), value, value_size); return this->Set(&key, sizeof(Key), value, value_size);
} }
template<typename Key, typename Value> template<typename Key, typename Value>
Result Set(const Key &key, const Value &value) { Result Set(const Key &key, const Value &value) {
static_assert(std::is_pod<Value>::value && !std::is_pointer<Value>::value, "Invalid FileKeyValueStore Value!"); static_assert(util::is_pod<Value>::value && !std::is_pointer<Value>::value, "Invalid FileKeyValueStore Value!");
return this->Set(key, &value, sizeof(Value)); return this->Set(key, &value, sizeof(Value));
} }

View file

@ -26,7 +26,7 @@ namespace ams::kvdb {
template<class Key> template<class Key>
class MemoryKeyValueStore { class MemoryKeyValueStore {
static_assert(std::is_pod<Key>::value, "KeyValueStore Keys must be pod!"); static_assert(util::is_pod<Key>::value, "KeyValueStore Keys must be pod!");
NON_COPYABLE(MemoryKeyValueStore); NON_COPYABLE(MemoryKeyValueStore);
NON_MOVEABLE(MemoryKeyValueStore); NON_MOVEABLE(MemoryKeyValueStore);
public: public:
@ -49,7 +49,7 @@ namespace ams::kvdb {
if constexpr (!std::is_same<Value, void>::value) { if constexpr (!std::is_same<Value, void>::value) {
AMS_ABORT_UNLESS(sizeof(Value) <= this->value_size); AMS_ABORT_UNLESS(sizeof(Value) <= this->value_size);
/* Ensure we only get pod. */ /* Ensure we only get pod. */
static_assert(std::is_pod<Value>::value, "KeyValueStore Values must be pod"); static_assert(util::is_pod<Value>::value, "KeyValueStore Values must be pod");
} }
return reinterpret_cast<Value *>(this->value); return reinterpret_cast<Value *>(this->value);
} }
@ -60,7 +60,7 @@ namespace ams::kvdb {
if constexpr (!std::is_same<Value, void>::value) { if constexpr (!std::is_same<Value, void>::value) {
AMS_ABORT_UNLESS(sizeof(Value) <= this->value_size); AMS_ABORT_UNLESS(sizeof(Value) <= this->value_size);
/* Ensure we only get pod. */ /* Ensure we only get pod. */
static_assert(std::is_pod<Value>::value, "KeyValueStore Values must be pod"); static_assert(util::is_pod<Value>::value, "KeyValueStore Values must be pod");
} }
return reinterpret_cast<Value *>(this->value); return reinterpret_cast<Value *>(this->value);
} }
@ -366,14 +366,14 @@ namespace ams::kvdb {
template<typename Value> template<typename Value>
Result Set(const Key &key, const Value &value) { Result Set(const Key &key, const Value &value) {
/* Only allow setting pod. */ /* Only allow setting pod. */
static_assert(std::is_pod<Value>::value, "KeyValueStore Values must be pod"); static_assert(util::is_pod<Value>::value, "KeyValueStore Values must be pod");
return this->Set(key, &value, sizeof(Value)); return this->Set(key, &value, sizeof(Value));
} }
template<typename Value> template<typename Value>
Result Set(const Key &key, const Value *value) { Result Set(const Key &key, const Value *value) {
/* Only allow setting pod. */ /* Only allow setting pod. */
static_assert(std::is_pod<Value>::value, "KeyValueStore Values must be pod"); static_assert(util::is_pod<Value>::value, "KeyValueStore Values must be pod");
return this->Set(key, value, sizeof(Value)); return this->Set(key, value, sizeof(Value));
} }

View file

@ -35,7 +35,7 @@ namespace ams::ldr {
u32 aci_fah_size; u32 aci_fah_size;
u8 ac_buffer[0x3E0]; u8 ac_buffer[0x3E0];
}; };
static_assert(std::is_pod<ProgramInfo>::value && sizeof(ProgramInfo) == 0x400, "ProgramInfo definition!"); static_assert(util::is_pod<ProgramInfo>::value && sizeof(ProgramInfo) == 0x400, "ProgramInfo definition!");
enum ProgramInfoFlag { enum ProgramInfoFlag {
ProgramInfoFlag_SystemModule = (0 << 0), ProgramInfoFlag_SystemModule = (0 << 0),
@ -71,7 +71,7 @@ namespace ams::ldr {
inline bool operator!=(const PinId &lhs, const PinId &rhs) { inline bool operator!=(const PinId &lhs, const PinId &rhs) {
return lhs.value != rhs.value; return lhs.value != rhs.value;
} }
static_assert(sizeof(PinId) == sizeof(u64) && std::is_pod<PinId>::value, "PinId definition!"); static_assert(sizeof(PinId) == sizeof(u64) && util::is_pod<PinId>::value, "PinId definition!");
/* Import ModuleInfo from libnx. */ /* Import ModuleInfo from libnx. */
using ModuleInfo = ::LoaderModuleInfo; using ModuleInfo = ::LoaderModuleInfo;
@ -142,7 +142,7 @@ namespace ams::ldr {
}; };
}; };
}; };
static_assert(sizeof(NsoHeader) == 0x100 && std::is_pod<NsoHeader>::value, "NsoHeader definition!"); static_assert(sizeof(NsoHeader) == 0x100 && util::is_pod<NsoHeader>::value, "NsoHeader definition!");
/* NPDM types. */ /* NPDM types. */
struct Aci { struct Aci {
@ -160,7 +160,7 @@ namespace ams::ldr {
u32 kac_size; u32 kac_size;
u8 reserved_38[0x8]; u8 reserved_38[0x8];
}; };
static_assert(sizeof(Aci) == 0x40 && std::is_pod<Aci>::value, "Aci definition!"); static_assert(sizeof(Aci) == 0x40 && util::is_pod<Aci>::value, "Aci definition!");
struct Acid { struct Acid {
static constexpr u32 Magic = util::FourCC<'A','C','I','D'>::Code; static constexpr u32 Magic = util::FourCC<'A','C','I','D'>::Code;
@ -199,7 +199,7 @@ namespace ams::ldr {
u32 kac_size; u32 kac_size;
u8 reserved_238[0x8]; u8 reserved_238[0x8];
}; };
static_assert(sizeof(Acid) == 0x240 && std::is_pod<Acid>::value, "Acid definition!"); static_assert(sizeof(Acid) == 0x240 && util::is_pod<Acid>::value, "Acid definition!");
struct Npdm { struct Npdm {
static constexpr u32 Magic = util::FourCC<'M','E','T','A'>::Code; static constexpr u32 Magic = util::FourCC<'M','E','T','A'>::Code;
@ -239,6 +239,6 @@ namespace ams::ldr {
u32 acid_offset; u32 acid_offset;
u32 acid_size; u32 acid_size;
}; };
static_assert(sizeof(Npdm) == 0x80 && std::is_pod<Npdm>::value, "Npdm definition!"); static_assert(sizeof(Npdm) == 0x80 && util::is_pod<Npdm>::value, "Npdm definition!");
} }

View file

@ -56,6 +56,6 @@ namespace ams::lr {
} }
}; };
static_assert(std::is_pod<Path>::value && sizeof(Path) == fs::EntryNameLengthMax); static_assert(util::is_pod<Path>::value && sizeof(Path) == fs::EntryNameLengthMax);
} }

View file

@ -65,6 +65,6 @@ namespace ams::mem::impl {
size_t alloc_size; size_t alloc_size;
size_t hash; size_t hash;
}; };
static_assert(std::is_pod<HeapHash>::value); static_assert(util::is_pod<HeapHash>::value);
} }

View file

@ -55,7 +55,7 @@ namespace ams::ncm {
} }
}; };
static_assert(sizeof(std::is_pod<ContentInfo>::value)); static_assert(sizeof(util::is_pod<ContentInfo>::value));
static_assert(sizeof(ContentInfo) == 0x18); static_assert(sizeof(ContentInfo) == 0x18);
} }

View file

@ -65,7 +65,7 @@ namespace ams::ncm {
u32 flags; u32 flags;
fs::SaveDataSpaceId space_id; fs::SaveDataSpaceId space_id;
}; };
static_assert(std::is_pod<SystemSaveDataInfo>::value); static_assert(util::is_pod<SystemSaveDataInfo>::value);
class ContentManagerImpl final : public IContentManager { class ContentManagerImpl final : public IContentManager {
private: private:

View file

@ -27,7 +27,7 @@ namespace ams::ncm {
return { .program_id = program_id, .storage_id = static_cast<u8>(storage_id), }; return { .program_id = program_id, .storage_id = static_cast<u8>(storage_id), };
} }
}; };
static_assert(sizeof(ProgramLocation) == 0x10 && std::is_pod<ProgramLocation>::value); static_assert(sizeof(ProgramLocation) == 0x10 && util::is_pod<ProgramLocation>::value);
static_assert(sizeof(ProgramLocation) == sizeof(::NcmProgramLocation) && alignof(ProgramLocation) == alignof(::NcmProgramLocation), "ProgramLocation Libnx Compatibility"); static_assert(sizeof(ProgramLocation) == sizeof(::NcmProgramLocation) && alignof(ProgramLocation) == alignof(::NcmProgramLocation), "ProgramLocation Libnx Compatibility");

View file

@ -25,7 +25,7 @@ namespace ams::ncm {
u8 reserved[7]; u8 reserved[7];
}; };
static_assert(sizeof(RightsId) == 0x18); static_assert(sizeof(RightsId) == 0x18);
static_assert(std::is_pod<RightsId>::value); static_assert(util::is_pod<RightsId>::value);
inline bool operator==(const RightsId &lhs, const RightsId &rhs) { inline bool operator==(const RightsId &lhs, const RightsId &rhs) {
return std::tie(lhs.id, lhs.key_generation) == std::tie(rhs.id, rhs.key_generation); return std::tie(lhs.id, lhs.key_generation) == std::tie(rhs.id, rhs.key_generation);

View file

@ -36,7 +36,7 @@ namespace ams::os {
}; };
util::BitPack32 counter; util::BitPack32 counter;
}; };
static_assert(std::is_pod<LockCount>::value); static_assert(util::is_pod<LockCount>::value);
static_assert(std::is_trivial<LockCount>::value); static_assert(std::is_trivial<LockCount>::value);
union { union {

View file

@ -52,6 +52,6 @@ namespace ams::pgl {
}; };
} }
}; };
static_assert(sizeof(ContentMetaInfo) == 0x10 && std::is_pod<ContentMetaInfo>::value); static_assert(sizeof(ContentMetaInfo) == 0x10 && util::is_pod<ContentMetaInfo>::value);
} }

View file

@ -97,6 +97,6 @@ namespace ams::pm {
u32 event; u32 event;
os::ProcessId process_id; os::ProcessId process_id;
}; };
static_assert(sizeof(ProcessEventInfo) == 0x10 && std::is_pod<ProcessEventInfo>::value, "ProcessEventInfo definition!"); static_assert(sizeof(ProcessEventInfo) == 0x10 && util::is_pod<ProcessEventInfo>::value, "ProcessEventInfo definition!");
} }

View file

@ -36,7 +36,7 @@ namespace ams::reg {
} }
inline void SetBits(volatile u32 *reg, u32 mask) { inline void SetBits(volatile u32 *reg, u32 mask) {
*reg |= mask; *reg = *reg | mask;
} }
inline void SetBits(uintptr_t reg, u32 mask) { inline void SetBits(uintptr_t reg, u32 mask) {
@ -44,7 +44,7 @@ namespace ams::reg {
} }
inline void ClearBits(volatile u32 *reg, u32 mask) { inline void ClearBits(volatile u32 *reg, u32 mask) {
*reg &= ~mask; *reg = *reg & ~mask;
} }
inline void ClearBits(uintptr_t reg, u32 mask) { inline void ClearBits(uintptr_t reg, u32 mask) {
@ -52,7 +52,7 @@ namespace ams::reg {
} }
inline void MaskBits(volatile u32 *reg, u32 mask) { inline void MaskBits(volatile u32 *reg, u32 mask) {
*reg &= mask; *reg = *reg & mask;
} }
inline void MaskBits(uintptr_t reg, u32 mask) { inline void MaskBits(uintptr_t reg, u32 mask) {

View file

@ -22,18 +22,18 @@ namespace ams::settings::factory {
u8 data[0x180]; u8 data[0x180];
}; };
static_assert(sizeof(EccP256DeviceCertificate) == 0x180); static_assert(sizeof(EccP256DeviceCertificate) == 0x180);
static_assert(std::is_pod<EccP256DeviceCertificate>::value); static_assert(util::is_pod<EccP256DeviceCertificate>::value);
struct EccB233DeviceCertificate { struct EccB233DeviceCertificate {
u8 data[0x180]; u8 data[0x180];
}; };
static_assert(sizeof(EccB233DeviceCertificate) == 0x180); static_assert(sizeof(EccB233DeviceCertificate) == 0x180);
static_assert(std::is_pod<EccB233DeviceCertificate>::value); static_assert(util::is_pod<EccB233DeviceCertificate>::value);
struct Rsa2048DeviceCertificate { struct Rsa2048DeviceCertificate {
u8 data[0x240]; u8 data[0x240];
}; };
static_assert(sizeof(Rsa2048DeviceCertificate) == 0x240); static_assert(sizeof(Rsa2048DeviceCertificate) == 0x240);
static_assert(std::is_pod<Rsa2048DeviceCertificate>::value); static_assert(util::is_pod<Rsa2048DeviceCertificate>::value);
} }

View file

@ -22,6 +22,6 @@ namespace ams::settings::factory {
char str[0x18]; char str[0x18];
}; };
static_assert(sizeof(SerialNumber) == 0x18); static_assert(sizeof(SerialNumber) == 0x18);
static_assert(std::is_pod<SerialNumber>::value); static_assert(util::is_pod<SerialNumber>::value);
} }

View file

@ -27,12 +27,12 @@ namespace ams::settings::fwdbg {
char value[util::AlignUp(SettingsNameLengthMax + 1, alignof(u64))]; char value[util::AlignUp(SettingsNameLengthMax + 1, alignof(u64))];
}; };
static_assert(std::is_pod<SettingsName>::value && sizeof(SettingsName) > SettingsNameLengthMax); static_assert(util::is_pod<SettingsName>::value && sizeof(SettingsName) > SettingsNameLengthMax);
struct SettingsItemKey : sf::LargeData { struct SettingsItemKey : sf::LargeData {
char value[util::AlignUp(SettingsItemKeyLengthMax + 1, alignof(u64))]; char value[util::AlignUp(SettingsItemKeyLengthMax + 1, alignof(u64))];
}; };
static_assert(std::is_pod<SettingsItemKey>::value && sizeof(SettingsItemKey) > SettingsItemKeyLengthMax); static_assert(util::is_pod<SettingsItemKey>::value && sizeof(SettingsItemKey) > SettingsItemKeyLengthMax);
} }

View file

@ -152,7 +152,7 @@ namespace ams::settings {
return impl::IsValidLanguageCode(lc, std::make_index_sequence<Language_Count>{}); return impl::IsValidLanguageCode(lc, std::make_index_sequence<Language_Count>{});
} }
static_assert(std::is_pod<LanguageCode>::value); static_assert(util::is_pod<LanguageCode>::value);
static_assert(sizeof(LanguageCode) == sizeof(u64)); static_assert(sizeof(LanguageCode) == sizeof(u64));
/* Not an official type, but convenient. */ /* Not an official type, but convenient. */
@ -193,7 +193,7 @@ namespace ams::settings {
} }
}; };
static_assert(std::is_pod<FirmwareVersion>::value); static_assert(util::is_pod<FirmwareVersion>::value);
static_assert(sizeof(FirmwareVersion) == sizeof(::SetSysFirmwareVersion)); static_assert(sizeof(FirmwareVersion) == sizeof(::SetSysFirmwareVersion));
constexpr inline bool operator==(const FirmwareVersion &lhs, const FirmwareVersion &rhs) { constexpr inline bool operator==(const FirmwareVersion &lhs, const FirmwareVersion &rhs) {

View file

@ -63,7 +63,7 @@ namespace ams::sf::cmif {
} }
}; };
static_assert(std::is_pod<ServerMessageRuntimeMetadata>::value, "std::is_pod<ServerMessageRuntimeMetadata>::value"); static_assert(util::is_pod<ServerMessageRuntimeMetadata>::value, "util::is_pod<ServerMessageRuntimeMetadata>::value");
static_assert(sizeof(ServerMessageRuntimeMetadata) == sizeof(u64), "sizeof(ServerMessageRuntimeMetadata)"); static_assert(sizeof(ServerMessageRuntimeMetadata) == sizeof(u64), "sizeof(ServerMessageRuntimeMetadata)");
class ServerMessageProcessor { class ServerMessageProcessor {

View file

@ -61,7 +61,7 @@ namespace ams::sf::cmif {
return this->handler; return this->handler;
} }
}; };
static_assert(std::is_pod<ServiceCommandMeta>::value && sizeof(ServiceCommandMeta) == 0x18, "sizeof(ServiceCommandMeta)"); static_assert(util::is_pod<ServiceCommandMeta>::value && sizeof(ServiceCommandMeta) == 0x18, "sizeof(ServiceCommandMeta)");
namespace impl { namespace impl {

View file

@ -1042,7 +1042,7 @@ namespace ams::sf::impl {
}; };
constexpr Result GetCmifOutHeaderPointer(CmifOutHeader **out_header_ptr, cmif::PointerAndSize &out_raw_data) { constexpr Result GetCmifOutHeaderPointer(CmifOutHeader **out_header_ptr, cmif::PointerAndSize &out_raw_data) {
CmifOutHeader *header = reinterpret_cast<CmifOutHeader *>(out_raw_data.GetPointer()); CmifOutHeader *header = static_cast<CmifOutHeader *>(out_raw_data.GetPointer());
R_UNLESS(out_raw_data.GetSize() >= sizeof(*header), sf::cmif::ResultInvalidHeaderSize()); R_UNLESS(out_raw_data.GetSize() >= sizeof(*header), sf::cmif::ResultInvalidHeaderSize());
out_raw_data = cmif::PointerAndSize(out_raw_data.GetAddress() + sizeof(*header), out_raw_data.GetSize() - sizeof(*header)); out_raw_data = cmif::PointerAndSize(out_raw_data.GetAddress() + sizeof(*header), out_raw_data.GetSize() - sizeof(*header));
*out_header_ptr = header; *out_header_ptr = header;

View file

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

View file

@ -23,6 +23,6 @@ namespace ams::capsrv::server {
}; };
static_assert(sizeof(DecoderWorkMemory) == SoftwareJpegDecoderWorkMemorySize); static_assert(sizeof(DecoderWorkMemory) == SoftwareJpegDecoderWorkMemorySize);
static_assert(alignof(DecoderWorkMemory) == os::MemoryPageSize); static_assert(alignof(DecoderWorkMemory) == os::MemoryPageSize);
static_assert(std::is_pod<DecoderWorkMemory>::value); static_assert(util::is_pod<DecoderWorkMemory>::value);
} }

View file

@ -23,7 +23,7 @@ namespace ams::fs::impl {
struct FilePathHash : public Newable { struct FilePathHash : public Newable {
u8 data[FilePathHashSize]; u8 data[FilePathHashSize];
}; };
static_assert(std::is_pod<FilePathHash>::value); static_assert(util::is_pod<FilePathHash>::value);
inline bool operator==(const FilePathHash &lhs, const FilePathHash &rhs) { inline bool operator==(const FilePathHash &lhs, const FilePathHash &rhs) {
return std::memcmp(lhs.data, rhs.data, FilePathHashSize) == 0; return std::memcmp(lhs.data, rhs.data, FilePathHashSize) == 0;

View file

@ -21,6 +21,6 @@ namespace ams::fs {
struct MountName { struct MountName {
char str[MountNameLengthMax + 1]; char str[MountNameLengthMax + 1];
}; };
static_assert(std::is_pod<MountName>::value); static_assert(util::is_pod<MountName>::value);
} }

View file

@ -24,7 +24,7 @@ namespace ams::fssystem {
u32 name_table_size; u32 name_table_size;
u32 reserved; u32 reserved;
}; };
static_assert(std::is_pod<PartitionFileSystemMeta::PartitionFileSystemHeader>::value); static_assert(util::is_pod<PartitionFileSystemMeta::PartitionFileSystemHeader>::value);
static_assert(sizeof(PartitionFileSystemMeta::PartitionFileSystemHeader) == 0x10); static_assert(sizeof(PartitionFileSystemMeta::PartitionFileSystemHeader) == 0x10);
template <typename Format> template <typename Format>

View file

@ -37,7 +37,7 @@ namespace ams::fssystem {
virtual ~RomFsFile() { /* ... */ } virtual ~RomFsFile() { /* ... */ }
public: public:
virtual Result ReadImpl(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override { virtual Result ReadImpl(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result { R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
size_t read_size = 0; size_t read_size = 0;
R_TRY(this->DryRead(std::addressof(read_size), offset, size, option, fs::OpenMode_Read)); R_TRY(this->DryRead(std::addressof(read_size), offset, size, option, fs::OpenMode_Read));
@ -84,7 +84,7 @@ namespace ams::fssystem {
operate_size = this->GetSize() - offset; operate_size = this->GetSize() - offset;
} }
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result { R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
R_TRY(this->parent->GetBaseStorage()->OperateRange(dst, dst_size, op_id, this->start + offset, operate_size, src, src_size)); R_TRY(this->parent->GetBaseStorage()->OperateRange(dst, dst_size, op_id, this->start + offset, operate_size, src, src_size));
return ResultSuccess(); return ResultSuccess();
}, AMS_CURRENT_FUNCTION_NAME)); }, AMS_CURRENT_FUNCTION_NAME));
@ -113,7 +113,7 @@ namespace ams::fssystem {
virtual ~RomFsDirectory() override { /* ... */ } virtual ~RomFsDirectory() override { /* ... */ }
public: public:
virtual Result ReadImpl(s64 *out_count, fs::DirectoryEntry *out_entries, s64 max_entries) { virtual Result ReadImpl(s64 *out_count, fs::DirectoryEntry *out_entries, s64 max_entries) {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result { R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
return this->ReadImpl(out_count, std::addressof(this->current_find), out_entries, max_entries); return this->ReadImpl(out_count, std::addressof(this->current_find), out_entries, max_entries);
}, AMS_CURRENT_FUNCTION_NAME)); }, AMS_CURRENT_FUNCTION_NAME));
return ResultSuccess(); return ResultSuccess();
@ -278,7 +278,7 @@ namespace ams::fssystem {
} }
Result RomFsFileSystem::GetFileInfo(RomFileTable::FileInfo *out, const char *path) { Result RomFsFileSystem::GetFileInfo(RomFileTable::FileInfo *out, const char *path) {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result { R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
R_TRY_CATCH(this->rom_file_table.OpenFile(out, path)) { R_TRY_CATCH(this->rom_file_table.OpenFile(out, path)) {
R_CONVERT(fs::ResultDbmNotFound, fs::ResultPathNotFound()); R_CONVERT(fs::ResultDbmNotFound, fs::ResultPathNotFound());
} R_END_TRY_CATCH; } R_END_TRY_CATCH;
@ -325,7 +325,7 @@ namespace ams::fssystem {
} }
Result RomFsFileSystem::GetEntryTypeImpl(fs::DirectoryEntryType *out, const char *path) { Result RomFsFileSystem::GetEntryTypeImpl(fs::DirectoryEntryType *out, const char *path) {
R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=]() -> Result { R_TRY(buffers::DoContinuouslyUntilBufferIsAllocated([=, this]() -> Result {
RomDirectoryInfo dir_info; RomDirectoryInfo dir_info;
R_TRY_CATCH(this->rom_file_table.GetDirectoryInformation(std::addressof(dir_info), path)) { R_TRY_CATCH(this->rom_file_table.GetDirectoryInformation(std::addressof(dir_info), path)) {

View file

@ -42,7 +42,7 @@ namespace ams::kvdb {
return header; return header;
} }
}; };
static_assert(sizeof(ArchiveHeader) == 0xC && std::is_pod<ArchiveHeader>::value, "ArchiveHeader definition!"); static_assert(sizeof(ArchiveHeader) == 0xC && util::is_pod<ArchiveHeader>::value, "ArchiveHeader definition!");
struct ArchiveEntryHeader { struct ArchiveEntryHeader {
u8 magic[sizeof(ArchiveEntryMagic)]; u8 magic[sizeof(ArchiveEntryMagic)];
@ -62,7 +62,7 @@ namespace ams::kvdb {
return header; return header;
} }
}; };
static_assert(sizeof(ArchiveEntryHeader) == 0xC && std::is_pod<ArchiveEntryHeader>::value, "ArchiveEntryHeader definition!"); static_assert(sizeof(ArchiveEntryHeader) == 0xC && util::is_pod<ArchiveEntryHeader>::value, "ArchiveEntryHeader definition!");
} }

View file

@ -160,7 +160,7 @@ namespace ams::mem::impl::heap {
template<typename T> template<typename T>
static ALWAYS_INLINE T *AlignUpPage(T *ptr) { static ALWAYS_INLINE T *AlignUpPage(T *ptr) {
static_assert(std::is_pod<T>::value); static_assert(util::is_pod<T>::value);
static_assert(util::IsAligned(PageSize, alignof(T))); static_assert(util::IsAligned(PageSize, alignof(T)));
return reinterpret_cast<T *>(AlignUpPage(reinterpret_cast<uintptr_t>(ptr))); return reinterpret_cast<T *>(AlignUpPage(reinterpret_cast<uintptr_t>(ptr)));
} }
@ -171,7 +171,7 @@ namespace ams::mem::impl::heap {
template<typename T> template<typename T>
static ALWAYS_INLINE T *AlignDownPage(T *ptr) { static ALWAYS_INLINE T *AlignDownPage(T *ptr) {
static_assert(std::is_pod<T>::value); static_assert(util::is_pod<T>::value);
static_assert(util::IsAligned(PageSize, alignof(T))); static_assert(util::IsAligned(PageSize, alignof(T)));
return reinterpret_cast<T *>(AlignDownPage(reinterpret_cast<uintptr_t>(ptr))); return reinterpret_cast<T *>(AlignDownPage(reinterpret_cast<uintptr_t>(ptr)));
} }
@ -182,7 +182,7 @@ namespace ams::mem::impl::heap {
template<typename T> template<typename T>
static ALWAYS_INLINE T *AlignUpPhysicalPage(T *ptr) { static ALWAYS_INLINE T *AlignUpPhysicalPage(T *ptr) {
static_assert(std::is_pod<T>::value); static_assert(util::is_pod<T>::value);
static_assert(util::IsAligned(PhysicalPageSize, alignof(T))); static_assert(util::IsAligned(PhysicalPageSize, alignof(T)));
return reinterpret_cast<T *>(AlignUpPhysicalPage(reinterpret_cast<uintptr_t>(ptr))); return reinterpret_cast<T *>(AlignUpPhysicalPage(reinterpret_cast<uintptr_t>(ptr)));
} }
@ -193,7 +193,7 @@ namespace ams::mem::impl::heap {
template<typename T> template<typename T>
static ALWAYS_INLINE T *AlignDownPhysicalPage(T *ptr) { static ALWAYS_INLINE T *AlignDownPhysicalPage(T *ptr) {
static_assert(std::is_pod<T>::value); static_assert(util::is_pod<T>::value);
static_assert(util::IsAligned(PhysicalPageSize, alignof(T))); static_assert(util::IsAligned(PhysicalPageSize, alignof(T)));
return reinterpret_cast<T *>(AlignDownPhysicalPage(reinterpret_cast<uintptr_t>(ptr))); return reinterpret_cast<T *>(AlignDownPhysicalPage(reinterpret_cast<uintptr_t>(ptr)));
} }

View file

@ -27,7 +27,7 @@ namespace ams::pgl::srv {
os::ProcessId process_id; os::ProcessId process_id;
u32 flags; u32 flags;
}; };
static_assert(std::is_pod<ProcessData>::value); static_assert(util::is_pod<ProcessData>::value);
enum ProcessDataFlag : u32 { enum ProcessDataFlag : u32 {
ProcessDataFlag_None = 0, ProcessDataFlag_None = 0,

View file

@ -70,7 +70,10 @@ static char* find_chars_or_comment(const char* s, const char* chars)
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */ /* Version of strncpy that ensures dest (size bytes) is null-terminated. */
static char* strncpy0(char* dest, const char* src, size_t size) static char* strncpy0(char* dest, const char* src, size_t size)
{ {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
strncpy(dest, src, size - 1); strncpy(dest, src, size - 1);
#pragma GCC diagnostic pop
dest[size - 1] = '\0'; dest[size - 1] = '\0';
return dest; return dest;
} }

View file

@ -35,9 +35,6 @@
#define CONST_FOLD(x) (__builtin_constant_p(x) ? (x) : (x)) #define CONST_FOLD(x) (__builtin_constant_p(x) ? (x) : (x))
#define WRAP_TEMPLATE_CONSTANT(...) ([] { using U = union { static constexpr auto GetValue() { return __VA_ARGS__; } }; return U{}; }())
#define UNWRAP_TEMPLATE_CONSTANT(tpnm) (tpnm::GetValue())
#define CONCATENATE_IMPL(s1, s2) s1##s2 #define CONCATENATE_IMPL(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2) #define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)

View file

@ -261,12 +261,11 @@ namespace ams::svc::codegen::impl {
/* TODO */ /* TODO */
}; };
template<typename CodeGenerator, typename MetaCodeHolder> template<typename CodeGenerator, auto MetaCode>
static ALWAYS_INLINE void GenerateCodeForMetaCode(MetaCodeHolder) { static ALWAYS_INLINE void GenerateCodeForMetaCode() {
constexpr auto MetaCode = UNWRAP_TEMPLATE_CONSTANT(MetaCodeHolder);
constexpr size_t NumOperations = MetaCode.GetNumOperations(); constexpr size_t NumOperations = MetaCode.GetNumOperations();
static_assert(NumOperations <= 64); static_assert(NumOperations <= 64);
#define SVC_CODEGEN_HANDLER(n) do { if constexpr (n < NumOperations) { constexpr auto Operation = MetaCode.GetOperation(n); GenerateCodeForOperation<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(Operation)); } } while (0) #define SVC_CODEGEN_HANDLER(n) do { if constexpr (n < NumOperations) { constexpr auto Operation = MetaCode.GetOperation(n); GenerateCodeForOperation<CodeGenerator, Operation>(); } } while (0)
SVC_CODEGEN_FOR_I_FROM_0_TO_64(SVC_CODEGEN_HANDLER) SVC_CODEGEN_FOR_I_FROM_0_TO_64(SVC_CODEGEN_HANDLER)
#undef SVC_CODEGEN_HANDLER #undef SVC_CODEGEN_HANDLER
} }

View file

@ -143,7 +143,7 @@ namespace ams::svc::codegen::impl {
template<size_t N> template<size_t N>
class RegisterAllocator { class RegisterAllocator {
private: public:
std::array<bool, N> map; std::array<bool, N> map;
public: public:
constexpr explicit RegisterAllocator() : map() { /* ... */ } constexpr explicit RegisterAllocator() : map() { /* ... */ }

View file

@ -319,38 +319,43 @@ namespace ams::svc::codegen::impl {
template<typename... T> template<typename... T>
struct TypeIndexFilter { struct TypeIndexFilter {
template<typename UseArrayHolder, typename HeadType, typename... TailType, size_t HeadIndex, size_t... TailIndex>
static constexpr auto GetFilteredTupleImpl(UseArrayHolder, std::tuple<HeadType, TailType...>, std::index_sequence<HeadIndex, TailIndex...>) {
constexpr auto UseArray = UNWRAP_TEMPLATE_CONSTANT(UseArrayHolder);
static_assert(sizeof...(TailType) == sizeof...(TailIndex));
static_assert(HeadIndex <= UseArray.size());
if constexpr (sizeof...(TailType) == 0) { template<auto UseArray, typename X, typename Y>
if constexpr (!UseArray[HeadIndex]) { struct Helper;
return std::tuple<HeadType>{};
} else {
return std::tuple<>{};
}
} else {
auto tail_tuple = GetFilteredTupleImpl(UseArrayHolder{}, std::tuple<TailType...>{}, std::index_sequence<TailIndex...>{});
if constexpr (!UseArray[HeadIndex]) {
return std::tuple_cat(std::tuple<HeadType>{}, tail_tuple);
} else {
return std::tuple_cat(std::tuple<>{}, tail_tuple);
}
}
}
template<typename UseArrayHolder> template<auto UseArray, size_t...Index>
static constexpr auto GetFilteredTuple(UseArrayHolder) { struct Helper<UseArray, std::tuple<>, std::index_sequence<Index...>> {
return GetFilteredTupleImpl(UseArrayHolder{}, std::tuple<T...>{}, std::make_index_sequence<sizeof...(T)>()); using Type = std::tuple<>;
} };
template<auto UseArray, typename HeadType, typename... TailType, size_t HeadIndex, size_t... TailIndex>
struct Helper<UseArray, std::tuple<HeadType, TailType...>, std::index_sequence<HeadIndex, TailIndex...>> {
using LastHeadType = std::tuple<HeadType>;
using LastNullType = std::tuple<>;
using LastType = typename std::conditional<!UseArray[HeadIndex], LastHeadType, LastNullType>::type;
using NextTailType = std::tuple<TailType...>;
using NextTailSequence = std::index_sequence<TailIndex...>;
using NextType = typename std::conditional<!UseArray[HeadIndex],
decltype(std::tuple_cat(std::declval<LastHeadType>(), std::declval<typename Helper<UseArray, NextTailType, NextTailSequence>::Type>())),
decltype(std::tuple_cat(std::declval<LastNullType>(), std::declval<typename Helper<UseArray, NextTailType, NextTailSequence>::Type>()))
>::type;
using Type = typename std::conditional<sizeof...(TailType) == 0, LastType, NextType>::type;
};
template<auto UseArray>
using FilteredTupleType = typename Helper<UseArray, std::tuple<T...>, decltype(std::make_index_sequence<sizeof...(T)>())>::Type;
}; };
template<typename AllocatorHolder, typename FirstOperation, typename...OtherOperations> template<auto Allocator, typename FirstOperation, typename...OtherOperations>
static constexpr auto GetModifiedOperations(AllocatorHolder, std::tuple<FirstOperation, OtherOperations...> ops) { static constexpr auto GetModifiedOperations(std::tuple<FirstOperation, OtherOperations...> ops) {
constexpr size_t ModifyRegister = [] { constexpr size_t ModifyRegister = [] {
auto allocator = UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder); auto allocator = Allocator;
return allocator.AllocateFirstFree(); return allocator.AllocateFirstFree();
}(); }();
@ -359,13 +364,13 @@ namespace ams::svc::codegen::impl {
return std::tuple<ModifiedFirstOperation, OtherOperations..., NewMoveOperation>{}; return std::tuple<ModifiedFirstOperation, OtherOperations..., NewMoveOperation>{};
} }
template<typename Conversion, typename AllocatorHolder, typename FirstOperation, typename... OtherOperations> template<typename Conversion, auto Allocator, typename FirstOperation, typename... OtherOperations>
static constexpr auto GenerateBeforeOperations(MetaCodeGenerator &mcg, AllocatorHolder, std::tuple<FirstOperation, OtherOperations...> ops) -> RegisterAllocator<UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder).GetRegisterCount()> { static constexpr auto GenerateBeforeOperations(MetaCodeGenerator &mcg, std::tuple<FirstOperation, OtherOperations...> ops) -> RegisterAllocator<Allocator.GetRegisterCount()> {
constexpr size_t NumOperations = 1 + sizeof...(OtherOperations); constexpr size_t NumOperations = 1 + sizeof...(OtherOperations);
using OperationsTuple = decltype(ops); using OperationsTuple = decltype(ops);
using FilterHelper = TypeIndexFilter<FirstOperation, OtherOperations...>; using FilterHelper = TypeIndexFilter<FirstOperation, OtherOperations...>;
constexpr auto ProcessOperation = []<typename Operation>(MetaCodeGenerator &pr_mcg, auto &allocator, Operation) { constexpr auto ProcessOperation = []<typename Operation>(MetaCodeGenerator &pr_mcg, auto &allocator) {
if (Conversion::template CanGenerateCode<Operation, CodeGenerationKind::SvcInvocationToKernelProcedure>(allocator)) { if (Conversion::template CanGenerateCode<Operation, CodeGenerationKind::SvcInvocationToKernelProcedure>(allocator)) {
Conversion::template GenerateCode<Operation, CodeGenerationKind::SvcInvocationToKernelProcedure>(pr_mcg, allocator); Conversion::template GenerateCode<Operation, CodeGenerationKind::SvcInvocationToKernelProcedure>(pr_mcg, allocator);
return true; return true;
@ -373,12 +378,12 @@ namespace ams::svc::codegen::impl {
return false; return false;
}; };
constexpr auto ProcessResults = [ProcessOperation]<typename... Operations>(std::tuple<Operations...>) { constexpr auto ProcessResults = []<auto AllocatorVal, auto ProcessOp, typename... Operations>(std::tuple<Operations...>) {
auto allocator = UNWRAP_TEMPLATE_CONSTANT(AllocatorHolder); auto allocator = AllocatorVal;
MetaCodeGenerator pr_mcg; MetaCodeGenerator pr_mcg;
auto use_array = std::array<bool, NumOperations>{ ProcessOperation(pr_mcg, allocator, Operations{})... }; auto use_array = std::array<bool, NumOperations>{ ProcessOp.template operator()<Operations>(pr_mcg, allocator)... };
return std::make_tuple(use_array, allocator, pr_mcg); return std::make_tuple(use_array, allocator, pr_mcg);
}(OperationsTuple{}); }.template operator()<Allocator, ProcessOperation>(OperationsTuple{});
constexpr auto CanGenerate = std::get<0>(ProcessResults); constexpr auto CanGenerate = std::get<0>(ProcessResults);
constexpr auto AfterAllocator = std::get<1>(ProcessResults); constexpr auto AfterAllocator = std::get<1>(ProcessResults);
@ -388,15 +393,15 @@ namespace ams::svc::codegen::impl {
mcg.AddOperationDirectly(GeneratedCode.GetOperation(i)); mcg.AddOperationDirectly(GeneratedCode.GetOperation(i));
} }
constexpr auto FilteredOperations = FilterHelper::template GetFilteredTuple(WRAP_TEMPLATE_CONSTANT(CanGenerate)); using FilteredOperations = typename FilterHelper::FilteredTupleType<CanGenerate>;
static_assert(std::tuple_size<decltype(FilteredOperations)>::value <= NumOperations); static_assert(std::tuple_size<FilteredOperations>::value <= NumOperations);
if constexpr (std::tuple_size<decltype(FilteredOperations)>::value > 0) { if constexpr (std::tuple_size<FilteredOperations>::value > 0) {
if constexpr (std::tuple_size<decltype(FilteredOperations)>::value != NumOperations) { if constexpr (std::tuple_size<FilteredOperations>::value != NumOperations) {
return GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(AfterAllocator), FilteredOperations); return GenerateBeforeOperations<Conversion, AfterAllocator>(mcg, FilteredOperations{});
} else { } else {
/* No progress was made, so we need to make a change. */ /* No progress was made, so we need to make a change. */
constexpr auto ModifiedOperations = GetModifiedOperations(WRAP_TEMPLATE_CONSTANT(AfterAllocator), FilteredOperations); constexpr auto ModifiedOperations = GetModifiedOperations<AfterAllocator>(FilteredOperations{});
return GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(AfterAllocator), ModifiedOperations); return GenerateBeforeOperations<Conversion, AfterAllocator>(mcg, ModifiedOperations);
} }
} else { } else {
return AfterAllocator; return AfterAllocator;
@ -433,7 +438,7 @@ namespace ams::svc::codegen::impl {
/* Generate code for before operations. */ /* Generate code for before operations. */
if constexpr (Conversion::NumBeforeOperations > 0) { if constexpr (Conversion::NumBeforeOperations > 0) {
allocator = GenerateBeforeOperations<Conversion>(mcg, WRAP_TEMPLATE_CONSTANT(InitialAllocator), typename Conversion::BeforeOperations{}); allocator = GenerateBeforeOperations<Conversion, InitialAllocator>(mcg, typename Conversion::BeforeOperations{});
} else { } else {
allocator = InitialAllocator; allocator = InitialAllocator;
} }
@ -527,8 +532,8 @@ namespace ams::svc::codegen::impl {
static ALWAYS_INLINE void WrapSvcFunction() { static ALWAYS_INLINE void WrapSvcFunction() {
/* Generate appropriate assembly. */ /* Generate appropriate assembly. */
GenerateCodeForMetaCode<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(BeforeMetaCode)); GenerateCodeForMetaCode<CodeGenerator, BeforeMetaCode>();
ON_SCOPE_EXIT { GenerateCodeForMetaCode<CodeGenerator>(WRAP_TEMPLATE_CONSTANT(AfterMetaCode)); }; ON_SCOPE_EXIT { GenerateCodeForMetaCode<CodeGenerator, AfterMetaCode>(); };
return reinterpret_cast<void (*)()>(Function)(); return reinterpret_cast<void (*)()>(Function)();
} }

View file

@ -24,7 +24,7 @@ namespace ams::svc::codegen::impl {
static constexpr size_t MaxParameters = 8; static constexpr size_t MaxParameters = 8;
private: private:
static constexpr size_t InvalidIndex = std::numeric_limits<size_t>::max(); static constexpr size_t InvalidIndex = std::numeric_limits<size_t>::max();
private: public:
/* ABI parameters. */ /* ABI parameters. */
Abi abi; Abi abi;
@ -102,7 +102,7 @@ namespace ams::svc::codegen::impl {
}; };
class ProcedureLayout { class ProcedureLayout {
private: public:
Abi abi; Abi abi;
ParameterLayout input; ParameterLayout input;
ParameterLayout output; ParameterLayout output;
@ -205,7 +205,7 @@ namespace ams::svc::codegen::impl {
}; };
class SvcInvocationLayout { class SvcInvocationLayout {
private: public:
Abi abi; Abi abi;
ParameterLayout input; ParameterLayout input;
ParameterLayout output; ParameterLayout output;

View file

@ -304,9 +304,8 @@ namespace ams::svc::codegen::impl {
static constexpr auto DetermineConversionOperations() { static constexpr auto DetermineConversionOperations() {
[[maybe_unused]] constexpr auto Procedure = LayoutForKernel; [[maybe_unused]] constexpr auto Procedure = LayoutForKernel;
[[maybe_unused]] constexpr ParameterLayout Svc = Input ? LayoutForSvc.GetInputLayout() : LayoutForSvc.GetOutputLayout(); [[maybe_unused]] constexpr ParameterLayout Svc = Input ? LayoutForSvc.GetInputLayout() : LayoutForSvc.GetOutputLayout();
[[maybe_unused]] constexpr std::array<size_t, Svc.GetNumParameters()> ParameterMap = []<typename SvcHolder>(SvcHolder){ [[maybe_unused]] constexpr std::array<size_t, Svc.GetNumParameters()> ParameterMap = []<auto CapturedSvc>(){
/* We want to iterate over the parameters in sorted order. */ /* We want to iterate over the parameters in sorted order. */
constexpr ParameterLayout CapturedSvc = UNWRAP_TEMPLATE_CONSTANT(SvcHolder);
std::array<size_t, CapturedSvc.GetNumParameters()> map{}; std::array<size_t, CapturedSvc.GetNumParameters()> map{};
const size_t num_parameters = CapturedSvc.GetNumParameters(); const size_t num_parameters = CapturedSvc.GetNumParameters();
for (size_t i = 0; i < num_parameters; i++) { for (size_t i = 0; i < num_parameters; i++) {
@ -322,7 +321,7 @@ namespace ams::svc::codegen::impl {
} }
} }
return map; return map;
}(WRAP_TEMPLATE_CONSTANT(Svc)); }.template operator()<Svc>();
if constexpr (ParameterIndex >= Svc.GetNumParameters()) { if constexpr (ParameterIndex >= Svc.GetNumParameters()) {
/* Base case: we're done. */ /* Base case: we're done. */
@ -378,15 +377,13 @@ namespace ams::svc::codegen::impl {
constexpr size_t PassedSize = ProcedureParam.GetTypeSize(); constexpr size_t PassedSize = ProcedureParam.GetTypeSize();
/* TODO: C++20 templated lambdas. For now, use GCC extension syntax. */ /* TODO: C++20 templated lambdas. For now, use GCC extension syntax. */
constexpr auto SvcIndexSequence = []<typename SvcParamWrapper, size_t... Is>(SvcParamWrapper, std::index_sequence<Is...>) { constexpr auto SvcIndexSequence = []<auto CapturedSvcParam, size_t... Is>(std::index_sequence<Is...>) {
constexpr Parameter CapturedSvcParam = UNWRAP_TEMPLATE_CONSTANT(SvcParamWrapper);
return std::index_sequence<CapturedSvcParam.GetLocation(Is).GetIndex()...>{}; return std::index_sequence<CapturedSvcParam.GetLocation(Is).GetIndex()...>{};
}(WRAP_TEMPLATE_CONSTANT(SvcParam), std::make_index_sequence<SvcParam.GetNumLocations()>()); }.template operator()<SvcParam>(std::make_index_sequence<SvcParam.GetNumLocations()>());
constexpr auto OperationValue = []<typename ProcedureLocWrapper, size_t... Is>(ProcedureLocWrapper, std::index_sequence<Is...>) { constexpr auto OperationValue = []<auto CapturedProcedureLoc, size_t... Is>(std::index_sequence<Is...>) {
constexpr Location CapturedProcedureLoc = UNWRAP_TEMPLATE_CONSTANT(ProcedureLocWrapper);
return LayoutConversionBase::OperationScatter<RegisterSize, PassedSize, StackIndex * KernelAbiType::RegisterSize, CapturedProcedureLoc.GetIndex(), Is...>{}; return LayoutConversionBase::OperationScatter<RegisterSize, PassedSize, StackIndex * KernelAbiType::RegisterSize, CapturedProcedureLoc.GetIndex(), Is...>{};
}(WRAP_TEMPLATE_CONSTANT(ProcedureLoc), SvcIndexSequence); }.template operator()<ProcedureLoc>(SvcIndexSequence);
constexpr auto cur_op = std::make_tuple(OperationValue); constexpr auto cur_op = std::make_tuple(OperationValue);

View file

@ -79,7 +79,7 @@ namespace ams::svc::codegen::impl {
return op; return op;
} }
private: public:
size_t num_operations; size_t num_operations;
std::array<Operation, MaxOperations> operations; std::array<Operation, MaxOperations> operations;
public: public:
@ -98,15 +98,13 @@ namespace ams::svc::codegen::impl {
} }
}; };
template<typename _OperationHolder> template<auto Operation>
static constexpr auto GetOperationParameterSequence() { static constexpr auto GetOperationParameterSequence() {
constexpr auto _Operation = UNWRAP_TEMPLATE_CONSTANT(_OperationHolder); constexpr size_t NumParameters = Operation.num_parameters;
constexpr size_t NumParameters = _Operation.num_parameters;
return []<typename OperationHolder, size_t... Is>(OperationHolder, std::index_sequence<Is...>) { return []<size_t... Is>(std::index_sequence<Is...>) {
constexpr auto Operation = UNWRAP_TEMPLATE_CONSTANT(OperationHolder);
return std::index_sequence<Operation.parameters[Is]...>{}; return std::index_sequence<Operation.parameters[Is]...>{};
}(_OperationHolder{}, std::make_index_sequence<NumParameters>()); }(std::make_index_sequence<NumParameters>());
} }
template<typename CodeGenerator, MetaCode::OperationKind Kind, size_t... Parameters> template<typename CodeGenerator, MetaCode::OperationKind Kind, size_t... Parameters>
@ -130,10 +128,9 @@ namespace ams::svc::codegen::impl {
#undef META_CODE_OPERATION_KIND_GENERATE_CODE #undef META_CODE_OPERATION_KIND_GENERATE_CODE
} }
template<typename CodeGenerator, typename OperationHolder> template<typename CodeGenerator, auto Operation>
static ALWAYS_INLINE void GenerateCodeForOperation(OperationHolder) { static ALWAYS_INLINE void GenerateCodeForOperation() {
constexpr auto Operation = UNWRAP_TEMPLATE_CONSTANT(OperationHolder); GenerateCodeForOperationImpl<CodeGenerator, Operation.kind>(GetOperationParameterSequence<Operation>());
GenerateCodeForOperationImpl<CodeGenerator, Operation.kind>(GetOperationParameterSequence<OperationHolder>());
} }
class MetaCodeGenerator { class MetaCodeGenerator {

View file

@ -27,7 +27,7 @@ namespace ams::svc::codegen::impl {
class Location { class Location {
private: private:
static constexpr size_t InvalidIndex = std::numeric_limits<size_t>::max(); static constexpr size_t InvalidIndex = std::numeric_limits<size_t>::max();
private: public:
Storage storage; Storage storage;
size_t index; size_t index;
public: public:
@ -75,7 +75,7 @@ namespace ams::svc::codegen::impl {
static constexpr size_t MaxLocations = 8; static constexpr size_t MaxLocations = 8;
static constexpr size_t IdentifierLengthMax = 0x40; static constexpr size_t IdentifierLengthMax = 0x40;
class Identifier { class Identifier {
private: public:
char name[IdentifierLengthMax]; char name[IdentifierLengthMax];
size_t index; size_t index;
public: public:
@ -99,7 +99,7 @@ namespace ams::svc::codegen::impl {
return !(*this == rhs); return !(*this == rhs);
} }
}; };
private: public:
Identifier identifier; Identifier identifier;
ArgumentType type; ArgumentType type;
size_t type_size; size_t type_size;

View file

@ -58,11 +58,11 @@ namespace ams::svc::ipc {
private: private:
util::BitPack32 header[2]; util::BitPack32 header[2];
public: public:
constexpr ALWAYS_INLINE MessageHeader() : header({util::BitPack32{0}, util::BitPack32{0}}) { constexpr ALWAYS_INLINE MessageHeader() : header{util::BitPack32{0}, util::BitPack32{0}} {
this->header[0].Set<Tag>(NullTag); this->header[0].Set<Tag>(NullTag);
} }
constexpr ALWAYS_INLINE MessageHeader(u16 tag, bool special, s32 ptr, s32 send, s32 recv, s32 exch, s32 raw, s32 recv_list) : header({util::BitPack32{0}, util::BitPack32{0}}) { constexpr ALWAYS_INLINE MessageHeader(u16 tag, bool special, s32 ptr, s32 send, s32 recv, s32 exch, s32 raw, s32 recv_list) : header{util::BitPack32{0}, util::BitPack32{0}} {
this->header[0].Set<Tag>(tag); this->header[0].Set<Tag>(tag);
this->header[0].Set<PointerCount>(ptr); this->header[0].Set<PointerCount>(ptr);
this->header[0].Set<SendCount>(send); this->header[0].Set<SendCount>(send);
@ -74,11 +74,11 @@ namespace ams::svc::ipc {
this->header[1].Set<HasSpecialHeader>(special); this->header[1].Set<HasSpecialHeader>(special);
} }
ALWAYS_INLINE explicit MessageHeader(const MessageBuffer &buf) : header({util::BitPack32{0}, util::BitPack32{0}}) { ALWAYS_INLINE explicit MessageHeader(const MessageBuffer &buf) : header{util::BitPack32{0}, util::BitPack32{0}} {
buf.Get(0, this->header, util::size(this->header)); buf.Get(0, this->header, util::size(this->header));
} }
ALWAYS_INLINE explicit MessageHeader(const u32 *msg) : header({util::BitPack32{msg[0]}, util::BitPack32{msg[1]}}) { /* ... */ } ALWAYS_INLINE explicit MessageHeader(const u32 *msg) : header{util::BitPack32{msg[0]}, util::BitPack32{msg[1]}} { /* ... */ }
constexpr ALWAYS_INLINE u16 GetTag() const { constexpr ALWAYS_INLINE u16 GetTag() const {
return this->header[0].Get<Tag>(); return this->header[0].Get<Tag>();
@ -219,9 +219,9 @@ namespace ams::svc::ipc {
private: private:
util::BitPack32 data[3]; util::BitPack32 data[3];
public: public:
constexpr ALWAYS_INLINE MapAliasDescriptor() : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ } constexpr ALWAYS_INLINE MapAliasDescriptor() : data{util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}} { /* ... */ }
ALWAYS_INLINE MapAliasDescriptor(const void *buffer, size_t _size, Attribute attr = Attribute_Ipc) : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) { ALWAYS_INLINE MapAliasDescriptor(const void *buffer, size_t _size, Attribute attr = Attribute_Ipc) : data{util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}} {
const u64 address = reinterpret_cast<u64>(buffer); const u64 address = reinterpret_cast<u64>(buffer);
const u64 size = static_cast<u64>(_size); const u64 size = static_cast<u64>(_size);
this->data[0] = { static_cast<u32>(size) }; this->data[0] = { static_cast<u32>(size) };
@ -233,7 +233,7 @@ namespace ams::svc::ipc {
this->data[2].Set<AddressHigh>(GetAddressHigh(address)); this->data[2].Set<AddressHigh>(GetAddressHigh(address));
} }
ALWAYS_INLINE MapAliasDescriptor(const MessageBuffer &buf, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}}) { ALWAYS_INLINE MapAliasDescriptor(const MessageBuffer &buf, s32 index) : data{util::BitPack32{0}, util::BitPack32{0}, util::BitPack32{0}} {
buf.Get(index, this->data, util::size(this->data)); buf.Get(index, this->data, util::size(this->data));
} }
@ -283,9 +283,9 @@ namespace ams::svc::ipc {
private: private:
util::BitPack32 data[2]; util::BitPack32 data[2];
public: public:
constexpr ALWAYS_INLINE PointerDescriptor() : data({util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ } constexpr ALWAYS_INLINE PointerDescriptor() : data{util::BitPack32{0}, util::BitPack32{0}} { /* ... */ }
ALWAYS_INLINE PointerDescriptor(const void *buffer, size_t size, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}}) { ALWAYS_INLINE PointerDescriptor(const void *buffer, size_t size, s32 index) : data{util::BitPack32{0}, util::BitPack32{0}} {
const u64 address = reinterpret_cast<u64>(buffer); const u64 address = reinterpret_cast<u64>(buffer);
this->data[0].Set<Index>(index); this->data[0].Set<Index>(index);
@ -296,7 +296,7 @@ namespace ams::svc::ipc {
this->data[1] = { static_cast<u32>(address) }; this->data[1] = { static_cast<u32>(address) };
} }
ALWAYS_INLINE PointerDescriptor(const MessageBuffer &buf, s32 index) : data({util::BitPack32{0}, util::BitPack32{0}}) { ALWAYS_INLINE PointerDescriptor(const MessageBuffer &buf, s32 index) : data{util::BitPack32{0}, util::BitPack32{0}} {
buf.Get(index, this->data, util::size(this->data)); buf.Get(index, this->data, util::size(this->data));
} }
@ -338,9 +338,9 @@ namespace ams::svc::ipc {
private: private:
util::BitPack32 data[2]; util::BitPack32 data[2];
public: public:
constexpr ALWAYS_INLINE ReceiveListEntry() : data({util::BitPack32{0}, util::BitPack32{0}}) { /* ... */ } constexpr ALWAYS_INLINE ReceiveListEntry() : data{util::BitPack32{0}, util::BitPack32{0}} { /* ... */ }
ALWAYS_INLINE ReceiveListEntry(const void *buffer, size_t size) : data({util::BitPack32{0}, util::BitPack32{0}}) { ALWAYS_INLINE ReceiveListEntry(const void *buffer, size_t size) : data{util::BitPack32{0}, util::BitPack32{0}} {
const u64 address = reinterpret_cast<u64>(buffer); const u64 address = reinterpret_cast<u64>(buffer);
this->data[0] = { static_cast<u32>(address) }; this->data[0] = { static_cast<u32>(address) };
@ -349,7 +349,7 @@ namespace ams::svc::ipc {
this->data[1].Set<Size>(size); this->data[1].Set<Size>(size);
} }
ALWAYS_INLINE ReceiveListEntry(u32 a, u32 b) : data({util::BitPack32{a}, util::BitPack32{b}}) { /* ... */ } ALWAYS_INLINE ReceiveListEntry(u32 a, u32 b) : data{util::BitPack32{a}, util::BitPack32{b}} { /* ... */ }
constexpr ALWAYS_INLINE uintptr_t GetAddress() { constexpr ALWAYS_INLINE uintptr_t GetAddress() {
const u64 address = (static_cast<u64>(this->data[1].Get<AddressHigh>()) << AddressLow::Count) | this->data[0].Get<AddressLow>(); const u64 address = (static_cast<u64>(this->data[1].Get<AddressHigh>()) << AddressLow::Count) | this->data[0].Get<AddressLow>();

View file

@ -18,6 +18,7 @@
#include <vapours/common.hpp> #include <vapours/common.hpp>
#include <vapours/assert.hpp> #include <vapours/assert.hpp>
#include <vapours/util/util_type_traits.hpp>
#include <vapours/util/util_alignment.hpp> #include <vapours/util/util_alignment.hpp>
#include <vapours/util/util_size.hpp> #include <vapours/util/util_size.hpp>
#include <vapours/util/util_endian.hpp> #include <vapours/util/util_endian.hpp>

View file

@ -50,7 +50,7 @@ namespace ams::util {
static constexpr size_t Next = Index + Count; static constexpr size_t Next = Index + Count;
using BitPackType = BitPack<IntegralStorageType>; using BitPackType = BitPack<IntegralStorageType>;
static_assert(std::is_pod<BitPackType>::value); static_assert(util::is_pod<BitPackType>::value);
static_assert(Mask<Index, Count> != 0); static_assert(Mask<Index, Count> != 0);
static_assert(std::is_integral<T>::value || std::is_enum<T>::value); static_assert(std::is_integral<T>::value || std::is_enum<T>::value);
@ -84,10 +84,10 @@ namespace ams::util {
using BitPack32 = impl::BitPack<u32>; using BitPack32 = impl::BitPack<u32>;
using BitPack64 = impl::BitPack<u64>; using BitPack64 = impl::BitPack<u64>;
static_assert(std::is_pod<BitPack8>::value); static_assert(util::is_pod<BitPack8>::value);
static_assert(std::is_pod<BitPack16>::value); static_assert(util::is_pod<BitPack16>::value);
static_assert(std::is_pod<BitPack32>::value); static_assert(util::is_pod<BitPack32>::value);
static_assert(std::is_pod<BitPack64>::value); static_assert(util::is_pod<BitPack64>::value);
static_assert(std::is_trivially_destructible<BitPack8 >::value); static_assert(std::is_trivially_destructible<BitPack8 >::value);
static_assert(std::is_trivially_destructible<BitPack16>::value); static_assert(std::is_trivially_destructible<BitPack16>::value);
static_assert(std::is_trivially_destructible<BitPack32>::value); static_assert(std::is_trivially_destructible<BitPack32>::value);

View file

@ -0,0 +1,26 @@
/*
* 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/common.hpp>
#include <vapours/assert.hpp>
namespace ams::util {
template<typename T>
using is_pod = std::bool_constant<std::is_standard_layout<T>::value && std::is_trivial<T>::value>;
}

View file

@ -40,7 +40,7 @@ namespace ams::mitm::fs {
s64 file_table_size; s64 file_table_size;
s64 file_partition_ofs; s64 file_partition_ofs;
}; };
static_assert(std::is_pod<Header>::value && sizeof(Header) == 0x50); static_assert(util::is_pod<Header>::value && sizeof(Header) == 0x50);
struct DirectoryEntry { struct DirectoryEntry {
u32 parent; u32 parent;
@ -51,7 +51,7 @@ namespace ams::mitm::fs {
u32 name_size; u32 name_size;
char name[]; char name[];
}; };
static_assert(std::is_pod<DirectoryEntry>::value && sizeof(DirectoryEntry) == 0x18); static_assert(util::is_pod<DirectoryEntry>::value && sizeof(DirectoryEntry) == 0x18);
struct FileEntry { struct FileEntry {
u32 parent; u32 parent;
@ -62,7 +62,7 @@ namespace ams::mitm::fs {
u32 name_size; u32 name_size;
char name[]; char name[];
}; };
static_assert(std::is_pod<FileEntry>::value && sizeof(FileEntry) == 0x20); static_assert(util::is_pod<FileEntry>::value && sizeof(FileEntry) == 0x20);
template<typename Entry> template<typename Entry>
class TableReader { class TableReader {

View file

@ -42,7 +42,7 @@ namespace ams::settings::fwdbg {
} }
}; };
static_assert(std::is_pod<SdKeyValueStoreEntry>::value); static_assert(util::is_pod<SdKeyValueStoreEntry>::value);
constexpr inline bool operator==(const SdKeyValueStoreEntry &lhs, const SdKeyValueStoreEntry &rhs) { constexpr inline bool operator==(const SdKeyValueStoreEntry &lhs, const SdKeyValueStoreEntry &rhs) {
if (lhs.HasValue() != rhs.HasValue()) { if (lhs.HasValue() != rhs.HasValue()) {

View file

@ -102,5 +102,7 @@ int main(int argc, char **argv)
/* Launch all programs off of SYSTEM/the SD. */ /* Launch all programs off of SYSTEM/the SD. */
boot2::LaunchPostSdCardBootPrograms(); boot2::LaunchPostSdCardBootPrograms();
return 0;
} }

View file

@ -351,7 +351,7 @@ namespace ams::creport {
} }
void CrashReport::SaveToFile(ScopedFile &file) { void CrashReport::SaveToFile(ScopedFile &file) {
file.WriteFormat(u8"Atmosphère Crash Report (v1.5):\n"); file.WriteFormat("Atmosphère Crash Report (v1.5):\n");
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", this->result.GetValue(), this->result.GetModule(), this->result.GetDescription()); file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", this->result.GetValue(), this->result.GetModule(), this->result.GetDescription());
/* Process Info. */ /* Process Info. */

View file

@ -141,7 +141,7 @@ namespace ams::dmnt::cheat::impl {
} }
/* Clear metadata. */ /* Clear metadata. */
static_assert(std::is_pod<decltype(this->cheat_process_metadata)>::value, "CheatProcessMetadata definition!"); static_assert(util::is_pod<decltype(this->cheat_process_metadata)>::value, "CheatProcessMetadata definition!");
std::memset(&this->cheat_process_metadata, 0, sizeof(this->cheat_process_metadata)); std::memset(&this->cheat_process_metadata, 0, sizeof(this->cheat_process_metadata));
/* Clear cheat list. */ /* Clear cheat list. */

View file

@ -55,7 +55,7 @@ namespace ams::dmnt {
} }
}; };
static_assert(std::is_pod<TargetIOFileHandle>::value && sizeof(TargetIOFileHandle) == sizeof(u64), "TargetIOFileHandle"); static_assert(util::is_pod<TargetIOFileHandle>::value && sizeof(TargetIOFileHandle) == sizeof(u64), "TargetIOFileHandle");
class DebugMonitorService final : public sf::IServiceObject { class DebugMonitorService final : public sf::IServiceObject {
private: private:

View file

@ -77,21 +77,21 @@ namespace ams::fatal::srv {
/* Setup messages. */ /* Setup messages. */
{ {
this->error_msg = u8"Error Code: 2%03d-%04d (0x%x)\n"; this->error_msg = "Error Code: 2%03d-%04d (0x%x)\n";
this->error_desc = u8"An error has occured.\n\n" this->error_desc = "An error has occured.\n\n"
u8"Please press the POWER Button to restart the console normally, or a VOL button\n" "Please press the POWER Button to restart the console normally, or a VOL button\n"
u8"to reboot to a payload (or RCM, if none is present). If you are unable to\n" "to reboot to a payload (or RCM, if none is present). If you are unable to\n"
u8"restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n" "restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n"
u8"If the problem persists, refer to the Nintendo Support Website.\n" "If the problem persists, refer to the Nintendo Support Website.\n"
u8"support.nintendo.com/switch/error\n"; "support.nintendo.com/switch/error\n";
/* If you're running Atmosphere on a quest unit for some reason, talk to me on discord. */ /* If you're running Atmosphere on a quest unit for some reason, talk to me on discord. */
this->quest_desc = u8"Please call 1-800-875-1852 for service.\n\n" this->quest_desc = "Please call 1-800-875-1852 for service.\n\n"
u8"Also, please be aware that running Atmosphere on a Quest device is not fully\n" "Also, please be aware that running Atmosphere on a Quest device is not fully\n"
u8"supported. Perhaps try booting your device without Atmosphere before calling\n" "supported. Perhaps try booting your device without Atmosphere before calling\n"
u8"an official Nintendo service hotline. If you encounter further issues, please\n" "an official Nintendo service hotline. If you encounter further issues, please\n"
u8"contact SciresM#0524 on Discord, or via some other means.\n"; "contact SciresM#0524 on Discord, or via some other means.\n";
/* TODO: Try to load dynamically? */ /* TODO: Try to load dynamically? */
/* FsStorage message_storage; */ /* FsStorage message_storage; */

View file

@ -79,13 +79,13 @@ namespace ams::fatal::srv {
std::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); ScopedFile file(file_path);
if (file.IsOpen()) { if (file.IsOpen()) {
file.WriteFormat(u8"Atmosphère Fatal Report (v1.1):\n"); file.WriteFormat("Atmosphère Fatal Report (v1.1):\n");
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", this->context->result.GetValue(), this->context->result.GetModule(), this->context->result.GetDescription()); file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", this->context->result.GetValue(), this->context->result.GetModule(), this->context->result.GetDescription());
file.WriteFormat("Program ID: %016lx\n", static_cast<u64>(this->context->program_id)); file.WriteFormat("Program ID: %016lx\n", static_cast<u64>(this->context->program_id));
if (strlen(this->context->proc_name)) { if (strlen(this->context->proc_name)) {
file.WriteFormat("Process Name: %s\n", this->context->proc_name); file.WriteFormat("Process Name: %s\n", this->context->proc_name);
} }
file.WriteFormat(u8"Firmware: %s (Atmosphère %u.%u.%u-%s)\n", GetFatalConfig().GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision()); file.WriteFormat("Firmware: %s (Atmosphère %u.%u.%u-%s)\n", GetFatalConfig().GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision());
if (this->context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32) { if (this->context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32) {
file.WriteFormat("General Purpose Registers:\n"); file.WriteFormat("General Purpose Registers:\n");

View file

@ -213,18 +213,18 @@ namespace ams::fatal::srv {
font::AddSpacingLines(0.5f); font::AddSpacingLines(0.5f);
font::PrintFormatLine( "Program: %016lX", static_cast<u64>(this->context->program_id)); font::PrintFormatLine( "Program: %016lX", static_cast<u64>(this->context->program_id));
font::AddSpacingLines(0.5f); font::AddSpacingLines(0.5f);
font::PrintFormatLine(u8"Firmware: %s (Atmosphère %u.%u.%u-%s)", config.GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision()); font::PrintFormatLine("Firmware: %s (Atmosphère %u.%u.%u-%s)", config.GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision());
font::AddSpacingLines(1.5f); font::AddSpacingLines(1.5f);
if (!exosphere::ResultVersionMismatch::Includes(this->context->result)) { if (!exosphere::ResultVersionMismatch::Includes(this->context->result)) {
font::Print(config.GetErrorDescription()); font::Print(config.GetErrorDescription());
} else { } else {
/* Print a special message for atmosphere version mismatch. */ /* Print a special message for atmosphere version mismatch. */
font::Print(u8"Atmosphère version mismatch detected.\n\n" font::Print("Atmosphère version mismatch detected.\n\n"
u8"Please press the POWER Button to restart the console normally, or a VOL button\n" "Please press the POWER Button to restart the console normally, or a VOL button\n"
u8"to reboot to a payload (or RCM, if none is present). If you are unable to\n" "to reboot to a payload (or RCM, if none is present). If you are unable to\n"
u8"restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n" "restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n"
u8"Please ensure that all Atmosphère components are updated.\n" "Please ensure that all Atmosphère components are updated.\n"
u8"github.com/Atmosphere-NX/Atmosphere/releases\n"); "github.com/Atmosphere-NX/Atmosphere/releases\n");
} }
/* Add a line. */ /* Add a line. */

View file

@ -70,7 +70,10 @@ static char* find_chars_or_comment(const char* s, const char* chars)
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */ /* Version of strncpy that ensures dest (size bytes) is null-terminated. */
static char* strncpy0(char* dest, const char* src, size_t size) static char* strncpy0(char* dest, const char* src, size_t size)
{ {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
strncpy(dest, src, size - 1); strncpy(dest, src, size - 1);
#pragma GCC diagnostic pop
dest[size - 1] = '\0'; dest[size - 1] = '\0';
return dest; return dest;
} }