mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-17 21:00:37 +02:00
Merge pull request #4866 from neobrain/refactor_reformat
Update code formatting
This commit is contained in:
26 files changed
+126
-130
No files matched your search
@@ -20,3 +20,5 @@
|
||||
# Whole-tree reformat with clang-format-19
|
||||
5267cde60e7642852d18f20ae8568643bb5293d5
|
||||
|
||||
# Minor reformat with clang-format-19
|
||||
9fdd96af61c969cb5732471223f00eda64b7a069
|
||||
@@ -2244,8 +2244,7 @@ public:
|
||||
|
||||
template<IsQOrDRegister T>
|
||||
void movi(SubRegSize size, T rd, uint64_t Imm, uint16_t Shift = 0) {
|
||||
LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit ||
|
||||
size == SubRegSize::i64Bit,
|
||||
LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit || size == SubRegSize::i64Bit,
|
||||
"Unsupported movi size");
|
||||
|
||||
uint32_t cmode;
|
||||
|
||||
@@ -998,9 +998,9 @@ void ContextImpl::MonoBackpatcherWrite(FEXCore::Core::CpuStateFrame* Frame, uint
|
||||
auto lk = GuardSignalDeferringSection(CTX->CodeInvalidationMutex, Thread);
|
||||
|
||||
if (Size == 8) {
|
||||
*reinterpret_cast<uint64_t *>(Address) = Value;
|
||||
*reinterpret_cast<uint64_t*>(Address) = Value;
|
||||
} else if (Size == 4) {
|
||||
*reinterpret_cast<uint32_t *>(Address) = Value;
|
||||
*reinterpret_cast<uint32_t*>(Address) = Value;
|
||||
} else {
|
||||
ERROR_AND_DIE_FMT("Unexpected write size for backpatcher: {}", Size);
|
||||
}
|
||||
|
||||
@@ -436,9 +436,8 @@ bool Decoder::NormalOp(const FEXCore::X86Tables::X86InstInfo* Info, uint16_t Op,
|
||||
// If the default operating mode is 32bit and we have the operand size flag then the operating size drops to 16bit
|
||||
DecodeInst->Flags |= DecodeFlags::GenSizeDstSize(DecodeFlags::SIZE_16BIT);
|
||||
DestSize = 2;
|
||||
} else if ((HasXMMDst || HasMMDst || BlockInfo.Is64BitMode) &&
|
||||
(HasWideningDisplacement || DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT ||
|
||||
DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF)) {
|
||||
} else if ((HasXMMDst || HasMMDst || BlockInfo.Is64BitMode) && (HasWideningDisplacement || DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT ||
|
||||
DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF)) {
|
||||
DecodeInst->Flags |= DecodeFlags::GenSizeDstSize(DecodeFlags::SIZE_64BIT);
|
||||
DestSize = 8;
|
||||
} else {
|
||||
@@ -465,9 +464,8 @@ bool Decoder::NormalOp(const FEXCore::X86Tables::X86InstInfo* Info, uint16_t Op,
|
||||
// See table 1-2. Operand-Size Overrides for this decoding
|
||||
// If the default operating mode is 32bit and we have the operand size flag then the operating size drops to 16bit
|
||||
DecodeInst->Flags |= DecodeFlags::GenSizeSrcSize(DecodeFlags::SIZE_16BIT);
|
||||
} else if ((HasXMMSrc || HasMMSrc || BlockInfo.Is64BitMode) &&
|
||||
(HasWideningDisplacement || SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT ||
|
||||
SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF)) {
|
||||
} else if ((HasXMMSrc || HasMMSrc || BlockInfo.Is64BitMode) && (HasWideningDisplacement || SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT ||
|
||||
SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF)) {
|
||||
DecodeInst->Flags |= DecodeFlags::GenSizeSrcSize(DecodeFlags::SIZE_64BIT);
|
||||
} else {
|
||||
DecodeInst->Flags |= DecodeFlags::GenSizeSrcSize(DecodeFlags::SIZE_32BIT);
|
||||
@@ -1301,7 +1299,7 @@ const uint8_t* Decoder::AdjustAddrForSpecialRegion(const uint8_t* _InstStream, u
|
||||
return _InstStream - EntryPoint + RIP;
|
||||
}
|
||||
|
||||
void Decoder::DecodeInstructionsAtEntry(FEXCore::Core::InternalThreadState *Thread, const uint8_t* _InstStream, uint64_t PC, uint64_t MaxInst) {
|
||||
void Decoder::DecodeInstructionsAtEntry(FEXCore::Core::InternalThreadState* Thread, const uint8_t* _InstStream, uint64_t PC, uint64_t MaxInst) {
|
||||
FEXCORE_PROFILE_SCOPED("DecodeInstructions");
|
||||
BlockInfo.TotalInstructionCount = 0;
|
||||
BlockInfo.Blocks.clear();
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
};
|
||||
|
||||
Decoder(FEXCore::Core::InternalThreadState* Thread);
|
||||
void DecodeInstructionsAtEntry(FEXCore::Core::InternalThreadState *Thread, const uint8_t* InstStream, uint64_t PC, uint64_t MaxInst);
|
||||
void DecodeInstructionsAtEntry(FEXCore::Core::InternalThreadState* Thread, const uint8_t* InstStream, uint64_t PC, uint64_t MaxInst);
|
||||
|
||||
const DecodedBlockInformation* GetDecodedBlockInfo() const {
|
||||
return &BlockInfo;
|
||||
|
||||
@@ -87,12 +87,10 @@ void InterpreterOps::FillFallbackIndexPointers(Core::FallbackABIInfo* Info, uint
|
||||
Info[Core::OPINDEX_F64SINCOS] = {ABIHandlers[FABI_F64x2_F64_PTR],
|
||||
reinterpret_cast<uint64_t>(&FEXCore::CPU::OpHandlers<IR::OP_F64SINCOS>::handle)};
|
||||
Info[Core::OPINDEX_F64TAN] = {ABIHandlers[FABI_F64_F64_PTR], reinterpret_cast<uint64_t>(&FEXCore::CPU::OpHandlers<IR::OP_F64TAN>::handle)};
|
||||
Info[Core::OPINDEX_F64F2XM1] = {ABIHandlers[FABI_F64_F64_PTR],
|
||||
reinterpret_cast<uint64_t>(&FEXCore::CPU::OpHandlers<IR::OP_F64F2XM1>::handle)};
|
||||
Info[Core::OPINDEX_F64F2XM1] = {ABIHandlers[FABI_F64_F64_PTR], reinterpret_cast<uint64_t>(&FEXCore::CPU::OpHandlers<IR::OP_F64F2XM1>::handle)};
|
||||
|
||||
// Double Precision Binary
|
||||
Info[Core::OPINDEX_F64ATAN] = {ABIHandlers[FABI_F64_F64_F64_PTR],
|
||||
reinterpret_cast<uint64_t>(&FEXCore::CPU::OpHandlers<IR::OP_F64ATAN>::handle)};
|
||||
Info[Core::OPINDEX_F64ATAN] = {ABIHandlers[FABI_F64_F64_F64_PTR], reinterpret_cast<uint64_t>(&FEXCore::CPU::OpHandlers<IR::OP_F64ATAN>::handle)};
|
||||
Info[Core::OPINDEX_F64FPREM] = {ABIHandlers[FABI_F64_F64_F64_PTR],
|
||||
reinterpret_cast<uint64_t>(&FEXCore::CPU::OpHandlers<IR::OP_F64FPREM>::handle)};
|
||||
Info[Core::OPINDEX_F64FPREM1] = {ABIHandlers[FABI_F64_F64_F64_PTR],
|
||||
@@ -220,21 +218,21 @@ bool InterpreterOps::GetFallbackHandler(const IR::IROp_Header* IROp, FallbackInf
|
||||
return true; \
|
||||
}
|
||||
|
||||
#define COMMON_UNARY_F64_OP(OP) \
|
||||
case IR::OP_F64##OP: { \
|
||||
#define COMMON_UNARY_F64_OP(OP) \
|
||||
case IR::OP_F64##OP: { \
|
||||
*Info = {FABI_F64_F64_PTR, Core::OPINDEX_F64##OP}; \
|
||||
return true; \
|
||||
return true; \
|
||||
}
|
||||
#define COMMON_UNARYPAIR_F64_OP(OP) \
|
||||
case IR::OP_F64##OP: { \
|
||||
#define COMMON_UNARYPAIR_F64_OP(OP) \
|
||||
case IR::OP_F64##OP: { \
|
||||
*Info = {FABI_F64x2_F64_PTR, Core::OPINDEX_F64##OP}; \
|
||||
return true; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
#define COMMON_BINARY_F64_OP(OP) \
|
||||
case IR::OP_F64##OP: { \
|
||||
#define COMMON_BINARY_F64_OP(OP) \
|
||||
case IR::OP_F64##OP: { \
|
||||
*Info = {FABI_F64_F64_F64_PTR, Core::OPINDEX_F64##OP}; \
|
||||
return true; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
// Unary
|
||||
|
||||
@@ -1046,24 +1046,19 @@ DEF_OP(Popcount) {
|
||||
|
||||
if (CTX->HostFeatures.SupportsCSSC) {
|
||||
switch (OpSize) {
|
||||
case IR::OpSize::i8Bit:
|
||||
uxtb(ARMEmitter::Size::i32Bit, Dst, Src);
|
||||
cnt(ARMEmitter::Size::i32Bit, Dst, Dst);
|
||||
break;
|
||||
case IR::OpSize::i16Bit:
|
||||
uxth(ARMEmitter::Size::i32Bit, Dst, Src);
|
||||
cnt(ARMEmitter::Size::i32Bit, Dst, Dst);
|
||||
break;
|
||||
case IR::OpSize::i32Bit:
|
||||
cnt(ARMEmitter::Size::i32Bit, Dst, Src);
|
||||
break;
|
||||
case IR::OpSize::i64Bit:
|
||||
cnt(ARMEmitter::Size::i64Bit, Dst, Src);
|
||||
break;
|
||||
default: LOGMAN_MSG_A_FMT("Unsupported Popcount size: {}", OpSize);
|
||||
case IR::OpSize::i8Bit:
|
||||
uxtb(ARMEmitter::Size::i32Bit, Dst, Src);
|
||||
cnt(ARMEmitter::Size::i32Bit, Dst, Dst);
|
||||
break;
|
||||
case IR::OpSize::i16Bit:
|
||||
uxth(ARMEmitter::Size::i32Bit, Dst, Src);
|
||||
cnt(ARMEmitter::Size::i32Bit, Dst, Dst);
|
||||
break;
|
||||
case IR::OpSize::i32Bit: cnt(ARMEmitter::Size::i32Bit, Dst, Src); break;
|
||||
case IR::OpSize::i64Bit: cnt(ARMEmitter::Size::i64Bit, Dst, Src); break;
|
||||
default: LOGMAN_MSG_A_FMT("Unsupported Popcount size: {}", OpSize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
switch (OpSize) {
|
||||
case IR::OpSize::i8Bit:
|
||||
fmov(ARMEmitter::Size::i32Bit, VTMP1.S(), Src);
|
||||
|
||||
@@ -538,7 +538,8 @@ uint64_t Arm64JITCore::ExitFunctionLink(FEXCore::Core::CpuStateFrame* Frame, FEX
|
||||
} else {
|
||||
{
|
||||
// Guard the LookupCache lock with the code invalidation mutex, to avoid issues with forking
|
||||
auto lk_inval = GuardSignalDeferringSection<std::shared_lock>(static_cast<Context::ContextImpl*>(Thread->CTX)->CodeInvalidationMutex, Thread);
|
||||
auto lk_inval =
|
||||
GuardSignalDeferringSection<std::shared_lock>(static_cast<Context::ContextImpl*>(Thread->CTX)->CodeInvalidationMutex, Thread);
|
||||
HostCode = Thread->LookupCache->FindBlock(GuestRip);
|
||||
}
|
||||
if (!HostCode) {
|
||||
|
||||
@@ -947,7 +947,7 @@ void OpDispatchBuilder::JUMPFARIndirectOp(OpcodeArgs) {
|
||||
// This uses ModRM to determine its location
|
||||
// No way to use this effectively in multiblock
|
||||
Ref Src = MakeSegmentAddress(Op, Op->Dest);
|
||||
AddressMode SrcCS = {.Base = Src, .Offset = 4, .AddrSize = OpSize::i64Bit};
|
||||
AddressMode SrcCS = {.Base = Src, .Offset = 4, .AddrSize = OpSize::i64Bit};
|
||||
auto RIPOffset = _LoadMemAutoTSO(GPRClass, OpSize::i32Bit, Src, OpSize::i8Bit);
|
||||
auto NewSegmentCS = _LoadMemAutoTSO(GPRClass, OpSize::i16Bit, SrcCS, OpSize::i8Bit);
|
||||
|
||||
@@ -968,7 +968,7 @@ void OpDispatchBuilder::CALLFARIndirectOp(OpcodeArgs) {
|
||||
BlockSetRIP = true;
|
||||
|
||||
Ref Src = MakeSegmentAddress(Op, Op->Dest);
|
||||
AddressMode SrcCS = {.Base = Src, .Offset = 4, .AddrSize = OpSize::i64Bit};
|
||||
AddressMode SrcCS = {.Base = Src, .Offset = 4, .AddrSize = OpSize::i64Bit};
|
||||
auto RIPOffset = _LoadMemAutoTSO(GPRClass, OpSize::i32Bit, Src, OpSize::i8Bit);
|
||||
auto NewSegmentCS = _LoadMemAutoTSO(GPRClass, OpSize::i16Bit, SrcCS, OpSize::i8Bit);
|
||||
auto CurrentCS = _LoadContext(OpSize::i16Bit, GPRClass, offsetof(FEXCore::Core::CPUState, cs_idx));
|
||||
@@ -3040,19 +3040,19 @@ void OpDispatchBuilder::SMSWOp(OpcodeArgs) {
|
||||
|
||||
IR::OpSize DstSize {OpSize::iInvalid};
|
||||
Ref Const = Constant((1U << 31) | ///< PG - Paging
|
||||
(0U << 30) | ///< CD - Cache Disable
|
||||
(0U << 29) | ///< NW - Not Writethrough (Legacy, now ignored)
|
||||
///< [28:19] - Reserved
|
||||
(1U << 18) | ///< AM - Alignment Mask
|
||||
///< 17 - Reserved
|
||||
(1U << 16) | ///< WP - Write Protect
|
||||
///< [15:6] - Reserved
|
||||
(1U << 5) | ///< NE - Numeric Error
|
||||
(1U << 4) | ///< ET - Extension Type (Legacy, now reserved and 1)
|
||||
(0U << 3) | ///< TS - Task Switched
|
||||
(0U << 2) | ///< EM - Emulation
|
||||
(1U << 1) | ///< MP - Monitor Coprocessor
|
||||
(1U << 0)); ///< PE - Protection Enabled
|
||||
(0U << 30) | ///< CD - Cache Disable
|
||||
(0U << 29) | ///< NW - Not Writethrough (Legacy, now ignored)
|
||||
///< [28:19] - Reserved
|
||||
(1U << 18) | ///< AM - Alignment Mask
|
||||
///< 17 - Reserved
|
||||
(1U << 16) | ///< WP - Write Protect
|
||||
///< [15:6] - Reserved
|
||||
(1U << 5) | ///< NE - Numeric Error
|
||||
(1U << 4) | ///< ET - Extension Type (Legacy, now reserved and 1)
|
||||
(0U << 3) | ///< TS - Task Switched
|
||||
(0U << 2) | ///< EM - Emulation
|
||||
(1U << 1) | ///< MP - Monitor Coprocessor
|
||||
(1U << 0)); ///< PE - Protection Enabled
|
||||
|
||||
if (Is64BitMode) {
|
||||
DstSize = X86Tables::DecodeFlags::GetOpAddr(Op->Flags, 0) == X86Tables::DecodeFlags::FLAG_OPERAND_SIZE_LAST ? OpSize::i16Bit :
|
||||
@@ -3917,7 +3917,8 @@ void OpDispatchBuilder::CreateJumpBlocks(const fextl::vector<FEXCore::Frontend::
|
||||
}
|
||||
}
|
||||
|
||||
void OpDispatchBuilder::BeginFunction(uint64_t RIP, const fextl::vector<FEXCore::Frontend::Decoder::DecodedBlocks>* Blocks, uint32_t NumInstructions, bool _Is64BitMode, bool MonoBackpatcherBlock) {
|
||||
void OpDispatchBuilder::BeginFunction(uint64_t RIP, const fextl::vector<FEXCore::Frontend::Decoder::DecodedBlocks>* Blocks,
|
||||
uint32_t NumInstructions, bool _Is64BitMode, bool MonoBackpatcherBlock) {
|
||||
Entry = RIP;
|
||||
Is64BitMode = _Is64BitMode;
|
||||
LOGMAN_THROW_A_FMT(Is64BitMode == CTX->Config.Is64BitMode, "Expected operating mode to not change at runtime!");
|
||||
@@ -3994,7 +3995,8 @@ Ref OpDispatchBuilder::GetSegment(uint32_t Flags, uint32_t DefaultPrefix, bool O
|
||||
// With the segment register optimization we store the GDT bases directly in the segment register to remove indexed loads
|
||||
Ref SegmentResult {};
|
||||
switch (Prefix) {
|
||||
[[likely]] case FEXCore::X86Tables::DecodeFlags::FLAG_NO_PREFIX: return nullptr;
|
||||
[[likely]] case FEXCore::X86Tables::DecodeFlags::FLAG_NO_PREFIX:
|
||||
return nullptr;
|
||||
case FEXCore::X86Tables::DecodeFlags::FLAG_ES_PREFIX:
|
||||
SegmentResult = _LoadContext(GPRSize, GPRClass, offsetof(FEXCore::Core::CPUState, es_cached));
|
||||
break;
|
||||
|
||||
@@ -300,7 +300,8 @@ public:
|
||||
return ShouldDump;
|
||||
}
|
||||
|
||||
void BeginFunction(uint64_t RIP, const fextl::vector<FEXCore::Frontend::Decoder::DecodedBlocks>* Blocks, uint32_t NumInstructions, bool Is64BitMode, bool MonoBackpatcherBlock);
|
||||
void BeginFunction(uint64_t RIP, const fextl::vector<FEXCore::Frontend::Decoder::DecodedBlocks>* Blocks, uint32_t NumInstructions,
|
||||
bool Is64BitMode, bool MonoBackpatcherBlock);
|
||||
void Finalize();
|
||||
|
||||
// Dispatch builder functions
|
||||
|
||||
@@ -591,8 +591,7 @@ void OpDispatchBuilder::X87FRSTOR(OpcodeArgs) {
|
||||
// Lower 64bits [63:0]
|
||||
// upper 16 bits [79:64]
|
||||
Ref Reg = _LoadMem(FPRClass, OpSize::i64Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * 7)), OpSize::i8Bit, MEM_OFFSET_SXTX, 1);
|
||||
Ref RegHigh =
|
||||
_LoadMem(FPRClass, OpSize::i16Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * 7) + 8), OpSize::i8Bit, MEM_OFFSET_SXTX, 1);
|
||||
Ref RegHigh = _LoadMem(FPRClass, OpSize::i16Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * 7) + 8), OpSize::i8Bit, MEM_OFFSET_SXTX, 1);
|
||||
Reg = _VInsElement(OpSize::i128Bit, OpSize::i16Bit, 4, 0, Reg, RegHigh);
|
||||
if (ReducedPrecisionMode) {
|
||||
Reg = _F80CVT(OpSize::i64Bit, Reg); // Convert to double precision
|
||||
|
||||
@@ -521,8 +521,8 @@ class NodeIterator;
|
||||
class NodeIterator {
|
||||
public:
|
||||
struct value_type final {
|
||||
OrderedNode *Node;
|
||||
IROp_Header *Header;
|
||||
OrderedNode* Node;
|
||||
IROp_Header* Header;
|
||||
};
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
@@ -315,7 +315,8 @@ void Dump(fextl::stringstream* out, const IRListView* IR) {
|
||||
|
||||
++CurrentIndent;
|
||||
AddIndent();
|
||||
*out << fextl::fmt::format("(%0) IRHeader %{}, #{:#x}, #{}, #{}\n", HeaderOp->Blocks.ID(), HeaderOp->OriginalRIP, HeaderOp->BlockCount, HeaderOp->NumHostInstructions);
|
||||
*out << fextl::fmt::format("(%0) IRHeader %{}, #{:#x}, #{}, #{}\n", HeaderOp->Blocks.ID(), HeaderOp->OriginalRIP, HeaderOp->BlockCount,
|
||||
HeaderOp->NumHostInstructions);
|
||||
|
||||
for (auto [BlockNode, BlockHeader] : IR->GetBlocks()) {
|
||||
{
|
||||
|
||||
@@ -165,7 +165,8 @@ private:
|
||||
size_t SizePlusManagedData = UsedSize + SizeOfLiveRegion;
|
||||
|
||||
auto Res = mprotect(reinterpret_cast<void*>(ReservedRegion->Base), SizePlusManagedData, PROT_READ | PROT_WRITE);
|
||||
LOGMAN_THROW_A_FMT(Res != -1, "Couldn't mprotect region: {} '{}' Likely occurs when running out of memory or Maximum VMAs", errno, strerror(errno));
|
||||
LOGMAN_THROW_A_FMT(Res != -1, "Couldn't mprotect region: {} '{}' Likely occurs when running out of memory or Maximum VMAs", errno,
|
||||
strerror(errno));
|
||||
|
||||
LiveVMARegion* LiveRange = new (reinterpret_cast<void*>(ReservedRegion->Base)) LiveVMARegion();
|
||||
|
||||
@@ -273,8 +274,8 @@ void* OSAllocator_64Bit::Mmap(void* addr, size_t length, int prot, int flags, in
|
||||
again:
|
||||
|
||||
struct RangeResult final {
|
||||
LiveVMARegion *RegionInsertedInto;
|
||||
void *Ptr;
|
||||
LiveVMARegion* RegionInsertedInto;
|
||||
void* Ptr;
|
||||
};
|
||||
|
||||
auto CheckIfRangeFits = [&AllocatedOffset](LiveVMARegion* Region, uint64_t length, int prot, int flags, int fd, off_t offset,
|
||||
|
||||
@@ -146,15 +146,15 @@ struct CPUState {
|
||||
// - Three are reserved for user-space to setup TLS segments in
|
||||
// LDT segments are entirely controlled by userspace.
|
||||
// - Kernel allocates up to 8192 ldt segments.
|
||||
gdt_segment *segment_arrays[2] {};
|
||||
gdt_segment* segment_arrays[2] {};
|
||||
|
||||
static gdt_segment* GetSegmentFromIndex(CPUState &State, uint16_t Selector) {
|
||||
static gdt_segment* GetSegmentFromIndex(CPUState& State, uint16_t Selector) {
|
||||
auto base = State.segment_arrays[(Selector >> 2) & 1];
|
||||
return &base[Selector >> 3];
|
||||
}
|
||||
|
||||
static uint32_t CalculateGDTBase(gdt_segment GDT) {
|
||||
uint32_t Base{};
|
||||
uint32_t Base {};
|
||||
Base |= GDT.Base2 << 24;
|
||||
Base |= GDT.Base1 << 16;
|
||||
Base |= GDT.Base0;
|
||||
@@ -162,19 +162,19 @@ struct CPUState {
|
||||
}
|
||||
|
||||
static uint32_t CalculateGDTLimit(gdt_segment GDT) {
|
||||
uint32_t Limit{};
|
||||
uint32_t Limit {};
|
||||
Limit |= GDT.Limit1 << 16;
|
||||
Limit |= GDT.Limit0;
|
||||
return Limit;
|
||||
}
|
||||
|
||||
static void SetGDTBase(gdt_segment *GDT, uint32_t Base) {
|
||||
static void SetGDTBase(gdt_segment* GDT, uint32_t Base) {
|
||||
GDT->Base0 = Base;
|
||||
GDT->Base1 = Base >> 16;
|
||||
GDT->Base2 = Base >> 24;
|
||||
}
|
||||
|
||||
static void SetGDTLimit(gdt_segment *GDT, uint32_t Limit) {
|
||||
static void SetGDTLimit(gdt_segment* GDT, uint32_t Limit) {
|
||||
GDT->Limit0 = Limit;
|
||||
GDT->Limit1 = Limit >> 16;
|
||||
}
|
||||
|
||||
@@ -2,24 +2,24 @@
|
||||
#pragma once
|
||||
#include <type_traits>
|
||||
|
||||
#define FEX_DEF_ENUM_CLASS_BIN_OP(Enum, Op) \
|
||||
#define FEX_DEF_ENUM_CLASS_BIN_OP(Enum, Op) \
|
||||
inline constexpr Enum operator Op(Enum lhs, Enum rhs) { \
|
||||
using Type = std::underlying_type_t<Enum>; \
|
||||
Type _lhs = static_cast<Type>(lhs); \
|
||||
Type _rhs = static_cast<Type>(rhs); \
|
||||
return static_cast<Enum>(_lhs Op _rhs); \
|
||||
} \
|
||||
using Type = std::underlying_type_t<Enum>; \
|
||||
Type _lhs = static_cast<Type>(lhs); \
|
||||
Type _rhs = static_cast<Type>(rhs); \
|
||||
return static_cast<Enum>(_lhs Op _rhs); \
|
||||
} \
|
||||
inline constexpr uint64_t operator Op(uint64_t lhs, Enum rhs) { \
|
||||
using Type = std::underlying_type_t<Enum>; \
|
||||
Type _rhs = static_cast<Type>(rhs); \
|
||||
return lhs Op _rhs; \
|
||||
using Type = std::underlying_type_t<Enum>; \
|
||||
Type _rhs = static_cast<Type>(rhs); \
|
||||
return lhs Op _rhs; \
|
||||
}
|
||||
|
||||
#define FEX_DEF_ENUM_CLASS_UNARY_OP(Enum, Op) \
|
||||
#define FEX_DEF_ENUM_CLASS_UNARY_OP(Enum, Op) \
|
||||
inline constexpr Enum operator Op(Enum rhs) { \
|
||||
using Type = std::underlying_type_t<Enum>; \
|
||||
Type _rhs = static_cast<Type>(rhs); \
|
||||
return static_cast<Enum>(Op _rhs); \
|
||||
using Type = std::underlying_type_t<Enum>; \
|
||||
Type _rhs = static_cast<Type>(rhs); \
|
||||
return static_cast<Enum>(Op _rhs); \
|
||||
}
|
||||
|
||||
#define FEX_DEF_NUM_OPS(Enum) \
|
||||
|
||||
@@ -681,13 +681,13 @@ int main(int argc, char** argv, char** const envp) {
|
||||
auto GDT = FEXCore::Core::CPUState::GetSegmentFromIndex(Frame->State, Frame->State.cs_idx);
|
||||
FEXCore::Core::CPUState::SetGDTBase(GDT, 0);
|
||||
FEXCore::Core::CPUState::SetGDTLimit(GDT, 0xF'FFFFU);
|
||||
Frame->State.cs_cached = FEXCore::Core::CPUState::CalculateGDTBase(*FEXCore::Core::CPUState::GetSegmentFromIndex(Frame->State, Frame->State.cs_idx));
|
||||
Frame->State.cs_cached =
|
||||
FEXCore::Core::CPUState::CalculateGDTBase(*FEXCore::Core::CPUState::GetSegmentFromIndex(Frame->State, Frame->State.cs_idx));
|
||||
|
||||
if (TestHeaderData->Bitness == 64) {
|
||||
GDT->L = 1; // L = Long Mode = 64-bit
|
||||
GDT->D = 0; // D = Default Operand SIze = Reserved
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
GDT->L = 0; // L = Long Mode = 32-bit
|
||||
GDT->D = 1; // D = Default Operand Size = 32-bit
|
||||
}
|
||||
|
||||
@@ -661,7 +661,7 @@ uint64_t FileManager::Open(const char* pathname, int flags, uint32_t mode) {
|
||||
FEX::HLE::open_how how = {
|
||||
.flags = (uint64_t)flags,
|
||||
.mode = (flags & (O_CREAT | O_TMPFILE)) ? mode & 07777 : 0, // openat2() is stricter about this
|
||||
.resolve = (Path.FD == AT_FDCWD) ? 0u : RESOLVE_IN_ROOT, // AT_FDCWD means it's a thunk and not via RootFS
|
||||
.resolve = (Path.FD == AT_FDCWD) ? 0u : RESOLVE_IN_ROOT, // AT_FDCWD means it's a thunk and not via RootFS
|
||||
};
|
||||
fd = ::syscall(SYSCALL_DEF(openat2), Path.FD, Path.Path, &how, sizeof(how));
|
||||
|
||||
@@ -915,7 +915,7 @@ uint64_t FileManager::Openat([[maybe_unused]] int dirfs, const char* pathname, i
|
||||
FEX::HLE::open_how how = {
|
||||
.flags = (uint64_t)flags,
|
||||
.mode = (flags & (O_CREAT | O_TMPFILE)) ? mode & 07777 : 0, // openat2() is stricter about this,
|
||||
.resolve = (Path.FD == AT_FDCWD) ? 0u : RESOLVE_IN_ROOT, // AT_FDCWD means it's a thunk and not via RootFS
|
||||
.resolve = (Path.FD == AT_FDCWD) ? 0u : RESOLVE_IN_ROOT, // AT_FDCWD means it's a thunk and not via RootFS
|
||||
};
|
||||
fd = ::syscall(SYSCALL_DEF(openat2), Path.FD, Path.Path, &how, sizeof(how));
|
||||
if (fd == -1 && errno == EXDEV) {
|
||||
|
||||
@@ -138,7 +138,7 @@ void SignalDelegator::RestoreFrame_x64(FEXCore::Core::InternalThreadState* Threa
|
||||
|
||||
// Restore segments.
|
||||
// FS and GS are explicitly ignored here, as WRFSGSbase is used instead.
|
||||
Frame->State.cs_idx = (guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_CSGSFS] >> 0) & 0xffff;
|
||||
Frame->State.cs_idx = (guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_CSGSFS] >> 0) & 0xffff;
|
||||
Frame->State.ss_idx = (guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_CSGSFS] >> 48) & 0xffff;
|
||||
|
||||
Frame->State.cs_cached = Frame->State.CalculateGDTBase(*Frame->State.GetSegmentFromIndex(Frame->State, Frame->State.cs_idx));
|
||||
@@ -400,9 +400,7 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr
|
||||
// This stores the CS/GS/FS selectors. It ALSO stores the SS selector in the top 16 bits...For some reason.
|
||||
// Despite the naming, the endianness is swapped from what you'd expect.
|
||||
guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_CSGSFS] =
|
||||
((uint64_t)Frame->State.ss_idx << 48) |
|
||||
((uint64_t)Frame->State.fs_idx << 32) |
|
||||
((uint64_t)Frame->State.gs_idx << 16) |
|
||||
((uint64_t)Frame->State.ss_idx << 48) | ((uint64_t)Frame->State.fs_idx << 32) | ((uint64_t)Frame->State.gs_idx << 16) |
|
||||
((uint64_t)Frame->State.cs_idx << 0);
|
||||
|
||||
// aarch64 and x86_64 siginfo_t matches. We can just copy this over
|
||||
|
||||
@@ -196,26 +196,26 @@ FEX::HLE::ThreadStateObject* ThreadManager::CreateThread(uint64_t InitialRIP, ui
|
||||
memcpy(ThreadStateObject->gdt, InheritThread->gdt, sizeof(ThreadStateObject->gdt));
|
||||
if (InheritThread->ldt_entry_count) {
|
||||
const auto new_ldt_size = InheritThread->ldt_entry_count * FEX::HLE::SyscallHandler::LDT_ENTRY_SIZE;
|
||||
ThreadStateObject->ldt_entries = reinterpret_cast<FEXCore::Core::CPUState::gdt_segment*>(FEXCore::Allocator::mmap(nullptr, new_ldt_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
ThreadStateObject->ldt_entries = reinterpret_cast<FEXCore::Core::CPUState::gdt_segment*>(
|
||||
FEXCore::Allocator::mmap(nullptr, new_ldt_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
|
||||
ThreadStateObject->ldt_entry_count = InheritThread->ldt_entry_count;
|
||||
memcpy(ThreadStateObject->ldt_entries, InheritThread->ldt_entries, new_ldt_size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Without any thread data to inherit, setup the default gdt.
|
||||
// Default code segment indexes match the numbers that the Linux kernel uses.
|
||||
Frame->State.cs_idx = FEXCore::Core::CPUState::DEFAULT_USER_CS << 3;
|
||||
auto GDT = FEXCore::Core::CPUState::GetSegmentFromIndex(Frame->State, Frame->State.cs_idx);
|
||||
FEXCore::Core::CPUState::SetGDTBase(GDT, 0);
|
||||
FEXCore::Core::CPUState::SetGDTLimit(GDT, 0xF'FFFFU);
|
||||
Frame->State.cs_cached = FEXCore::Core::CPUState::CalculateGDTBase(*FEXCore::Core::CPUState::GetSegmentFromIndex(Frame->State, Frame->State.cs_idx));
|
||||
Frame->State.cs_cached =
|
||||
FEXCore::Core::CPUState::CalculateGDTBase(*FEXCore::Core::CPUState::GetSegmentFromIndex(Frame->State, Frame->State.cs_idx));
|
||||
|
||||
if (Is64BitMode()) {
|
||||
GDT->L = 1; // L = Long Mode = 64-bit
|
||||
GDT->D = 0; // D = Default Operand SIze = Reserved
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
GDT->L = 0; // L = Long Mode = 32-bit
|
||||
GDT->D = 1; // D = Default Operand Size = 32-bit
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ struct ThreadStateObject : public FEXCore::Allocator::FEXAllocOperators {
|
||||
// GDT and LDT tracking
|
||||
FEXCore::Core::CPUState::gdt_segment gdt[32] {};
|
||||
size_t ldt_entry_count {};
|
||||
FEXCore::Core::CPUState::gdt_segment *ldt_entries {};
|
||||
FEXCore::Core::CPUState::gdt_segment* ldt_entries {};
|
||||
};
|
||||
|
||||
class ThreadManager final {
|
||||
|
||||
@@ -63,7 +63,9 @@ void x64SyscallHandler::RegisterSyscallHandlers() {
|
||||
constexpr int SYSCALL_GAP_END = 424;
|
||||
|
||||
const SyscallFunctionDefinition InvalidSyscall {
|
||||
.NumArgs = 0, .Flags = FEXCore::IR::SyscallFlags::DEFAULT, .Ptr = reinterpret_cast<void*>(&UnimplementedSyscall),
|
||||
.NumArgs = 0,
|
||||
.Flags = FEXCore::IR::SyscallFlags::DEFAULT,
|
||||
.Ptr = reinterpret_cast<void*>(&UnimplementedSyscall),
|
||||
.HostSyscallNumber = SYSCALL_DEF(MAX),
|
||||
#ifdef DEBUG_STRACE
|
||||
.StraceFmt = "Invalid",
|
||||
|
||||
@@ -41,7 +41,7 @@ uint64_t SyscallHandler::read_ldt(FEXCore::Core::CpuStateFrame* Frame, void* ptr
|
||||
// This means the guest can't ever know the actual size of the LDT.
|
||||
size_t RemainingSize = bytecount - EntriesToCopySize;
|
||||
if (RemainingSize) {
|
||||
void *remaining = alloca(RemainingSize);
|
||||
void* remaining = alloca(RemainingSize);
|
||||
memset(remaining, 0, RemainingSize);
|
||||
if (FaultSafeUserMemAccess::CopyToUser(reinterpret_cast<uint8_t*>(ptr) + EntriesToCopySize, remaining, RemainingSize) != RemainingSize) {
|
||||
return -EFAULT;
|
||||
@@ -105,27 +105,28 @@ uint64_t SyscallHandler::write_ldt(FEXCore::Core::CpuStateFrame* Frame, void* pt
|
||||
if (ldt_info.contents == MODIFY_LDT_CONTENTS_CONFORMING) {
|
||||
// Conforming is mostly ignored.
|
||||
// Legacy doesn't support it at all. Good.
|
||||
if (legacy) return -EINVAL;
|
||||
if (legacy) {
|
||||
return -EINVAL;
|
||||
}
|
||||
// Non-legacy ignores if only if the `seg_not_present` is set.
|
||||
if (ldt_info.seg_not_present == 0) return -EINVAL;
|
||||
if (ldt_info.seg_not_present == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
auto is_empty = [](user_desc_x64 ldt_info, bool legacy) {
|
||||
// Legacy empty is trivial.
|
||||
const bool legacy_empty = legacy && ldt_info.base_addr == 0 && ldt_info.limit == 0;
|
||||
if (legacy_empty) return true;
|
||||
if (legacy_empty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Non-legacy is a bit more work.
|
||||
return ldt_info.base_addr == 0 &&
|
||||
ldt_info.limit == 0 &&
|
||||
ldt_info.contents == 0 &&
|
||||
ldt_info.read_exec_only == 1 &&
|
||||
ldt_info.limit_in_pages == 0 &&
|
||||
ldt_info.seg_not_present == 1 &&
|
||||
ldt_info.useable == 0;
|
||||
return ldt_info.base_addr == 0 && ldt_info.limit == 0 && ldt_info.contents == 0 && ldt_info.read_exec_only == 1 &&
|
||||
ldt_info.limit_in_pages == 0 && ldt_info.seg_not_present == 1 && ldt_info.useable == 0;
|
||||
};
|
||||
|
||||
auto fill_ldt = [](FEXCore::Core::CPUState::gdt_segment &segment, user_desc_x64 ldt_info) {
|
||||
auto fill_ldt = [](FEXCore::Core::CPUState::gdt_segment& segment, user_desc_x64 ldt_info) {
|
||||
FEXCore::Core::CPUState::SetGDTBase(&segment, ldt_info.base_addr);
|
||||
FEXCore::Core::CPUState::SetGDTLimit(&segment, ldt_info.limit);
|
||||
|
||||
@@ -137,10 +138,9 @@ uint64_t SyscallHandler::write_ldt(FEXCore::Core::CpuStateFrame* Frame, void* pt
|
||||
// - bit[11]
|
||||
// - 1 - Code
|
||||
// - 0 - Data
|
||||
segment.Type =
|
||||
((ldt_info.read_exec_only ^ 1) << 1) | // Readable
|
||||
(ldt_info.contents << 2) | // Code/Data+Conforming
|
||||
1; // Accessed
|
||||
segment.Type = ((ldt_info.read_exec_only ^ 1) << 1) | // Readable
|
||||
(ldt_info.contents << 2) | // Code/Data+Conforming
|
||||
1; // Accessed
|
||||
// S: bit [12]
|
||||
// - 0 (System descriptor)
|
||||
// - 1 (User descriptor)
|
||||
@@ -165,8 +165,7 @@ uint64_t SyscallHandler::write_ldt(FEXCore::Core::CpuStateFrame* Frame, void* pt
|
||||
if (is_empty(ldt_info, legacy)) {
|
||||
// If the ldt_info is considered empty then this is a zeroing operation.
|
||||
// Just use the zero ldt.
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// This syscall only allows installing 32-bit segments. If `seg_32bit` isn't set then
|
||||
// it assumes a 16-bit segment!
|
||||
if (!ldt_info.seg_32bit) {
|
||||
@@ -188,7 +187,8 @@ uint64_t SyscallHandler::write_ldt(FEXCore::Core::CpuStateFrame* Frame, void* pt
|
||||
const auto new_ldt_count = std::max<size_t>(old_ldt_entries, ldt_info.entry_number + 1);
|
||||
const auto new_ldt_size = new_ldt_count * LDT_ENTRY_SIZE;
|
||||
|
||||
const auto new_ldt_entries = reinterpret_cast<FEXCore::Core::CPUState::gdt_segment*>(FEXCore::Allocator::mmap(nullptr, new_ldt_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
const auto new_ldt_entries = reinterpret_cast<FEXCore::Core::CPUState::gdt_segment*>(
|
||||
FEXCore::Allocator::mmap(nullptr, new_ldt_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
|
||||
if (old_ldt) {
|
||||
// Copy old entries if they existed.
|
||||
@@ -212,7 +212,7 @@ uint64_t SyscallHandler::write_ldt(FEXCore::Core::CpuStateFrame* Frame, void* pt
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace FEX::HLE
|
||||
|
||||
namespace FEX::HLE::x64 {
|
||||
uint64_t SetThreadArea(FEXCore::Core::CpuStateFrame* Frame, void* tls) {
|
||||
|
||||
@@ -28,7 +28,7 @@ fextl::string GetSectionFilePath(uint64_t Address) {
|
||||
std::array<WCHAR, PATH_MAX> PathW;
|
||||
} Buffer;
|
||||
|
||||
if (NtQueryVirtualMemory(GetCurrentProcess(), reinterpret_cast<void *>(Address), MemoryMappedFilenameInformation, &Buffer, sizeof(Buffer), NULL)) {
|
||||
if (NtQueryVirtualMemory(GetCurrentProcess(), reinterpret_cast<void*>(Address), MemoryMappedFilenameInformation, &Buffer, sizeof(Buffer), NULL)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ void InitBasicInfo() {
|
||||
__attribute__((used, section(".CRT$FEXH"))) void (*_InitBasicInfo)(void) = InitBasicInfo;
|
||||
|
||||
MEM_ADDRESS_REQUIREMENTS MakeWOW64AddressReqs() {
|
||||
MEM_ADDRESS_REQUIREMENTS Reqs{};
|
||||
MEM_ADDRESS_REQUIREMENTS Reqs {};
|
||||
Reqs.LowestStartingAddress = reinterpret_cast<void*>(BasicInfo.HighestUserAddress & ~(BasicInfo.AllocationGranularity - 1));
|
||||
return Reqs;
|
||||
}
|
||||
|
||||
@@ -478,9 +478,8 @@ typedef struct _MEMORY_FEX_STATS_SHM_INFORMATION {
|
||||
DWORD max_size;
|
||||
} MEMORY_FEX_STATS_SHM_INFORMATION, *PMEMORY_FEX_STATS_SHM_INFORMATION;
|
||||
|
||||
typedef struct _MEMORY_SECTION_NAME
|
||||
{
|
||||
UNICODE_STRING SectionFileName;
|
||||
typedef struct _MEMORY_SECTION_NAME {
|
||||
UNICODE_STRING SectionFileName;
|
||||
} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
|
||||
|
||||
NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...);
|
||||
|
||||
Reference in new issue
Block a user