Coverage Report

Created: 2025-12-31 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/x86-0.47.0/src/bits32/eflags.rs
Line
Count
Source
1
//! Processor state stored in the EFLAGS register.
2
3
use bitflags::*;
4
5
use crate::Ring;
6
use core::arch::asm;
7
8
bitflags! {
9
    /// The EFLAGS register.
10
    pub struct EFlags: u32 {
11
        /// ID Flag (ID)
12
        const FLAGS_ID = 1 << 21;
13
        /// Virtual Interrupt Pending (VIP)
14
        const FLAGS_VIP = 1 << 20;
15
        /// Virtual Interrupt Flag (VIF)
16
        const FLAGS_VIF = 1 << 19;
17
        /// Alignment Check (AC)
18
        const FLAGS_AC = 1 << 18;
19
        /// Virtual-8086 Mode (VM)
20
        const FLAGS_VM = 1 << 17;
21
        /// Resume Flag (RF)
22
        const FLAGS_RF = 1 << 16;
23
        /// Nested Task (NT)
24
        const FLAGS_NT = 1 << 14;
25
        /// I/O Privilege Level (IOPL) 0
26
        const FLAGS_IOPL0 = 0b00 << 12;
27
        /// I/O Privilege Level (IOPL) 1
28
        const FLAGS_IOPL1 = 0b01 << 12;
29
        /// I/O Privilege Level (IOPL) 2
30
        const FLAGS_IOPL2 = 0b10 << 12;
31
        /// I/O Privilege Level (IOPL) 3
32
        const FLAGS_IOPL3 = 0b11 << 12;
33
        /// Overflow Flag (OF)
34
        const FLAGS_OF = 1 << 11;
35
        /// Direction Flag (DF)
36
        const FLAGS_DF = 1 << 10;
37
        /// Interrupt Enable Flag (IF)
38
        const FLAGS_IF = 1 << 9;
39
        /// Trap Flag (TF)
40
        const FLAGS_TF = 1 << 8;
41
        /// Sign Flag (SF)
42
        const FLAGS_SF = 1 << 7;
43
        /// Zero Flag (ZF)
44
        const FLAGS_ZF = 1 << 6;
45
        /// Auxiliary Carry Flag (AF)
46
        const FLAGS_AF = 1 << 4;
47
        /// Parity Flag (PF)
48
        const FLAGS_PF = 1 << 2;
49
        /// Bit 1 is always 1.
50
        const FLAGS_A1 = 1 << 1;
51
        /// Carry Flag (CF)
52
        const FLAGS_CF = 1 << 0;
53
    }
54
}
55
56
impl EFlags {
57
    /// Creates a new Flags entry. Ensures bit 1 is set.
58
0
    pub const fn new() -> EFlags {
59
0
        EFlags::FLAGS_A1
60
0
    }
61
62
    /// Creates a new Flags with the given I/O privilege level.
63
0
    pub const fn from_priv(iopl: Ring) -> EFlags {
64
0
        EFlags {
65
0
            bits: (iopl as u32) << 12,
66
0
        }
67
0
    }
68
}
69
70
#[cfg(target_arch = "x86")]
71
#[inline(always)]
72
pub unsafe fn read() -> EFlags {
73
    let r: u32;
74
    asm!("pushfl; popl {0}", out(reg) r, options(att_syntax));
75
    EFlags::from_bits_truncate(r)
76
}
77
78
#[cfg(target_arch = "x86")]
79
#[inline(always)]
80
pub unsafe fn set(val: EFlags) {
81
    asm!("pushl {0}; popfl", in(reg) val.bits(), options(att_syntax));
82
}
83
84
/// Clears the AC flag bit in EFLAGS register.
85
///
86
/// This disables any alignment checking of user-mode data accesses.
87
/// If the SMAP bit is set in the CR4 register, this disallows
88
/// explicit supervisor-mode data accesses to user-mode pages.
89
///
90
/// # Safety
91
///
92
/// This instruction is only valid in Ring 0 and requires
93
/// that the CPU supports the instruction (check CPUID).
94
#[inline(always)]
95
0
pub unsafe fn clac() {
96
0
    asm!("clac");
97
0
}
98
99
/// Sets the AC flag bit in EFLAGS register.
100
///
101
/// This may enable alignment checking of user-mode data accesses.
102
/// This allows explicit supervisor-mode data accesses to user-mode
103
/// pages even if the SMAP bit is set in the CR4 register.
104
///
105
/// # Safety
106
///
107
/// This instruction is only valid in Ring 0 and requires
108
/// that the CPU supports the instruction (check CPUID).
109
#[inline(always)]
110
0
pub unsafe fn stac() {
111
0
    asm!("stac");
112
0
}