diff --git a/app/src/main/cpp/skyline/common.cpp b/app/src/main/cpp/skyline/common.cpp index 46e92180..9227c1a2 100644 --- a/app/src/main/cpp/skyline/common.cpp +++ b/app/src/main/cpp/skyline/common.cpp @@ -37,7 +37,6 @@ namespace skyline { std::lock_guard guard(mtx); logFile << "0|" << str << "\n"; - logFile.flush(); } void Logger::Write(LogLevel level, std::string str) { @@ -55,7 +54,6 @@ namespace skyline { std::lock_guard guard(mtx); logFile << "1|" << levelCharacter[static_cast(level)] << '|' << threadName << '|' << str << '\n'; - logFile.flush(); } DeviceState::DeviceState(kernel::OS *os, std::shared_ptr jvmManager, std::shared_ptr settings, std::shared_ptr logger) diff --git a/app/src/main/cpp/skyline/common.h b/app/src/main/cpp/skyline/common.h index 64110138..10fb2733 100644 --- a/app/src/main/cpp/skyline/common.h +++ b/app/src/main/cpp/skyline/common.h @@ -96,7 +96,7 @@ namespace skyline { * @note There's the exception of signed char pointers as they represent C Strings * @note This does not cover std::shared_ptr or std::unique_ptr and those will have to be explicitly casted to uintptr_t or passed through fmt::ptr */ - template + template constexpr auto FmtCast(T object) { if constexpr (std::is_pointer::value) if constexpr (std::is_same::type>::type>::value) @@ -147,12 +147,12 @@ namespace skyline { /** * @brief A way to implicitly convert a pointer to uintptr_t and leave it unaffected if it isn't a pointer */ - template + template T PointerValue(T item) { return item; } - template + template uintptr_t PointerValue(T *item) { return reinterpret_cast(item); } @@ -160,7 +160,7 @@ namespace skyline { /** * @brief A way to implicitly convert an integral to a pointer, if the return type is a pointer */ - template + template Return ValuePointer(T item) { if constexpr (std::is_pointer::value) return reinterpret_cast(item); @@ -253,7 +253,7 @@ namespace skyline { return result; } - template + template constexpr Type HexStringToInt(std::string_view string) { if (string.size() > sizeof(Type) * 2) throw exception("String size larger than type: {} (sizeof(Type): {})", string.size(), sizeof(Type)); @@ -299,7 +299,7 @@ namespace skyline { /** * @brief We want to support implicitly casting from std::string_view -> span as it is just a specialization of a data view which span is a generic form of, the opposite doesn't hold true as not all data held by a span is string data therefore the conversion isn't implicit there */ - template + template constexpr span(const std::basic_string_view &string) : std::span(const_cast(string.data()), string.size()) {} template @@ -375,21 +375,21 @@ namespace skyline { /** * @brief Deduction guides required for arguments to span, CTAD will fail for iterators, arrays and containers without this */ - template + template span(It, End) -> span::value_type, Extent>; - template + template span(T (&)[Size]) -> span; - template + template span(std::array &) -> span; - template + template span(const std::array &) -> span; - template + template span(Container &) -> span; - template + template span(const Container &) -> span; /** - * @brief The Logger class is to write log output to file and logcat + * @brief A wrapper around writing logs into a log file and logcat using Android Log APIs */ class Logger { private: diff --git a/app/src/main/cpp/skyline/common/circular_queue.h b/app/src/main/cpp/skyline/common/circular_queue.h index a57decb6..f8fcb3d0 100644 --- a/app/src/main/cpp/skyline/common/circular_queue.h +++ b/app/src/main/cpp/skyline/common/circular_queue.h @@ -21,6 +21,9 @@ namespace skyline { std::condition_variable produceCondition; public: + /** + * @note The internal allocation is an item larger as we require a sentinel value + */ inline CircularQueue(size_t size) : vector((size + 1) * sizeof(Type)) {} inline CircularQueue(const CircularQueue &) = delete; diff --git a/app/src/main/cpp/skyline/common/signal.cpp b/app/src/main/cpp/skyline/common/signal.cpp index 3d44b9ee..e35095f6 100644 --- a/app/src/main/cpp/skyline/common/signal.cpp +++ b/app/src/main/cpp/skyline/common/signal.cpp @@ -46,7 +46,7 @@ namespace skyline::signal { void ExceptionalSignalHandler(int signal, siginfo *info, ucontext *context) { SignalException signalException; signalException.signal = signal; - signalException.pc = context->uc_mcontext.pc; + signalException.pc = reinterpret_cast(context->uc_mcontext.pc); if (signal == SIGSEGV) signalException.fault = info->si_addr; SignalExceptionPtr = std::make_exception_ptr(signalException); diff --git a/app/src/main/cpp/skyline/common/signal.h b/app/src/main/cpp/skyline/common/signal.h index 004fc331..c8e3ae20 100644 --- a/app/src/main/cpp/skyline/common/signal.h +++ b/app/src/main/cpp/skyline/common/signal.h @@ -14,14 +14,14 @@ namespace skyline::signal { class SignalException { public: int signal{}; - u64 pc{}; + void* pc{}; void *fault{}; inline std::string what() const { if (!fault) - return fmt::format("Signal: {} (PC: 0x{:X})", strsignal(signal), pc); + return fmt::format("Signal: {} (PC: 0x{:X})", strsignal(signal), reinterpret_cast(pc)); else - return fmt::format("Signal: {} @ 0x{:X} (PC: 0x{:X})", strsignal(signal), reinterpret_cast(fault), pc); + return fmt::format("Signal: {} @ 0x{:X} (PC: 0x{:X})", strsignal(signal), reinterpret_cast(fault), reinterpret_cast(pc)); } }; diff --git a/app/src/main/cpp/skyline/kernel/ipc.cpp b/app/src/main/cpp/skyline/kernel/ipc.cpp index ebcc1499..06d00930 100644 --- a/app/src/main/cpp/skyline/kernel/ipc.cpp +++ b/app/src/main/cpp/skyline/kernel/ipc.cpp @@ -94,7 +94,7 @@ namespace skyline::kernel::ipc { payloadOffset = cmdArg; - if (payload->magic != util::MakeMagic("SFCI") && (header->type != CommandType::Control && header->type != CommandType::ControlWithContext)) // SFCI is the magic in received IPC messages + if (payload->magic != util::MakeMagic("SFCI") && (header->type != CommandType::Control && header->type != CommandType::ControlWithContext && header->type != CommandType::Close) && (!domain || domain->command != DomainCommand::CloseVHandle)) // SFCI is the magic in received IPC messages state.logger->Debug("Unexpected Magic in PayloadHeader: 0x{:X}", static_cast(payload->magic)); pointer += constant::IpcPaddingSum - padding + cBufferLengthSize; diff --git a/app/src/main/cpp/skyline/kernel/memory.h b/app/src/main/cpp/skyline/kernel/memory.h index fa9eecc5..589ea45f 100644 --- a/app/src/main/cpp/skyline/kernel/memory.h +++ b/app/src/main/cpp/skyline/kernel/memory.h @@ -7,12 +7,17 @@ namespace skyline { namespace memory { - struct Permission { + union Permission { /** * @brief Initializes all permissions to false */ constexpr Permission() : r(), w(), x() {} + /** + * @brief Initializes permissions where the first three bits correspond to RWX + */ + constexpr explicit Permission(u8 raw) : raw(raw) {} + /** * @param read If memory has read permission * @param write If memory has write permission @@ -38,10 +43,14 @@ namespace skyline { return perm; } - bool r; //!< The permission to read - bool w; //!< The permission to write - bool x; //!< The permission to execute + struct { + bool r : 1; //!< The permission to read + bool w : 1; //!< The permission to write + bool x : 1; //!< The permission to execute + }; + u8 raw; }; + static_assert(sizeof(Permission) == sizeof(u8)); /** * @url https://switchbrew.org/wiki/SVC#MemoryAttribute diff --git a/app/src/main/cpp/skyline/kernel/svc.cpp b/app/src/main/cpp/skyline/kernel/svc.cpp index e2b3d3f2..00784f93 100644 --- a/app/src/main/cpp/skyline/kernel/svc.cpp +++ b/app/src/main/cpp/skyline/kernel/svc.cpp @@ -419,7 +419,7 @@ namespace skyline::kernel::svc { return; } - auto permission{*reinterpret_cast(&state.ctx->gpr.w3)}; + memory::Permission permission(state.ctx->gpr.w3); if ((permission.w && !permission.r) || (permission.x && !permission.r)) { state.logger->Warn("svcMapSharedMemory: 'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-'); state.ctx->gpr.w0 = result::InvalidNewMemoryPermission; @@ -452,7 +452,7 @@ namespace skyline::kernel::svc { return; } - auto permission{*reinterpret_cast(&state.ctx->gpr.w3)}; + memory::Permission permission(state.ctx->gpr.w3); if ((permission.w && !permission.r) || (permission.x && !permission.r)) { state.logger->Warn("svcCreateTransferMemory: 'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-'); state.ctx->gpr.w0 = result::InvalidNewMemoryPermission; diff --git a/app/src/main/cpp/skyline/kernel/types/KThread.cpp b/app/src/main/cpp/skyline/kernel/types/KThread.cpp index 385cde4e..b2845214 100644 --- a/app/src/main/cpp/skyline/kernel/types/KThread.cpp +++ b/app/src/main/cpp/skyline/kernel/types/KThread.cpp @@ -62,7 +62,7 @@ namespace skyline::kernel::type { "MOV LR, %x2\n\t" // Store entry in Link Register so it is jumped to on return "MOV X0, %x3\n\t" // Store the argument in X0 "MOV X1, %x4\n\t" // Store the thread handle in X1, NCA applications require this - "MOV X2, XZR\n\t" + "MOV X2, XZR\n\t" // Zero out other GP and SIMD registers, not doing this will break applications "MOV X3, XZR\n\t" "MOV X4, XZR\n\t" "MOV X5, XZR\n\t" diff --git a/app/src/main/cpp/skyline/loader/nca.cpp b/app/src/main/cpp/skyline/loader/nca.cpp index da62c1ce..10e756df 100644 --- a/app/src/main/cpp/skyline/loader/nca.cpp +++ b/app/src/main/cpp/skyline/loader/nca.cpp @@ -27,7 +27,7 @@ namespace skyline::loader { u8 *base{loadInfo.base}; void *entry{loadInfo.entry}; - state.logger->Info("Loaded nso 'rtld' at 0x{:X} (.text @ 0x{:X})", base, entry); + state.logger->Info("Loaded 'rtld.nso' at 0x{:X} (.text @ 0x{:X})", base, entry); for (const auto &nso : {"main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { if (exeFs->FileExists(nso)) diff --git a/app/src/main/cpp/skyline/nce.cpp b/app/src/main/cpp/skyline/nce.cpp index 08d24160..9fd268c2 100644 --- a/app/src/main/cpp/skyline/nce.cpp +++ b/app/src/main/cpp/skyline/nce.cpp @@ -45,8 +45,9 @@ namespace skyline::nce { } } - void NCE::SignalHandler(int signal, siginfo *info, ucontext *context, void **tls) { + void NCE::SignalHandler(int signal, siginfo *info, ucontext *ctx, void **tls) { if (*tls) { + auto &mctx{ctx->uc_mcontext}; const auto &state{*reinterpret_cast(*tls)->state}; if (signal != SIGINT) { state.logger->Warn("Thread #{} has crashed due to signal: {}", state.thread->id, strsignal(signal)); @@ -55,15 +56,14 @@ namespace skyline::nce { std::string trace; std::string cpuContext; - const auto &ctx{reinterpret_cast(context)->uc_mcontext}; constexpr u16 instructionCount{20}; // The amount of previous instructions to print - auto offset{ctx.pc - (instructionCount * sizeof(u32)) + (2 * sizeof(u32))}; + auto offset{mctx.pc - (instructionCount * sizeof(u32)) + (2 * sizeof(u32))}; span instructions(reinterpret_cast(offset), instructionCount); if (mprotect(util::AlignDown(instructions.data(), PAGE_SIZE), util::AlignUp(instructions.size_bytes(), PAGE_SIZE), PROT_READ | PROT_WRITE | PROT_EXEC) == 0) { for (auto &instruction : instructions) { instruction = __builtin_bswap32(instruction); - if (offset == ctx.pc) + if (offset == mctx.pc) trace += fmt::format("\n-> 0x{:X} : 0x{:08X}", offset, instruction); else trace += fmt::format("\n 0x{:X} : 0x{:08X}", offset, instruction); @@ -75,28 +75,28 @@ namespace skyline::nce { state.logger->Debug("Process Trace:{}", trace); state.logger->Debug("Raw Instructions: 0x{}", raw); } else { - cpuContext += fmt::format("\nPC: 0x{:X} ('mprotect' failed with '{}')", ctx.pc, strerror(errno)); + cpuContext += fmt::format("\nPC: 0x{:X} ('mprotect' failed with '{}')", mctx.pc, strerror(errno)); } - if (ctx.fault_address) - cpuContext += fmt::format("\nFault Address: 0x{:X}", ctx.fault_address); + if (mctx.fault_address) + cpuContext += fmt::format("\nFault Address: 0x{:X}", mctx.fault_address); - if (ctx.sp) - cpuContext += fmt::format("\nStack Pointer: 0x{:X}", ctx.sp); + if (mctx.sp) + cpuContext += fmt::format("\nStack Pointer: 0x{:X}", mctx.sp); for (u8 index{}; index < ((sizeof(mcontext_t::regs) / sizeof(u64)) - 2); index += 2) - cpuContext += fmt::format("\n{}X{}: 0x{:<16X} {}{}: 0x{:X}", index < 10 ? ' ' : '\0', index, ctx.regs[index], index < 10 ? 'X' : '\0', index + 1, ctx.regs[index]); + cpuContext += fmt::format("\n{}X{}: 0x{:<16X} {}{}: 0x{:X}", index < 10 ? ' ' : '\0', index, mctx.regs[index], index < 10 ? 'X' : '\0', index + 1, mctx.regs[index]); state.logger->Debug("CPU Context:{}", cpuContext); } - context->uc_mcontext.pc = reinterpret_cast(&std::longjmp); - context->uc_mcontext.regs[0] = reinterpret_cast(state.thread->originalCtx); - context->uc_mcontext.regs[1] = true; + mctx.pc = reinterpret_cast(&std::longjmp); + mctx.regs[0] = reinterpret_cast(state.thread->originalCtx); + mctx.regs[1] = true; *tls = nullptr; } else { - signal::ExceptionalSignalHandler(signal, info, context); //!< Delegate throwing a host exception to the exceptional signal handler + signal::ExceptionalSignalHandler(signal, info, ctx); //!< Delegate throwing a host exception to the exceptional signal handler } } @@ -131,16 +131,16 @@ namespace skyline::nce { auto start{reinterpret_cast(text.data())}, end{reinterpret_cast(text.data() + text.size())}; for (const u32 *instruction{start}; instruction < end; instruction++) { - auto svc{*reinterpret_cast(instruction)}; - auto mrs{*reinterpret_cast(instruction)}; - auto msr{*reinterpret_cast(instruction)}; + auto svc{*reinterpret_cast(instruction)}; + auto mrs{*reinterpret_cast(instruction)}; + auto msr{*reinterpret_cast(instruction)}; if (svc.Verify()) { size += 7; offsets.push_back(instruction - start); } else if (mrs.Verify()) { if (mrs.srcReg == TpidrroEl0 || mrs.srcReg == TpidrEl0) { - size += ((mrs.destReg != regs::X0) ? 6 : 3); + size += ((mrs.destReg != registers::X0) ? 6 : 3); offsets.push_back(instruction - start); } else { if (rescaleClock) { @@ -189,7 +189,7 @@ namespace skyline::nce { *patch++ = 0xA9BF0BE1; // STP X1, X2, [SP, #-16]! /* Jump to SvcHandler */ - for (const auto &mov : instr::MoveRegister(regs::X2, reinterpret_cast(&NCE::SvcHandler))) + for (const auto &mov : instructions::MoveRegister(registers::X2, reinterpret_cast(&NCE::SvcHandler))) if (mov) *patch++ = mov; *patch++ = 0xD63F0040; // BLR X2 @@ -213,39 +213,39 @@ namespace skyline::nce { for (auto offset : offsets) { u32 *instruction{reinterpret_cast(text.data()) + offset}; - auto svc{*reinterpret_cast(instruction)}; - auto mrs{*reinterpret_cast(instruction)}; - auto msr{*reinterpret_cast(instruction)}; + auto svc{*reinterpret_cast(instruction)}; + auto mrs{*reinterpret_cast(instruction)}; + auto msr{*reinterpret_cast(instruction)}; if (svc.Verify()) { /* Per-SVC Trampoline */ /* Rewrite SVC with B to trampoline */ - *instruction = instr::B((end - patch) + offset, true).raw; + *instruction = instructions::B((end - patch) + offset, true).raw; /* Save Context */ *patch++ = 0xF81F0FFE; // STR LR, [SP, #-16]! - *patch = instr::BL(start - patch).raw; + *patch = instructions::BL(start - patch).raw; patch++; /* Jump to main SVC trampoline */ - *patch++ = instr::Movz(regs::W0, static_cast(svc.value)).raw; - *patch = instr::BL((start - patch) + guest::SaveCtxSize).raw; + *patch++ = instructions::Movz(registers::W0, static_cast(svc.value)).raw; + *patch = instructions::BL((start - patch) + guest::SaveCtxSize).raw; patch++; /* Restore Context and Return */ - *patch = instr::BL((start - patch) + guest::SaveCtxSize + MainSvcTrampolineSize).raw; + *patch = instructions::BL((start - patch) + guest::SaveCtxSize + MainSvcTrampolineSize).raw; patch++; *patch++ = 0xF84107FE; // LDR LR, [SP], #16 - *patch = instr::B((end - patch) + offset + 1).raw; + *patch = instructions::B((end - patch) + offset + 1).raw; patch++; } else if (mrs.Verify()) { if (mrs.srcReg == TpidrroEl0 || mrs.srcReg == TpidrEl0) { /* Emulated TLS Register Load */ /* Rewrite MRS with B to trampoline */ - *instruction = instr::B((end - patch) + offset, true).raw; + *instruction = instructions::B((end - patch) + offset, true).raw; /* Allocate Scratch Register */ - if (mrs.destReg != regs::X0) + if (mrs.destReg != registers::X0) *patch++ = 0xF81F0FE0; // STR X0, [SP, #-16]! /* Retrieve emulated TLS register from ThreadContext */ @@ -256,66 +256,66 @@ namespace skyline::nce { *patch++ = 0xF9415C00; // LDR X0, [X0, #0x2B8] (ThreadContext::tpidrEl0) /* Restore Scratch Register and Return */ - if (mrs.destReg != regs::X0) { - *patch++ = instr::Mov(regs::X(mrs.destReg), regs::X0).raw; + if (mrs.destReg != registers::X0) { + *patch++ = instructions::Mov(registers::X(mrs.destReg), registers::X0).raw; *patch++ = 0xF84107E0; // LDR X0, [SP], #16 } - *patch = instr::B((end - patch) + offset + 1).raw; + *patch = instructions::B((end - patch) + offset + 1).raw; patch++; } else { if (rescaleClock) { if (mrs.srcReg == CntpctEl0) { /* Physical Counter Load Emulation (With Rescaling) */ /* Rewrite MRS with B to trampoline */ - *instruction = instr::B((end - patch) + offset, true).raw; + *instruction = instructions::B((end - patch) + offset, true).raw; /* Rescale host clock */ std::memcpy(patch, reinterpret_cast(&guest::RescaleClock), guest::RescaleClockSize * sizeof(u32)); patch += guest::RescaleClockSize; /* Load result from stack into destination register */ - instr::Ldr ldr(0xF94003E0); // LDR XOUT, [SP] + instructions::Ldr ldr(0xF94003E0); // LDR XOUT, [SP] ldr.destReg = mrs.destReg; *patch++ = ldr.raw; /* Free 32B stack allocation by RescaleClock and Return */ *patch++ = {0x910083FF}; // ADD SP, SP, #32 - *patch = instr::B((end - patch) + offset + 1).raw; + *patch = instructions::B((end - patch) + offset + 1).raw; patch++; } else if (mrs.srcReg == CntfrqEl0) { /* Physical Counter Frequency Load Emulation */ /* Rewrite MRS with B to trampoline */ - *instruction = instr::B((end - patch) + offset, true).raw; + *instruction = instructions::B((end - patch) + offset, true).raw; /* Write back Tegra X1 Counter Frequency and Return */ - for (const auto &mov : instr::MoveRegister(regs::X(mrs.destReg), TegraX1Freq)) + for (const auto &mov : instructions::MoveRegister(registers::X(mrs.destReg), TegraX1Freq)) *patch++ = mov; - *patch = instr::B((end - patch) + offset + 1).raw; + *patch = instructions::B((end - patch) + offset + 1).raw; patch++; } } else if (mrs.srcReg == CntpctEl0) { /* Physical Counter Load Emulation (Without Rescaling) */ // We just convert CNTPCT_EL0 -> CNTVCT_EL0 as Linux doesn't allow access to the physical counter - *instruction = instr::Mrs(CntvctEl0, regs::X(mrs.destReg)).raw; + *instruction = instructions::Mrs(CntvctEl0, registers::X(mrs.destReg)).raw; } } } else if (msr.Verify() && msr.destReg == TpidrEl0) { /* Emulated TLS Register Store */ /* Rewrite MSR with B to trampoline */ - *instruction = instr::B((end - patch) + offset, true).raw; + *instruction = instructions::B((end - patch) + offset, true).raw; /* Allocate Scratch Registers */ - bool x0x1{mrs.srcReg != regs::X0 && mrs.srcReg != regs::X1}; + bool x0x1{mrs.srcReg != registers::X0 && mrs.srcReg != registers::X1}; *patch++ = x0x1 ? 0xA9BF07E0 : 0xA9BF0FE2; // STP X(0/2), X(1/3), [SP, #-16]! /* Store new TLS value into ThreadContext */ *patch++ = x0x1 ? 0xD53BD040 : 0xD53BD042; // MRS X(0/2), TPIDR_EL0 - *patch++ = instr::Mov(x0x1 ? regs::X1 : regs::X3, regs::X(msr.srcReg)).raw; + *patch++ = instructions::Mov(x0x1 ? registers::X1 : registers::X3, registers::X(msr.srcReg)).raw; *patch++ = x0x1 ? 0xF9015C01 : 0xF9015C03; // STR X(1/3), [X0, #0x4B8] (ThreadContext::tpidrEl0) /* Restore Scratch Registers and Return */ *patch++ = x0x1 ? 0xA8C107E0 : 0xA8C10FE2; // LDP X(0/2), X(1/3), [SP], #16 - *patch = instr::B((end - patch) + offset + 1).raw; + *patch = instructions::B((end - patch) + offset + 1).raw; patch++; } } diff --git a/app/src/main/cpp/skyline/nce.h b/app/src/main/cpp/skyline/nce.h index ef421840..e6553f4b 100644 --- a/app/src/main/cpp/skyline/nce.h +++ b/app/src/main/cpp/skyline/nce.h @@ -17,7 +17,7 @@ namespace skyline::nce { static void SvcHandler(u16 svc, ThreadContext *ctx); public: - static void SignalHandler(int signal, siginfo *info, ucontext *context, void **tls); + static void SignalHandler(int signal, siginfo *info, ucontext *ctx, void **tls); NCE(const DeviceState &state); diff --git a/app/src/main/cpp/skyline/nce/instructions.h b/app/src/main/cpp/skyline/nce/instructions.h index 8dfea45a..dd71c226 100644 --- a/app/src/main/cpp/skyline/nce/instructions.h +++ b/app/src/main/cpp/skyline/nce/instructions.h @@ -4,12 +4,15 @@ #include namespace skyline::nce { - namespace regs { - enum X { X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30 }; - enum W { W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, W16, W17, W18, W19, W20, W21, W22, W23, W24, W25, W26, W27, W28, W29, W30 }; + /** + * @note We use unscoped enumerations to leak all register enumerations into the registers namespace + */ + namespace registers { + enum X : u8 { X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30 }; + enum W : u8 { W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, W16, W17, W18, W19, W20, W21, W22, W23, W24, W25, W26, W27, W28, W29, W30 }; } - namespace instr { + namespace instructions { /** * @url https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/brk-breakpoint-instruction */ @@ -66,7 +69,7 @@ namespace skyline::nce { * @param srcReg The source system register * @param dstReg The destination Xn register */ - constexpr Mrs(u32 srcReg, regs::X dstReg) { + constexpr Mrs(u32 srcReg, registers::X dstReg) { this->srcReg = srcReg; this->destReg = dstReg; sig = 0xD53; @@ -184,7 +187,7 @@ namespace skyline::nce { * @param imm16 The 16-bit value to store * @param shift The offset (in units of 16-bits) in the register to store the value at */ - constexpr Movz(regs::X destReg, u16 imm16, u8 shift = 0) { + constexpr Movz(registers::X destReg, u16 imm16, u8 shift = 0) { this->destReg = static_cast(destReg); this->imm16 = imm16; hw = shift; @@ -197,7 +200,7 @@ namespace skyline::nce { * @param imm16 The 16-bit value to store * @param shift The offset (in units of 16-bits) in the register to store the value at */ - constexpr Movz(regs::W destReg, u16 imm16, u8 shift = 0) { + constexpr Movz(registers::W destReg, u16 imm16, u8 shift = 0) { this->destReg = static_cast(destReg); this->imm16 = imm16; hw = shift; @@ -239,7 +242,7 @@ namespace skyline::nce { * @param imm16 The 16-bit value to store * @param shift The offset (in units of 16-bits) in the register to store the value at */ - constexpr Movk(regs::X destReg, u16 imm16, u8 shift = 0) { + constexpr Movk(registers::X destReg, u16 imm16, u8 shift = 0) { this->destReg = static_cast(destReg); this->imm16 = imm16; hw = shift; @@ -252,7 +255,7 @@ namespace skyline::nce { * @param imm16 The 16-bit value to store * @param shift The offset (in units of 16-bits) in the register to store the value at */ - constexpr Movk(regs::W destReg, u16 imm16, u8 shift = 0) { + constexpr Movk(registers::W destReg, u16 imm16, u8 shift = 0) { this->destReg = static_cast(destReg); this->imm16 = imm16; hw = shift; @@ -291,7 +294,7 @@ namespace skyline::nce { * @note 0 is returned for any instruction that isn't required */ template - constexpr std::array MoveRegister(regs::X destination, Type value) { + constexpr std::array MoveRegister(registers::X destination, Type value) { std::array instructions; auto valuePointer{reinterpret_cast(&value)}; @@ -302,9 +305,9 @@ namespace skyline::nce { auto offsetValue{*(valuePointer + offset)}; if (offsetValue) { if (zeroed) { - instruction = instr::Movk(destination, offsetValue, offset).raw; + instruction = instructions::Movk(destination, offsetValue, offset).raw; } else { - instruction = instr::Movz(destination, offsetValue, offset).raw; + instruction = instructions::Movz(destination, offsetValue, offset).raw; zeroed = true; } } else { @@ -326,7 +329,7 @@ namespace skyline::nce { * @param destReg The destination Xn register to store the value in * @param srcReg The source Xn register to retrieve the value from */ - constexpr Mov(regs::X destReg, regs::X srcReg) { + constexpr Mov(registers::X destReg, registers::X srcReg) { this->destReg = static_cast(destReg); sig0 = 0x1F; imm = 0; @@ -340,7 +343,7 @@ namespace skyline::nce { * @param destReg The destination Wn register to store the value in * @param srcReg The source Wn register to retrieve the value from */ - constexpr Mov(regs::W destReg, regs::W srcReg) { + constexpr Mov(registers::W destReg, registers::W srcReg) { this->destReg = static_cast(destReg); sig0 = 0x1F; imm = 0; diff --git a/app/src/main/cpp/skyline/os.cpp b/app/src/main/cpp/skyline/os.cpp index 97774786..625adf44 100644 --- a/app/src/main/cpp/skyline/os.cpp +++ b/app/src/main/cpp/skyline/os.cpp @@ -18,16 +18,20 @@ namespace skyline::kernel { auto romFile{std::make_shared(romFd)}; auto keyStore{std::make_shared(appFilesPath)}; - if (romType == loader::RomFormat::NRO) - state.loader = std::make_shared(romFile); - else if (romType == loader::RomFormat::NSO) - state.loader = std::make_shared(romFile); - else if (romType == loader::RomFormat::NCA) - state.loader = std::make_shared(romFile, keyStore); - else if (romType == loader::RomFormat::NSP) - state.loader = std::make_shared(romFile, keyStore); - else - throw exception("Unsupported ROM extension."); + state.loader = [=]() -> std::shared_ptr { + switch (romType) { + case loader::RomFormat::NRO: + return std::make_shared(romFile); + case loader::RomFormat::NSO: + return std::make_shared(romFile); + case loader::RomFormat::NCA: + return std::make_shared(romFile, keyStore); + case loader::RomFormat::NSP: + return std::make_shared(romFile, keyStore); + default: + throw exception("Unsupported ROM extension."); + } + }(); auto &process{state.process}; process = std::make_shared(state); diff --git a/app/src/main/cpp/skyline/vfs/backing.h b/app/src/main/cpp/skyline/vfs/backing.h index 715b9def..aec2bcd7 100644 --- a/app/src/main/cpp/skyline/vfs/backing.h +++ b/app/src/main/cpp/skyline/vfs/backing.h @@ -47,7 +47,7 @@ namespace skyline::vfs { /** * @brief Implicit casting for reading into spans of different types */ - template, bool>::type = true> + template, bool>::type = true> inline size_t Read(span output, size_t offset = 0) { return Read(output.template cast(), offset); } diff --git a/app/src/main/cpp/skyline/vfs/npdm.h b/app/src/main/cpp/skyline/vfs/npdm.h index c66b8ca1..fefc8c4d 100644 --- a/app/src/main/cpp/skyline/vfs/npdm.h +++ b/app/src/main/cpp/skyline/vfs/npdm.h @@ -18,7 +18,7 @@ namespace skyline { u32 offset; u32 size; - template + template inline T Read(const std::shared_ptr &backing, size_t baseOffset = 0) { if (sizeof(T) > size) throw exception("Section size ({}) smaller than Read type size ({})", size, sizeof(T));