mirror of
https://github.com/RPCSX/rpcsx.git
synced 2024-10-07 08:43:34 +00:00
[rpcsx-os] [orbis-kernel] implement lazy symbol binding
Use libSceSysmodule to resolve dependencies Stub /dev/camera
This commit is contained in:
parent
08a097e46e
commit
3232e57445
@ -69,6 +69,121 @@ static void allocateTlsOffset(orbis::Process *process, orbis::Module *module) {
|
||||
module->isTlsDone = true;
|
||||
}
|
||||
|
||||
static orbis::SysResult doPltRelocation(orbis::Process *process,
|
||||
orbis::Module *module,
|
||||
orbis::Relocation rel) {
|
||||
auto symbol = module->symbols.at(rel.symbolIndex);
|
||||
|
||||
auto A = rel.addend;
|
||||
auto B = reinterpret_cast<std::uint64_t>(module->base);
|
||||
auto where = reinterpret_cast<std::uint64_t *>(B + rel.offset);
|
||||
auto where32 = reinterpret_cast<std::uint32_t *>(B + rel.offset);
|
||||
auto P = reinterpret_cast<std::uintptr_t>(where);
|
||||
|
||||
auto findDefModule = [module,
|
||||
symbol] -> std::pair<orbis::Module *, std::uint64_t> {
|
||||
if (symbol.moduleIndex == -1 || symbol.bind == orbis::SymbolBind::Local) {
|
||||
return std::pair(module, symbol.address);
|
||||
}
|
||||
|
||||
auto &defModule = module->importedModules.at(symbol.moduleIndex);
|
||||
if (!defModule) {
|
||||
// std::printf(
|
||||
// "Delaying plt relocation '%s' ('%s'), symbol '%llx' in %s
|
||||
// module\n", module->moduleName, module->soName, (unsigned long
|
||||
// long)symbol.id,
|
||||
// module->neededModules[symbol.moduleIndex].name.c_str());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
auto library = module->neededLibraries.at(symbol.libraryIndex);
|
||||
|
||||
std::vector<std::string> foundInLibs;
|
||||
for (auto defSym : defModule->symbols) {
|
||||
if (defSym.id != symbol.id || defSym.bind == orbis::SymbolBind::Local) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (defSym.visibility == orbis::SymbolVisibility::Hidden) {
|
||||
std::printf("Ignoring hidden symbol\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto defLib = defModule->neededLibraries.at(defSym.libraryIndex);
|
||||
|
||||
if (defLib.name == library.name) {
|
||||
return std::pair(defModule.get(), defSym.address);
|
||||
}
|
||||
|
||||
foundInLibs.emplace_back(std::string_view(defLib.name));
|
||||
}
|
||||
|
||||
for (auto nsDefModule : defModule->namespaceModules) {
|
||||
for (auto defSym : nsDefModule->symbols) {
|
||||
if (defSym.id != symbol.id || defSym.bind == orbis::SymbolBind::Local) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (defSym.visibility == orbis::SymbolVisibility::Hidden) {
|
||||
std::printf("Ignoring hidden symbol\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto defLib = nsDefModule->neededLibraries.at(defSym.libraryIndex);
|
||||
|
||||
if (defLib.name == library.name) {
|
||||
return std::pair(nsDefModule.get(), defSym.address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::printf(
|
||||
"'%s' ('%s') uses undefined symbol '%llx' in '%s' ('%s') module\n",
|
||||
module->moduleName, module->soName, (unsigned long long)symbol.id,
|
||||
defModule->moduleName, defModule->soName);
|
||||
if (foundInLibs.size() > 0) {
|
||||
std::printf("Requested library is '%s', exists in libraries: [",
|
||||
library.name.c_str());
|
||||
|
||||
for (bool isFirst = true; auto &lib : foundInLibs) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
std::printf(", ");
|
||||
}
|
||||
|
||||
std::printf("'%s'", lib.c_str());
|
||||
}
|
||||
std::printf("]\n");
|
||||
}
|
||||
return std::pair(module, symbol.address);
|
||||
};
|
||||
|
||||
switch (rel.relType) {
|
||||
case kRelJumpSlot: {
|
||||
bool isLazyBind = false; // TODO
|
||||
if (isLazyBind) {
|
||||
*where += B;
|
||||
} else {
|
||||
auto [defObj, S] = findDefModule();
|
||||
|
||||
if (defObj == nullptr) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
*where = reinterpret_cast<std::uintptr_t>(defObj->base) + S;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::fprintf(stderr, "unimplemented relocation type %u\n",
|
||||
(unsigned)rel.relType);
|
||||
std::abort();
|
||||
return {};
|
||||
}
|
||||
|
||||
static orbis::SysResult doRelocation(orbis::Process *process,
|
||||
orbis::Module *module,
|
||||
orbis::Relocation rel) {
|
||||
@ -80,18 +195,22 @@ static orbis::SysResult doRelocation(orbis::Process *process,
|
||||
auto where32 = reinterpret_cast<std::uint32_t *>(B + rel.offset);
|
||||
auto P = reinterpret_cast<std::uintptr_t>(where);
|
||||
|
||||
auto findDefModule = [module, symbol] {
|
||||
auto findDefModule = [module, symbol,
|
||||
rel] -> std::pair<orbis::Module *, std::uint64_t> {
|
||||
if (symbol.moduleIndex == -1 || symbol.bind == orbis::SymbolBind::Local) {
|
||||
return std::pair(module, symbol.address);
|
||||
}
|
||||
|
||||
auto &defModule = module->importedModules.at(symbol.moduleIndex);
|
||||
if (!defModule) {
|
||||
std::printf(
|
||||
"'%s' ('%s') uses undefined symbol '%llx' in unloaded module\n",
|
||||
module->moduleName, module->soName, (unsigned long long)symbol.id);
|
||||
std::printf("'%s' ('%s') uses undefined symbol '%llx' in unloaded module "
|
||||
"'%s', rel %u\n",
|
||||
module->moduleName, module->soName,
|
||||
(unsigned long long)symbol.id,
|
||||
module->neededModules.at(symbol.moduleIndex).name.c_str(),
|
||||
rel.relType);
|
||||
|
||||
return std::pair(module, symbol.address);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto library = module->neededLibraries.at(symbol.libraryIndex);
|
||||
@ -162,12 +281,20 @@ static orbis::SysResult doRelocation(orbis::Process *process,
|
||||
return {};
|
||||
case kRel64: {
|
||||
auto [defObj, S] = findDefModule();
|
||||
|
||||
if (defObj == nullptr) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
*where = reinterpret_cast<std::uintptr_t>(defObj->base) + S + A;
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
case kRelPc32: {
|
||||
auto [defObj, S] = findDefModule();
|
||||
|
||||
if (defObj == nullptr) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
*where32 = reinterpret_cast<std::uintptr_t>(defObj->base) + S + A - P;
|
||||
return {};
|
||||
}
|
||||
@ -175,37 +302,39 @@ static orbis::SysResult doRelocation(orbis::Process *process,
|
||||
// return{};
|
||||
case kRelGlobDat: {
|
||||
auto [defObj, S] = findDefModule();
|
||||
|
||||
if (defObj == nullptr) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
*where = reinterpret_cast<std::uintptr_t>(defObj->base) + S;
|
||||
return {};
|
||||
}
|
||||
case kRelJumpSlot: {
|
||||
bool isLazyBind = false; // TODO
|
||||
if (isLazyBind) {
|
||||
*where += B;
|
||||
} else {
|
||||
auto [defObj, S] = findDefModule();
|
||||
*where = reinterpret_cast<std::uintptr_t>(defObj->base) + S;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
case kRelRelative:
|
||||
*where = B + A;
|
||||
return {};
|
||||
case kRelDtpMod64: {
|
||||
auto [defObj, S] = findDefModule();
|
||||
if (defObj == nullptr) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
*where += defObj->tlsIndex;
|
||||
return {};
|
||||
}
|
||||
case kRelDtpOff64: {
|
||||
auto [defObj, S] = findDefModule();
|
||||
if (defObj == nullptr) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
*where += S + A;
|
||||
return {};
|
||||
}
|
||||
case kRelTpOff64: {
|
||||
auto [defObj, S] = findDefModule();
|
||||
if (defObj == nullptr) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
if (!defObj->isTlsDone) {
|
||||
allocateTlsOffset(process, module);
|
||||
allocateTlsOffset(process, defObj);
|
||||
}
|
||||
*where = S - defObj->tlsOffset + A;
|
||||
return {};
|
||||
@ -217,8 +346,11 @@ static orbis::SysResult doRelocation(orbis::Process *process,
|
||||
}
|
||||
case kRelTpOff32: {
|
||||
auto [defObj, S] = findDefModule();
|
||||
if (defObj == nullptr) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
if (!defObj->isTlsDone) {
|
||||
allocateTlsOffset(process, module);
|
||||
allocateTlsOffset(process, defObj);
|
||||
}
|
||||
*where32 = S - defObj->tlsOffset + A;
|
||||
return {};
|
||||
@ -232,25 +364,45 @@ static orbis::SysResult doRelocation(orbis::Process *process,
|
||||
}
|
||||
|
||||
orbis::SysResult orbis::Module::relocate(Process *process) {
|
||||
for (auto rel : pltRelocations) {
|
||||
auto result = doRelocation(process, this, rel);
|
||||
if (!pltRelocations.empty()) {
|
||||
kvector<Relocation> delayedRelocations;
|
||||
std::size_t resolved = 0;
|
||||
std::size_t delayed = 0;
|
||||
for (auto rel : pltRelocations) {
|
||||
auto result = doPltRelocation(process, this, rel);
|
||||
|
||||
if (result.isError()) {
|
||||
return result;
|
||||
if (result.isError()) {
|
||||
delayedRelocations.push_back(rel);
|
||||
++delayed;
|
||||
} else {
|
||||
++resolved;
|
||||
}
|
||||
}
|
||||
|
||||
std::printf("plt relocation of %s: delayed/resolved: %zu/%zu\n", moduleName,
|
||||
delayed, resolved);
|
||||
pltRelocations = std::move(delayedRelocations);
|
||||
}
|
||||
|
||||
pltRelocations = {};
|
||||
if (!nonPltRelocations.empty()) {
|
||||
kvector<Relocation> delayedRelocations;
|
||||
std::size_t resolved = 0;
|
||||
std::size_t delayed = 0;
|
||||
for (auto rel : nonPltRelocations) {
|
||||
auto result = doRelocation(process, this, rel);
|
||||
|
||||
for (auto rel : nonPltRelocations) {
|
||||
auto result = doRelocation(process, this, rel);
|
||||
|
||||
if (result.isError()) {
|
||||
return result;
|
||||
if (result.isError()) {
|
||||
delayedRelocations.push_back(rel);
|
||||
++delayed;
|
||||
} else {
|
||||
++resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonPltRelocations = {};
|
||||
std::printf("non-plt relocation of %s: delayed/resolved: %zu/%zu\n",
|
||||
moduleName, delayed, resolved);
|
||||
nonPltRelocations = std::move(delayedRelocations);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -93,7 +93,10 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op,
|
||||
if (int_value->encoded_id == 0x12356328ECF5617B ||
|
||||
int_value->encoded_id == 0x22666251FE7BECFF) {
|
||||
int_value->value = 1;
|
||||
return {};
|
||||
}
|
||||
|
||||
int_value->value = 0;
|
||||
}
|
||||
|
||||
return {};
|
||||
@ -623,14 +626,30 @@ orbis::SysResult orbis::sys_dmem_container(Thread *thread, uint id) {
|
||||
orbis::SysResult orbis::sys_get_authinfo(Thread *thread, pid_t pid,
|
||||
ptr<void> info) {
|
||||
struct authinfo {
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
uint64_t unk0;
|
||||
uint64_t caps[4];
|
||||
uint64_t attrs[4];
|
||||
uint64_t unk[8];
|
||||
};
|
||||
static_assert(sizeof(authinfo) == 136);
|
||||
|
||||
authinfo result {
|
||||
.unk0 = 0x3100000000000001,
|
||||
.caps = {
|
||||
0x2000038000000000,
|
||||
0x000000000000FF00,
|
||||
0x0000000000000000,
|
||||
0x0000000000000000,
|
||||
},
|
||||
.attrs = {
|
||||
0x4000400040000000,
|
||||
0x4000000000000000,
|
||||
0x0080000000000002,
|
||||
0xF0000000FFFF4000,
|
||||
},
|
||||
};
|
||||
|
||||
std::memset(info, 0, 136);
|
||||
((authinfo *)info)->b = ~0;
|
||||
|
||||
return {};
|
||||
return uwrite((ptr<authinfo>)info, result);
|
||||
}
|
||||
orbis::SysResult orbis::sys_mname(Thread *thread, uint64_t addr, uint64_t len,
|
||||
ptr<const char[32]> name) {
|
||||
@ -688,11 +707,9 @@ orbis::SysResult orbis::sys_dynlib_get_list(Thread *thread,
|
||||
if (actualNum >= numArray) {
|
||||
break;
|
||||
}
|
||||
|
||||
pArray[actualNum++] = id;
|
||||
}
|
||||
uwrite(pActualNum, actualNum);
|
||||
return {};
|
||||
return uwrite(pActualNum, actualNum);
|
||||
}
|
||||
orbis::SysResult orbis::sys_dynlib_get_info(Thread *thread,
|
||||
SceKernelModule handle,
|
||||
@ -847,7 +864,8 @@ orbis::SysResult orbis::sys_dl_get_metadata(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_workaround8849(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
thread->retval[0] = 1;
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult orbis::sys_is_development_mode(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
@ -887,12 +905,12 @@ orbis::sys_dynlib_get_info_ex(Thread *thread, SceKernelModule handle,
|
||||
std::memcpy(result.segments, module->segments,
|
||||
sizeof(ModuleSegment) * module->segmentCount);
|
||||
result.segmentCount = module->segmentCount;
|
||||
result.refCount = module->references.load(std::memory_order::relaxed);
|
||||
result.refCount = 1;
|
||||
ORBIS_LOG_WARNING(__FUNCTION__, result.id, result.name, result.tlsIndex,
|
||||
result.tlsInit, result.tlsInitSize, result.tlsSize,
|
||||
result.tlsOffset, result.tlsAlign, result.initProc,
|
||||
result.finiProc, result.ehFrameHdr, result.ehFrame,
|
||||
result.ehFrameHdrSize, result.ehFrameSize);
|
||||
result.ehFrameHdrSize, result.ehFrameSize, result.segmentCount, result.refCount);
|
||||
return uwrite(destModuleInfoEx, result);
|
||||
}
|
||||
orbis::SysResult orbis::sys_budget_getid(Thread *thread) {
|
||||
|
@ -64,6 +64,23 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
memset(old, 0, sizeof(app_info));
|
||||
return {};
|
||||
}
|
||||
|
||||
if (name[0] == 1 && name[1] == 14 && name[2] == 44) {
|
||||
// GetLibkernelTextLocation
|
||||
if (*oldlenp != 16) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
auto *dest = (uint64_t *)old;
|
||||
|
||||
for (auto [id, mod] : thread->tproc->modulesMap) {
|
||||
if (std::string_view("libkernel") == mod->moduleName) {
|
||||
dest[0] = (uint64_t)mod->segments[0].addr;
|
||||
dest[1] = mod->segments[0].size;
|
||||
return{};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (namelen == 2) {
|
||||
@ -169,7 +186,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
}
|
||||
|
||||
*(uint32_t *)old = 1;
|
||||
break;
|
||||
return{};
|
||||
|
||||
case sysctl_kern::sdk_version: {
|
||||
if (*oldlenp != 4 || new_ != nullptr || newlen != 0) {
|
||||
@ -187,7 +204,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
std::printf("Reporting SDK version %x\n",
|
||||
*reinterpret_cast<uint32_t *>(sdkVersion));
|
||||
*(uint32_t *)old = *reinterpret_cast<uint32_t *>(sdkVersion);
|
||||
break;
|
||||
return{};
|
||||
}
|
||||
|
||||
case sysctl_kern::sched_cpusetsize:
|
||||
@ -196,7 +213,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
}
|
||||
|
||||
*(std::uint32_t *)old = 4;
|
||||
break;
|
||||
return{};
|
||||
|
||||
case sysctl_kern::rng_pseudo:
|
||||
if (*oldlenp != 0x40 || new_ != nullptr || newlen != 0) {
|
||||
@ -205,7 +222,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
|
||||
|
||||
std::memset(old, 0, 0x40);
|
||||
break;
|
||||
return{};
|
||||
|
||||
case sysctl_kern::kern_37: {
|
||||
struct kern37_value {
|
||||
@ -220,7 +237,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
|
||||
auto value = (kern37_value *)old;
|
||||
value->size = sizeof(kern37_value);
|
||||
break;
|
||||
return{};
|
||||
}
|
||||
|
||||
case sysctl_kern::proc_ptc: {
|
||||
@ -229,7 +246,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
}
|
||||
|
||||
*(std::uint64_t *)old = 1357;
|
||||
break;
|
||||
return{};
|
||||
}
|
||||
|
||||
case sysctl_kern::cpu_mode: {
|
||||
@ -241,7 +258,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
// 1 - 7 cpu, low power
|
||||
// 5 - 7 cpu, normal
|
||||
*(std::uint32_t *)old = 5;
|
||||
break;
|
||||
return{};
|
||||
}
|
||||
|
||||
default:
|
||||
@ -263,7 +280,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
}
|
||||
|
||||
*(uint32_t *)old = 0x4000;
|
||||
break;
|
||||
return{};
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -289,5 +306,15 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
|
||||
}
|
||||
}
|
||||
|
||||
std::string concatName;
|
||||
for (unsigned int i = 0; i < namelen; ++i) {
|
||||
if (i != 0) {
|
||||
concatName += '.';
|
||||
}
|
||||
|
||||
concatName += std::to_string(name[i]);
|
||||
}
|
||||
|
||||
ORBIS_LOG_TODO(__FUNCTION__, concatName);
|
||||
return {};
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ add_library(orbis::kernel::config ALIAS standalone-config)
|
||||
add_executable(rpcsx-os
|
||||
iodev/ajm.cpp
|
||||
iodev/blockpool.cpp
|
||||
iodev/camera.cpp
|
||||
iodev/console.cpp
|
||||
iodev/dce.cpp
|
||||
iodev/dipsw.cpp
|
||||
|
@ -22,3 +22,4 @@ IoDevice *createSblSrvCharacterDevice();
|
||||
IoDevice *createShmDevice();
|
||||
IoDevice *createBlockPoolDevice();
|
||||
IoDevice *createUrandomCharacterDevice();
|
||||
IoDevice *createCameraCharacterDevice();
|
||||
|
32
rpcsx-os/iodev/camera.cpp
Normal file
32
rpcsx-os/iodev/camera.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include "io-device.hpp"
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
|
||||
struct CameraFile : orbis::File {};
|
||||
|
||||
static orbis::ErrorCode camera_ioctl(orbis::File *file, std::uint64_t request,
|
||||
void *argp, orbis::Thread *thread) {
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled camera ioctl", request);
|
||||
return {};
|
||||
}
|
||||
|
||||
static const orbis::FileOps fileOps = {
|
||||
.ioctl = camera_ioctl,
|
||||
};
|
||||
|
||||
struct CameraDevice : IoDevice {
|
||||
orbis::ErrorCode open(orbis::Ref<orbis::File> *file, const char *path,
|
||||
std::uint32_t flags, std::uint32_t mode,
|
||||
orbis::Thread *thread) override {
|
||||
auto newFile = orbis::knew<CameraFile>();
|
||||
newFile->ops = &fileOps;
|
||||
newFile->device = this;
|
||||
|
||||
*file = newFile;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
IoDevice *createCameraCharacterDevice() { return orbis::knew<CameraDevice>(); }
|
@ -2,18 +2,25 @@
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
|
||||
struct DipswFile : public orbis::File {};
|
||||
|
||||
static orbis::ErrorCode dipsw_ioctl(orbis::File *file, std::uint64_t request,
|
||||
void *argp, orbis::Thread *thread) {
|
||||
if (request == 0x40048806) { // is connected?
|
||||
ORBIS_LOG_ERROR("dipsw ioctl 0x40048806", argp);
|
||||
if (request == 0x40048806) { // isDevelopmentMode
|
||||
ORBIS_LOG_ERROR("dipsw ioctl isDevelopmentMode", argp);
|
||||
|
||||
*reinterpret_cast<std::uint32_t *>(argp) = 0;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (request == 0x40048807) {
|
||||
ORBIS_LOG_ERROR("dipsw ioctl 0x40048807", argp);
|
||||
*reinterpret_cast<std::uint32_t *>(argp) = 1;
|
||||
return {};
|
||||
}
|
||||
|
||||
// 0x40088808
|
||||
// 0x40088809
|
||||
|
||||
@ -38,6 +45,7 @@ static orbis::ErrorCode dipsw_ioctl(orbis::File *file, std::uint64_t request,
|
||||
}
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled dipsw ioctl", request);
|
||||
thread->where();
|
||||
//__builtin_trap();
|
||||
return {};
|
||||
}
|
||||
|
@ -659,20 +659,20 @@ Ref<orbis::Module> rx::linker::loadModule(std::span<std::byte> image,
|
||||
std::memcpy(result->soName + name.size(), ".prx", sizeof(".prx"));
|
||||
}
|
||||
|
||||
if (dyn.d_tag == kElfDynamicTypeNeeded) {
|
||||
auto name = std::string_view(
|
||||
sceStrtab + static_cast<std::uint32_t>(dyn.d_un.d_val));
|
||||
if (name == "STREQUAL") {
|
||||
// HACK for broken FWs
|
||||
result->needed.push_back("libSceDolbyVision.prx");
|
||||
} else {
|
||||
name = patchSoName(name);
|
||||
if (name != "libSceFreeTypeOptBm") { // TODO
|
||||
result->needed.emplace_back(name);
|
||||
result->needed.back() += ".prx";
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (dyn.d_tag == kElfDynamicTypeNeeded) {
|
||||
// auto name = std::string_view(
|
||||
// sceStrtab + static_cast<std::uint32_t>(dyn.d_un.d_val));
|
||||
// if (name == "STREQUAL") {
|
||||
// // HACK for broken FWs
|
||||
// result->needed.push_back("libSceDolbyVision.prx");
|
||||
// } else {
|
||||
// name = patchSoName(name);
|
||||
// if (name != "libSceFreeTypeOptBm") { // TODO
|
||||
// result->needed.emplace_back(name);
|
||||
// result->needed.back() += ".prx";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (dyn.d_tag == kElfDynamicTypeSceModuleInfo) {
|
||||
idToModuleIndex[dyn.d_un.d_val >> 48] = -1;
|
||||
@ -1054,16 +1054,5 @@ Ref<orbis::Module> rx::linker::loadModuleByName(std::string_view name,
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: implement lazy bind support
|
||||
for (auto path : { "/app0/Media/Modules/" }) {
|
||||
auto filePath = std::string(path);
|
||||
filePath += name;
|
||||
filePath += ".prx";
|
||||
|
||||
if (auto result = rx::linker::loadModuleFile(filePath.c_str(), thread)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -326,6 +326,7 @@ static int ps4Exec(orbis::Thread *mainThread,
|
||||
rx::vfs::mount("/dev/npdrm", createNpdrmCharacterDevice());
|
||||
rx::vfs::mount("/dev/icc_configuration", createIccConfigurationCharacterDevice());
|
||||
rx::vfs::mount("/dev/console", createConsoleCharacterDevice());
|
||||
rx::vfs::mount("/dev/camera", createCameraCharacterDevice());
|
||||
rx::vfs::mount("/dev/dmem1", dmem1);
|
||||
rx::vfs::mount("/dev/dmem2", createDmemCharacterDevice(2));
|
||||
rx::vfs::mount("/dev/stdout", createFdWrapDevice(STDOUT_FILENO));
|
||||
@ -363,6 +364,16 @@ static int ps4Exec(orbis::Thread *mainThread,
|
||||
std::vector<std::uint64_t> argvOffsets;
|
||||
std::vector<std::uint64_t> envpOffsets;
|
||||
|
||||
auto libSceLibcInternal = rx::linker::loadModuleFile(
|
||||
"/system/common/lib/libSceLibcInternal.sprx", mainThread);
|
||||
|
||||
if (libSceLibcInternal == nullptr) {
|
||||
std::fprintf(stderr, "libSceLibcInternal not found\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
libSceLibcInternal->id = mainThread->tproc->modulesMap.insert(libSceLibcInternal);
|
||||
|
||||
auto libkernel = rx::linker::loadModuleFile(
|
||||
"/system/common/lib/libkernel_sys.sprx", mainThread);
|
||||
|
||||
|
@ -85,6 +85,7 @@ loadPrx(orbis::Thread *thread, std::string_view name, bool relocate,
|
||||
}
|
||||
}
|
||||
|
||||
module->importedModules.clear();
|
||||
module->importedModules.reserve(module->neededModules.size());
|
||||
|
||||
for (auto mod : module->neededModules) {
|
||||
@ -182,8 +183,7 @@ orbis::SysResult dmem_mmap(orbis::Thread *thread, orbis::caddr_t addr,
|
||||
orbis::off_t directMemoryStart) {
|
||||
auto dmem = static_cast<DmemDevice *>(orbis::g_context.dmemDevice.get());
|
||||
void *address = addr;
|
||||
auto result =
|
||||
dmem->mmap(&address, len, prot, flags, directMemoryStart);
|
||||
auto result = dmem->mmap(&address, len, prot, flags, directMemoryStart);
|
||||
if (result != ErrorCode{}) {
|
||||
return result;
|
||||
}
|
||||
@ -405,6 +405,32 @@ orbis::SysResult dynlib_load_prx(orbis::Thread *thread,
|
||||
return result;
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, Module *, std::less<>> loadedModules;
|
||||
|
||||
for (auto [id, module] : thread->tproc->modulesMap) {
|
||||
// std::fprintf(stderr, "%u: %s\n", (unsigned)id, module->moduleName);
|
||||
loadedModules[module->moduleName] = module;
|
||||
}
|
||||
|
||||
for (auto [id, module] : thread->tproc->modulesMap) {
|
||||
module->importedModules.clear();
|
||||
module->importedModules.reserve(module->neededModules.size());
|
||||
|
||||
for (auto mod : module->neededModules) {
|
||||
if (auto it = loadedModules.find(std::string_view(mod.name));
|
||||
it != loadedModules.end()) {
|
||||
module->importedModules.emplace_back(it->second);
|
||||
continue;
|
||||
}
|
||||
|
||||
module->importedModules.push_back({});
|
||||
}
|
||||
|
||||
module->relocate(thread->tproc);
|
||||
}
|
||||
}
|
||||
|
||||
*pHandle = module->id;
|
||||
return {};
|
||||
}
|
||||
@ -554,6 +580,7 @@ SysResult processNeeded(Thread *thread) {
|
||||
}
|
||||
|
||||
for (auto [id, module] : thread->tproc->modulesMap) {
|
||||
module->importedModules.clear();
|
||||
module->importedModules.reserve(module->neededModules.size());
|
||||
|
||||
for (auto mod : module->neededModules) {
|
||||
|
Loading…
Reference in New Issue
Block a user