core: Address a few more regressions (#202)
* tls: Actaully fix TLS on linux * emulator: Remove nptoolkit * Not quite supported yet, makes games misbehave * kernel: Back to SCHED_OTHER * kernel: Remove unused signal function * address_space: Fix Unmap call on linux * clang format
This commit is contained in:
parent
3552484b33
commit
ca25333a1e
|
@ -267,7 +267,7 @@ struct AddressSpace::Impl {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unmap(VAddr virtual_addr, PAddr phys_addr, size_t size) {
|
void Unmap(VAddr virtual_addr, size_t size, bool) {
|
||||||
// Check to see if we are adjacent to any regions.
|
// Check to see if we are adjacent to any regions.
|
||||||
auto start_address = virtual_addr;
|
auto start_address = virtual_addr;
|
||||||
auto end_address = start_address + size;
|
auto end_address = start_address + size;
|
||||||
|
|
|
@ -262,18 +262,8 @@ int PS4_SYSV_ABI sceKernelDebugRaiseException() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char PS4_SYSV_ABI _is_signal_return(s64* param_1) {
|
|
||||||
char cVar1;
|
|
||||||
|
|
||||||
if (((*param_1 != 0x48006a40247c8d48ULL) || (param_1[1] != 0x50f000001a1c0c7ULL)) ||
|
|
||||||
(cVar1 = '\x01', (param_1[2] & 0xffffffU) != 0xfdebf4)) {
|
|
||||||
cVar1 = ((*(u64*)((s64)param_1 + -5) & 0xffffffffff) == 0x50fca8949) * '\x02';
|
|
||||||
}
|
|
||||||
return cVar1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelGetCpumode() {
|
int PS4_SYSV_ABI sceKernelGetCpumode() {
|
||||||
return 5;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS4_SYSV_ABI sched_yield() {
|
void PS4_SYSV_ABI sched_yield() {
|
||||||
|
@ -347,7 +337,6 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
|
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
|
||||||
LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCompiledSdkVersion);
|
LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCompiledSdkVersion);
|
||||||
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
|
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
|
||||||
LIB_FUNCTION("crb5j7mkk1c", "libkernel", 1, "libkernel", 1, 1, _is_signal_return);
|
|
||||||
|
|
||||||
Libraries::Kernel::fileSystemSymbolsRegister(sym);
|
Libraries::Kernel::fileSystemSymbolsRegister(sym);
|
||||||
Libraries::Kernel::timeSymbolsRegister(sym);
|
Libraries::Kernel::timeSymbolsRegister(sym);
|
||||||
|
|
|
@ -42,7 +42,6 @@ void init_pthreads() {
|
||||||
scePthreadRwlockattrInit(&default_rwattr);
|
scePthreadRwlockattrInit(&default_rwattr);
|
||||||
g_pthread_cxt->setDefaultRwattr(default_rwattr);
|
g_pthread_cxt->setDefaultRwattr(default_rwattr);
|
||||||
|
|
||||||
g_pthread_cxt->setPthreadKeys(new PthreadKeys);
|
|
||||||
g_pthread_cxt->SetPthreadPool(new PThreadPool);
|
g_pthread_cxt->SetPthreadPool(new PThreadPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,8 +236,9 @@ int PS4_SYSV_ABI scePthreadAttrSetschedparam(ScePthreadAttr* attr,
|
||||||
pparam.sched_priority = 0;
|
pparam.sched_priority = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = pthread_attr_setschedparam(&(*attr)->pth_attr, &pparam);
|
// We always use SCHED_OTHER for now, so don't call this for now.
|
||||||
|
// int result = pthread_attr_setschedparam(&(*attr)->pth_attr, &pparam);
|
||||||
|
int result = 0;
|
||||||
return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
|
return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,19 +271,9 @@ int PS4_SYSV_ABI scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy)
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ppolicy = SCHED_OTHER;
|
int ppolicy = SCHED_OTHER; // winpthreads only supports SCHED_OTHER
|
||||||
switch (policy) {
|
if (policy != SCHED_OTHER) {
|
||||||
case 0:
|
LOG_ERROR(Kernel_Pthread, "policy={} not supported by winpthreads", policy);
|
||||||
ppolicy = SCHED_OTHER;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ppolicy = SCHED_FIFO;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
ppolicy = SCHED_OTHER;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*attr)->policy = policy;
|
(*attr)->policy = policy;
|
||||||
|
@ -1274,7 +1264,9 @@ int PS4_SYSV_ABI scePthreadGetschedparam(ScePthread thread, int* policy,
|
||||||
|
|
||||||
int PS4_SYSV_ABI scePthreadSetschedparam(ScePthread thread, int policy,
|
int PS4_SYSV_ABI scePthreadSetschedparam(ScePthread thread, int policy,
|
||||||
const SceKernelSchedParam* param) {
|
const SceKernelSchedParam* param) {
|
||||||
return pthread_setschedparam(thread->pth, policy, param);
|
LOG_ERROR(Kernel_Pthread, "(STUBBED) called policy={}, sched_priority={}", policy,
|
||||||
|
param->sched_priority);
|
||||||
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
|
int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
|
||||||
|
|
|
@ -113,30 +113,6 @@ private:
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PthreadKeys {
|
|
||||||
public:
|
|
||||||
PthreadKeys() {}
|
|
||||||
virtual ~PthreadKeys() {}
|
|
||||||
|
|
||||||
bool CreateKey(int* key, PthreadKeyDestructor destructor);
|
|
||||||
bool GetKey(int key, int thread_id, void** data);
|
|
||||||
bool SetKey(int key, int thread_id, void* data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Map {
|
|
||||||
int thread_id = -1;
|
|
||||||
void* data = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Key {
|
|
||||||
bool used = false;
|
|
||||||
PthreadKeyDestructor destructor = nullptr;
|
|
||||||
std::vector<Map> specific_values;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::mutex m_mutex;
|
|
||||||
Key m_keys[256];
|
|
||||||
};
|
|
||||||
class PThreadCxt {
|
class PThreadCxt {
|
||||||
public:
|
public:
|
||||||
ScePthreadMutexattr* getDefaultMutexattr() {
|
ScePthreadMutexattr* getDefaultMutexattr() {
|
||||||
|
@ -169,12 +145,6 @@ public:
|
||||||
void setDefaultRwattr(OrbisPthreadRwlockattr attr) {
|
void setDefaultRwattr(OrbisPthreadRwlockattr attr) {
|
||||||
m_default_Rwattr = attr;
|
m_default_Rwattr = attr;
|
||||||
}
|
}
|
||||||
PthreadKeys* getPthreadKeys() {
|
|
||||||
return m_pthread_keys;
|
|
||||||
}
|
|
||||||
void setPthreadKeys(PthreadKeys* keys) {
|
|
||||||
m_pthread_keys = keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScePthreadMutexattr m_default_mutexattr = nullptr;
|
ScePthreadMutexattr m_default_mutexattr = nullptr;
|
||||||
|
@ -182,7 +152,6 @@ private:
|
||||||
ScePthreadAttr m_default_attr = nullptr;
|
ScePthreadAttr m_default_attr = nullptr;
|
||||||
PThreadPool* m_pthread_pool = nullptr;
|
PThreadPool* m_pthread_pool = nullptr;
|
||||||
OrbisPthreadRwlockattr m_default_Rwattr = nullptr;
|
OrbisPthreadRwlockattr m_default_Rwattr = nullptr;
|
||||||
PthreadKeys* m_pthread_keys = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_pthreads();
|
void init_pthreads();
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct wrapper_impl<name, PS4_SYSV_ABI R (*)(Args...), f> {
|
||||||
static R PS4_SYSV_ABI wrap(Args... args) {
|
static R PS4_SYSV_ABI wrap(Args... args) {
|
||||||
if (std::string_view(name.value) != "scePthreadEqual" &&
|
if (std::string_view(name.value) != "scePthreadEqual" &&
|
||||||
std::string_view(name.value) != "sceUserServiceGetEvent") {
|
std::string_view(name.value) != "sceUserServiceGetEvent") {
|
||||||
LOG_WARNING(Core_Linker, "Function {} called", name.value);
|
// LOG_WARNING(Core_Linker, "Function {} called", name.value);
|
||||||
}
|
}
|
||||||
if constexpr (std::is_same_v<R, s32> || std::is_same_v<R, u32>) {
|
if constexpr (std::is_same_v<R, s32> || std::is_same_v<R, u32>) {
|
||||||
const u32 ret = f(args...);
|
const u32 ret = f(args...);
|
||||||
|
|
|
@ -100,7 +100,7 @@ Tcb* GetTcbBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AllocTcbKey() {
|
static void AllocTcbKey() {
|
||||||
slot = pthread_key_create(&slot, nullptr);
|
ASSERT(pthread_key_create(&slot, nullptr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PatchFsAccess(u8* code, const TLSPattern& tls_pattern, Xbyak::CodeGenerator& c) {
|
static void PatchFsAccess(u8* code, const TLSPattern& tls_pattern, Xbyak::CodeGenerator& c) {
|
||||||
|
@ -117,17 +117,19 @@ static void PatchFsAccess(u8* code, const TLSPattern& tls_pattern, Xbyak::CodeGe
|
||||||
// The following logic is based on the glibc implementation of pthread_getspecific
|
// The following logic is based on the glibc implementation of pthread_getspecific
|
||||||
// https://github.com/bminor/glibc/blob/29807a27/nptl/pthread_getspecific.c#L23
|
// https://github.com/bminor/glibc/blob/29807a27/nptl/pthread_getspecific.c#L23
|
||||||
static constexpr u32 PthreadKeySecondLevelSize = 32;
|
static constexpr u32 PthreadKeySecondLevelSize = 32;
|
||||||
static constexpr u32 SpecificFirstBlockOffset = 0x308;
|
static constexpr u32 PthreadSpecificOffset = 0x510;
|
||||||
static constexpr u32 SelfInTcbheadOffset = 16;
|
|
||||||
static constexpr u32 PthreadKeyDataSize = 16;
|
static constexpr u32 PthreadKeyDataSize = 16;
|
||||||
ASSERT(slot < PthreadKeySecondLevelSize);
|
ASSERT(slot >= PthreadKeySecondLevelSize);
|
||||||
|
|
||||||
|
const u32 idx1st = slot / PthreadKeySecondLevelSize;
|
||||||
|
const u32 idx2nd = slot % PthreadKeySecondLevelSize;
|
||||||
const auto target_reg = Xbyak::Reg64(tls_pattern.target_reg);
|
const auto target_reg = Xbyak::Reg64(tls_pattern.target_reg);
|
||||||
c.putSeg(fs);
|
c.putSeg(fs);
|
||||||
c.mov(target_reg, qword[SelfInTcbheadOffset]); // Load self member pointer of tcbhead_t.
|
c.mov(target_reg,
|
||||||
c.add(target_reg, SpecificFirstBlockOffset + sizeof(uintptr_t) * 2 + slot * PthreadKeyDataSize);
|
qword[PthreadSpecificOffset + idx1st * 8]); // Load first level specific array.
|
||||||
c.mov(target_reg, qword[target_reg]);
|
c.mov(target_reg, qword[target_reg + idx2nd * 16 +
|
||||||
c.jmp(code + total_size); // Return to the instruction right after the mov.
|
8]); // Load data member of pthread_key_data our slot specifies.
|
||||||
|
c.jmp(code + total_size); // Return to the instruction right after the mov.
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -106,7 +106,6 @@ void Emulator::Run(const std::filesystem::path& file) {
|
||||||
entry.path().filename() == "libSceFios2.prx" ||
|
entry.path().filename() == "libSceFios2.prx" ||
|
||||||
entry.path().filename() == "libSceAudioLatencyEstimation.prx" ||
|
entry.path().filename() == "libSceAudioLatencyEstimation.prx" ||
|
||||||
entry.path().filename() == "libSceJobManager.prx" ||
|
entry.path().filename() == "libSceJobManager.prx" ||
|
||||||
entry.path().filename() == "libSceNpToolkit2.prx" ||
|
|
||||||
entry.path().filename() == "libSceS3DConversion.prx") {
|
entry.path().filename() == "libSceS3DConversion.prx") {
|
||||||
found = true;
|
found = true;
|
||||||
LOG_INFO(Loader, "Loading {}", entry.path().string().c_str());
|
LOG_INFO(Loader, "Loading {}", entry.path().string().c_str());
|
||||||
|
|
Loading…
Reference in New Issue