mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-24 19:14:40 +00:00
kernel: Implement module loading
* Now it's easy to do anyway with new module rework
This commit is contained in:
parent
dcaedc89a0
commit
5d230cb542
@ -6,6 +6,7 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/singleton.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/cpu_management.h"
|
||||
#include "core/libraries/kernel/event_flag/event_flag.h"
|
||||
@ -199,6 +200,41 @@ s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) {
|
||||
strlen(std::fgets(static_cast<char*>(buf), static_cast<int>(nbytes), stdin)));
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, size_t args, const void* argp,
|
||||
u32 flags, const void* pOpt, int* pRes) {
|
||||
LOG_INFO(Lib_Kernel, "called filename = {}, args = {}", moduleFileName, args);
|
||||
|
||||
if (flags != 0) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||
const auto path = mnt->GetHostFile(moduleFileName);
|
||||
|
||||
// Load PRX module.
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
u32 handle = linker->LoadModule(path);
|
||||
auto* module = linker->GetModule(handle);
|
||||
linker->Relocate(module);
|
||||
|
||||
// Retrieve and verify proc param according to libkernel.
|
||||
u64* param = module->GetProcParam<u64*>();
|
||||
ASSERT_MSG(!param || param[0] >= 0x18, "Invalid module param size: {}", param[0]);
|
||||
module->Start(args, argp, param);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelDlsym(s32 handle, const char* symbol, void** addrp) {
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
auto* module = linker->GetModule(handle);
|
||||
*addrp = module->FindByName(symbol);
|
||||
if (*addrp == nullptr) {
|
||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||
// obj
|
||||
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
||||
@ -216,6 +252,8 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("IWIBBdTHit4", "libkernel", 1, "libkernel", 1, 1, sceKernelMapFlexibleMemory);
|
||||
LIB_FUNCTION("p5EcQeEeJAE", "libkernel", 1, "libkernel", 1, 1,
|
||||
_sceKernelRtldSetApplicationHeapAPI);
|
||||
LIB_FUNCTION("wzvqT4UqKX8", "libkernel", 1, "libkernel", 1, 1, sceKernelLoadStartModule);
|
||||
LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym);
|
||||
|
||||
// equeue
|
||||
LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEqueue);
|
||||
|
@ -252,6 +252,8 @@ void Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Modul
|
||||
}
|
||||
|
||||
void* Linker::TlsGetAddr(u64 module_index, u64 offset) {
|
||||
std::scoped_lock lk{mutex};
|
||||
|
||||
DtvEntry* dtv_table = GetTcbBase()->tcb_dtv;
|
||||
ASSERT_MSG(dtv_table[0].counter == dtv_generation_counter,
|
||||
"Reallocation of DTV table is not supported");
|
||||
|
@ -11,9 +11,7 @@
|
||||
namespace Core::Loader {
|
||||
|
||||
void SymbolsResolver::AddSymbol(const SymbolResolver& s, u64 virtual_addr) {
|
||||
SymbolRecord& r = m_symbols.emplace_back();
|
||||
r.name = GenerateName(s);
|
||||
r.virtual_address = virtual_addr;
|
||||
m_symbols.emplace_back(GenerateName(s), s.nidName, virtual_addr);
|
||||
}
|
||||
|
||||
std::string SymbolsResolver::GenerateName(const SymbolResolver& s) {
|
||||
|
@ -21,6 +21,7 @@ enum class SymbolType {
|
||||
|
||||
struct SymbolRecord {
|
||||
std::string name;
|
||||
std::string nid_name;
|
||||
u64 virtual_address;
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
namespace Core {
|
||||
|
||||
using EntryFunc = PS4_SYSV_ABI int (*)(size_t args, const void* argp, ModuleFunc func);
|
||||
using EntryFunc = PS4_SYSV_ABI int (*)(size_t args, const void* argp, void* param);
|
||||
|
||||
static u64 LoadAddress = SYSTEM_RESERVED + CODE_BASE_OFFSET;
|
||||
static constexpr u64 CODE_BASE_INCR = 0x010000000u;
|
||||
@ -64,10 +64,10 @@ Module::Module(const std::filesystem::path& file_) : file{file_} {
|
||||
|
||||
Module::~Module() = default;
|
||||
|
||||
void Module::Start(size_t args, const void* argp, ModuleFunc func) {
|
||||
void Module::Start(size_t args, const void* argp, void* param) {
|
||||
LOG_INFO(Core_Linker, "Module started : {}", file.filename().string());
|
||||
const VAddr addr = dynamic_info.init_virtual_addr + GetBaseAddress();
|
||||
reinterpret_cast<EntryFunc>(addr)(args, argp, func);
|
||||
reinterpret_cast<EntryFunc>(addr)(args, argp, param);
|
||||
}
|
||||
|
||||
void Module::LoadModuleToMemory() {
|
||||
|
@ -119,8 +119,17 @@ public:
|
||||
return elf.IsSharedLib();
|
||||
}
|
||||
|
||||
void* FindByName(std::string_view name) {
|
||||
const auto symbols = export_sym.GetSymbols();
|
||||
const auto it = std::ranges::find(symbols, name, &Loader::SymbolRecord::nid_name);
|
||||
if (it != symbols.end()) {
|
||||
return reinterpret_cast<void*>(it->virtual_address);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T = VAddr>
|
||||
const T GetProcParam() const noexcept {
|
||||
T GetProcParam() const noexcept {
|
||||
return reinterpret_cast<T>(proc_param_virtual_addr);
|
||||
}
|
||||
|
||||
@ -149,7 +158,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void Start(size_t args, const void* argp, ModuleFunc func);
|
||||
void Start(size_t args, const void* argp, void* param);
|
||||
void LoadModuleToMemory();
|
||||
void LoadDynamicInfo();
|
||||
void LoadSymbols();
|
||||
|
@ -135,7 +135,11 @@ void PatchTLS(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c) {
|
||||
|
||||
#else
|
||||
|
||||
void SetTLSStorage(u64 image_address) {
|
||||
void SetTcbBase(void* image_address) {
|
||||
UNREACHABLE_MSG("Thread local storage is unimplemented on posix platforms!");
|
||||
}
|
||||
|
||||
Tcb* GetTcbBase() {
|
||||
UNREACHABLE_MSG("Thread local storage is unimplemented on posix platforms!");
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,6 @@ void Rasterizer::Draw(bool is_indexed) {
|
||||
}
|
||||
|
||||
void Rasterizer::DispatchDirect() {
|
||||
compute_done = true;
|
||||
return;
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
const auto& cs_program = liverpool->regs.cs_program;
|
||||
|
@ -49,7 +49,6 @@ private:
|
||||
Core::MemoryManager* memory;
|
||||
PipelineCache pipeline_cache;
|
||||
StreamBuffer vertex_index_buffer;
|
||||
bool compute_done{};
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
@ -58,7 +58,7 @@ LONG WINAPI GuestFaultSignalHandler(EXCEPTION_POINTERS* pExp) noexcept {
|
||||
}
|
||||
#endif
|
||||
|
||||
static constexpr u64 StreamBufferSize = 128_MB;
|
||||
static constexpr u64 StreamBufferSize = 512_MB;
|
||||
static constexpr u64 PageShift = 12;
|
||||
|
||||
TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_)
|
||||
|
Loading…
Reference in New Issue
Block a user