Misc implementations and fixes. (#250)

* Implement `sceKernelFtruncate` and `sceKernelUnlink`.

* Remove unused variable.

* Implement `sceKernelReserveVirtualRange`, misc fixes

* Fix `sceKernelReserveVirtualRange`.

* Add TODO on reserve

* Replace comment with assert.

* Add missing copyright header

* Add `UNREACHABLE` for `IOFile::Unlink`.

* Move NT API initialization out of the header

* Fix bug where files were always mapped as read only.

* `clang-format`
This commit is contained in:
Daniel R 2024-07-11 14:35:58 +02:00 committed by GitHub
parent 989f88837d
commit 914aa10875
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 331 additions and 19 deletions

View file

@ -157,6 +157,33 @@ size_t PS4_SYSV_ABI sceKernelWrite(int d, const void* buf, size_t nbytes) {
return file->f.WriteRaw<u8>(buf, nbytes);
}
int PS4_SYSV_ABI sceKernelUnlink(const char* path) {
if (path == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
std::string host_path = mnt->GetHostFile(path);
if (host_path.empty()) {
return SCE_KERNEL_ERROR_EACCES;
}
if (std::filesystem::is_directory(host_path)) {
return SCE_KERNEL_ERROR_EPERM;
}
auto* file = h->getFile(host_path);
if (file != nullptr) {
file->f.Unlink();
}
LOG_INFO(Kernel_Fs, "Unlinked {}", path);
return SCE_OK;
}
size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) {
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(d);
@ -356,6 +383,22 @@ s32 PS4_SYSV_ABI sceKernelFsync(int fd) {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelFtruncate(int fd, s64 length) {
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(fd);
if (file == nullptr) {
return SCE_KERNEL_ERROR_EBADF;
}
if (file->m_host_name.empty()) {
return SCE_KERNEL_ERROR_EACCES;
}
file->f.SetSize(length);
return SCE_OK;
}
static int GetDents(int fd, char* buf, int nbytes, s64* basep) {
// TODO error codes
ASSERT(buf != nullptr);
@ -372,7 +415,7 @@ static int GetDents(int fd, char* buf, int nbytes, s64* basep) {
static int fileno = 1000; // random
OrbisKernelDirent* sce_ent = (OrbisKernelDirent*)buf;
sce_ent->d_fileno = fileno++; // TODO this should be unique but atm it changes maybe switch to a
// hash or something?
// hash or something?
sce_ent->d_reclen = sizeof(OrbisKernelDirent);
sce_ent->d_type = (entry.isFile ? 8 : 4);
sce_ent->d_namlen = str_size;
@ -435,6 +478,7 @@ void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("eV9wAD2riIA", "libkernel", 1, "libkernel", 1, 1, sceKernelStat);
LIB_FUNCTION("kBwCPsYX-m4", "libkernel", 1, "libkernel", 1, 1, sceKernelFStat);
LIB_FUNCTION("mqQMh1zPPT8", "libScePosix", 1, "libkernel", 1, 1, posix_fstat);
LIB_FUNCTION("VW3TVZiM4-E", "libkernel", 1, "libkernel", 1, 1, sceKernelFtruncate);
LIB_FUNCTION("E6ao34wPw+U", "libScePosix", 1, "libkernel", 1, 1, posix_stat);
LIB_FUNCTION("+r3rMFwItV4", "libkernel", 1, "libkernel", 1, 1, sceKernelPread);
@ -443,6 +487,7 @@ void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("j2AIqSqJP0w", "libkernel", 1, "libkernel", 1, 1, sceKernelGetdents);
LIB_FUNCTION("taRWhTJFTgE", "libkernel", 1, "libkernel", 1, 1, sceKernelGetdirentries);
LIB_FUNCTION("nKWi-N2HBV4", "libkernel", 1, "libkernel", 1, 1, sceKernelPwrite);
LIB_FUNCTION("AUXVxWeJU-A", "libkernel", 1, "libkernel", 1, 1, sceKernelUnlink);
// openOrbis (to check if it is valid out of OpenOrbis
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1,

View file

@ -370,6 +370,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("hwVSPCmp5tM", "libkernel", 1, "libkernel", 1, 1,
sceKernelCheckedReleaseDirectMemory);
LIB_FUNCTION("rVjRvHJ0X6c", "libkernel", 1, "libkernel", 1, 1, sceKernelVirtualQuery);
LIB_FUNCTION("7oxv3PPCumo", "libkernel", 1, "libkernel", 1, 1, sceKernelReserveVirtualRange);
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory);
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);

View file

@ -87,6 +87,33 @@ s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtual
return memory->VirtualQuery(std::bit_cast<VAddr>(addr), flags, info);
}
s32 PS4_SYSV_ABI sceKernelReserveVirtualRange(void** addr, u64 len, int flags, u64 alignment) {
LOG_INFO(Kernel_Vmm, "addr = {}, len = {:#x}, flags = {:#x}, alignment = {:#x}",
fmt::ptr(*addr), len, flags, alignment);
if (addr == nullptr) {
LOG_ERROR(Kernel_Vmm, "Address is invalid!");
return SCE_KERNEL_ERROR_EINVAL;
}
if (len == 0 || !Common::Is16KBAligned(len)) {
LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 16KB aligned!");
return SCE_KERNEL_ERROR_EINVAL;
}
if (alignment != 0) {
if ((!std::has_single_bit(alignment) && !Common::Is16KBAligned(alignment))) {
LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!");
return SCE_KERNEL_ERROR_EINVAL;
}
}
auto* memory = Core::Memory::Instance();
const VAddr in_addr = reinterpret_cast<VAddr>(*addr);
const auto map_flags = static_cast<Core::MemoryMapFlags>(flags);
memory->Reserve(addr, in_addr, len, map_flags, alignment);
return SCE_OK;
}
int PS4_SYSV_ABI sceKernelMapNamedDirectMemory(void** addr, u64 len, int prot, int flags,
s64 directMemoryStart, u64 alignment,
const char* name) {

View file

@ -70,6 +70,7 @@ s32 PS4_SYSV_ABI sceKernelAvailableDirectMemorySize(u64 searchStart, u64 searchE
size_t* sizeOut);
s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtualQueryInfo* info,
size_t infoSize);
s32 PS4_SYSV_ABI sceKernelReserveVirtualRange(void** addr, u64 len, int flags, u64 alignment);
s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addrInOut, std::size_t len, int prot,
int flags, const char* name);
s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, std::size_t len, int prot,

View file

@ -12,10 +12,8 @@
#include <pthread_time.h>
#include <windows.h>
// http://stackoverflow.com/a/31411628/4725495
static u32(__stdcall* NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval) =
(u32(__stdcall*)(BOOL, PLARGE_INTEGER))GetProcAddress(GetModuleHandleA("ntdll.dll"),
"NtDelayExecution");
#include "common/ntapi.h"
#else
#include <time.h>
#include <unistd.h>