mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 09:00:17 +02:00
Move Linux version calculation to common code
This commit is contained in:
10 files changed
+69
-53
No files matched your search
@@ -14,7 +14,8 @@ if (NOT MINGW)
|
||||
list(APPEND SRCS
|
||||
FEXServerClient.cpp
|
||||
FileFormatCheck.cpp
|
||||
Linux/SBRKAllocations.cpp)
|
||||
Linux/SBRKAllocations.cpp
|
||||
Linux/LinuxVersion.cpp)
|
||||
endif()
|
||||
|
||||
add_library(${NAME} STATIC ${SRCS})
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#include <cstdint>
|
||||
#include <charconv>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
namespace FEX::LinuxVersion {
|
||||
uint32_t CalculateHostKernelVersion() {
|
||||
struct utsname buf {};
|
||||
if (uname(&buf) == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Major {};
|
||||
uint32_t Minor {};
|
||||
uint32_t Patch {};
|
||||
|
||||
// Parse kernel version in the form of `<Major>.<Minor>.<Patch>[Optional Data]`
|
||||
const auto End = buf.release + sizeof(buf.release);
|
||||
auto Results = std::from_chars(buf.release, End, Major, 10);
|
||||
Results = std::from_chars(Results.ptr + 1, End, Minor, 10);
|
||||
Results = std::from_chars(Results.ptr + 1, End, Patch, 10);
|
||||
|
||||
return (Major << 24) | (Minor << 16) | Patch;
|
||||
}
|
||||
} // namespace FEX::LinuxVersion
|
||||
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace FEX::LinuxVersion {
|
||||
inline uint32_t KernelVersion(uint32_t Major, uint32_t Minor = 0, uint32_t Patch = 0) {
|
||||
return (Major << 24) | (Minor << 16) | Patch;
|
||||
}
|
||||
|
||||
inline uint32_t KernelMajor(uint32_t Version) {
|
||||
return Version >> 24;
|
||||
}
|
||||
inline uint32_t KernelMinor(uint32_t Version) {
|
||||
return (Version >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
inline uint32_t KernelPatch(uint32_t Version) {
|
||||
return Version & 0xFFFF;
|
||||
}
|
||||
|
||||
uint32_t CalculateHostKernelVersion();
|
||||
} // namespace FEX::LinuxVersion
|
||||
@@ -297,8 +297,8 @@ public:
|
||||
#ifndef AT_FLAGS_PRESERVE_ARGV0
|
||||
#define AT_FLAGS_PRESERVE_ARGV0 1
|
||||
#endif
|
||||
uint32_t HostKernel = FEX::HLE::SyscallHandler::CalculateHostKernelVersion();
|
||||
if ((HostKernel >= FEX::HLE::SyscallHandler::KernelVersion(5, 12, 0) && (AtFlags & AT_FLAGS_PRESERVE_ARGV0)) || LoadedWithFD) {
|
||||
uint32_t HostKernel = FEX::LinuxVersion::CalculateHostKernelVersion();
|
||||
if ((HostKernel >= FEX::LinuxVersion::KernelVersion(5, 12, 0) && (AtFlags & AT_FLAGS_PRESERVE_ARGV0)) || LoadedWithFD) {
|
||||
|
||||
// Erase the initial argument from the list in this case
|
||||
ApplicationArgs.erase(ApplicationArgs.begin());
|
||||
|
||||
@@ -10,6 +10,7 @@ $end_info$
|
||||
#include "Common/FEXServerClient.h"
|
||||
#include "Common/Config.h"
|
||||
#include "Common/HostFeatures.h"
|
||||
#include "Common/Linux/LinuxVersion.h"
|
||||
#include "Common/Linux/SBRKAllocations.h"
|
||||
#include "PortabilityInfo.h"
|
||||
#include "ELFCodeLoader.h"
|
||||
@@ -463,8 +464,8 @@ int main(int argc, char** argv, char** const envp) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
uint32_t KernelVersion = FEX::HLE::SyscallHandler::CalculateHostKernelVersion();
|
||||
if (KernelVersion < FEX::HLE::SyscallHandler::KernelVersion(5, 15)) {
|
||||
uint32_t KernelVersion = FEX::LinuxVersion::CalculateHostKernelVersion();
|
||||
if (KernelVersion < FEX::LinuxVersion::KernelVersion(5, 15)) {
|
||||
LogMan::Msg::EFmt("FEX requires kernel 5.15 minimum. Expect problems.");
|
||||
}
|
||||
|
||||
|
||||
@@ -532,8 +532,8 @@ EmulatedFDManager::EmulatedFDManager(FEXCore::Context::Context* ctx)
|
||||
int FD = GenTmpFD(pathname, flags);
|
||||
uint32_t GuestVersion = FEX::HLE::_SyscallHandler->GetGuestKernelVersion();
|
||||
char Tmp[64] {};
|
||||
snprintf(Tmp, sizeof(Tmp), "%d.%d.%d\n", FEX::HLE::SyscallHandler::KernelMajor(GuestVersion),
|
||||
FEX::HLE::SyscallHandler::KernelMinor(GuestVersion), FEX::HLE::SyscallHandler::KernelPatch(GuestVersion));
|
||||
snprintf(Tmp, sizeof(Tmp), "%d.%d.%d\n", FEX::LinuxVersion::KernelMajor(GuestVersion), FEX::LinuxVersion::KernelMinor(GuestVersion),
|
||||
FEX::LinuxVersion::KernelPatch(GuestVersion));
|
||||
// + 1 to ensure null at the end
|
||||
write(FD, Tmp, strlen(Tmp) + 1);
|
||||
lseek(FD, 0, SEEK_SET);
|
||||
@@ -548,8 +548,8 @@ EmulatedFDManager::EmulatedFDManager(FEXCore::Context::Context* ctx)
|
||||
const char kernel_version[] = "Linux version %d.%d.%d (FEX@FEX) (clang) #" GIT_DESCRIBE_STRING " SMP " __DATE__ " " __TIME__ "\n";
|
||||
uint32_t GuestVersion = FEX::HLE::_SyscallHandler->GetGuestKernelVersion();
|
||||
char Tmp[sizeof(kernel_version) + 64] {};
|
||||
snprintf(Tmp, sizeof(Tmp), kernel_version, FEX::HLE::SyscallHandler::KernelMajor(GuestVersion),
|
||||
FEX::HLE::SyscallHandler::KernelMinor(GuestVersion), FEX::HLE::SyscallHandler::KernelPatch(GuestVersion));
|
||||
snprintf(Tmp, sizeof(Tmp), kernel_version, FEX::LinuxVersion::KernelMajor(GuestVersion), FEX::LinuxVersion::KernelMinor(GuestVersion),
|
||||
FEX::LinuxVersion::KernelPatch(GuestVersion));
|
||||
// + 1 to ensure null at the end
|
||||
write(FD, Tmp, strlen(Tmp) + 1);
|
||||
lseek(FD, 0, SEEK_SET);
|
||||
|
||||
@@ -790,7 +790,7 @@ SyscallHandler::SyscallHandler(FEXCore::Context::Context* _CTX, FEX::HLE::Signal
|
||||
, SignalDelegation {_SignalDelegation}
|
||||
, ThunkHandler {ThunkHandler} {
|
||||
FEX::HLE::_SyscallHandler = this;
|
||||
HostKernelVersion = CalculateHostKernelVersion();
|
||||
HostKernelVersion = LinuxVersion::CalculateHostKernelVersion();
|
||||
GuestKernelVersion = CalculateGuestKernelVersion();
|
||||
Alloc32Handler = FEX::HLE::Create32BitAllocator();
|
||||
|
||||
@@ -803,28 +803,9 @@ SyscallHandler::~SyscallHandler() {
|
||||
FEXCore::Allocator::munmap(reinterpret_cast<void*>(DataSpace), DataSpaceMappedSize);
|
||||
}
|
||||
|
||||
uint32_t SyscallHandler::CalculateHostKernelVersion() {
|
||||
struct utsname buf {};
|
||||
if (uname(&buf) == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Major {};
|
||||
uint32_t Minor {};
|
||||
uint32_t Patch {};
|
||||
|
||||
// Parse kernel version in the form of `<Major>.<Minor>.<Patch>[Optional Data]`
|
||||
const auto End = buf.release + sizeof(buf.release);
|
||||
auto Results = std::from_chars(buf.release, End, Major, 10);
|
||||
Results = std::from_chars(Results.ptr + 1, End, Minor, 10);
|
||||
Results = std::from_chars(Results.ptr + 1, End, Patch, 10);
|
||||
|
||||
return (Major << 24) | (Minor << 16) | Patch;
|
||||
}
|
||||
|
||||
uint32_t SyscallHandler::CalculateGuestKernelVersion() {
|
||||
// We currently only emulate a kernel between the ranges of Kernel 5.15.0 and 6.11.0
|
||||
return std::max(KernelVersion(5, 15), std::min(KernelVersion(6, 11), GetHostKernelVersion()));
|
||||
return std::max(LinuxVersion::KernelVersion(5, 15), std::min(LinuxVersion::KernelVersion(6, 11), GetHostKernelVersion()));
|
||||
}
|
||||
|
||||
uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::CpuStateFrame* Frame, FEXCore::HLE::SyscallArguments* Args) {
|
||||
|
||||
@@ -8,6 +8,7 @@ $end_info$
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/Linux/LinuxVersion.h"
|
||||
#include "Common/VolatileMetadata.h"
|
||||
#include "LinuxSyscalls/FileManagement.h"
|
||||
#include "LinuxSyscalls/LinuxAllocator.h"
|
||||
@@ -210,26 +211,11 @@ public:
|
||||
}
|
||||
|
||||
bool IsHostKernelVersionAtLeast(uint32_t Major, uint32_t Minor = 0, uint32_t Patch = 0) const {
|
||||
return GetHostKernelVersion() >= KernelVersion(Major, Minor, Patch);
|
||||
return GetHostKernelVersion() >= LinuxVersion::KernelVersion(Major, Minor, Patch);
|
||||
}
|
||||
|
||||
static uint32_t CalculateHostKernelVersion();
|
||||
uint32_t CalculateGuestKernelVersion();
|
||||
|
||||
static uint32_t KernelVersion(uint32_t Major, uint32_t Minor = 0, uint32_t Patch = 0) {
|
||||
return (Major << 24) | (Minor << 16) | Patch;
|
||||
}
|
||||
|
||||
static uint32_t KernelMajor(uint32_t Version) {
|
||||
return Version >> 24;
|
||||
}
|
||||
static uint32_t KernelMinor(uint32_t Version) {
|
||||
return (Version >> 16) & 0xFF;
|
||||
}
|
||||
static uint32_t KernelPatch(uint32_t Version) {
|
||||
return Version & 0xFFFF;
|
||||
}
|
||||
|
||||
virtual FEX::HLE::MemAllocator* Get32BitAllocator() {
|
||||
return Alloc32Handler.get();
|
||||
}
|
||||
|
||||
@@ -51,10 +51,10 @@ void RegisterInfo(FEX::HLE::SyscallHandler* Handler) {
|
||||
uint32_t GuestVersion = FEX::HLE::_SyscallHandler->GetGuestKernelVersion();
|
||||
if (Thread->persona & UNAME26) {
|
||||
// Kernel version converts from 6.x.y to 2.6.60+x.
|
||||
GuestVersion = FEX::HLE::SyscallHandler::KernelVersion(2, 6, 60 + FEX::HLE::SyscallHandler::KernelMinor(GuestVersion));
|
||||
GuestVersion = FEX::LinuxVersion::KernelVersion(2, 6, 60 + FEX::LinuxVersion::KernelMinor(GuestVersion));
|
||||
}
|
||||
snprintf(buf->release, sizeof(buf->release), "%d.%d.%d", FEX::HLE::SyscallHandler::KernelMajor(GuestVersion),
|
||||
FEX::HLE::SyscallHandler::KernelMinor(GuestVersion), FEX::HLE::SyscallHandler::KernelPatch(GuestVersion));
|
||||
snprintf(buf->release, sizeof(buf->release), "%d.%d.%d", FEX::LinuxVersion::KernelMajor(GuestVersion),
|
||||
FEX::LinuxVersion::KernelMinor(GuestVersion), FEX::LinuxVersion::KernelPatch(GuestVersion));
|
||||
|
||||
const char version[] = "#" GIT_DESCRIBE_STRING " SMP " __DATE__ " " __TIME__;
|
||||
strcpy(buf->version, version);
|
||||
|
||||
@@ -61,8 +61,8 @@ void RegisterInfo(FEX::HLE::SyscallHandler* Handler) {
|
||||
}
|
||||
strncpy(buf->sysname, "Linux", __OLD_UTS_LEN);
|
||||
uint32_t GuestVersion = FEX::HLE::_SyscallHandler->GetGuestKernelVersion();
|
||||
snprintf(buf->release, __OLD_UTS_LEN, "%d.%d.%d", FEX::HLE::SyscallHandler::KernelMajor(GuestVersion),
|
||||
FEX::HLE::SyscallHandler::KernelMinor(GuestVersion), FEX::HLE::SyscallHandler::KernelPatch(GuestVersion));
|
||||
snprintf(buf->release, __OLD_UTS_LEN, "%d.%d.%d", FEX::LinuxVersion::KernelMajor(GuestVersion),
|
||||
FEX::LinuxVersion::KernelMinor(GuestVersion), FEX::LinuxVersion::KernelPatch(GuestVersion));
|
||||
|
||||
const char version[] = "#" GIT_DESCRIBE_STRING " SMP " __DATE__ " " __TIME__;
|
||||
strncpy(buf->version, version, __OLD_UTS_LEN);
|
||||
@@ -85,8 +85,8 @@ void RegisterInfo(FEX::HLE::SyscallHandler* Handler) {
|
||||
}
|
||||
strncpy(buf->sysname, "Linux", __NEW_UTS_LEN);
|
||||
uint32_t GuestVersion = FEX::HLE::_SyscallHandler->GetGuestKernelVersion();
|
||||
snprintf(buf->release, __NEW_UTS_LEN, "%d.%d.%d", FEX::HLE::SyscallHandler::KernelMajor(GuestVersion),
|
||||
FEX::HLE::SyscallHandler::KernelMinor(GuestVersion), FEX::HLE::SyscallHandler::KernelPatch(GuestVersion));
|
||||
snprintf(buf->release, __NEW_UTS_LEN, "%d.%d.%d", FEX::LinuxVersion::KernelMajor(GuestVersion),
|
||||
FEX::LinuxVersion::KernelMinor(GuestVersion), FEX::LinuxVersion::KernelPatch(GuestVersion));
|
||||
|
||||
const char version[] = "#" GIT_DESCRIBE_STRING " SMP " __DATE__ " " __TIME__;
|
||||
strncpy(buf->version, version, __NEW_UTS_LEN);
|
||||
|
||||
Reference in new issue
Block a user