Skip to content

Commit

Permalink
Merge pull request #4283 from Sonicadvance1/v6.13_syscalls
Browse files Browse the repository at this point in the history
LinuxSyscalls: Update for new v6.13 syscalls
  • Loading branch information
lioncash authored Jan 21, 2025
2 parents bb6e98a + fca4c7e commit ac1b6d9
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ enum Syscalls_Arm64 {
SYSCALL_Arm64_lsm_set_self_attr = 460,
SYSCALL_Arm64_lsm_list_modules = 461,
SYSCALL_Arm64_mseal = 462,
SYSCALL_Arm64_setxattrat = 463,
SYSCALL_Arm64_getxattrat = 464,
SYSCALL_Arm64_listxattrat = 465,
SYSCALL_Arm64_removexattrat = 466,
SYSCALL_Arm64_MAX = 512,

// Unsupported syscalls on this host
Expand Down
80 changes: 80 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,86 @@ uint64_t FileManager::LRemovexattr(const char* path, const char* name) {
return ::lremovexattr(SelfPath, name);
}

uint64_t FileManager::SetxattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name, const xattr_args* uargs, size_t usize) {
if (IsSelfNoFollow(pathname, at_flags)) {
// See Statx
return syscall(SYSCALL_DEF(setxattrat), dfd, pathname, at_flags, name, uargs, usize);
}

auto NewPath = GetSelf(pathname);
const char* SelfPath = NewPath ? NewPath->data() : nullptr;

FDPathTmpData TmpFilename;
auto Path = GetEmulatedFDPath(dfd, SelfPath, (at_flags & AT_SYMLINK_NOFOLLOW) == 0, TmpFilename);
if (Path.first != -1) {
uint64_t Result = syscall(SYSCALL_DEF(setxattrat), Path.first, Path.second, at_flags, name, uargs, usize);
if (Result != -1) {
return Result;
}
}
return syscall(SYSCALL_DEF(setxattrat), dfd, SelfPath, at_flags, name, uargs, usize);
}

uint64_t FileManager::GetxattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name, const xattr_args* uargs, size_t usize) {
if (IsSelfNoFollow(pathname, at_flags)) {
// See Statx
return syscall(SYSCALL_DEF(getxattrat), dfd, pathname, at_flags, name, uargs, usize);
}

auto NewPath = GetSelf(pathname);
const char* SelfPath = NewPath ? NewPath->data() : nullptr;

FDPathTmpData TmpFilename;
auto Path = GetEmulatedFDPath(dfd, SelfPath, (at_flags & AT_SYMLINK_NOFOLLOW) == 0, TmpFilename);
if (Path.first != -1) {
uint64_t Result = syscall(SYSCALL_DEF(getxattrat), Path.first, Path.second, at_flags, name, uargs, usize);
if (Result != -1) {
return Result;
}
}
return syscall(SYSCALL_DEF(getxattrat), dfd, SelfPath, at_flags, name, uargs, usize);
}

uint64_t FileManager::ListxattrAt(int dfd, const char* pathname, uint32_t at_flags, char* list, size_t size) {
if (IsSelfNoFollow(pathname, at_flags)) {
// See Statx
return syscall(SYSCALL_DEF(listxattrat), dfd, pathname, at_flags, list, size);
}

auto NewPath = GetSelf(pathname);
const char* SelfPath = NewPath ? NewPath->data() : nullptr;

FDPathTmpData TmpFilename;
auto Path = GetEmulatedFDPath(dfd, SelfPath, (at_flags & AT_SYMLINK_NOFOLLOW) == 0, TmpFilename);
if (Path.first != -1) {
uint64_t Result = syscall(SYSCALL_DEF(listxattrat), Path.first, Path.second, at_flags, list, size);
if (Result != -1) {
return Result;
}
}
return syscall(SYSCALL_DEF(listxattrat), dfd, SelfPath, at_flags, list, size);
}

uint64_t FileManager::RemovexattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name) {
if (IsSelfNoFollow(pathname, at_flags)) {
// See Statx
return syscall(SYSCALL_DEF(removexattrat), dfd, pathname, at_flags, name);
}

auto NewPath = GetSelf(pathname);
const char* SelfPath = NewPath ? NewPath->data() : nullptr;

FDPathTmpData TmpFilename;
auto Path = GetEmulatedFDPath(dfd, SelfPath, (at_flags & AT_SYMLINK_NOFOLLOW) == 0, TmpFilename);
if (Path.first != -1) {
uint64_t Result = syscall(SYSCALL_DEF(removexattrat), Path.first, Path.second, at_flags, name);
if (Result != -1) {
return Result;
}
}
return syscall(SYSCALL_DEF(removexattrat), dfd, SelfPath, at_flags, name);
}

void FileManager::UpdatePID(uint32_t PID) {
CurrentPID = PID;

Expand Down
11 changes: 11 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ class FileManager final {
uint64_t LListxattr(const char* path, char* list, size_t size);
uint64_t Removexattr(const char* path, const char* name);
uint64_t LRemovexattr(const char* path, const char* name);
struct xattr_args {
uint64_t value;
uint32_t size;
uint32_t flags;
};

uint64_t SetxattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name, const xattr_args* uargs, size_t usize);
uint64_t GetxattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name, const xattr_args* uargs, size_t usize);
uint64_t ListxattrAt(int dfd, const char* pathname, uint32_t at_flags, char* list, size_t size);
uint64_t RemovexattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name);

// vfs
uint64_t Statfs(const char* path, void* buf);

Expand Down
26 changes: 26 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/FS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,31 @@ void RegisterFS(FEX::HLE::SyscallHandler* Handler) {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.LRemovexattr(path, name);
SYSCALL_ERRNO();
});
if (Handler->IsHostKernelVersionAtLeast(6, 13, 0)) {
REGISTER_SYSCALL_IMPL(
setxattrat, [](int dfd, const char* pathname, uint32_t at_flags, const char* name, const FileManager::xattr_args* uargs, size_t usize) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.SetxattrAt(dfd, pathname, at_flags, name, uargs, usize);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(
getxattrat, [](int dfd, const char* pathname, uint32_t at_flags, const char* name, const FileManager::xattr_args* uargs, size_t usize) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.GetxattrAt(dfd, pathname, at_flags, name, uargs, usize);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL(listxattrat, [](int dfd, const char* pathname, uint32_t at_flags, char* list, size_t size) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.ListxattrAt(dfd, pathname, at_flags, list, size);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(removexattrat, [](int dfd, const char* pathname, uint32_t at_flags, const char* name) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.RemovexattrAt(dfd, pathname, at_flags, name);
SYSCALL_ERRNO();
});
} else {
REGISTER_SYSCALL_IMPL(setxattrat, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(getxattrat, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(listxattrat, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(removexattrat, UnimplementedSyscallSafe);
}
}
} // namespace FEX::HLE
4 changes: 4 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/x32/SyscallsEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,10 @@ enum Syscalls_x86 {
SYSCALL_x86_lsm_set_self_attr = 460,
SYSCALL_x86_lsm_list_modules = 461,
SYSCALL_x86_mseal = 462,
SYSCALL_x86_setxattrat = 463,
SYSCALL_x86_getxattrat = 464,
SYSCALL_x86_listxattrat = 465,
SYSCALL_x86_removexattrat = 466,
SYSCALL_x86_MAX = 512,
};
} // namespace FEX::HLE::x32
4 changes: 4 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/x64/SyscallsEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ enum Syscalls_x64 {
SYSCALL_x64_lsm_set_self_attr = 460,
SYSCALL_x64_lsm_list_modules = 461,
SYSCALL_x64_mseal = 462,
SYSCALL_x64_setxattrat = 463,
SYSCALL_x64_getxattrat = 464,
SYSCALL_x64_listxattrat = 465,
SYSCALL_x64_removexattrat = 466,
SYSCALL_x64_MAX = 512,

// Unsupported syscalls on this host
Expand Down

0 comments on commit ac1b6d9

Please sign in to comment.