diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6261b0dc..6f6f9f20 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -37,7 +37,7 @@ jobs:
run: chmod +x gradlew
- name: Install CMake from Android SDK Manager
- run: yes | sdkmanager --install "cmake;3.10.2.4988404" | grep -v = || true
+ run: yes | sdkmanager --install "ndk;21.0.6113669" "cmake;3.10.2.4988404" | grep -v = || true
- name: Android Lint
run: ./gradlew --stacktrace lint
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 30c29deb..f4faad14 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -3,9 +3,6 @@
-
-
-
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 6c18ee41..1acfbe56 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -1,6 +1,7 @@
-
+
+
@@ -10,6 +11,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -30,13 +400,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -52,6 +437,9 @@
+
+
+
@@ -84,8 +472,13 @@
+
+
+
+
+
@@ -95,9 +488,15 @@
+
+
+
+
+
+
@@ -109,29 +508,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
@@ -140,6 +565,8 @@
+
+
@@ -154,7 +581,10 @@
+
+
+
@@ -191,42 +621,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -235,26 +713,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -280,13 +856,22 @@
+
+
+
+
+
+
+
+
+
@@ -295,6 +880,7 @@
+
@@ -307,47 +893,264 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -372,16 +1175,25 @@
+
+
+
+
+
+
+
+
+
@@ -393,24 +1205,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -420,10 +1330,12 @@
+
+
@@ -437,14 +1349,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -455,11 +1391,14 @@
+
+
+
@@ -469,18 +1408,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -488,10 +1453,16 @@
+
+
+
+
+
+
@@ -499,10 +1470,12 @@
+
+
@@ -516,6 +1489,7 @@
+
@@ -527,7 +1501,18 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -537,6 +1522,7 @@
+
@@ -568,28 +1554,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -609,10 +1656,17 @@
+
+
+
+
+
+
+
@@ -629,6 +1683,7 @@
+
@@ -652,18 +1707,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -680,27 +1768,230 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -708,13 +1999,24 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -737,19 +2039,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -759,6 +2094,7 @@
+
@@ -769,42 +2105,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -812,14 +2196,19 @@
+
+
+
+
+
@@ -839,17 +2228,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -857,54 +2262,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -917,6 +2397,11 @@
+
+
+
+
+
@@ -930,7 +2415,10 @@
+
+
+
@@ -938,6 +2426,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jsonSchemas.xml b/.idea/jsonSchemas.xml
new file mode 100644
index 00000000..f1b2a7ca
--- /dev/null
+++ b/.idea/jsonSchemas.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/cpp/skyline/kernel/types/KProcess.cpp b/app/src/main/cpp/skyline/kernel/types/KProcess.cpp
index f6b5a170..9599a400 100644
--- a/app/src/main/cpp/skyline/kernel/types/KProcess.cpp
+++ b/app/src/main/cpp/skyline/kernel/types/KProcess.cpp
@@ -51,8 +51,8 @@ namespace skyline::kernel::type {
threads[pid]->tls = GetTlsSlot();
}
- KProcess::KProcess(const DeviceState &state, pid_t pid, u64 entryPoint, u64 stackBase, u64 stackSize, std::shared_ptr &tlsMemory) : pid(pid), KSyncObject(state, KType::KProcess) {
- auto thread = NewHandle(pid, entryPoint, 0x0, stackBase + stackSize, 0, constant::DefaultPriority, this, tlsMemory).item;
+ KProcess::KProcess(const DeviceState &state, pid_t pid, u64 entryPoint, std::shared_ptr &stack, std::shared_ptr &tlsMemory) : pid(pid), stack(stack), KSyncObject(state, KType::KProcess) {
+ auto thread = NewHandle(pid, entryPoint, 0x0, stack->guest.address + stack->guest.size, 0, constant::DefaultPriority, this, tlsMemory).item;
threads[pid] = thread;
state.nce->WaitThreadInit(thread);
memFd = open(fmt::format("/proc/{}/mem", pid).c_str(), O_RDWR | O_CLOEXEC);
diff --git a/app/src/main/cpp/skyline/kernel/types/KProcess.h b/app/src/main/cpp/skyline/kernel/types/KProcess.h
index c04180b3..dd6a789e 100644
--- a/app/src/main/cpp/skyline/kernel/types/KProcess.h
+++ b/app/src/main/cpp/skyline/kernel/types/KProcess.h
@@ -107,6 +107,7 @@ namespace skyline::kernel::type {
std::unordered_map>> mutexes; //!< A map from a mutex's address to a vector of Mutex objects for threads waiting on it
std::unordered_map>> conditionals; //!< A map from a conditional variable's address to a vector of threads waiting on it
std::vector> tlsPages; //!< A vector of all allocated TLS pages
+ std::shared_ptr stack; //!< The shared memory used to hold the stack of the main thread
std::shared_ptr heap; //!< The kernel memory object backing the allocated heap
Mutex mutexLock; //!< This mutex is to prevent concurrent mutex operations to happen at once
Mutex conditionalLock; //!< This mutex is to prevent concurrent conditional variable operations to happen at once
@@ -116,11 +117,10 @@ namespace skyline::kernel::type {
* @param state The state of the device
* @param pid The PID of the main thread
* @param entryPoint The address to start execution at
- * @param stackBase The base of the stack
- * @param stackSize The size of the stack
+ * @param stack The KSharedMemory object for Stack memory allocated by the guest process
* @param tlsMemory The KSharedMemory object for TLS memory allocated by the guest process
*/
- KProcess(const DeviceState &state, pid_t pid, u64 entryPoint, u64 stackBase, u64 stackSize, std::shared_ptr &tlsMemory);
+ KProcess(const DeviceState &state, pid_t pid, u64 entryPoint, std::shared_ptr &stack, std::shared_ptr &tlsMemory);
/**
* Close the file descriptor to the process's memory
diff --git a/app/src/main/cpp/skyline/kernel/types/KSharedMemory.cpp b/app/src/main/cpp/skyline/kernel/types/KSharedMemory.cpp
index a812ae44..286ad94c 100644
--- a/app/src/main/cpp/skyline/kernel/types/KSharedMemory.cpp
+++ b/app/src/main/cpp/skyline/kernel/types/KSharedMemory.cpp
@@ -6,13 +6,13 @@
#include
namespace skyline::kernel::type {
- KSharedMemory::KSharedMemory(const DeviceState &state, u64 address, size_t size, const memory::Permission permission, memory::MemoryState memState) : initialState(memState), KMemory(state, KType::KSharedMemory) {
+ KSharedMemory::KSharedMemory(const DeviceState &state, u64 address, size_t size, const memory::Permission permission, memory::MemoryState memState, int mmapFlags) : initialState(memState), KMemory(state, KType::KSharedMemory) {
if (address && !utils::PageAligned(address))
throw exception("KSharedMemory was created with non-page-aligned address: 0x{:X}", address);
fd = ASharedMemory_create("KSharedMemory", size);
if (fd < 0)
throw exception("An error occurred while creating shared memory: {}", fd);
- address = reinterpret_cast(mmap(reinterpret_cast(address), size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | ((address) ? MAP_FIXED : 0), fd, 0));
+ address = reinterpret_cast(mmap(reinterpret_cast(address), size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | ((address) ? MAP_FIXED : 0) | mmapFlags, fd, 0));
if (address == reinterpret_cast(MAP_FAILED))
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
kernel = {.address = address, .size = size, .permission = permission};
diff --git a/app/src/main/cpp/skyline/kernel/types/KSharedMemory.h b/app/src/main/cpp/skyline/kernel/types/KSharedMemory.h
index 1f95c2e0..8dffee25 100644
--- a/app/src/main/cpp/skyline/kernel/types/KSharedMemory.h
+++ b/app/src/main/cpp/skyline/kernel/types/KSharedMemory.h
@@ -33,8 +33,9 @@ namespace skyline::kernel::type {
* @param size The size of the allocation on the kernel
* @param permission The permission of the kernel process
* @param memState The MemoryState of the chunk of memory
+ * @param mmapFlags Additional flags to pass to mmap
*/
- KSharedMemory(const DeviceState &state, u64 address, size_t size, const memory::Permission permission, memory::MemoryState memState = memory::MemoryStates::SharedMemory);
+ KSharedMemory(const DeviceState &state, u64 address, size_t size, const memory::Permission permission, memory::MemoryState memState = memory::MemoryStates::SharedMemory, int mmapFlags = 0);
/**
* @brief Maps the shared memory in the guest
diff --git a/app/src/main/cpp/skyline/nce.cpp b/app/src/main/cpp/skyline/nce.cpp
index 4d8c9e6d..b191d995 100644
--- a/app/src/main/cpp/skyline/nce.cpp
+++ b/app/src/main/cpp/skyline/nce.cpp
@@ -18,15 +18,15 @@ namespace skyline {
state.ctx = reinterpret_cast(state.thread->ctxMemory->kernel.address);
while (true) {
asm("yield");
- if (Halt)
+ if (__predict_false(Halt))
break;
- if (!Surface)
+ if (__predict_false(!Surface))
continue;
if (state.ctx->state == ThreadState::WaitKernel) {
std::lock_guard jniGd(jniMtx);
- if (Halt)
+ if (__predict_false(Halt))
break;
- if (!Surface)
+ if (__predict_false(!Surface))
continue;
const u16 svc = static_cast(state.ctx->commandId);
try {
@@ -40,7 +40,7 @@ namespace skyline {
throw exception("{} (SVC: 0x{:X})", e.what(), svc);
}
state.ctx->state = ThreadState::WaitRun;
- } else if (state.ctx->state == ThreadState::GuestCrash) {
+ } else if (__predict_false(state.ctx->state == ThreadState::GuestCrash)) {
state.logger->Warn("Thread with PID {} has crashed due to signal: {}", thread, strsignal(state.ctx->commandId));
ThreadTrace();
state.ctx->state = ThreadState::WaitRun;
@@ -72,11 +72,17 @@ namespace skyline {
}
void NCE::Execute() {
- while (true) {
- std::lock_guard guard(jniMtx);
- if (Halt)
- break;
- state.gpu->Loop();
+ try {
+ while (true) {
+ std::lock_guard guard(jniMtx);
+ if (Halt)
+ break;
+ state.gpu->Loop();
+ }
+ } catch (const std::exception &e) {
+ state.logger->Error(e.what());
+ } catch (...) {
+ state.logger->Error("An unknown exception has occurred");
}
if (!Halt) {
jniMtx.lock(GroupMutex::Group::Group2);
diff --git a/app/src/main/cpp/skyline/os.cpp b/app/src/main/cpp/skyline/os.cpp
index be457580..8021c74b 100644
--- a/app/src/main/cpp/skyline/os.cpp
+++ b/app/src/main/cpp/skyline/os.cpp
@@ -19,20 +19,17 @@ namespace skyline::kernel {
}
std::shared_ptr OS::CreateProcess(u64 entry, u64 argument, size_t stackSize) {
- auto *stack = static_cast(mmap(nullptr, stackSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS | MAP_STACK, -1, 0));
- if (stack == MAP_FAILED)
- throw exception("Failed to allocate stack memory");
- if (mprotect(stack, PAGE_SIZE, PROT_NONE)) {
- munmap(stack, stackSize);
+ auto stack = std::make_shared(state, 0, stackSize, memory::Permission{true, true, false}, memory::MemoryStates::Reserved, MAP_NORESERVE | MAP_STACK);
+ stack->guest = stack->kernel;
+ if (mprotect(reinterpret_cast(stack->guest.address), PAGE_SIZE, PROT_NONE))
throw exception("Failed to create guard pages");
- }
auto tlsMem = std::make_shared(state, 0, (sizeof(ThreadContext) + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1), memory::Permission{true, true, false}, memory::MemoryStates::Reserved);
tlsMem->guest = tlsMem->kernel;
- pid_t pid = clone(reinterpret_cast(&guest::GuestEntry), stack + stackSize, CLONE_FILES | CLONE_FS | CLONE_SETTLS | SIGCHLD, reinterpret_cast(entry), nullptr, reinterpret_cast(tlsMem->guest.address));
+ pid_t pid = clone(reinterpret_cast(&guest::GuestEntry), reinterpret_cast(stack->guest.address + stackSize), CLONE_FILES | CLONE_FS | CLONE_SETTLS | SIGCHLD, reinterpret_cast(entry), nullptr, reinterpret_cast(tlsMem->guest.address));
if (pid == -1)
throw exception("Call to clone() has failed: {}", strerror(errno));
state.logger->Debug("Successfully created process with PID: {}", pid);
- process = std::make_shared(state, pid, argument, reinterpret_cast(stack), stackSize, tlsMem);
+ process = std::make_shared(state, pid, argument, stack, tlsMem);
return process;
}
diff --git a/build.gradle b/build.gradle
index 9d504c73..7c8b017d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.0'
+ classpath 'com.android.tools.build:gradle:3.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong