mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
add load exec
Co-authored-by: thenotsoquietninja44-collab <thenotsoquietninja44@gmail.com>
This commit is contained in:
@@ -182,4 +182,8 @@ const Keymap& GetKeymap() {
|
|||||||
return g_config->keymap;
|
return g_config->keymap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& GetGuestArguments() {
|
||||||
|
return g_config->guest_arguments;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Config
|
} // namespace Config
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ struct ConfigOptions {
|
|||||||
bool red_zone_protection_enabled = false;
|
bool red_zone_protection_enabled = false;
|
||||||
#endif
|
#endif
|
||||||
Keymap keymap;
|
Keymap keymap;
|
||||||
|
std::vector<std::string> guest_arguments;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Load(const ConfigOptions& cfg);
|
void Load(const ConfigOptions& cfg);
|
||||||
@@ -136,6 +137,7 @@ bool RedZoneProtectionEnabled();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
const Keymap& GetKeymap();
|
const Keymap& GetKeymap();
|
||||||
|
const std::vector<std::string>& GetGuestArguments();
|
||||||
|
|
||||||
} // namespace Config
|
} // namespace Config
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ struct RunOptions {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void Run(const RunOptions& options);
|
void Run(const RunOptions& options);
|
||||||
|
int LoadExec(const char* path, const char* const argv[]);
|
||||||
|
|
||||||
} // namespace Emulator
|
} // namespace Emulator
|
||||||
|
|
||||||
|
|||||||
+2
-8
@@ -54,11 +54,7 @@ struct CContext {
|
|||||||
std::list<atexit_func_t> atexit;
|
std::list<atexit_func_t> atexit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InitEnvParams {
|
using InitEnvParams = Loader::EntryParams;
|
||||||
int argc;
|
|
||||||
uint32_t pad;
|
|
||||||
const char* argv[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
static int g_argc = 0;
|
static int g_argc = 0;
|
||||||
static const char* const* g_argv = nullptr;
|
static const char* const* g_argv = nullptr;
|
||||||
@@ -271,9 +267,7 @@ static KYTY_SYSV_ABI void init_env(const InitEnvParams* params) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr int argv_capacity = static_cast<int>(sizeof(params->argv) / sizeof(params->argv[0]));
|
EXIT_NOT_IMPLEMENTED(params->argc < 0);
|
||||||
|
|
||||||
EXIT_NOT_IMPLEMENTED(params->argc < 0 || params->argc >= argv_capacity);
|
|
||||||
|
|
||||||
g_argc = params->argc;
|
g_argc = params->argc;
|
||||||
g_argv = params->argv;
|
g_argv = params->argv;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "common/emulatorConfig.h"
|
#include "common/emulatorConfig.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
#include "emulator.h"
|
||||||
#include "graphics/presentation/systemOverlay.h"
|
#include "graphics/presentation/systemOverlay.h"
|
||||||
#include "libs/dialog.h"
|
#include "libs/dialog.h"
|
||||||
#include "libs/errno.h"
|
#include "libs/errno.h"
|
||||||
@@ -99,6 +100,11 @@ static int KYTY_SYSV_ABI SystemServiceHideSplashScreen() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int KYTY_SYSV_ABI SystemServiceLoadExec(const char* path, const char* const argv[]) {
|
||||||
|
PRINT_NAME();
|
||||||
|
return Emulator::LoadExec(path, argv);
|
||||||
|
}
|
||||||
|
|
||||||
static int KYTY_SYSV_ABI SystemServiceParamGetInt(int param_id, int* value) {
|
static int KYTY_SYSV_ABI SystemServiceParamGetInt(int param_id, int* value) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
@@ -559,6 +565,7 @@ LIB_DEFINE(InitSystemGesture_1) {
|
|||||||
} // namespace SystemGesture
|
} // namespace SystemGesture
|
||||||
|
|
||||||
LIB_DEFINE(InitSystemService_1) {
|
LIB_DEFINE(InitSystemService_1) {
|
||||||
|
LIB_FUNC("JoBqSQt1yyA", SystemService::SystemServiceLoadExec);
|
||||||
LIB_FUNC("Vo5V8KAwCmk", SystemService::SystemServiceHideSplashScreen);
|
LIB_FUNC("Vo5V8KAwCmk", SystemService::SystemServiceHideSplashScreen);
|
||||||
LIB_FUNC("fZo48un7LK4", SystemService::SystemServiceParamGetInt);
|
LIB_FUNC("fZo48un7LK4", SystemService::SystemServiceParamGetInt);
|
||||||
LIB_FUNC("SsC-m-S9JTA", SystemService::SystemServiceParamGetString);
|
LIB_FUNC("SsC-m-S9JTA", SystemService::SystemServiceParamGetString);
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include "emulator.h"
|
||||||
|
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "kernel/fileSystem.h"
|
||||||
|
#include "libs/errno.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#if KYTY_PLATFORM == KYTY_PLATFORM_LINUX
|
||||||
|
#include <linux/close_range.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Emulator {
|
||||||
|
|
||||||
|
int LoadExec(const char* path, const char* const argv[]) {
|
||||||
|
using namespace Libs::SystemService;
|
||||||
|
if (path == nullptr || !std::string_view(path).starts_with("/app0/") ||
|
||||||
|
!Common::File::IsFileExisting(Libs::LibKernel::FileSystem::GetRealFilename(path))) {
|
||||||
|
return SYSTEM_SERVICE_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
#if KYTY_PLATFORM == KYTY_PLATFORM_LINUX
|
||||||
|
std::ifstream command("/proc/self/cmdline", std::ios::binary);
|
||||||
|
std::vector<std::string> arguments;
|
||||||
|
for (std::string argument; std::getline(command, argument, '\0') && argument != "--guest-exec";) {
|
||||||
|
arguments.push_back(std::move(argument));
|
||||||
|
}
|
||||||
|
if (arguments.empty()) {
|
||||||
|
return SYSTEM_SERVICE_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
arguments.insert(arguments.end(), {"--guest-exec", path});
|
||||||
|
size_t bytes = 0;
|
||||||
|
for (size_t i = 0; argv != nullptr && argv[i] != nullptr; ++i) {
|
||||||
|
const auto size = strnlen(argv[i], 4096 - bytes) + 1;
|
||||||
|
if (size > 4096 - bytes) {
|
||||||
|
return SYSTEM_SERVICE_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
bytes += size;
|
||||||
|
arguments.emplace_back(argv[i]);
|
||||||
|
}
|
||||||
|
std::vector<char*> host_argv;
|
||||||
|
for (auto& argument: arguments) {
|
||||||
|
host_argv.push_back(argument.data());
|
||||||
|
}
|
||||||
|
host_argv.push_back(nullptr);
|
||||||
|
LOGF("LoadExec: %s\n", path);
|
||||||
|
Log::Flush();
|
||||||
|
if (close_range(3, ~0u, CLOSE_RANGE_UNSHARE | CLOSE_RANGE_CLOEXEC) == 0) {
|
||||||
|
execvp(host_argv[0], host_argv.data());
|
||||||
|
}
|
||||||
|
LOGF("LoadExec failed: %s\n", std::strerror(errno));
|
||||||
|
return SYSTEM_SERVICE_ERROR_INTERNAL;
|
||||||
|
#else
|
||||||
|
return SYSTEM_SERVICE_ERROR_UNAVAILABLE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Emulator
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -88,16 +89,6 @@ ThreadLocalStorage::~ThreadLocalStorage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
struct EntryParams {
|
|
||||||
int argc;
|
|
||||||
uint32_t pad;
|
|
||||||
const char* argv[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
using atexit_func_t = KYTY_SYSV_ABI void (*)();
|
using atexit_func_t = KYTY_SYSV_ABI void (*)();
|
||||||
using entry_func_t = KYTY_SYSV_ABI void (*)(EntryParams* params, atexit_func_t atexit_func);
|
using entry_func_t = KYTY_SYSV_ABI void (*)(EntryParams* params, atexit_func_t atexit_func);
|
||||||
using module_ini_fini_func_t = KYTY_SYSV_ABI int (*)(size_t args, const void* argp,
|
using module_ini_fini_func_t = KYTY_SYSV_ABI int (*)(size_t args, const void* argp,
|
||||||
@@ -1283,11 +1274,16 @@ void RuntimeLinker::Execute(const std::filesystem::path& game_patch) {
|
|||||||
LOGF_COLOR(Log::Color::BrightYellow, "---\n--- Execute: %s\n---\n", "Main");
|
LOGF_COLOR(Log::Color::BrightYellow, "---\n--- Execute: %s\n---\n", "Main");
|
||||||
|
|
||||||
if (auto entry = GetEntry(); entry != 0) {
|
if (auto entry = GetEntry(); entry != 0) {
|
||||||
|
const auto& arguments = Config::GetGuestArguments();
|
||||||
|
const auto params_size = offsetof(EntryParams, argv) +
|
||||||
|
(arguments.size() + 2) * sizeof(const char*);
|
||||||
auto* params = reinterpret_cast<EntryParams*>(
|
auto* params = reinterpret_cast<EntryParams*>(
|
||||||
(reinterpret_cast<uintptr_t>(main_stack_top) - 0x100u) & ~static_cast<uintptr_t>(0x0f));
|
(reinterpret_cast<uintptr_t>(main_stack_top) - params_size - 0x100u) &
|
||||||
std::memset(params, 0, sizeof(EntryParams));
|
~static_cast<uintptr_t>(0x0f));
|
||||||
params->argc = 1;
|
std::memset(params, 0, params_size);
|
||||||
params->argv[0] = "KytyEmu";
|
for (const auto& argument: arguments) {
|
||||||
|
params->argv[params->argc++] = argument.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
LOGF("stack_addr = %" PRIx64 "\n", reinterpret_cast<uint64_t>(params));
|
LOGF("stack_addr = %" PRIx64 "\n", reinterpret_cast<uint64_t>(params));
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,12 @@
|
|||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
|
|
||||||
|
struct EntryParams {
|
||||||
|
int argc;
|
||||||
|
uint32_t pad;
|
||||||
|
const char* argv[1];
|
||||||
|
};
|
||||||
|
|
||||||
class Elf64;
|
class Elf64;
|
||||||
struct Elf64_Sym;
|
struct Elf64_Sym;
|
||||||
struct Elf64_Rela;
|
struct Elf64_Rela;
|
||||||
|
|||||||
@@ -300,6 +300,10 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
|
|||||||
value.c_str());
|
value.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (arg == "--guest-exec") {
|
||||||
|
options.elf = Common::PathFromUtf8(Common::FixFilenameSlash(value));
|
||||||
|
options.config.guest_arguments.assign(argv + i + 1, argv + argc);
|
||||||
|
break;
|
||||||
} else if (arg == "--game-patch") {
|
} else if (arg == "--game-patch") {
|
||||||
if (!options.game_patch.empty()) {
|
if (!options.game_patch.empty()) {
|
||||||
::printf("--game-patch can only be specified once\n");
|
::printf("--game-patch can only be specified once\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user