mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-26 00:04:17 +01:00
Fix GitHub Actions Build + Move Stack to Shared Memory
This commit mainly fixes GitHub Actions builds which were broken due to an outdated version of Android NDK. In addition, it moves all stack to shared memory.
This commit is contained in:
parent
38f63eced3
commit
5f072da2b8
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -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
|
||||
|
3
.idea/codeStyles/Project.xml
generated
3
.idea/codeStyles/Project.xml
generated
@ -3,9 +3,6 @@
|
||||
<option name="RIGHT_MARGIN" value="400" />
|
||||
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
|
||||
<option name="SOFT_MARGINS" value="80,140" />
|
||||
<AndroidXmlCodeStyleSettings>
|
||||
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
|
||||
</AndroidXmlCodeStyleSettings>
|
||||
<Objective-C>
|
||||
<option name="INDENT_VISIBILITY_KEYWORDS" value="2" />
|
||||
<option name="INDENT_PREPROCESSOR_DIRECTIVE" value="4" />
|
||||
|
1530
.idea/inspectionProfiles/Project_Default.xml
generated
1530
.idea/inspectionProfiles/Project_Default.xml
generated
File diff suppressed because it is too large
Load Diff
25
.idea/jsonSchemas.xml
generated
Normal file
25
.idea/jsonSchemas.xml
generated
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JsonSchemaMappingsProjectConfiguration">
|
||||
<state>
|
||||
<map>
|
||||
<entry key="github-workflow">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="name" value="github-workflow" />
|
||||
<option name="relativePathToSchema" value="http://json.schemastore.org/github-workflow" />
|
||||
<option name="applicationDefined" value="true" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="path" value=".github/workflows/ci.yml" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</state>
|
||||
</component>
|
||||
</project>
|
@ -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<type::KSharedMemory> &tlsMemory) : pid(pid), KSyncObject(state, KType::KProcess) {
|
||||
auto thread = NewHandle<KThread>(pid, entryPoint, 0x0, stackBase + stackSize, 0, constant::DefaultPriority, this, tlsMemory).item;
|
||||
KProcess::KProcess(const DeviceState &state, pid_t pid, u64 entryPoint, std::shared_ptr<type::KSharedMemory> &stack, std::shared_ptr<type::KSharedMemory> &tlsMemory) : pid(pid), stack(stack), KSyncObject(state, KType::KProcess) {
|
||||
auto thread = NewHandle<KThread>(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);
|
||||
|
@ -107,6 +107,7 @@ namespace skyline::kernel::type {
|
||||
std::unordered_map<u64, std::vector<std::shared_ptr<WaitStatus>>> mutexes; //!< A map from a mutex's address to a vector of Mutex objects for threads waiting on it
|
||||
std::unordered_map<u64, std::list<std::shared_ptr<WaitStatus>>> conditionals; //!< A map from a conditional variable's address to a vector of threads waiting on it
|
||||
std::vector<std::shared_ptr<TlsPage>> tlsPages; //!< A vector of all allocated TLS pages
|
||||
std::shared_ptr<type::KSharedMemory> stack; //!< The shared memory used to hold the stack of the main thread
|
||||
std::shared_ptr<KPrivateMemory> 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<type::KSharedMemory> &tlsMemory);
|
||||
KProcess(const DeviceState &state, pid_t pid, u64 entryPoint, std::shared_ptr<type::KSharedMemory> &stack, std::shared_ptr<type::KSharedMemory> &tlsMemory);
|
||||
|
||||
/**
|
||||
* Close the file descriptor to the process's memory
|
||||
|
@ -6,13 +6,13 @@
|
||||
#include <asm/unistd.h>
|
||||
|
||||
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<u64>(mmap(reinterpret_cast<void *>(address), size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | ((address) ? MAP_FIXED : 0), fd, 0));
|
||||
address = reinterpret_cast<u64>(mmap(reinterpret_cast<void *>(address), size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | ((address) ? MAP_FIXED : 0) | mmapFlags, fd, 0));
|
||||
if (address == reinterpret_cast<u64>(MAP_FAILED))
|
||||
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
||||
kernel = {.address = address, .size = size, .permission = permission};
|
||||
|
@ -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
|
||||
|
@ -18,15 +18,15 @@ namespace skyline {
|
||||
state.ctx = reinterpret_cast<ThreadContext *>(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<const u16>(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,12 +72,18 @@ namespace skyline {
|
||||
}
|
||||
|
||||
void NCE::Execute() {
|
||||
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);
|
||||
Halt = true;
|
||||
|
@ -19,20 +19,17 @@ namespace skyline::kernel {
|
||||
}
|
||||
|
||||
std::shared_ptr<type::KProcess> OS::CreateProcess(u64 entry, u64 argument, size_t stackSize) {
|
||||
auto *stack = static_cast<u8 *>(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<type::KSharedMemory>(state, 0, stackSize, memory::Permission{true, true, false}, memory::MemoryStates::Reserved, MAP_NORESERVE | MAP_STACK);
|
||||
stack->guest = stack->kernel;
|
||||
if (mprotect(reinterpret_cast<void *>(stack->guest.address), PAGE_SIZE, PROT_NONE))
|
||||
throw exception("Failed to create guard pages");
|
||||
}
|
||||
auto tlsMem = std::make_shared<type::KSharedMemory>(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<int (*)(void *)>(&guest::GuestEntry), stack + stackSize, CLONE_FILES | CLONE_FS | CLONE_SETTLS | SIGCHLD, reinterpret_cast<void *>(entry), nullptr, reinterpret_cast<void *>(tlsMem->guest.address));
|
||||
pid_t pid = clone(reinterpret_cast<int (*)(void *)>(&guest::GuestEntry), reinterpret_cast<void *>(stack->guest.address + stackSize), CLONE_FILES | CLONE_FS | CLONE_SETTLS | SIGCHLD, reinterpret_cast<void *>(entry), nullptr, reinterpret_cast<void *>(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<kernel::type::KProcess>(state, pid, argument, reinterpret_cast<u64>(stack), stackSize, tlsMem);
|
||||
process = std::make_shared<kernel::type::KProcess>(state, pid, argument, stack, tlsMem);
|
||||
return process;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user