diff --git a/Cargo.toml b/Cargo.toml index 3e72bbba..be726003 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ rust-version = "1.57" # Needed to support panic! in const fns [dependencies] bit_field = "0.10.1" -bitflags = "1.3.2" +bitflags = "2.3.2" volatile = "0.4.4" rustversion = "1.0.5" diff --git a/src/registers/control.rs b/src/registers/control.rs index 5334e049..a37dcbf9 100644 --- a/src/registers/control.rs +++ b/src/registers/control.rs @@ -10,6 +10,7 @@ pub struct Cr0; bitflags! { /// Configuration flags of the [`Cr0`] register. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct Cr0Flags: u64 { /// Enables protected mode. const PROTECTED_MODE_ENABLE = 1; @@ -50,6 +51,14 @@ bitflags! { } } +impl Cr0Flags { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + /// Contains the Page Fault Linear Address (PFLA). /// /// When a page fault occurs, the CPU sets this register to the faulting virtual address. @@ -64,6 +73,7 @@ bitflags! { /// Controls cache settings for the highest-level page table. /// /// Unused if paging is disabled or if [`PCID`](Cr4Flags::PCID) is enabled. + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct Cr3Flags: u64 { /// Use a writethrough cache policy for the table (otherwise a writeback policy is used). const PAGE_LEVEL_WRITETHROUGH = 1 << 3; @@ -72,6 +82,14 @@ bitflags! { } } +impl Cr3Flags { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + /// Contains various control flags that enable architectural extensions, and /// indicate support for specific processor capabilities. #[derive(Debug)] @@ -80,6 +98,7 @@ pub struct Cr4; bitflags! { /// Configuration flags of the [`Cr4`] register. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct Cr4Flags: u64 { /// Enables hardware-supported performance enhancements for software running in /// virtual-8086 mode. @@ -159,6 +178,14 @@ bitflags! { } } +impl Cr4Flags { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + #[cfg(feature = "instructions")] mod x86_64 { use super::*; diff --git a/src/registers/debug.rs b/src/registers/debug.rs index b905324f..f7011974 100644 --- a/src/registers/debug.rs +++ b/src/registers/debug.rs @@ -110,6 +110,7 @@ pub struct Dr6; bitflags! { /// Debug condition flags of the [`Dr6`] register. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct Dr6Flags: u64 { /// Breakpoint condition 0 was detected. const TRAP0 = 1; @@ -124,7 +125,7 @@ bitflags! { const TRAP3 = 1 << 3; /// Breakpoint condition was detected. - const TRAP = Self::TRAP0.bits | Self::TRAP1.bits | Self::TRAP2.bits | Self::TRAP3.bits; + const TRAP = Self::TRAP0.bits() | Self::TRAP1.bits() | Self::TRAP2.bits() | Self::TRAP3.bits(); /// Next instruction accesses one of the debug registers. /// @@ -159,11 +160,18 @@ impl Dr6Flags { DebugAddressRegisterNumber::Dr3 => Self::TRAP3, } } + + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } } bitflags! { /// Debug control flags of the [`Dr7`] register. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct Dr7Flags: u64 { /// Breakpoint 0 is enabled for the current task. const LOCAL_BREAKPOINT_0_ENABLE = 1; @@ -231,6 +239,12 @@ impl Dr7Flags { DebugAddressRegisterNumber::Dr3 => Self::GLOBAL_BREAKPOINT_3_ENABLE, } } + + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } } /// The condition for a hardware breakpoint. diff --git a/src/registers/model_specific.rs b/src/registers/model_specific.rs index aa2e1e04..529ca9d6 100644 --- a/src/registers/model_specific.rs +++ b/src/registers/model_specific.rs @@ -111,6 +111,7 @@ impl SCet { bitflags! { /// Flags of the Extended Feature Enable Register. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct EferFlags: u64 { /// Enables the `syscall` and `sysret` instructions. const SYSTEM_CALL_EXTENSIONS = 1; @@ -131,10 +132,19 @@ bitflags! { } } +impl EferFlags { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + bitflags! { /// Flags stored in IA32_U_CET and IA32_S_CET (Table-2-2 in Intel SDM Volume /// 4). The Intel SDM-equivalent names are described in parentheses. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct CetFlags: u64 { /// Enable shadow stack (SH_STK_EN) const SS_ENABLE = 1 << 0; @@ -155,6 +165,14 @@ bitflags! { } } +impl CetFlags { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + #[cfg(feature = "instructions")] mod x86_64 { use super::*; diff --git a/src/registers/mxcsr.rs b/src/registers/mxcsr.rs index ecb13a93..55e05cc5 100644 --- a/src/registers/mxcsr.rs +++ b/src/registers/mxcsr.rs @@ -8,6 +8,7 @@ use bitflags::bitflags; bitflags! { /// MXCSR register. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct MxCsr: u32 { /// Invalid operation const INVALID_OPERATION = 1 << 0; @@ -59,6 +60,14 @@ impl Default for MxCsr { } } +impl MxCsr { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u32) -> Self { + Self::from_bits_retain(bits) + } +} + #[cfg(feature = "instructions")] mod x86_64 { use super::*; diff --git a/src/registers/rflags.rs b/src/registers/rflags.rs index 2f2c931a..be0624f8 100644 --- a/src/registers/rflags.rs +++ b/src/registers/rflags.rs @@ -8,6 +8,7 @@ use bitflags::bitflags; bitflags! { /// The RFLAGS register. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct RFlags: u64 { /// Processor feature identification flag. /// @@ -63,6 +64,14 @@ bitflags! { } } +impl RFlags { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + #[cfg(feature = "instructions")] mod x86_64 { use super::*; diff --git a/src/registers/xcontrol.rs b/src/registers/xcontrol.rs index ffad7569..2ab9924f 100644 --- a/src/registers/xcontrol.rs +++ b/src/registers/xcontrol.rs @@ -11,6 +11,7 @@ bitflags! { /// For MPX, [`BNDREG`](XCr0Flags::BNDREG) and [`BNDCSR`](XCr0Flags::BNDCSR) must be set/unset simultaneously. /// For AVX-512, [`OPMASK`](XCr0Flags::OPMASK), [`ZMM_HI256`](XCr0Flags::ZMM_HI256), and [`HI16_ZMM`](XCr0Flags::HI16_ZMM) must be set/unset simultaneously. #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct XCr0Flags: u64 { /// Enables using the x87 FPU state /// with `XSAVE`/`XRSTOR`. @@ -52,6 +53,14 @@ bitflags! { } } +impl XCr0Flags { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + #[cfg(feature = "instructions")] mod x86_64 { use super::*; diff --git a/src/structures/gdt.rs b/src/structures/gdt.rs index 7e6c66a5..4945b8fb 100644 --- a/src/structures/gdt.rs +++ b/src/structures/gdt.rs @@ -187,6 +187,7 @@ pub enum Descriptor { bitflags! { /// Flags for a GDT descriptor. Not all flags are valid for all descriptor types. + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct DescriptorFlags: u64 { /// Set by the processor if this segment has been accessed. Only cleared by software. /// _Setting_ this bit in software prevents GDT writes on first use. @@ -268,6 +269,12 @@ impl DescriptorFlags { /// A 64-bit user code segment pub const USER_CODE64: Self = Self::from_bits_truncate(Self::KERNEL_CODE64.bits() | Self::DPL_RING_3.bits()); + + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } } impl Descriptor { diff --git a/src/structures/idt.rs b/src/structures/idt.rs index fe0d467a..d88e0c0c 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -968,6 +968,7 @@ bitflags! { /// * AMD Volume 2: 8.4.2 /// * Intel Volume 3A: 4.7 #[repr(transparent)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct PageFaultErrorCode: u64 { /// If this flag is set, the page fault was caused by a page-protection violation, /// else the page fault was caused by a not-present page. @@ -1008,6 +1009,14 @@ bitflags! { } } +impl PageFaultErrorCode { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + /// Describes an error code referencing a segment selector. #[derive(Clone, Copy, PartialEq, Eq, Hash)] #[repr(transparent)] diff --git a/src/structures/paging/page_table.rs b/src/structures/paging/page_table.rs index b9edbce1..6211f559 100644 --- a/src/structures/paging/page_table.rs +++ b/src/structures/paging/page_table.rs @@ -106,6 +106,7 @@ impl fmt::Debug for PageTableEntry { bitflags! { /// Possible flags for a page table entry. + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct PageTableFlags: u64 { /// Specifies whether the mapped frame or page table is loaded in memory. const PRESENT = 1; @@ -168,6 +169,14 @@ bitflags! { } } +impl PageTableFlags { + #[deprecated = "use the safe `from_bits_retain` method instead"] + /// Convert from underlying bit representation, preserving all bits (even those not corresponding to a defined flag). + pub const unsafe fn from_bits_unchecked(bits: u64) -> Self { + Self::from_bits_retain(bits) + } +} + /// The number of entries in a page table. const ENTRY_COUNT: usize = 512;