Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinuxSyscalls: Update for new v6.13 syscalls #4283

Merged
merged 1 commit into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading